diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index c4bbfe91..a30b7b82 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -8947,14 +8947,14 @@ fn_801CFF50 = .text:0x801CFF50; // type:function size:0x1D8 PreRender__10CFishCloudFR13CStateManagerRC14CFrustumPlanes = .text:0x801D0128; // type:function size:0x80 scope:global Think__10CFishCloudFfR13CStateManager = .text:0x801D01A8; // type:function size:0x784 scope:global GetTouchBounds__10CFishCloudCFv = .text:0x801D092C; // type:function size:0x70 scope:global -fn_801D099C = .text:0x801D099C; // type:function size:0xF4 +RemoveRepulsor__10CFishCloudF9TUniqueId = .text:0x801D099C; // type:function size:0xF4 fn_801D0A90 = .text:0x801D0A90; // type:function size:0x4C fn_801D0ADC = .text:0x801D0ADC; // type:function size:0xB4 -fn_801D0B90 = .text:0x801D0B90; // type:function size:0xF4 -fn_801D0C84 = .text:0x801D0C84; // type:function size:0x15C +RemoveAttractor__10CFishCloudF9TUniqueId = .text:0x801D0B90; // type:function size:0xF4 +AddRepulsor__10CFishCloudF9TUniqueIdbff = .text:0x801D0C84; // type:function size:0x15C fn_801D0DE0 = .text:0x801D0DE0; // type:function size:0x8C fn_801D0E6C = .text:0x801D0E6C; // type:function size:0x2D8 -fn_801D1144 = .text:0x801D1144; // type:function size:0x15C +AddAttractor__10CFishCloudF9TUniqueIdbff = .text:0x801D1144; // type:function size:0x15C AcceptScriptMsg__10CFishCloudF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x801D12A0; // type:function size:0x320 scope:global PlaceBoid__10CFishCloudFR13CStateManagerRQ210CFishCloud5CBoidRC6CAABox = .text:0x801D15C0; // type:function size:0x294 scope:global FindClosestPlane__10CFishCloudCFRC6CAABoxRC9CVector3f = .text:0x801D1854; // type:function size:0x46C scope:global @@ -9089,7 +9089,7 @@ Flinch__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D7EC0; // type:funct Attack__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D7F60; // type:function size:0x1AC scope:global GetDamageVulnerability__9CJellyZapCFRC9CVector3fRC9CVector3fRC11CDamageInfo = .text:0x801D810C; // type:function size:0x48 scope:global GetCollisionResponseType__9CJellyZapCFRC9CVector3fRC9CVector3fRC11CWeaponModei = .text:0x801D8154; // type:function size:0x3C scope:global -sub801d8190__9CJellyZapFv = .text:0x801D8190; // type:function size:0x18 scope:global +HitShell__9CJellyZapCFRC9CVector3f = .text:0x801D8190; // type:function size:0x18 scope:global Suck__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D81A8; // type:function size:0x318 scope:global Active__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D84C0; // type:function size:0x16C scope:global InActive__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D862C; // type:function size:0x70 scope:global @@ -9097,11 +9097,11 @@ ShouldAttack__9CJellyZapFR13CStateManagerf = .text:0x801D869C; // type:function ShouldSpecialAttack__9CJellyZapFR13CStateManagerf = .text:0x801D86B4; // type:function size:0x20 scope:global InAttackPosition__9CJellyZapFR13CStateManagerf = .text:0x801D86D4; // type:function size:0x88 scope:global InDetectionRange__9CJellyZapFR13CStateManagerf = .text:0x801D875C; // type:function size:0x38 scope:global -DoUserAnimEvent__9CJellyZapFR13CStateManagerRC13CInt32POINode14EUserEventType = .text:0x801D8794; // type:function size:0x120 scope:global +DoUserAnimEvent__9CJellyZapFR13CStateManagerRC13CInt32POINode14EUserEventTypef = .text:0x801D8794; // type:function size:0x120 scope:global AcceptScriptMsg__9CJellyZapF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x801D88B4; // type:function size:0xAC scope:global Think__9CJellyZapFfR13CStateManager = .text:0x801D8960; // type:function size:0x120 scope:global Accept__9CJellyZapFR8IVisitor = .text:0x801D8A80; // type:function size:0x38 scope:global -__ct__9CJellyZapF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC10CModelDataRC11CDamageInfofffffffffffRC14CPatternedInfoRC16CActorParameters = .text:0x801D8AB8; // type:function size:0x23C scope:global +__ct__9CJellyZapF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC10CModelDataRC11CDamageInfobffffffffffffRC14CPatternedInfoRC16CActorParameters = .text:0x801D8AB8; // type:function size:0x23C scope:global __dt__23CScriptControllerActionFv = .text:0x801D8CF4; // type:function size:0x60 scope:weak GetCommand__23CScriptControllerActionFQ223CScriptControllerAction9ECommands = .text:0x801D8D54; // type:function size:0x4 scope:global Think__23CScriptControllerActionFfR13CStateManager = .text:0x801D8D58; // type:function size:0x14C scope:global @@ -18552,7 +18552,7 @@ __vt__15CScriptVisorGoo = .data:0x803E58C0; // type:object size:0x6C scope:globa lbl_803E5930 = .data:0x803E5930; // type:object size:0xC data:4byte lbl_803E593C = .data:0x803E593C; // type:object size:0xC data:4byte lbl_803E5948 = .data:0x803E5948; // type:object size:0xC data:4byte -lbl_803E5954 = .data:0x803E5954; // type:object size:0x2CC +__vt__9CJellyZap = .data:0x803E5954; // type:object size:0x2CC __vt__23CScriptControllerAction = .data:0x803E5C20; // type:object size:0x20 scope:global __vt__13CScriptSwitch = .data:0x803E5C40; // type:object size:0x20 scope:global __vt__8CABSIdle = .data:0x803E5C60; // type:object size:0x20 scope:global @@ -18562,7 +18562,7 @@ __vt__24CScriptPlayerStateChange = .data:0x803E5CC0; // type:object size:0x20 sc lbl_803E5CE0 = .data:0x803E5CE0; // type:object size:0x2CC jumptable_803E5FAC = .data:0x803E5FAC; // type:object size:0x48 scope:local jumptable_803E5FF4 = .data:0x803E5FF4; // type:object size:0x80 scope:local -lbl_803E6074 = .data:0x803E6074; // type:object size:0x294 +__vt__16CDestroyableRock = .data:0x803E6074; // type:object size:0x294 lbl_803E6308 = .data:0x803E6308; // type:object size:0x6C jumptable_803E6374 = .data:0x803E6374; // type:object size:0x20 scope:local __vt__18CScriptAiJumpPoint = .data:0x803E6398; // type:object size:0x6C scope:global @@ -25022,9 +25022,9 @@ lbl_805AC87C = .sdata2:0x805AC87C; // type:object size:0x4 align:4 data:float lbl_805AC880 = .sdata2:0x805AC880; // type:object size:0x4 align:4 data:float lbl_805AC884 = .sdata2:0x805AC884; // type:object size:0x4 align:4 data:float lbl_805AC888 = .sdata2:0x805AC888; // type:object size:0x8 align:4 data:float -lbl_805AC890 = .sdata2:0x805AC890; // type:object size:0x4 align:4 data:float -lbl_805AC894 = .sdata2:0x805AC894; // type:object size:0x4 align:4 data:float -lbl_805AC898 = .sdata2:0x805AC898; // type:object size:0x8 align:4 data:float +@520 = .sdata2:0x805AC890; // type:object size:0x4 align:4 data:float +@653 = .sdata2:0x805AC894; // type:object size:0x4 align:4 data:float +@654 = .sdata2:0x805AC898; // type:object size:0x4 align:4 data:float lbl_805AC8A0 = .sdata2:0x805AC8A0; // type:object size:0x4 align:4 data:float lbl_805AC8A4 = .sdata2:0x805AC8A4; // type:object size:0x4 align:4 data:float lbl_805AC8A8 = .sdata2:0x805AC8A8; // type:object size:0x8 align:4 data:float diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index eeaa591d..7d5f4172 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -8947,14 +8947,14 @@ fn_801CFF50 = .text:0x801CFFCC; // type:function size:0x1D8 scope:global PreRender__10CFishCloudFR13CStateManagerRC14CFrustumPlanes = .text:0x801D01A4; // type:function size:0x80 scope:global Think__10CFishCloudFfR13CStateManager = .text:0x801D0224; // type:function size:0x784 scope:global GetTouchBounds__10CFishCloudCFv = .text:0x801D09A8; // type:function size:0x70 scope:global -fn_801D099C = .text:0x801D0A18; // type:function size:0xF4 scope:global +RemoveRepulsor__10CFishCloudF9TUniqueId = .text:0x801D0A18; // type:function size:0xF4 scope:global fn_801D0A90 = .text:0x801D0B0C; // type:function size:0x4C scope:global fn_801D0ADC = .text:0x801D0B58; // type:function size:0xB4 scope:global -fn_801D0B90 = .text:0x801D0C0C; // type:function size:0xF4 scope:global -fn_801D0C84 = .text:0x801D0D00; // type:function size:0x15C scope:global +RemoveAttractor__10CFishCloudF9TUniqueId = .text:0x801D0C0C; // type:function size:0xF4 scope:global +AddRepulsor__10CFishCloudF9TUniqueIdbff = .text:0x801D0D00; // type:function size:0x15C scope:global fn_801D0DE0 = .text:0x801D0E5C; // type:function size:0x8C scope:global fn_801D0E6C = .text:0x801D0EE8; // type:function size:0x2D8 scope:global -fn_801D1144 = .text:0x801D11C0; // type:function size:0x15C scope:global +AddAttractor__10CFishCloudF9TUniqueIdbff = .text:0x801D11C0; // type:function size:0x15C scope:global AcceptScriptMsg__10CFishCloudF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x801D131C; // type:function size:0x320 scope:global PlaceBoid__10CFishCloudFR13CStateManagerRQ210CFishCloud5CBoidRC6CAABox = .text:0x801D163C; // type:function size:0x294 scope:global FindClosestPlane__10CFishCloudCFRC6CAABoxRC9CVector3f = .text:0x801D18D0; // type:function size:0x46C scope:global @@ -9089,7 +9089,7 @@ Flinch__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D7F3C; // type:funct Attack__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D7FDC; // type:function size:0x1AC scope:global GetDamageVulnerability__9CJellyZapCFRC9CVector3fRC9CVector3fRC11CDamageInfo = .text:0x801D8188; // type:function size:0x48 scope:global GetCollisionResponseType__9CJellyZapCFRC9CVector3fRC9CVector3fRC11CWeaponModei = .text:0x801D81D0; // type:function size:0x3C scope:global -sub801d8190__9CJellyZapFv = .text:0x801D820C; // type:function size:0x18 scope:global +HitShell__9CJellyZapCFRC9CVector3f = .text:0x801D820C; // type:function size:0x18 scope:global Suck__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D8224; // type:function size:0x318 scope:global Active__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D853C; // type:function size:0x16C scope:global InActive__9CJellyZapFR13CStateManager9EStateMsgf = .text:0x801D86A8; // type:function size:0x70 scope:global @@ -9097,11 +9097,11 @@ ShouldAttack__9CJellyZapFR13CStateManagerf = .text:0x801D8718; // type:function ShouldSpecialAttack__9CJellyZapFR13CStateManagerf = .text:0x801D8730; // type:function size:0x20 scope:global InAttackPosition__9CJellyZapFR13CStateManagerf = .text:0x801D8750; // type:function size:0x88 scope:global InDetectionRange__9CJellyZapFR13CStateManagerf = .text:0x801D87D8; // type:function size:0x38 scope:global -DoUserAnimEvent__9CJellyZapFR13CStateManagerRC13CInt32POINode14EUserEventType = .text:0x801D8810; // type:function size:0x120 scope:global +DoUserAnimEvent__9CJellyZapFR13CStateManagerRC13CInt32POINode14EUserEventTypef = .text:0x801D8810; // type:function size:0x120 scope:global AcceptScriptMsg__9CJellyZapF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x801D8930; // type:function size:0xAC scope:global Think__9CJellyZapFfR13CStateManager = .text:0x801D89DC; // type:function size:0x120 scope:global Accept__9CJellyZapFR8IVisitor = .text:0x801D8AFC; // type:function size:0x38 scope:global -__ct__9CJellyZapF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC10CModelDataRC11CDamageInfofffffffffffRC14CPatternedInfoRC16CActorParameters = .text:0x801D8B34; // type:function size:0x23C scope:global +__ct__9CJellyZapF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fRC10CModelDataRC11CDamageInfobffffffffffffRC14CPatternedInfoRC16CActorParameters = .text:0x801D8B34; // type:function size:0x23C scope:global __dt__23CScriptControllerActionFv = .text:0x801D8D70; // type:function size:0x60 scope:weak GetCommand__23CScriptControllerActionFQ223CScriptControllerAction9ECommands = .text:0x801D8DD0; // type:function size:0x4 scope:global Think__23CScriptControllerActionFfR13CStateManager = .text:0x801D8DD4; // type:function size:0x14C scope:global diff --git a/configure.py b/configure.py index fc04bbf1..e0c8ae47 100755 --- a/configure.py +++ b/configure.py @@ -948,7 +948,7 @@ config.libs = [ Object(NonMatching, "MetroidPrime/PathFinding/CPathFindRegion.cpp"), Object(NonMatching, "MetroidPrime/PathFinding/CPathFindArea.cpp"), Object( - NonMatching, "MetroidPrime/Weapons/GunController/CGunController.cpp" + MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/Weapons/GunController/CGunController.cpp" ), Object(NonMatching, "MetroidPrime/Weapons/GunController/CGSFreeLook.cpp"), Object( diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index a9d31ce0..203d411a 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -157,6 +157,8 @@ public: TUniqueId InFluidId() const { return xc4_fluidId; } + void SetDamageMag(const float d) { xd0_damageMag = d; } + bool GetTransformDirty() const { return xe4_27_notInSortedLists; } bool GetTransformDirtySpare() const { return xe4_28_transformDirty; } bool GetPreRenderHasMoved() const { return xe4_29_actorLightsDirty; } @@ -182,6 +184,7 @@ public: void SetMuted(bool b); void SetThermalFlags(EThermalFlags flags) { xe6_27_thermalVisorFlags = flags; } void SetRenderParticleDatabaseInside(bool b) { xe6_29_renderParticleDBInside = b; } + void SetDoTargetDistanceTest(const bool b) { xe7_30_doTargetDistanceTest = b; } void SetTargetable(bool b) { xe7_31_targetable = b; } void RemoveMaterial(EMaterialTypes, EMaterialTypes, EMaterialTypes, EMaterialTypes, diff --git a/include/MetroidPrime/CAnimData.hpp b/include/MetroidPrime/CAnimData.hpp index 5600cc47..bc4eb828 100644 --- a/include/MetroidPrime/CAnimData.hpp +++ b/include/MetroidPrime/CAnimData.hpp @@ -52,8 +52,8 @@ public: void SetIsAnimating(bool v) { x220_24_animating = v; } void SetParticleEffectState(const rstl::string& name, const bool active, CStateManager& mgr) { - x120_particleDB.SetParticleEffectState(name, active, mgr); - } + x120_particleDB.SetParticleEffectState(name, active, mgr); + } int GetCharacterIndex() const { return x204_charIdx; } float GetAverageVelocity(int idx) const; @@ -94,7 +94,7 @@ public: // AdvanceIgnoreParticles__9CAnimDataFfR9CRandom16b // Advance__9CAnimDataFfRC9CVector3fR13CStateManagerb // DoAdvance__9CAnimDataFfRbR9CRandom16b - void SetAnimation(const CAnimPlaybackParms& parms, bool noTrans); + void SetAnimation(const CAnimPlaybackParms& parms, const bool noTrans); void GetAnimationPrimitives(const CAnimPlaybackParms& parms, rstl::set< CPrimitive >& primsOut) const; // PrimitiveSetToTokenVector__9CAnimDataFRCQ24rstl72set<10CPrimitive,Q24rstl18less<10CPrimitive>,Q24rstl17rmemory_allocator>RQ24rstl42vector<6CToken,Q24rstl17rmemory_allocator>b diff --git a/include/MetroidPrime/CAnimPlaybackParms.hpp b/include/MetroidPrime/CAnimPlaybackParms.hpp index e3b04655..5d5bb1f5 100644 --- a/include/MetroidPrime/CAnimPlaybackParms.hpp +++ b/include/MetroidPrime/CAnimPlaybackParms.hpp @@ -21,7 +21,8 @@ private: const CVector3f* x24_objectScale; public: - CAnimPlaybackParms(int animA, int animB, float blendWeight, bool animating) + CAnimPlaybackParms(const int animA, const int animB, const float blendWeight, + const bool animating) : x0_animA(animA) , x4_animB(animB) , x8_blendWeight(blendWeight) diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index 8acf9553..e0388e16 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -70,6 +70,7 @@ public: CModelData(); CModelData(const CAnimRes&); CModelData(const CStaticRes&); + //CModelData(const CModelData&); ~CModelData(); CAdvancementDeltas AdvanceAnimation(float dt, CStateManager& mgr, TAreaId aid, bool advTree); diff --git a/include/MetroidPrime/Enemies/CJellyZap.hpp b/include/MetroidPrime/Enemies/CJellyZap.hpp index 47ba7898..2128c7b1 100644 --- a/include/MetroidPrime/Enemies/CJellyZap.hpp +++ b/include/MetroidPrime/Enemies/CJellyZap.hpp @@ -4,7 +4,60 @@ #include "MetroidPrime/Enemies/CPatterned.hpp" class CJellyZap : public CPatterned { +public: + CJellyZap(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& mData, const CDamageInfo& attackDamage, + bool b1, float attackRadius, float f2, float f3, float f4, float attackDelay, float f6, + float f7, float f8, float priority, float repulseRadius, float attractRadius, float f12, + const CPatternedInfo& pInfo, const CActorParameters& actParms); + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, + float dt) override; + + bool InDetectionRange(CStateManager& mgr, float arg) override; + bool InAttackPosition(CStateManager& mgr, float arg) override; + bool ShouldSpecialAttack(CStateManager& mgr, float arg) override; + bool ShouldAttack(CStateManager& mgr, float arg) override; + void InActive(CStateManager& mgr, EStateMsg msg, float arg) override; + void Active(CStateManager& mgr, EStateMsg msg, float arg) override; + void Suck(CStateManager& mgr, EStateMsg msg, float arg) override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const CVector3f&, const CVector3f&, + const CWeaponMode&, int) const override; + const CDamageVulnerability* GetDamageVulnerability(const CVector3f& pos, const CVector3f& dir, + const CDamageInfo& info) const override; + void Attack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Flinch(CStateManager& mgr, EStateMsg msg, float arg) override; + void KnockBack(const CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; + +private: + void AddAttractor(CStateManager& mgr); + void RemoveAllAttractors(CStateManager& mgr); + void AddRepulsor(CStateManager& mgr); + void AddSelfToFishCloud(CStateManager& mgr, float radius, float priority, bool repulsor); + void RemoveSelfFromFishCloud(CStateManager& mgr); + bool ClosestToPlayer(CStateManager& mgr) const; + bool HitShell(const CVector3f&) const; + uint x568_; + CDamageInfo x56c_attackDamage; + float x588_attackRadius; + float x58c_; + float x590_; + float x594_; + float x598_; + float x59c_priority; + float x5a0_repulseRadius; + float x5a4_attractRadius; + float x5a8_attackDelay; + float x5ac_; + float x5b0_; + float x5b4_; + bool x5b8_24_ : 1; + bool x5b8_25_ : 1; + bool x5b8_26_ : 1; }; #endif // _CJELLYZAP diff --git a/include/MetroidPrime/Enemies/CPatterned.hpp b/include/MetroidPrime/Enemies/CPatterned.hpp index 5e77847a..d9934dd9 100644 --- a/include/MetroidPrime/Enemies/CPatterned.hpp +++ b/include/MetroidPrime/Enemies/CPatterned.hpp @@ -274,11 +274,16 @@ public: const CVector3f& GetMoveVector() const { return x310_moveVec; } void SetMoveVector(const CVector3f& vec) { x310_moveVec = vec; } + float GetFreezeDuration() const { return x4fc_freezeDur; } + + void SetBaseDamageMag(const float mag) { x50c_baseDamageMag = mag; } + bool ApplyBoneTracking() const; template < class T > static T* CastTo(const TPatternedCast< T >& ent); + void TryKnockBack(CStateManager& mgr, int arg); void TryLoopReaction(CStateManager& mgr, int arg); void TryCommand(CStateManager& mgr, int state, FTryCommandCallback cb, int arg); @@ -289,6 +294,8 @@ public: float GetAnimationDistance(const CPASAnimParmData& data) const; + void UpdateThermalFrozenState(const bool thawed); + protected: EPatrolState x2d8_patrolState; TUniqueId x2dc_destObj; diff --git a/include/MetroidPrime/Enemies/CThardus.hpp b/include/MetroidPrime/Enemies/CThardus.hpp index 166dffcb..8f4f1d8f 100644 --- a/include/MetroidPrime/Enemies/CThardus.hpp +++ b/include/MetroidPrime/Enemies/CThardus.hpp @@ -1,8 +1,34 @@ #ifndef _CTHARDUS #define _CTHARDUS +#include "MetroidPrime/Enemies/CPatterned.hpp" + +class CDestroyableRock : public CAi { +public: + CDestroyableRock(TUniqueId id, bool active, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& modelData, float mass, + const CHealthInfo& health, const CDamageVulnerability& vulnerability, + const CMaterialList& matList, CAssetId fsm, const CActorParameters& actParams, + const CModelData& phazonModel, int w1); + + void PreThink(float dt, CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + +private: + CModelData x2d8_phazonModel; + float x324_; + float x328_; + float x32c_thermalMag; + CColor x330_; + bool x334_isCold; + bool x335_usePhazonModel; + CHealthInfo x338_healthInfo; + bool x340_; + bool x341_; +}; class CThardus : public CPatterned { public: + void RenderThermalSpot(float dt) const; void ShakeScreen(CStateManager& mgr, const CVector3f& position, const float, const float, const float); void StartTimedThermalFlash(CStateManager& mgr, float, CActor& actor); diff --git a/include/MetroidPrime/ScriptObjects/CFishCloud.hpp b/include/MetroidPrime/ScriptObjects/CFishCloud.hpp new file mode 100644 index 00000000..c50cf3a9 --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CFishCloud.hpp @@ -0,0 +1,13 @@ +#ifndef _CFISHCLOUD +#define _CFISHCLOUD + +#include "MetroidPrime/CActor.hpp" + +class CFishCloud : public CActor { +public: + bool AddRepulsor(TUniqueId source, bool swirl, float radius, float priority); + bool AddAttractor(TUniqueId source, bool swirl, float radius, float priority); + void RemoveRepulsor(TUniqueId source); + void RemoveAttractor(TUniqueId source); +}; +#endif diff --git a/include/MetroidPrime/Weapons/GunController/CGSComboFire.hpp b/include/MetroidPrime/Weapons/GunController/CGSComboFire.hpp index 7eac8b88..49c481f7 100644 --- a/include/MetroidPrime/Weapons/GunController/CGSComboFire.hpp +++ b/include/MetroidPrime/Weapons/GunController/CGSComboFire.hpp @@ -9,8 +9,8 @@ public: bool IsComboOver() const { return x10_24_over; } int GetLoopState() const { return x4_loopState; } - void SetLoopState(int l) { x4_loopState = l; } - void SetIdle(bool i) { x10_25_idle = i; } + void SetLoopState(const int l) { x4_loopState = l; } + void SetIdle(const bool i) { x10_25_idle = i; } int GetGunId() const { return xc_gunId; } bool Update(CAnimData& data, float dt, CStateManager& mgr); int SetAnim(CAnimData& data, int gunId, int loopState, CStateManager& mgr, float delay); diff --git a/include/MetroidPrime/Weapons/GunController/CGSFreeLook.hpp b/include/MetroidPrime/Weapons/GunController/CGSFreeLook.hpp index d772d808..95276a58 100644 --- a/include/MetroidPrime/Weapons/GunController/CGSFreeLook.hpp +++ b/include/MetroidPrime/Weapons/GunController/CGSFreeLook.hpp @@ -18,9 +18,9 @@ public: CGSFreeLook(); int GetSetId() const { return x10_setId; } - void SetLoopState(int l) { x8_loopState = l; } + void SetLoopState(const int l) { x8_loopState = l; } int GetLoopState() const { return x8_loopState; } - void SetIdle(bool l) { x14_idle = l; } + void SetIdle(const bool l) { x14_idle = l; } int GetGunId() const { return xc_gunId; } bool Update(CAnimData& data, float dt, CStateManager& mgr); int SetAnim(CAnimData& data, int gunId, int setId, int loopState, CStateManager& mgr, diff --git a/include/MetroidPrime/Weapons/GunController/CGunController.hpp b/include/MetroidPrime/Weapons/GunController/CGunController.hpp index 52ba16bd..5a8c0e5c 100644 --- a/include/MetroidPrime/Weapons/GunController/CGunController.hpp +++ b/include/MetroidPrime/Weapons/GunController/CGunController.hpp @@ -3,9 +3,9 @@ #include "types.h" -#include "MetroidPrime/Weapons/GunController/CGSFreeLook.hpp" #include "MetroidPrime/Weapons/GunController/CGSComboFire.hpp" #include "MetroidPrime/Weapons/GunController/CGSFidget.hpp" +#include "MetroidPrime/Weapons/GunController/CGSFreeLook.hpp" class CModelData; @@ -27,7 +27,7 @@ class CGunController { CGSFreeLook x4_freeLook; CGSComboFire x1c_comboFire; CGSFidget x30_fidget; - char x48_pad[0x4]; + char x4c_pad[0x4]; EGunState x50_gunState; int x54_curAnimId; bool x58_24_animDone : 1; @@ -35,7 +35,7 @@ class CGunController { public: explicit CGunController(CModelData& modelData); - ~CGunController(); + ~CGunController(); void EnterFreeLook(CStateManager&, int, int); void EnterComboFire(CStateManager&, int); diff --git a/src/MetroidPrime/CControlMapper.cpp b/src/MetroidPrime/CControlMapper.cpp index e1175768..a3db987a 100644 --- a/src/MetroidPrime/CControlMapper.cpp +++ b/src/MetroidPrime/CControlMapper.cpp @@ -259,6 +259,8 @@ const char* ControlMapper::GetDescriptionForCommand(ECommands command) { return "Use Shield"; case kC_ScanItem: return "Scan Item"; + default: + break; } return "UNKNOWN"; diff --git a/src/MetroidPrime/Enemies/CJellyZap.cpp b/src/MetroidPrime/Enemies/CJellyZap.cpp new file mode 100644 index 00000000..2fcbe118 --- /dev/null +++ b/src/MetroidPrime/Enemies/CJellyZap.cpp @@ -0,0 +1,267 @@ +#include "MetroidPrime/Enemies/CJellyZap.hpp" + +#include "MetroidPrime/ScriptObjects/CFishCloud.hpp" + +#include "MetroidPrime/BodyState/CBodyController.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/ScriptObjects/CFishCloud.hpp" + +CJellyZap::CJellyZap(const TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& mData, + const CDamageInfo& attackDamage, const bool b1, const float attackRadius, + const float f2, const float f3, const float f4, const float attackDelay, + const float f6, const float f7, const float f8, const float priority, + const float repulseRadius, const float attractRadius, const float f12, + const CPatternedInfo& pInfo, const CActorParameters& actParms) +: CPatterned(kC_JellyZap, uid, name, kFT_Zero, info, xf, mData, pInfo, kMT_Flyer, kCT_One, + kBT_BiPedal, actParms, kKBV_Medium) +, x568_(0) +, x56c_attackDamage(attackDamage) +, x588_attackRadius(attackRadius) +, x58c_(f2) +, x590_(f4) +, x594_(f3) +, x598_(f8) +, x59c_priority(priority) +, x5a0_repulseRadius(repulseRadius) +, x5a4_attractRadius(attractRadius) +, x5a8_attackDelay(attackDelay) +, x5ac_(f6) +, x5b0_(f7) +, x5b4_(f12) +, x5b8_24_(false) +, x5b8_25_(false) +, x5b8_26_(b1) { + UpdateThermalFrozenState(true); + SetBaseDamageMag(0.f); +} + +void CJellyZap::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CJellyZap::Think(const float dt, CStateManager& mgr) { + CPatterned::Think(dt, mgr); + + if (!GetActive()) { + return; + } + + if (x5b8_24_) { + BodyCtrl()->FaceDirection(mgr.GetPlayer()->GetTranslation() - GetTranslation(), dt); + } + + float damage = x50c_baseDamageMag; + + if (x5b8_25_ && GetBodyCtrl()->GetPercentageFrozen() == 0.f) { + damage += dt / 0.3f; + } else { + damage -= dt / 0.75f; + } + + SetBaseDamageMag(CMath::Clamp(0.f, damage, 1.f)); +} + +void CJellyZap::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); + + switch (msg) { + case kSM_Activate: + AddAttractor(mgr); + break; + case kSM_Registered: + BodyCtrl()->Activate(mgr); + break; + case kSM_Deleted: + case kSM_Deactivate: + RemoveAllAttractors(mgr); + break; + default: + break; + } +} + +void CJellyZap::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, + float dt) { + + static CMaterialFilter playerFilter = CMaterialFilter::MakeInclude(CMaterialList(kMT_Player)); + bool skipCall = false; + switch (type) { + case kUE_DamageOn: { + mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), x56c_attackDamage, playerFilter); + skipCall = true; + } break; + default: + break; + } + + if (!skipCall) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); + } +} + +bool CJellyZap::InDetectionRange(CStateManager& mgr, float arg) { + if (mgr.GetPlayer()->IsInFluid() != true) { + return false; + } + return CPatterned::InDetectionRange(mgr, arg); +} + +bool CJellyZap::InAttackPosition(CStateManager& mgr, float arg) { + if (mgr.GetPlayer()->IsInFluid() != true) { + return false; + } + + return (mgr.GetPlayer()->GetTranslation() - GetTranslation()).MagSquared() < + x588_attackRadius * x588_attackRadius; +} + +bool CJellyZap::ShouldSpecialAttack(CStateManager& mgr, float arg) { return ClosestToPlayer(mgr); } + +bool CJellyZap::ShouldAttack(CStateManager& mgr, float arg) { + return GetStateMachineTime() > x5a8_attackDelay; +} + +void CJellyZap::InActive(CStateManager& mgr, EStateMsg msg, float arg) { + switch (msg) { + case kStateMsg_Activate: + SetWasHit(false); + BodyCtrl()->SetLocomotionType(pas::kLT_Relaxed); + AddAttractor(mgr); + x568_ = 0; + break; + default: + break; + } +} + +void CJellyZap::Active(CStateManager& mgr, EStateMsg msg, float arg) { + switch (msg) { + case kStateMsg_Activate: { + x5b8_24_ = true; + BodyCtrl()->SetLocomotionType(pas::kLT_Lurk); + x568_ = 0; + StateMachineState().SetDelay(GetPlayerLeashTime()); + } break; + case kStateMsg_Update: { + BodyCtrl()->CommandMgr().DeliverTargetVector( + (mgr.GetPlayer()->GetTranslation() + CVector3f(0.f, 0.f, 1.f)) - GetTranslation()); + + if (x5b8_26_) { + const CVector3f tmpMove = arg * (x598_ * CVector3f(0.f, 1.f, 0.f)); + const CVector3f moveToImpulse = + GetMoveToORImpulseWR(GetTransform().TransposeRotate(tmpMove), arg); + + ApplyImpulseOR(moveToImpulse, CAxisAngle::Identity()); + } + } break; + case kStateMsg_Deactivate: + x5b8_24_ = false; + break; + } +} + +void CJellyZap::Suck(CStateManager& mgr, EStateMsg msg, float arg) {} +bool CJellyZap::HitShell(const CVector3f&) const { return x568_ != 1; } + +EWeaponCollisionResponseTypes CJellyZap::GetCollisionResponseType(const CVector3f& pos, + const CVector3f&, + const CWeaponMode&, int) const { + EWeaponCollisionResponseTypes ret = kWCR_Unknown39; + if (HitShell(pos)) { + ret = kWCR_Unknown89; + } + + return ret; +} + +const CDamageVulnerability* CJellyZap::GetDamageVulnerability(const CVector3f& pos, + const CVector3f& dir, + const CDamageInfo& info) const { + if (HitShell(pos)) { + return &CDamageVulnerability::ReflectVulnerabilty(); + } + + return CAi::GetDamageVulnerability(); +} + +void CJellyZap::Attack(CStateManager& mgr, EStateMsg msg, float arg) {} + +void CJellyZap::Flinch(CStateManager& mgr, EStateMsg msg, float arg) { + switch (msg) { + case kStateMsg_Activate: + SetWasHit(false); + SetAnimationState(kAS_Ready); + StateMachineState().SetDelay(x5b0_); + break; + case kStateMsg_Update: + TryCommand(mgr, pas::kAS_KnockBack, &CPatterned::TryKnockBack, 0); + break; + case kStateMsg_Deactivate: + SetAnimationState(kAS_NotReady); + break; + } +} + +void CJellyZap::AddAttractor(CStateManager& mgr) { + AddSelfToFishCloud(mgr, x5a0_repulseRadius, x59c_priority, true); + AddSelfToFishCloud(mgr, x5a4_attractRadius, x59c_priority, false); +} + +void CJellyZap::RemoveAllAttractors(CStateManager& mgr) { RemoveSelfFromFishCloud(mgr); } + +void CJellyZap::AddRepulsor(CStateManager& mgr) { + AddSelfToFishCloud(mgr, x5a0_repulseRadius, x59c_priority, true); +} + +void CJellyZap::AddSelfToFishCloud(CStateManager& mgr, const float radius, const float priority, + const bool repulsor) { + for (AUTO(conn, GetConnectionList().begin()); conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Modify || conn->x4_msg != kSM_Follow) { + continue; + } + TUniqueId id = mgr.GetIdForScript(conn->x8_objId); + if (id == kInvalidUniqueId) { + continue; + } + + CFishCloud* fishCloud = TCastToPtr< CFishCloud >(mgr.ObjectById(id)); + if (!fishCloud) { + continue; + } + + if (repulsor) { + fishCloud->AddRepulsor(GetUniqueId(), false, radius, priority); + } else { + fishCloud->AddAttractor(GetUniqueId(), false, radius, priority); + } + } +} + +void CJellyZap::RemoveSelfFromFishCloud(CStateManager& mgr) { + for (AUTO(conn, GetConnectionList().begin()); conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state != kSS_Modify || conn->x4_msg != kSM_Follow) { + continue; + } + TUniqueId id = mgr.GetIdForScript(conn->x8_objId); + if (id == kInvalidUniqueId) { + continue; + } + + CFishCloud* fishCloud = TCastToPtr< CFishCloud >(mgr.ObjectById(id)); + if (!fishCloud) { + continue; + } + fishCloud->RemoveAttractor(GetUniqueId()); + fishCloud->RemoveRepulsor(GetUniqueId()); + } +} + +bool CJellyZap::ClosestToPlayer(CStateManager& mgr) const { return false; } + +void CJellyZap::KnockBack(const CVector3f& pos, CStateManager& mgr, const CDamageInfo& info, + const EKnockBackType type, const bool inDeferred, const float magnitude) { + if (info.GetWeaponMode().GetType() == kWT_Ice) { + const CVector3f newPos(0.f, 0.f, 0.f); + const CUnitVector3f dir = CUnitVector3f(GetTransform().TransposeRotate(pos)); + Freeze(mgr, newPos, dir, GetFreezeDuration()); + } +} diff --git a/src/MetroidPrime/Enemies/CThardus.cpp b/src/MetroidPrime/Enemies/CThardus.cpp new file mode 100644 index 00000000..452960be --- /dev/null +++ b/src/MetroidPrime/Enemies/CThardus.cpp @@ -0,0 +1,49 @@ +#include "MetroidPrime/Enemies/CThardus.hpp" + +#include "MetroidPrime/CActorParameters.hpp" + +#pragma inline_max_size(250) +CDestroyableRock::CDestroyableRock( + TUniqueId id, bool active, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const CModelData& modelData, float mass, const CHealthInfo& health, + const CDamageVulnerability& vulnerability, const CMaterialList& matList, CAssetId fsm, + const CActorParameters& actParams, const CModelData& phazonModel, int w1) +: CAi(id, active, name, info, xf, modelData, modelData.GetBounds(), mass, health, vulnerability, + matList, fsm, actParams, 0.3f, 0.8f) +, x2d8_phazonModel(phazonModel) +, x324_(0.f) +, x328_(0.f) +, x32c_thermalMag(actParams.GetThermalMag()) +, x330_(1.f, 1.f, 1.f) +, x334_isCold(false) +, x335_usePhazonModel(false) +, x338_healthInfo(health) +, x341_(w1 == 0) { + SetDoTargetDistanceTest(false); + x2d8_phazonModel.SetSortThermal(true); + SetDrawShadow(false); +} + +void CDestroyableRock::PreThink(float dt, CStateManager& mgr) { CEntity::PreThink(dt, mgr); } + +void CDestroyableRock::Think(float dt, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + float damageMag = x32c_thermalMag; + if (x324_ > 0.f) { + x324_ = CMath::Max(0.f, x324_ - dt); + x330_ = CColor::Lerp(CColor(0.f, 0.f, 0.f), CColor(0.5f, 0.0f, 0.0f), x324_); + if (x335_usePhazonModel) { + damageMag = x324_ * 0.5f + damageMag; + } else { + damageMag = x324_ * 0.25f + damageMag; + } + } + SetDamageMag(damageMag); + CEntity::Think(dt, mgr); +} + +void CThardus::RenderThermalSpot(float dt) const { +} \ No newline at end of file diff --git a/src/MetroidPrime/ScriptObjects/CScriptControllerAction.cpp b/src/MetroidPrime/ScriptObjects/CScriptControllerAction.cpp index ae9e9d34..98027f6d 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptControllerAction.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptControllerAction.cpp @@ -51,6 +51,6 @@ void CScriptControllerAction::Think(float dt, CStateManager& stateMgr) { } } -ControlMapper::ECommands CScriptControllerAction::GetCommand(CScriptControllerAction::ECommands c) { - return (ControlMapper::ECommands)(c); +ControlMapper::ECommands CScriptControllerAction::GetCommand(const ECommands cmd) { + return static_cast< ControlMapper::ECommands >(cmd); } diff --git a/src/MetroidPrime/Weapons/CElectricBeamProjectile.cpp b/src/MetroidPrime/Weapons/CElectricBeamProjectile.cpp index 124d1ce5..4c99af9d 100644 --- a/src/MetroidPrime/Weapons/CElectricBeamProjectile.cpp +++ b/src/MetroidPrime/Weapons/CElectricBeamProjectile.cpp @@ -33,13 +33,6 @@ void CElectricBeamProjectile::Accept(IVisitor& visitor) { visitor.Visit(*this); void CElectricBeamProjectile::Touch(CActor&, CStateManager&) {} -void CElectricBeamProjectile::AddToRenderer(const CFrustumPlanes&, const CStateManager& mgr) const { - if (GetActive()) { - gpRender->AddParticleGen(*x478_elementGen); - gpRender->AddParticleGen(*x468_electric); - } -} - void CElectricBeamProjectile::UpdateFx(const CTransform4f& xf, float dt, CStateManager& mgr) { if (!GetActive()) return; @@ -89,6 +82,19 @@ void CElectricBeamProjectile::UpdateFx(const CTransform4f& xf, float dt, CStateM x468_electric->Update(dt); } +void CElectricBeamProjectile::AddToRenderer(const CFrustumPlanes&, const CStateManager& mgr) const { + if (GetActive()) { + gpRender->AddParticleGen(*x478_elementGen); + gpRender->AddParticleGen(*x468_electric); + } +} + +void CElectricBeamProjectile::Fire(const CTransform4f&, CStateManager&, bool) { + x48c_ = true; + SetActive(true); + x480_intensity = 0.f; +} + void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) { if (b) { SetActive(false); @@ -100,12 +106,6 @@ void CElectricBeamProjectile::ResetBeam(CStateManager& mgr, bool b) { } } -void CElectricBeamProjectile::Fire(const CTransform4f&, CStateManager&, bool) { - x48c_ = true; - SetActive(true); - x480_intensity = 0.f; -} - void CElectricBeamProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { switch (msg) { diff --git a/src/MetroidPrime/Weapons/CPhazonBeam.cpp b/src/MetroidPrime/Weapons/CPhazonBeam.cpp index a9d41472..332a7696 100644 --- a/src/MetroidPrime/Weapons/CPhazonBeam.cpp +++ b/src/MetroidPrime/Weapons/CPhazonBeam.cpp @@ -75,7 +75,7 @@ void CPhazonBeam::PostRenderGunFx(const CStateManager& mgr, const CTransform4f& CGunWeapon::PostRenderGunFx(mgr, xf); } -void CPhazonBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, +void CPhazonBeam::UpdateGunFx(const bool shotSmoke, const float dt, const CStateManager& mgr, const CTransform4f& xf) { if (!mChargeFxGen.null()) { mChargeFxGen->SetGlobalOrientAndTrans(xf); diff --git a/src/MetroidPrime/Weapons/GunController/CGunController.cpp b/src/MetroidPrime/Weapons/GunController/CGunController.cpp index 7e967571..d0e27cee 100644 --- a/src/MetroidPrime/Weapons/GunController/CGunController.cpp +++ b/src/MetroidPrime/Weapons/GunController/CGunController.cpp @@ -1,5 +1,12 @@ #include "MetroidPrime/Weapons/GunController/CGunController.hpp" +#include "Kyoto/Animation/CPASAnimParm.hpp" +#include "Kyoto/Animation/CPASAnimParmData.hpp" +#include "Kyoto/Animation/CPASDatabase.hpp" +#include "MetroidPrime/CAnimData.hpp" +#include "MetroidPrime/CModelData.hpp" +#include "MetroidPrime/CStateManager.hpp" + CGunController::CGunController(CModelData& modelData) : x0_modelData(modelData) , x50_gunState(kGS_Inactive) @@ -7,22 +14,183 @@ CGunController::CGunController(CModelData& modelData) , x58_24_animDone(true) , x58_25_enteredComboFire(false) {} -void CGunController::EnterFreeLook(CStateManager&, int, int) {} +void CGunController::EnterFreeLook(CStateManager& mgr, const int gunId, const int setId) { + if (x50_gunState != kGS_ComboFire && !x58_25_enteredComboFire) { + x54_curAnimId = x4_freeLook.SetAnim(*x0_modelData.AnimationData(), gunId, setId, 0, mgr, 0.f); + } else { + x4_freeLook.SetLoopState(x1c_comboFire.GetLoopState()); + } -void CGunController::EnterComboFire(CStateManager&, int) {} + x50_gunState = kGS_FreeLook; +} -void CGunController::EnterFidget(CStateManager&, int, int, int) {} +void CGunController::EnterComboFire(CStateManager& mgr, const int gunId) { + if (x50_gunState != kGS_FreeLook) { + x54_curAnimId = x1c_comboFire.SetAnim(*x0_modelData.AnimationData(), gunId, 0, mgr, 0.f); + } else { + x1c_comboFire.SetLoopState(x4_freeLook.GetLoopState()); + } -void CGunController::EnterStruck(CStateManager&, float, bool, bool) {} + x50_gunState = kGS_ComboFire; + x58_25_enteredComboFire = true; +} -void CGunController::LoadFidgetAnimAsync(CStateManager&, int, int, int) {} +void CGunController::EnterFidget(CStateManager& mgr, const int type, const int gunId, + const int setId) { + x54_curAnimId = x30_fidget.SetAnim(*x0_modelData.AnimationData(), type, gunId, setId, mgr); + x50_gunState = kGS_Fidget; +} -int CGunController::Update(float, CStateManager&) { return 0; } +void CGunController::EnterStruck(CStateManager& mgr, const float angle, const bool bigStrike, + const bool b2) { + switch (x50_gunState) { + case kGS_FreeLook: + x4_freeLook.SetIdle(true); + break; + case kGS_Inactive: + case kGS_Fidget: + break; + default: + return; + } + const CPASAnimParmData aparam = + CPASAnimParmData(pas::kAS_LieOnGround, CPASAnimParm::FromInt32(x4_freeLook.GetGunId()), + CPASAnimParm::FromReal32(angle), CPASAnimParm::FromBool(bigStrike), + CPASAnimParm::FromBool(b2)); + CAnimData& animData = *x0_modelData.AnimationData(); + const rstl::pair< float, int > anim = + animData.GetPASDatabase().FindBestAnimation(aparam, *mgr.Random(), -1); + animData.EnableLooping(false); + animData.SetAnimation(CAnimPlaybackParms(anim.second, -1, 1.f, true), false); + x54_curAnimId = anim.second; + x50_gunState = bigStrike ? kGS_BigStrike : kGS_Strike; +} -void CGunController::EnterIdle(CStateManager&) {} +void CGunController::LoadFidgetAnimAsync(CStateManager& mgr, const int type, const int gunId, + const int setId) { + x30_fidget.LoadAnimAsync(*x0_modelData.AnimationData(), type, gunId, setId, mgr); +} -void CGunController::ReturnToDefault(CStateManager&, float, bool) {} +int CGunController::Update(float dt, CStateManager& mgr) { + CAnimData& animData = *x0_modelData.AnimationData(); + x58_24_animDone = false; + switch (x50_gunState) { + case kGS_FreeLook: { + x58_24_animDone = x4_freeLook.Update(animData, dt, mgr); + if (!x58_24_animDone || !x58_25_enteredComboFire) { + break; + } -void CGunController::Reset() {} + EnterComboFire(mgr, x4_freeLook.GetGunId()); + x58_24_animDone = false; + break; + } + case kGS_ComboFire: + x58_24_animDone = x1c_comboFire.Update(animData, dt, mgr); + break; + case kGS_Fidget: + x58_24_animDone = x30_fidget.Update(animData, dt, mgr); + break; + case kGS_Strike: { + if (animData.IsAnimTimeRemaining(0.001f, rstl::string_l("Whole Body"))) { + break; + } -void CGunController::ReturnToBasePosition(CStateManager&) {} + x54_curAnimId = x4_freeLook.SetAnim(*x0_modelData.AnimationData(), x4_freeLook.GetGunId(), + x4_freeLook.GetSetId(), 0, mgr, 0.f); + x50_gunState = kGS_FreeLook; + break; + } + case kGS_BigStrike: + x58_24_animDone = !animData.IsAnimTimeRemaining(0.001f, rstl::string_l("Whole Body")); + break; + case kGS_Inactive: + case kGS_Default: + case kGS_Idle: + break; + } + + if (x58_24_animDone) { + x50_gunState = kGS_Inactive; + x58_25_enteredComboFire = false; + return true; + } + return false; +} + +void CGunController::EnterIdle(CStateManager& mgr) { + CPASAnimParm parm = CPASAnimParm::NoParameter(); + switch (x50_gunState) { + case kGS_FreeLook: + parm = CPASAnimParm::FromEnum(1); + x4_freeLook.SetIdle(true); + break; + case kGS_ComboFire: + parm = CPASAnimParm::FromEnum(1); + x1c_comboFire.SetIdle(true); + break; + default: + return; + } + + CAnimData& animData = *x0_modelData.AnimationData(); + const rstl::pair< float, int > anim = + animData.GetCharacterInfo().GetPASDatabase().FindBestAnimation( + CPASAnimParmData(pas::kAS_Locomotion, parm), *mgr.Random(), -1); + animData.EnableLooping(false); + animData.SetAnimation(CAnimPlaybackParms(anim.second, -1, 1.f, true), false); + x54_curAnimId = anim.second; + x50_gunState = kGS_Idle; + x58_25_enteredComboFire = false; +} + +void CGunController::ReturnToDefault(CStateManager& mgr, const float dt, const bool setState) { + CAnimData& animData = *x0_modelData.AnimationData(); + + switch (x50_gunState) { + case kGS_Strike: + x50_gunState = kGS_FreeLook; + case kGS_Idle: + x4_freeLook.SetIdle(false); + case kGS_FreeLook: + if (setState) { + break; + } + x54_curAnimId = + x4_freeLook.SetAnim(animData, x4_freeLook.GetGunId(), x4_freeLook.GetSetId(), 2, mgr, dt); + x58_25_enteredComboFire = false; + break; + case kGS_ComboFire: + x54_curAnimId = x1c_comboFire.SetAnim(animData, x1c_comboFire.GetGunId(), 2, mgr, dt); + break; + case kGS_Fidget: + ReturnToBasePosition(mgr); + break; + case kGS_BigStrike: + x4_freeLook.SetIdle(false); + break; + default: + break; + } + + if (setState) { + x50_gunState = kGS_Default; + } +} + +void CGunController::Reset() { + x58_24_animDone = true; + x58_25_enteredComboFire = false; + x50_gunState = kGS_Inactive; +} + +void CGunController::ReturnToBasePosition(CStateManager& mgr) { + CAnimData& animData = *x0_modelData.AnimationData(); + const rstl::pair< float, int > anim = + animData.GetCharacterInfo().GetPASDatabase().FindBestAnimation( + CPASAnimParmData(pas::kAS_KnockBack), *mgr.Random(), -1); + animData.EnableLooping(false); + animData.SetAnimation(CAnimPlaybackParms(anim.second, -1, 1.f, true), false); + x54_curAnimId = anim.second; + x58_25_enteredComboFire = false; +}