#pragma once #include "RetroTypes.hpp" #include "zeus/CVector3f.hpp" #include "Character/CharacterCommon.hpp" #include "Weapon/WeaponCommon.hpp" namespace urde { class CPatterned; class CDamageInfo; enum class EKnockBackType { Zero, One }; enum class EKnockBackVariant { Zero, One, Two }; enum class EKnockBackWeaponType { Invalid = -1, Power, PowerCharged, PowerComboed, PowerExtra, Wave, WaveCharged, WaveComboed, WaveExtra, Ice, IceCharged, IceComboed, IceExtra, Plasma, PlasmaCharged, PlasmaComboed, Missile, Bomb, PowerBomb, Phazon }; enum class EKnockBackCharacterState { Alive, Dead, FrozenAlive, FrozenDead }; enum class EKnockBackAnimationState { Invalid = -1, None, Flinch, KnockBack, Hurled, Fall }; enum class EKnockBackAnimationCondition { Invalid = -1, Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine }; class CKnockBackController { public: struct KnockBackParms { EKnockBackAnimationState x0_animState; EKnockBackAnimationCondition x4_animCondition; float x8_; float xc_; }; private: friend class CPatterned; EKnockBackVariant x0_variant; KnockBackParms x4_activeParms; EWeaponType x14_deferWeaponType = EWeaponType::None; EKnockBackAnimationState x18_minAnimState = EKnockBackAnimationState::None; EKnockBackAnimationState x1c_maxAnimState = EKnockBackAnimationState::Fall; u32 x20_impulseDurationIdx = 0; rstl::reserved_vector, 4> x24_; zeus::CVector3f x50_impulseDir; float x5c_impulseMag = 0.f; float x60_impulseRemTime = 0.f; float x64_flinchRemTime = 0.f; float x68_deferRemTime = 0.f; u32 x6c_ = 0; u32 x70_ = 0; u32 x74_ = 0; pas::ESeverity x7c_severity = pas::ESeverity::One; std::bitset<4> x80_availableStates; union { struct { bool x81_24_autoResetImpulse : 1; // t bool x81_25_ : 1; // t bool x81_26_ : 1; bool x81_27_ : 1; // t bool x81_28_ : 1; // t bool x81_29_ : 1; // t bool x81_30_ : 1; // t bool x81_31_ : 1; // t bool x82_24_ : 1; // t bool x82_25_inDeferredKnockBack : 1; bool x82_26_ : 1; }; u32 dummy = 0; }; void ApplyImpulse(float dt, CPatterned& parent); bool TickDeferredTimer(float dt); EKnockBackCharacterState GetKnockBackCharacterState(CPatterned& parent); void ValidateState(CPatterned& parent); float CalculateExtraHurlVelocity(CStateManager& mgr, float magnitude, float kbResistance); void DoKnockBackAnimation(const zeus::CVector3f& backVec, CStateManager& mgr, CPatterned& parent, float magnitude); void ResetKnockBackImpulse(CPatterned& parent, const zeus::CVector3f& backVec, float magnitude); void DoDeferredKnockBack(CStateManager& mgr, CPatterned& parent); EKnockBackWeaponType GetKnockBackWeaponType(const CDamageInfo& info, EWeaponType wType, EKnockBackType type); void SelectDamageState(CPatterned& parent, const CDamageInfo& info, EWeaponType wType, EKnockBackType type); public: explicit CKnockBackController(EKnockBackVariant variant); void SetKnockBackVariant(EKnockBackVariant v) { x0_variant = v; } void DeferKnockBack(EWeaponType tp) { x14_deferWeaponType = tp; x68_deferRemTime = 0.05f; } void sub80233d40(int i, float f1, float f2); void SetAutoResetImpulse(bool b); void SetImpulseDurationIdx(u32 i) { x20_impulseDurationIdx = i; } void SetAnimationStateRange(EKnockBackAnimationState a, EKnockBackAnimationState b) { x18_minAnimState = a; x1c_maxAnimState = b; } void Update(float dt, CStateManager& mgr, CPatterned& parent); void KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, CPatterned& parent, const CDamageInfo& info, EKnockBackType type, float magnitude); void SetX81_25(bool b) { x81_25_ = b; } }; }