diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 5090d44f8..0e26acd38 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -29,6 +29,7 @@ set(MP1_WORLD_SOURCES CRidley.hpp CRidley.cpp CPuddleToadGamma.hpp CPuddleToadGamma.cpp CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp - CSpankWeed.hpp CSpankWeed.cpp) + CSpankWeed.hpp CSpankWeed.cpp + CPuddleSpore.hpp CPuddleSpore.cpp) runtime_add_list(World MP1_WORLD_SOURCES) diff --git a/Runtime/MP1/World/CPuddleSpore.cpp b/Runtime/MP1/World/CPuddleSpore.cpp new file mode 100644 index 000000000..746c42620 --- /dev/null +++ b/Runtime/MP1/World/CPuddleSpore.cpp @@ -0,0 +1,68 @@ +#include "CPuddleSpore.hpp" +#include "World/CPatternedInfo.hpp" +#include "CStateManager.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "TCastTo.hpp" + +namespace urde::MP1 { +const std::string_view CPuddleSpore::kEyeLocators[16] = { + "Glow_1_LCTR"sv, + "Glow_2_LCTR"sv, + "Glow_3_LCTR"sv, + "Glow_4_LCTR"sv, + "Glow_5_LCTR"sv, + "Glow_6_LCTR"sv, + "Glow_7_LCTR"sv, + "Glow_8_LCTR"sv, + "Glow_9_LCTR"sv, + "Glow_10_LCTR"sv, + "Glow_11_LCTR"sv, + "Glow_12_LCTR"sv, + "Glow_13_LCTR"sv, + "Glow_14_LCTR"sv, + "Glow_15_LCTR"sv, + "Glow_16_LCTR"sv, +}; +CPuddleSpore::CPuddleSpore(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, + EColliderType colType, CAssetId glowFx, float f1, float f2, float f3, float f4, float f5, + const CActorParameters& actParms, CAssetId weapon, const CDamageInfo& dInfo) +: CPatterned(ECharacter::PuddleSpore, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer, + colType, EBodyType::Restricted, actParms, EKnockBackVariant::Medium) +, x570_(f1) +, x574_(f2) +, x578_(f3) +, x57c_(f4) +, x580_(f5) +, x584_bodyOrigin(pInfo.GetBodyOrigin()) +, x590_halfExtent(pInfo.GetHalfExtent()) +, x594_height(pInfo.GetHeight()) +, x5a0_(CalculateBoundingBox(), GetMaterialList()) +, x5ec_projectileInfo(weapon, dInfo) +, x5d0_(g_SimplePool->GetObj({SBIG('PART'), glowFx})) +, x614_24(false) +, x614_25(false) { + x5dc_.reserve(kEyeCount); + for (u32 i = 0; i < kEyeCount; ++i) + x5dc_.emplace_back(new CElementGen(x5d0_)); + const_cast*>(&x5ec_projectileInfo.Token())->Lock(); + x460_knockBackController.SetAutoResetImpulse(false); +} + +zeus::CAABox CPuddleSpore::CalculateBoundingBox() const { + return {((zeus::CVector3f(-x590_halfExtent, -x590_halfExtent, x598_) + x584_bodyOrigin) * 0.5f) + + (GetBaseBoundingBox().min * 0.95f), + ((zeus::CVector3f(x590_halfExtent, x590_halfExtent, (x594_height * x59c_) + x598_) + x584_bodyOrigin) * 0.5f) + + (GetBaseBoundingBox().max * 0.95f)}; +} + +void CPuddleSpore::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + if (msg == EScriptObjectMessage::InvulnDamage) + return; + if (msg == EScriptObjectMessage::Registered) + x450_bodyController->Activate(mgr); + + CPatterned::AcceptScriptMsg(msg, uid, mgr); +} +} \ No newline at end of file diff --git a/Runtime/MP1/World/CPuddleSpore.hpp b/Runtime/MP1/World/CPuddleSpore.hpp new file mode 100644 index 000000000..00fd5c667 --- /dev/null +++ b/Runtime/MP1/World/CPuddleSpore.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "World/CPatterned.hpp" +#include "Weapon/CProjectileInfo.hpp" +#include "Particle/CElementGen.hpp" + +namespace urde::MP1 { +class CPuddleSpore : public CPatterned { + static constexpr u32 kEyeCount = 16; + static const std::string_view kEyeLocators[16]; + float x568_ = 0.f; + float x56c_ = 0.f; + float x570_; + float x574_; + float x578_; + float x57c_; + float x580_; + zeus::CVector3f x584_bodyOrigin; + float x590_halfExtent; + float x594_height; + float x598_ = 0.f; + float x59c_ = 1.f; + CCollidableAABox x5a0_; + u32 x5c8_ = 0; + u32 x5cc_ = 0; + TToken x5d0_; + std::vector> x5dc_; // originally a vector of CElementGen + CProjectileInfo x5ec_projectileInfo; + bool x614_24 : 1; + bool x614_25 : 1; +public: + DEFINE_PATTERNED(PuddleSpore) + + CPuddleSpore(TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&, + CModelData&&, const CPatternedInfo&, EColliderType, CAssetId, float, float, float, float, float, + const CActorParameters&, CAssetId, const CDamageInfo&); + + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr); + zeus::CAABox CalculateBoundingBox() const; + CProjectileInfo* GetProjectileInfo() { return &x5ec_projectileInfo; } +}; +} \ No newline at end of file diff --git a/Runtime/World/CPatternedInfo.hpp b/Runtime/World/CPatternedInfo.hpp index c4308470b..67536d236 100644 --- a/Runtime/World/CPatternedInfo.hpp +++ b/Runtime/World/CPatternedInfo.hpp @@ -61,6 +61,7 @@ public: float GetHalfExtent() const { return xc4_halfExtent; } float GetHeight() const { return xc8_height; } const CHealthInfo& GetHealthInfo() const { return x54_healthInfo; } + zeus::CVector3f GetBodyOrigin() const { return xcc_bodyOrigin; } CAnimationParameters& GetAnimationParameters() { return xec_animParams; } const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; } u32 GetPathfindingIndex() const { return x10c_pathfindingIndex; } diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index be9dbcde0..da4b61ee4 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -48,6 +48,7 @@ #include "CScriptEffect.hpp" #include "CScriptGenerator.hpp" #include "CScriptGrapplePoint.hpp" +#include "MP1/World/CPuddleSpore.hpp" #include "CScriptHUDMemo.hpp" #include "CScriptMazeNode.hpp" #include "CScriptMemoryRelay.hpp" @@ -1605,8 +1606,25 @@ CEntity* ScriptLoader::LoadPuddleSpore(CStateManager& mgr, CInputStream& in, int return nullptr; CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + bool b1 = in.readBool(); + CAssetId w1(in); + float f1 = in.readFloatBig(); + float f2 = in.readFloatBig(); + float f3 = in.readFloatBig(); + float f4 = in.readFloatBig(); + float f5 = in.readFloatBig(); + CAssetId w2(in); + CDamageInfo dInfo(in); - return nullptr; + const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); + if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS')) + return nullptr; + + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); + return new MP1::CPuddleSpore(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, + CPatterned::EColliderType(b1), w1, f1, f2, f3, f4, f5, actParms, w2, dInfo); } CEntity* ScriptLoader::LoadDebugCameraWaypoint(CStateManager& mgr, CInputStream& in, int propCount,