diff --git a/asm/MetroidPrime/Enemies/CMetaree.s b/asm/MetroidPrime/Enemies/CMetaree.s index 343abd52..98871cf5 100644 --- a/asm/MetroidPrime/Enemies/CMetaree.s +++ b/asm/MetroidPrime/Enemies/CMetaree.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E2878 -lbl_803E2878: +.global __vt__8CMetaree +__vt__8CMetaree: # ROM: 0x3DF878 .4byte 0 .4byte 0 @@ -218,9 +218,9 @@ __dt__8CMetareeFv: /* 8014E118 0014B078 93 C1 00 08 */ stw r30, 8(r1) /* 8014E11C 0014B07C 7C 7E 1B 79 */ or. r30, r3, r3 /* 8014E120 0014B080 41 82 00 28 */ beq lbl_8014E148 -/* 8014E124 0014B084 3C A0 80 3E */ lis r5, lbl_803E2878@ha +/* 8014E124 0014B084 3C A0 80 3E */ lis r5, __vt__8CMetaree@ha /* 8014E128 0014B088 38 80 00 00 */ li r4, 0 -/* 8014E12C 0014B08C 38 05 28 78 */ addi r0, r5, lbl_803E2878@l +/* 8014E12C 0014B08C 38 05 28 78 */ addi r0, r5, __vt__8CMetaree@l /* 8014E130 0014B090 90 1E 00 00 */ stw r0, 0(r30) /* 8014E134 0014B094 4B F2 94 3D */ bl __dt__10CPatternedFv /* 8014E138 0014B098 7F E0 07 35 */ extsh. r0, r31 @@ -1140,9 +1140,9 @@ Accept__8CMetareeFR8IVisitor: /* 8014EE24 0014BD84 38 A1 00 20 */ addi r5, r1, 0x20 /* 8014EE28 0014BD88 38 80 00 12 */ li r4, 0x12 /* 8014EE2C 0014BD8C 4B F2 E6 25 */ bl "__ct__10CPatternedFQ210CPatterned10ECharacter9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>Q210CPatterned11EFlavorTypeRC11CEntityInfoRC12CTransform4fRC10CModelDataRC14CPatternedInfoQ210CPatterned13EMovementTypeQ210CPatterned13EColliderType9EBodyTypeRC16CActorParameters17EKnockBackVariant" -/* 8014EE30 0014BD90 3C 80 80 3E */ lis r4, lbl_803E2878@ha +/* 8014EE30 0014BD90 3C 80 80 3E */ lis r4, __vt__8CMetaree@ha /* 8014EE34 0014BD94 3C 60 80 5A */ lis r3, sZeroVector__9CVector3f@ha -/* 8014EE38 0014BD98 38 04 28 78 */ addi r0, r4, lbl_803E2878@l +/* 8014EE38 0014BD98 38 04 28 78 */ addi r0, r4, __vt__8CMetaree@l /* 8014EE3C 0014BD9C C0 02 9D 8C */ lfs f0, lbl_805ABAAC@sda21(r2) /* 8014EE40 0014BDA0 90 1F 00 00 */ stw r0, 0(r31) /* 8014EE44 0014BDA4 38 A3 66 A0 */ addi r5, r3, sZeroVector__9CVector3f@l diff --git a/configure.py b/configure.py index 12a158ca..58c9faa5 100755 --- a/configure.py +++ b/configure.py @@ -215,7 +215,7 @@ LIBS = [ ["MetroidPrime/ScriptObjects/CScriptDistanceFog", False], "MetroidPrime/BodyState/CBSProjectileAttack", "MetroidPrime/Weapons/CPowerBomb", - "MetroidPrime/Enemies/CMetaree", + ["MetroidPrime/Enemies/CMetaree", False], ["MetroidPrime/ScriptObjects/CScriptDockAreaChange", False], ["MetroidPrime/ScriptObjects/CScriptSpecialFunction", False], "MetroidPrime/ScriptObjects/CScriptActorRotate", @@ -354,7 +354,7 @@ LIBS = [ "MetroidPrime/Enemies/CAtomicBeta", "MetroidPrime/Weapons/CElectricBeamProjectile", "MetroidPrime/Enemies/CRidley", - "MetroidPrime/Enemies/CPuffer", + ["MetroidPrime/Enemies/CPuffer", False], ["MetroidPrime/ScriptObjects/CFire", False], "MetroidPrime/CPauseScreenBlur", "MetroidPrime/Enemies/CTryclops", diff --git a/include/Collision/CCollisionInfoList.hpp b/include/Collision/CCollisionInfoList.hpp index 98ee7d9a..8b0d7341 100644 --- a/include/Collision/CCollisionInfoList.hpp +++ b/include/Collision/CCollisionInfoList.hpp @@ -20,6 +20,7 @@ public: else x0_list.push_back(info.GetSwapped()); } + int GetCount() const { return x0_list.size(); } iterator End() { return x0_list.end(); } const_iterator End() const { return x0_list.end(); } diff --git a/include/MetroidPrime/BodyState/CBodyController.hpp b/include/MetroidPrime/BodyState/CBodyController.hpp index a01bac2a..0b4efaa5 100644 --- a/include/MetroidPrime/BodyState/CBodyController.hpp +++ b/include/MetroidPrime/BodyState/CBodyController.hpp @@ -28,9 +28,12 @@ public: void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r); bool HasIceBreakoutState(); void Activate(CStateManager& mgr); + void SetLocomotionType(pas::ELocomotionType type); + float GetPercentageFrozen() const; void SetFallState(pas::EFallState state); // { x2f0_fallState = state; } pas::EFallState GetFallState() const; // { return x2f0_fallState; } + const CBodyStateInfo& GetBodyStateInfo() const { return x2a4_bodyStateInfo; } int GetCurrentAnimId() const { return x2f8_curAnim; } pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; } bool IsAnimationOver() const { return x300_24_animationOver; } diff --git a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp index faba1893..00daa633 100644 --- a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp +++ b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp @@ -49,21 +49,22 @@ public: : CBodyStateCmd(kBSC_Generate) , x8_type(type) , xc_targetPos(vec) + , x18_animId(-1) , x1c_24_targetTransform(targetTransform) , x1c_25_overrideAnim(overrideAnim) {} pas::EGenerateType GetGenerateType() const { return x8_type; } const CVector3f& GetExitTargetPos() const { return xc_targetPos; } - bool HasExitTargetPos() const { return x1c_24_targetTransform; } int GetSpecialAnimId() const { return x18_animId; } + bool HasExitTargetPos() const { return x1c_24_targetTransform; } bool UseSpecialAnimId() const { return x1c_25_overrideAnim; } private: pas::EGenerateType x8_type; CVector3f xc_targetPos; int x18_animId; - bool x1c_24_targetTransform : 1; - bool x1c_25_overrideAnim : 1; + uint x1c_24_targetTransform : 1; + uint x1c_25_overrideAnim : 1; }; // @@ -390,8 +391,20 @@ class CBodyStateCmdMgr { public: void ClearLocomotionCmds(); void DeliverCmd(const CBCLocomotionCmd& cmd); - CBodyStateCmd* GetCmd(EBodyStateCmd cmd); + void DeliverCmd(EBodyStateCmd cmd); + void DeliverCmd(const CBCGenerateCmd& cmd) { + DeliverCmd(kBSC_Generate); + x18c_generate = cmd; + } + void DeliverCmd(const CBCKnockDownCmd& cmd) { + DeliverCmd(kBSC_KnockDown); + xdc_knockDown = cmd; + } + + void DeliverTargetVector(const CVector3f& t) { x18_target = t; } + + CBodyStateCmd* GetCmd(EBodyStateCmd cmd); const CVector3f& GetMoveVector() const { return x0_move; } const CVector3f& GetTargetVector() const { return x18_target; } diff --git a/include/MetroidPrime/Enemies/CMetaree.hpp b/include/MetroidPrime/Enemies/CMetaree.hpp new file mode 100644 index 00000000..7ac46d41 --- /dev/null +++ b/include/MetroidPrime/Enemies/CMetaree.hpp @@ -0,0 +1,64 @@ +#ifndef _CMETAREE +#define _CMETAREE + +#include "types.h" + +#include "MetroidPrime/CDamageInfo.hpp" +#include "MetroidPrime/Enemies/CPatterned.hpp" + +class CPatternedInfo; +class CGenDescription; + +class CMetaree : public CPatterned { +public: + CMetaree(TUniqueId uid, const rstl::string& name, EFlavorType flavor, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& mData, const CPatternedInfo& pInfo, + const CDamageInfo& dInfo, float f1, const CVector3f& v1, float f2, EBodyType bodyType, + float f3, float f4, const CActorParameters& aParms); + + // CEntity + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + + // CActor + void Touch(CActor&, CStateManager&) override; + + // CPhysicsActor + void CollidedWith(const TUniqueId& id, const CCollisionInfoList& list, + CStateManager& mgr) override; + + // CAi + void Dead(CStateManager&, EStateMsg, float) override; + void Halt(CStateManager&, EStateMsg, float) override; + void Attack(CStateManager&, EStateMsg, float) override; + void Active(CStateManager&, EStateMsg, float) override; + void InActive(CStateManager&, EStateMsg, float) override; + void Flee(CStateManager&, EStateMsg, float) override; + void Explode(CStateManager&, EStateMsg, float) override; + bool InRange(CStateManager&, float) override; + bool Delay(CStateManager&, float) override; + bool ShouldAttack(CStateManager&, float) override; + + // CPatterned + void ThinkAboutMove(float) override; + +private: + float x568_delay; + float x56c_haltDelay; + float x570_dropHeight; + CVector3f x574_offset; + float x580_attackSpeed; + CVector3f x584_lookPos; + CVector3f x590_projectileDelta; + CVector3f x59c_velocity; + int x5a8_; + CDamageInfo x5ac_damageInfo; + ushort x5c8_attackSfx; + bool x5ca_24_ : 1; + bool x5ca_25_started : 1; + bool x5ca_26_deactivated : 1; + uint x5cc_; +}; + +#endif // _CMETAREE diff --git a/include/MetroidPrime/Enemies/CPatterned.hpp b/include/MetroidPrime/Enemies/CPatterned.hpp index bda20645..ddc26486 100644 --- a/include/MetroidPrime/Enemies/CPatterned.hpp +++ b/include/MetroidPrime/Enemies/CPatterned.hpp @@ -240,7 +240,15 @@ public: return x520_deathExplosionParticle; } + void DeathDelete(CStateManager& mgr); + + TUniqueId GetDestObj() const { return x2dc_destObj; } // TODO: name? + CStateMachineState& StateMachineState() { return x330_stateMachineState; } + const CStateMachineState& GetStateMachineState() const { return x330_stateMachineState; } ECharacter GetCharacterType() const { return x34c_characterType; } + bool IsAlive() const { return x400_25_alive; } + void SetWasHit(bool v) { x400_24_hitByPlayerProjectile = v; } + void SetPendingDeath(bool v) { x401_30_pendingDeath = v; } CBodyController* GetBodyCtrl() { return x450_bodyController.get(); } const CBodyController* GetBodyCtrl() const { return x450_bodyController.get(); } CKnockBackController& GetKnockBackCtrl() { return x460_knockBackController; } @@ -249,7 +257,7 @@ public: template < class T > static T* CastTo(const TPatternedCast< T >& ent); -public: +private: EPatrolState x2d8_patrolState; TUniqueId x2dc_destObj; CVector3f x2e0_destPos; diff --git a/include/MetroidPrime/Weapons/CGameProjectile.hpp b/include/MetroidPrime/Weapons/CGameProjectile.hpp index ff7ee6d9..e8f60d5f 100644 --- a/include/MetroidPrime/Weapons/CGameProjectile.hpp +++ b/include/MetroidPrime/Weapons/CGameProjectile.hpp @@ -32,6 +32,7 @@ public: virtual void ResolveCollisionWithActor(const CRayCastResult& res, CActor& act, CStateManager& mgr); + const CVector3f& GetPreviousPos() const { return x298_previousPos; } TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; } private: diff --git a/include/MetroidPrime/Weapons/CWeapon.hpp b/include/MetroidPrime/Weapons/CWeapon.hpp index d27e3be7..b7eaf92a 100644 --- a/include/MetroidPrime/Weapons/CWeapon.hpp +++ b/include/MetroidPrime/Weapons/CWeapon.hpp @@ -25,8 +25,11 @@ public: int /*EProjectileAttrib?*/) const override; void FluidFXThink(EFluidState, CScriptWater&, CStateManager&) override; - EProjectileAttrib GetAttribField() const { return xe8_projectileAttribs; } void SetDamageFalloffSpeed(float d); + + EProjectileAttrib GetAttribField() const { return xe8_projectileAttribs; } + TUniqueId GetOwnerId() const { return xec_ownerId; } + private: EProjectileAttrib xe8_projectileAttribs; TUniqueId xec_ownerId; diff --git a/src/MetroidPrime/CPhysicsActor.cpp b/src/MetroidPrime/CPhysicsActor.cpp index efbd7d7f..5a9b38a8 100644 --- a/src/MetroidPrime/CPhysicsActor.cpp +++ b/src/MetroidPrime/CPhysicsActor.cpp @@ -2,7 +2,7 @@ #include "Kyoto/Math/CloseEnough.hpp" -const float CPhysicsActor::skGravityConstant = 9.81f * 2.5f; +const float CPhysicsActor::kGravityAccel = 9.81f * 2.5f; CPhysicsActor::CPhysicsActor(TUniqueId uid, bool active, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, diff --git a/src/MetroidPrime/Enemies/CMetaree.cpp b/src/MetroidPrime/Enemies/CMetaree.cpp new file mode 100644 index 00000000..aded05cb --- /dev/null +++ b/src/MetroidPrime/Enemies/CMetaree.cpp @@ -0,0 +1,232 @@ +#include "MetroidPrime/Enemies/CMetaree.hpp" + +#include "MetroidPrime/BodyState/CBodyController.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/SFX/Metaree.h" +#include "MetroidPrime/Weapons/CGameProjectile.hpp" + +#include "Kyoto/Audio/CSfxManager.hpp" + +#include "Collision/CCollisionInfoList.hpp" + +CMetaree::CMetaree(TUniqueId uid, const rstl::string& name, EFlavorType flavor, + const CEntityInfo& info, const CTransform4f& xf, const CModelData& mData, + const CPatternedInfo& pInfo, const CDamageInfo& dInfo, float f1, + const CVector3f& v1, float f2, EBodyType bodyType, float f3, float f4, + const CActorParameters& aParms) +: CPatterned(kC_Metaree, uid, name, flavor, info, xf, mData, pInfo, kMT_Flyer, kCT_Zero, bodyType, + aParms, kKBV_Small) +, x568_delay(f3) +, x56c_haltDelay(f4) +, x570_dropHeight(f1) +, x574_offset(v1) +, x580_attackSpeed(f2) +, x584_lookPos(CVector3f::Zero()) +, x590_projectileDelta(0.f, 0.f, 0.f) +, x59c_velocity(CVector3f::Zero()) +, x5a8_(0) +, x5ac_damageInfo(dInfo) +, x5c8_attackSfx(SFXsfx0225) +, x5ca_24_(true) +, x5ca_25_started(false) +, x5ca_26_deactivated(false) {} + +void CMetaree::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CMetaree::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); + + switch (msg) { + break; + case kSM_Registered: + GetBodyCtrl()->Activate(mgr); + break; + case kSM_Start: + x5ca_25_started = true; + break; + case kSM_Activate: + default: + break; + } +} + +void CMetaree::ThinkAboutMove(float) {} + +void CMetaree::CollidedWith(const TUniqueId& id, const CCollisionInfoList& colList, + CStateManager& mgr) { + if (IsAlive() && colList.GetCount() > 0) { + mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), x5ac_damageInfo, + CMaterialFilter::MakeInclude(kMT_Player)); + SendScriptMsgs(kSS_Arrived, mgr, kSM_None); + MassiveDeath(mgr); + } +} + +void CMetaree::Touch(CActor& act, CStateManager& mgr) { + if (!IsAlive()) { + return; + } + + if (CGameProjectile* projectile = TCastToPtr< CGameProjectile >(act)) { + if (projectile->GetOwnerId() != mgr.GetPlayer()->GetUniqueId()) { + return; + } + + SetWasHit(true); + x590_projectileDelta = projectile->GetTranslation() - projectile->GetPreviousPos(); + } +} + +bool CMetaree::ShouldAttack(CStateManager&, float) { + return GetTranslation().GetZ() < x584_lookPos.GetZ(); +} + +bool CMetaree::InRange(CStateManager& mgr, float arg) { + return x5ca_25_started || CPatterned::InRange(mgr, arg); +} + +void CMetaree::InActive(CStateManager&, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: + if (!x5ca_26_deactivated) { + GetBodyCtrl()->SetLocomotionType(pas::kLT_Relaxed); + } else { + GetBodyCtrl()->SetLocomotionType(pas::kLT_Crouch); + } + break; + case kStateMsg_Update: + break; + case kStateMsg_Deactivate: + x5ca_26_deactivated = true; + break; + } +} + +void CMetaree::Active(CStateManager& mgr, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: + SetWasHit(false); + x584_lookPos = GetTranslation() - CVector3f(0.f, 0.f, x570_dropHeight); + GetBodyCtrl()->CommandMgr().DeliverCmd(CBCGenerateCmd(pas::kGType_Zero, x584_lookPos)); + SetMomentumWR(CVector3f(0.f, 0.f, -GetGravityConstant() * GetMass())); + break; + case kStateMsg_Update: + GetBodyCtrl()->CommandMgr().DeliverTargetVector( + (mgr.GetPlayer()->GetTranslation() - GetTranslation()).AsNormalized()); + break; + case kStateMsg_Deactivate: + SetMomentumWR(CVector3f::Zero()); + break; + } +} + +void CMetaree::Halt(CStateManager& mgr, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: { + Stop(); + SetVelocityWR(CVector3f::Zero()); + SetMomentumWR(CVector3f::Zero()); + GetBodyCtrl()->SetLocomotionType(pas::kLT_Lurk); + x584_lookPos = mgr.GetPlayer()->GetTranslation() + x574_offset; + SetTransform(CTransform4f::LookAt(GetTranslation(), x584_lookPos)); + StateMachineState().SetDelay(x56c_haltDelay); + break; + } + case kStateMsg_Update: + case kStateMsg_Deactivate: + break; + } +} + +void CMetaree::Attack(CStateManager&, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: { + x5a8_ = 0; + CVector3f dir = (x584_lookPos - GetTranslation()).AsNormalized(); + SetVelocityWR(x580_attackSpeed * dir); + CSfxManager::AddEmitter(x5c8_attackSfx, GetTranslation(), CVector3f::Zero(), true, false); + GetBodyCtrl()->SetLocomotionType(pas::kLT_Combat); + x59c_velocity = x580_attackSpeed * dir; + break; + } + case kStateMsg_Update: + if (GetBodyCtrl()->GetPercentageFrozen() == 0.f) { + SetVelocityWR(x59c_velocity); + } else { + Stop(); + SetVelocityWR(CVector3f::Zero()); + } + break; + case kStateMsg_Deactivate: + break; + } +} + +void CMetaree::Dead(CStateManager& mgr, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: + mgr.ApplyDamageToWorld( + GetUniqueId(), *this, GetTranslation(), x5ac_damageInfo, + CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Player), CMaterialList())); + DeathDelete(mgr); + break; + default: + break; + } +} + +void CMetaree::Flee(CStateManager& mgr, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: { + CVector3f ang = + GetMass() * CVector3f(x590_projectileDelta.GetX(), x590_projectileDelta.GetY(), 0.f) * 5.f; + ApplyImpulseWR(ang, CAxisAngle::Identity()); + + SetMomentumWR(CVector3f(0.f, 0.f, -GetGravityConstant() * GetMass())); + SetTransform(CTransform4f::Translate(GetTranslation())); + x5a8_ = 0; + break; + } + case kStateMsg_Update: { + if (x5a8_ == 0) { + if (GetBodyCtrl()->GetBodyStateInfo().GetCurrentStateId() == pas::kAS_LieOnGround) { + x5a8_ = 1; + } else { + GetBodyCtrl()->CommandMgr().DeliverCmd( + CBCKnockDownCmd(CVector3f(0.f, 1.f, 0.f), pas::kS_Zero)); + } + } + break; + } + case kStateMsg_Deactivate: + break; + } +} + +void CMetaree::Explode(CStateManager& mgr, EStateMsg msg, float) { + switch (msg) { + case kStateMsg_Activate: + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer()->GetUniqueId(), GetUniqueId(), x5ac_damageInfo, + CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Solid), CMaterialList()), + CVector3f::Zero()); + MassiveDeath(mgr); + break; + default: + break; + } +} + +void CMetaree::Think(float dt, CStateManager& mgr) { + bool target = true; + CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetCurrentVisor(); + bool b = visor != CPlayerState::kPV_Thermal && visor != CPlayerState::kPV_Scan; + if (!b && !x5ca_26_deactivated) { + target = false; + } + xe7_31_targetable = target; + CPatterned::Think(dt, mgr); +} + +bool CMetaree::Delay(CStateManager&, float) override { + return GetStateMachineState().GetTime() > x568_delay; +} diff --git a/src/MetroidPrime/Enemies/CPuffer.cpp b/src/MetroidPrime/Enemies/CPuffer.cpp index cafafadd..b3c6d33a 100644 --- a/src/MetroidPrime/Enemies/CPuffer.cpp +++ b/src/MetroidPrime/Enemies/CPuffer.cpp @@ -58,7 +58,7 @@ void CPuffer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMan break; case kSM_Action: if (GetActive()) { - x401_30_pendingDeath = true; + SetPendingDeath(true); } break; default: @@ -69,8 +69,8 @@ void CPuffer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMan void CPuffer::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); - if (x400_25_alive && mgr.GetPlayer()->GetUniqueId() == act.GetUniqueId()) { - x401_30_pendingDeath = true; + if (IsAlive() && mgr.GetPlayer()->GetUniqueId() == act.GetUniqueId()) { + SetPendingDeath(true); } } @@ -105,24 +105,24 @@ void CPuffer::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); sub8025bfa4(mgr); - CVector3f moveVector = x450_bodyController->GetCommandMgr().GetMoveVector(); + CVector3f moveVector = GetBodyCtrl()->GetCommandMgr().GetMoveVector(); - if (x5cc_ != x2dc_destObj) { - x5cc_ = x2dc_destObj; + if (x5cc_ != GetDestObj()) { + x5cc_ = GetDestObj(); CSfxManager::AddEmitter(x59a_, GetTranslation(), CVector3f::Zero(), true, false); } - x450_bodyController->CommandMgr().ClearLocomotionCmds(); + GetBodyCtrl()->CommandMgr().ClearLocomotionCmds(); if (moveVector.CanBeNormalized()) { x5c0_move = CVector3f::Lerp(x5c0_move, moveVector, dt / 0.5f).AsNormalized(); - x450_bodyController->CommandMgr().DeliverCmd(CBCLocomotionCmd(x5c0_move, x568_face, 1.f)); + GetBodyCtrl()->CommandMgr().DeliverCmd(CBCLocomotionCmd(x5c0_move, x568_face, 1.f)); } } -#define ARRAY_SIZE(arr) int(sizeof(arr) / sizeof(arr[0])) +#define ARRAY_SIZE(arr) static_cast< int >(sizeof(arr) / sizeof(arr[0])) void CPuffer::sub8025bfa4(CStateManager& mgr) { - CVector3f moveVector = x450_bodyController->GetCommandMgr().GetMoveVector(); + CVector3f moveVector = GetBodyCtrl()->GetCommandMgr().GetMoveVector(); if (x5d4_gasLocators.empty()) { for (int i = 0; i < ARRAY_SIZE(skGasLocators); ++i) {