#pragma once #include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CBodyStateCmdMgr.hpp" #include "Runtime/Character/CBodyStateInfo.hpp" #include "Runtime/Character/CharacterCommon.hpp" #include #include namespace metaforce { class CActor; class CAnimPlaybackParms; class CPASAnimParmData; class CPASDatabase; class CRandom16; class CStateManager; struct CFinalInput; class CBodyController { CActor& x0_actor; CBodyStateCmdMgr x4_cmdMgr; CBodyStateInfo x2a4_bodyStateInfo; zeus::CQuaternion x2dc_rot; pas::ELocomotionType x2ec_locomotionType = pas::ELocomotionType::Relaxed; pas::EFallState x2f0_fallState = pas::EFallState::Zero; EBodyType x2f4_bodyType; s32 x2f8_curAnim = -1; float x2fc_turnSpeed; bool x300_24_animationOver : 1 = false; bool x300_25_active : 1 = false; bool x300_26_frozen : 1 = false; bool x300_27_hasBeenFrozen : 1 = false; bool x300_28_playDeathAnims : 1 = true; float x304_intoFreezeDur = 0.f; float x308_frozenDur = 0.f; float x30c_breakoutDur = 0.f; float x310_timeFrozen = 0.f; zeus::CVector3f x314_backedUpForce; float x320_fireDur = 0.f; float x324_electrocutionDur = 0.f; float x328_timeOnFire = 0.f; float x32c_timeElectrocuting = 0.f; float x330_restrictedFlyerMoveSpeed = 0.f; public: CBodyController(CActor& owner, float turnSpeed, EBodyType bodyType); pas::EAnimationState GetCurrentStateId() const { return x2a4_bodyStateInfo.GetCurrentStateId(); } CBodyStateCmdMgr& GetCommandMgr() { return x4_cmdMgr; } const CBodyStateCmdMgr& GetCommandMgr() const { return x4_cmdMgr; } void SetDoDeathAnims(bool d) { x300_28_playDeathAnims = d; } bool IsElectrocuting() const { return x324_electrocutionDur > 0.f; } bool IsOnFire() const { return x320_fireDur > 0.f; } bool IsFrozen() const { return x300_26_frozen; } const CBodyStateInfo& GetBodyStateInfo() const { return x2a4_bodyStateInfo; } CBodyStateInfo& BodyStateInfo() { return x2a4_bodyStateInfo; } float GetTurnSpeed() const { return x2fc_turnSpeed; } void SetLocomotionType(pas::ELocomotionType type) { x2ec_locomotionType = type; } pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; } CActor& GetOwner() const { return x0_actor; } bool IsAnimationOver() const { return x300_24_animationOver; } void EnableAnimation(bool enable); bool ShouldPlayDeathAnims() const { return x300_28_playDeathAnims; } s32 GetCurrentAnimId() const { return x2f8_curAnim; } void Activate(CStateManager& mgr); CAdditiveBodyState* GetCurrentAdditiveState() { return x2a4_bodyStateInfo.GetCurrentAdditiveState(); } void SetState(pas::EAnimationState state) { x2a4_bodyStateInfo.SetState(state); } void Update(float dt, CStateManager& mgr); bool ShouldBeHurled() const { return HasBodyState(pas::EAnimationState::Hurled); } bool HasBodyState(pas::EAnimationState state) const; pas::EFallState GetFallState() const { return x2f0_fallState; } void SetFallState(pas::EFallState state) { x2f0_fallState = state; } void UpdateBody(float dt, CStateManager& mgr); void SetAdditiveState(pas::EAnimationState state) { x2a4_bodyStateInfo.SetAdditiveState(state); } void SetTurnSpeed(float speed); void SetCurrentAnimation(const CAnimPlaybackParms& parms, bool loop, bool noTrans); float GetAnimTimeRemaining() const; void SetPlaybackRate(float rate); void MultiplyPlaybackRate(float mul); void SetDeltaRotation(const zeus::CQuaternion& q) { x2dc_rot *= q; } void FaceDirection(const zeus::CVector3f& v0, float dt); void FaceDirection3D(const zeus::CVector3f& v0, const zeus::CVector3f& v1, float dt); static bool HasBodyInfo(const CActor& actor); const CPASDatabase& GetPASDatabase() const; void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r); void LoopBestAnimation(const CPASAnimParmData& parms, CRandom16& r); void Freeze(float intoFreezeDur, float frozenDur, float breakoutDur); void UnFreeze(); float GetPercentageFrozen() const; void SetOnFire(float duration); void DouseFlames(); void SetElectrocuting(float duration); void DouseElectrocuting(); void UpdateFrozenInfo(float dt, CStateManager& mgr); bool HasIceBreakoutState() const; void StopElectrocution(); void FrozenBreakout(); pas::EAnimationState GetCurrentAdditiveStateId() const { return x2a4_bodyStateInfo.GetCurrentAdditiveStateId(); } EBodyType GetBodyType() const { return x2f4_bodyType; } bool HasBeenFrozen() const { return x300_27_hasBeenFrozen; } float GetRestrictedFlyerMoveSpeed() const { return x330_restrictedFlyerMoveSpeed; } void SetRestrictedFlyerMoveSpeed(float speed) { x330_restrictedFlyerMoveSpeed = speed; } bool GetActive() const { return x300_25_active; } }; } // namespace metaforce