diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp index 4e0a90625..cc613ed4a 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp @@ -31,6 +31,14 @@ struct SChargedShotParam : SShotParam bool Charged() const { return true; } }; +struct SWeaponInfo : BigYAML +{ + DECL_YAML + Value x0_coolDown = 0.1f; + SShotParam x4_normal; + SChargedShotParam x20_charged; +}; + struct ITweakPlayerGun : ITweak { DECL_YAML @@ -55,6 +63,8 @@ struct ITweakPlayerGun : ITweak virtual const zeus::CVector3f& GetGunPosition() const = 0; virtual const zeus::CVector3f& GetGrapplingArmPosition() const = 0; virtual float GetRichochetDamage(atUint32) const = 0; + virtual const SWeaponInfo& GetBeamInfo(atInt32 beam) const = 0; + virtual const SComboShotParam& GetComboShotInfo(atInt32 beam) const = 0; }; } diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp index 764372bdb..a4e30e810 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp @@ -35,13 +35,6 @@ struct CTweakPlayerGun : ITweakPlayerGun SShotParam x70_bomb; SShotParam x8c_powerBomb; SShotParam x1d4_missile; - struct SWeaponInfo : BigYAML - { - DECL_YAML - Value x0_coolDown = 0.1f; - SShotParam x4_normal; - SChargedShotParam x20_charged; - }; SWeaponInfo xa8_beams[5]; SComboShotParam x1f0_combos[5]; // Originally rstl::prereserved_vector Value x280_ricochetData[6]; // Originally rstl::prereserved_vector, extended to 6 to capture @@ -103,12 +96,19 @@ struct CTweakPlayerGun : ITweakPlayerGun } } - SWeaponInfo GetBeamInfo(atInt32 beam) const + const SWeaponInfo& GetBeamInfo(atInt32 beam) const { if (beam < 0 || beam > 5) return xa8_beams[0]; return xa8_beams[beam]; } + + const SComboShotParam& GetComboShotInfo(atInt32 beam) const + { + if (beam < 0 || beam > 5) + return x1f0_combos[0]; + return x1f0_combos[beam]; + } }; } } diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 47f01b73f..6e022ea02 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -543,7 +543,7 @@ bool CAnimData::IsAnimTimeRemaining(float rem, const std::string& name) const { if (!x1f8_animRoot) return false; - return x1f8_animRoot->VGetTimeRemaining().GetSeconds() <= rem; + return x1f8_animRoot->VGetTimeRemaining().GetSeconds() >= rem; } float CAnimData::GetAnimTimeRemaining(const std::string& name) const diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 0e0b65f53..e6810a4ae 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -49,7 +49,7 @@ SAdvancementDeltas CModelData::GetAdvancementDeltas(const CCharAnimTime& a, } void CModelData::Render(const CStateManager& stateMgr, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags) + const CActorLights* lights, const CModelFlags& drawFlags) const { Render(GetRenderingModel(stateMgr), xf, lights, drawFlags); } @@ -293,7 +293,7 @@ void CModelData::Touch(const CStateManager& stateMgr, int shaderIdx) const } void CModelData::RenderThermal(const zeus::CTransform& xf, - const zeus::CColor& a, const zeus::CColor& b) + const zeus::CColor& a, const zeus::CColor& b) const { CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); CGraphics::DisableAllLights(); @@ -314,7 +314,7 @@ void CModelData::RenderThermal(const zeus::CTransform& xf, } void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags) + const CActorLights* lights, const CModelFlags& drawFlags) const { if ((x14_25_sortThermal && which == EWhichModel::Thermal) || x10_animData || !x1c_normalModel || drawFlags.x0_blendMode > 2) @@ -338,7 +338,7 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& } void CModelData::Render(EWhichModel which, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags) + const CActorLights* lights, const CModelFlags& drawFlags) const { if (x14_25_sortThermal && which == EWhichModel::Thermal) { diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index 1cea163cd..a999c8d17 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -110,7 +110,7 @@ public: SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; void Render(const CStateManager& stateMgr, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags); + const CActorLights* lights, const CModelFlags& drawFlags) const; static EWhichModel GetRenderingModel(const CStateManager& stateMgr); CSkinnedModel& PickAnimatedModel(EWhichModel which) const; const std::unique_ptr& PickStaticModel(EWhichModel which) const; @@ -134,11 +134,11 @@ public: void RenderParticles(const zeus::CFrustum& frustum) const; void Touch(EWhichModel, int shaderIdx) const; void Touch(const CStateManager& stateMgr, int shaderIdx) const; - void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& a, const zeus::CColor& b); + void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& a, const zeus::CColor& b) const; void RenderUnsortedParts(EWhichModel, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags); + const CActorLights* lights, const CModelFlags& drawFlags) const; void Render(EWhichModel, const zeus::CTransform& xf, - const CActorLights* lights, const CModelFlags& drawFlags); + const CActorLights* lights, const CModelFlags& drawFlags) const; void InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, const zeus::CColor& color0, const zeus::CColor& color1); diff --git a/Runtime/Input/CRumbleManager.hpp b/Runtime/Input/CRumbleManager.hpp index b241b3216..db706f2b1 100644 --- a/Runtime/Input/CRumbleManager.hpp +++ b/Runtime/Input/CRumbleManager.hpp @@ -15,7 +15,7 @@ public: bool IsDisabled() const { return xf0_24_disabled; } void SetDisabled(bool disabled); void Update(float); - void StopRumble(u16) {} + void StopRumble(s16) {} void Rumble(CStateManager&, ERumbleFxId, ERumblePriority priority) {} void Rumble(CStateManager&, ERumbleFxId, float, ERumblePriority priority) {} }; diff --git a/Runtime/MP1/CSamusFaceReflection.cpp b/Runtime/MP1/CSamusFaceReflection.cpp index 33eb0909c..ea4293a60 100644 --- a/Runtime/MP1/CSamusFaceReflection.cpp +++ b/Runtime/MP1/CSamusFaceReflection.cpp @@ -66,7 +66,7 @@ void CSamusFaceReflection::Draw(const CStateManager& mgr) const CActorLights* lights = x6c_ == 1 ? nullptr : x4c_lights.get(); if (x6c_ == 3) { - const_cast(x0_modelData).Render(mgr, modelXf, lights, CModelFlags(0, 0, 3, zeus::CColor::skWhite)); + x0_modelData.Render(mgr, modelXf, lights, CModelFlags(0, 0, 3, zeus::CColor::skWhite)); } else { @@ -77,8 +77,8 @@ void CSamusFaceReflection::Draw(const CStateManager& mgr) const transFactor = 0.f; if (transFactor > 0.f) { - const_cast(x0_modelData).Render(mgr, modelXf, nullptr, CModelFlags(7, 0, 3, zeus::CColor::skBlack)); - const_cast(x0_modelData).Render(mgr, modelXf, lights, CModelFlags(7, 0, 1, zeus::CColor(1.f, transFactor))); + x0_modelData.Render(mgr, modelXf, nullptr, CModelFlags(7, 0, 3, zeus::CColor::skBlack)); + x0_modelData.Render(mgr, modelXf, lights, CModelFlags(7, 0, 1, zeus::CColor(1.f, transFactor))); } } } diff --git a/Runtime/Weapon/CAuxWeapon.cpp b/Runtime/Weapon/CAuxWeapon.cpp index fd5beb3e0..6fe5591db 100644 --- a/Runtime/Weapon/CAuxWeapon.cpp +++ b/Runtime/Weapon/CAuxWeapon.cpp @@ -23,4 +23,14 @@ void CAuxWeapon::Load(int curBeam, CStateManager& mgr) } +void CAuxWeapon::StopComboFx(CStateManager& mgr, bool b1) +{ + +} + +void CAuxWeapon::LoadIdle() +{ + +} + } diff --git a/Runtime/Weapon/CAuxWeapon.hpp b/Runtime/Weapon/CAuxWeapon.hpp index 42beecd03..092db769e 100644 --- a/Runtime/Weapon/CAuxWeapon.hpp +++ b/Runtime/Weapon/CAuxWeapon.hpp @@ -9,11 +9,15 @@ namespace urde class CAuxWeapon { + bool x80_24_isLoaded : 1; public: explicit CAuxWeapon(TUniqueId id); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); bool IsComboFxActive(const CStateManager& mgr) const; void Load(int curBeam, CStateManager& mgr); + void StopComboFx(CStateManager& mgr, bool b1); + void LoadIdle(); + bool IsLoaded() const { return x80_24_isLoaded; } }; } diff --git a/Runtime/Weapon/CFidget.cpp b/Runtime/Weapon/CFidget.cpp index e69de29bb..53583850f 100644 --- a/Runtime/Weapon/CFidget.cpp +++ b/Runtime/Weapon/CFidget.cpp @@ -0,0 +1,22 @@ +#include "CFidget.hpp" + +namespace urde +{ + +void CFidget::ResetAll() +{ + x0_state = EState::Zero; + x4_ = -1; + x18_ = 0.f; + x1c_ = 0.f; + x14_ = 0.f; + x24_ = 0.f; + x28_ = 0.f; + x2c_ = 0.f; + x8_ = 0; + xc_ = -1; + x10_ = 3; + x34_24_ = false; +} + +} \ No newline at end of file diff --git a/Runtime/Weapon/CFidget.hpp b/Runtime/Weapon/CFidget.hpp index 8a9bae1d8..2266030db 100644 --- a/Runtime/Weapon/CFidget.hpp +++ b/Runtime/Weapon/CFidget.hpp @@ -8,10 +8,23 @@ namespace urde class CFidget { - u32 x0_ = 0; - u32 x4_ = -1; +public: + enum class EState + { + Zero, + One, + Two, + Three, + Four, + Five, + Six, + Seven + }; +private: + EState x0_state = EState::Zero; + s32 x4_ = -1; u32 x8_ = 0; - u32 xc_ = -1; + s32 xc_ = -1; u32 x10_ = 3; float x14_ = 0.f; float x18_ = 0.f; @@ -23,7 +36,8 @@ class CFidget float x30_ = 105.f; bool x34_24_ = false; public: - + EState GetState() const { return x0_state; } + void ResetAll(); }; } diff --git a/Runtime/Weapon/CGSComboFire.cpp b/Runtime/Weapon/CGSComboFire.cpp index f8a37caca..d4f447773 100644 --- a/Runtime/Weapon/CGSComboFire.cpp +++ b/Runtime/Weapon/CGSComboFire.cpp @@ -1,31 +1,76 @@ #include "CGSComboFire.hpp" #include "Character/CAnimData.hpp" +#include "Character/CPASAnimParmData.hpp" +#include "CStateManager.hpp" namespace urde { -bool CGSComboFire::Update(CAnimData& aData, float dt, CStateManager& mgr) +bool CGSComboFire::Update(CAnimData& data, float dt, CStateManager& mgr) { - if (x8_ == -1) + if (x8_cueAnimId != -1) { - + x0_delay -= dt; + if (x0_delay <= 0.f) + { + data.EnableLooping(x4_loopState == 1); + CAnimPlaybackParms aparms(x8_cueAnimId, -1, 1.f, true); + data.SetAnimation(aparms, false); + x0_delay = 0.f; + x8_cueAnimId = -1; + } } - else + else if (!data.IsAnimTimeRemaining(0.001f, "Whole Body")) { - x0_timeRemaining -= dt; - if (x0_timeRemaining > 0.f) - return false; - - //aData.x220_25_loop = (x4_ - 1) != 0; - //aData.x220_24_animating = true; + switch (x4_loopState) + { + case 0: + SetAnim(data, xc_gunId, 1, mgr, 0.f); + switch (xc_gunId) + { + case 4: + case 0: + case 1: + x10_24_over = true; + break; + default: + break; + } + break; + case 2: + x4_loopState = -1; + return true; + default: + break; + } } - return false; } -void CGSComboFire::SetAnim(CAnimData&, s32, s32, CStateManager&, float) +s32 CGSComboFire::SetAnim(CAnimData& data, s32 gunId, s32 loopState, CStateManager& mgr, float delay) { - + s32 useLoopState = 2; + if (!x10_25_idle) + useLoopState = loopState; + x10_25_idle = false; + const CPASDatabase& pas = data.GetCharacterInfo().GetPASDatabase(); + CPASAnimParmData parms(4, CPASAnimParm::FromInt32(gunId), CPASAnimParm::FromEnum(useLoopState)); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + x10_24_over = false; + xc_gunId = gunId; + x4_loopState = useLoopState; + if (delay != 0.f) + { + x0_delay = delay; + x8_cueAnimId = anim.second; + } + else + { + data.EnableLooping(loopState == 1); + CAnimPlaybackParms aparms(anim.second, -1, 1.f, true); + data.SetAnimation(aparms, false); + } + return anim.second; } } diff --git a/Runtime/Weapon/CGSComboFire.hpp b/Runtime/Weapon/CGSComboFire.hpp index cba8c8159..103136d2a 100644 --- a/Runtime/Weapon/CGSComboFire.hpp +++ b/Runtime/Weapon/CGSComboFire.hpp @@ -10,28 +10,28 @@ class CAnimData; class CStateManager; class CGSComboFire { - float x0_timeRemaining = 0.f; - u32 x4_ = -1; - u32 x8_ = -1; - u32 xc_ = -1; + float x0_delay = 0.f; + s32 x4_loopState = -1; // In, loop, out + s32 x8_cueAnimId = -1; + s32 xc_gunId = -1; union { struct { - bool x10_24_ : 1; - bool x10_25_ : 1; + bool x10_24_over : 1; + bool x10_25_idle : 1; }; u8 _dummy = 0; }; public: - bool IsComboOver() const; - s32 GetLoopState() const; - void SetLoopState(s32); - void SetIdle(bool); - void GetGunId() const; - bool Update(CAnimData&, float, CStateManager&); - void SetAnim(CAnimData&, s32, s32, CStateManager&, float); + bool IsComboOver() const { return x10_24_over; } + s32 GetLoopState() const { return x4_loopState; } + void SetLoopState(s32 l) { x4_loopState = l; } + void SetIdle(bool i) { x10_25_idle = i; } + s32 GetGunId() const { return xc_gunId; } + bool Update(CAnimData& data, float dt, CStateManager& mgr); + s32 SetAnim(CAnimData& data, s32 gunId, s32 loopState, CStateManager& mgr, float delay); }; } diff --git a/Runtime/Weapon/CGSFidget.cpp b/Runtime/Weapon/CGSFidget.cpp index b4c29c4ff..13b5cd2ca 100644 --- a/Runtime/Weapon/CGSFidget.cpp +++ b/Runtime/Weapon/CGSFidget.cpp @@ -1,9 +1,51 @@ #include "CGSFidget.hpp" +#include "WeaponCommon.hpp" +#include "Character/CPASAnimParmData.hpp" +#include "Character/CAnimData.hpp" +#include "CStateManager.hpp" namespace urde { -bool CGSFidget::Update(CAnimData&, float, CStateManager&) +bool CGSFidget::Update(CAnimData& data, float dt, CStateManager& mgr) { - return false; + return !data.IsAnimTimeRemaining(0.001f, "Whole Body"); +} + +s32 CGSFidget::SetAnim(CAnimData& data, s32 type, s32 parm1, s32 parm2, CStateManager& mgr) +{ + const CPASDatabase& pas = data.GetCharacterInfo().GetPASDatabase(); + CPASAnimParmData parms(1, CPASAnimParm::FromEnum(type), CPASAnimParm::FromInt32(parm1), + CPASAnimParm::FromEnum(parm2)); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + bool loop = pas.GetAnimState(1)->GetAnimParmData(anim.second, 3).GetBoolValue(); + x14_parm1 = parm1; + x18_parm2 = parm2; + if (anim.second != -1) + { + data.EnableLooping(loop); + CAnimPlaybackParms aParms(anim.second, -1, 1.f, true); + data.SetAnimation(aParms, false); + UnLoadAnim(); + } + return anim.second; +} + +void CGSFidget::LoadAnimAsync(CAnimData& data, s32 type, s32 parm1, s32 parm2, CStateManager& mgr) +{ + CPASAnimParmData parms(1, CPASAnimParm::FromEnum(type), CPASAnimParm::FromInt32(parm1), + CPASAnimParm::FromEnum(parm2)); + auto anim = data.GetCharacterInfo().GetPASDatabase().FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + if (anim.second != -1) + NWeaponTypes::get_token_vector(data, anim.second, x0_anims, true); +} + +void CGSFidget::UnLoadAnim() +{ + x0_anims.clear(); +} + +bool CGSFidget::IsAnimLoaded() const +{ + return NWeaponTypes::are_tokens_ready(x0_anims); } } diff --git a/Runtime/Weapon/CGSFidget.hpp b/Runtime/Weapon/CGSFidget.hpp index 3f6558fba..bee091fde 100644 --- a/Runtime/Weapon/CGSFidget.hpp +++ b/Runtime/Weapon/CGSFidget.hpp @@ -2,6 +2,7 @@ #define __URDE_CGSFIDGET_HPP__ #include "RetroTypes.hpp" +#include "CToken.hpp" namespace urde { @@ -9,16 +10,14 @@ class CAnimData; class CStateManager; class CGSFidget { - u32 x4_ = 0; - u32 x8_ = 0; - u32 xc_ = 0; - u32 x10_ = -1; - u32 x14_ = -1; - u32 x18_ = -1; + std::vector x0_anims; + s32 x10_ = -1; + s32 x14_parm1 = -1; + s32 x18_parm2 = -1; public: - bool Update(CAnimData&, float, CStateManager&); - void SetAnim(CAnimData&, s32, s32, s32, CStateManager&); - void LoadAnimAsync(CAnimData, s32, s32, s32, CStateManager&); + bool Update(CAnimData& data, float dt, CStateManager& mgr); + s32 SetAnim(CAnimData& data, s32 type, s32 parm1, s32 parm2, CStateManager& mgr); + void LoadAnimAsync(CAnimData& data, s32 type, s32 parm1, s32 parm2, CStateManager& mgr); void UnLoadAnim(); bool IsAnimLoaded() const; }; diff --git a/Runtime/Weapon/CGSFreeLook.cpp b/Runtime/Weapon/CGSFreeLook.cpp index 44cfc6f32..05203e67f 100644 --- a/Runtime/Weapon/CGSFreeLook.cpp +++ b/Runtime/Weapon/CGSFreeLook.cpp @@ -1,21 +1,66 @@ #include "CGSFreeLook.hpp" #include "CStateManager.hpp" -#include "Character/CAnimData.hpp" +#include "Character/CPASAnimParmData.hpp" namespace urde { -s32 CGSFreeLook::GetSetId() const -{ - return -1; -} -bool CGSFreeLook::Update(CAnimData& animData, float dt, CStateManager& mgr) +bool CGSFreeLook::Update(CAnimData& data, float dt, CStateManager& mgr) { + if (x4_cueAnimId != -1) + { + x0_delay -= dt; + if (x0_delay <= 0.f) + { + data.EnableLooping(x8_loopState == 1); + CAnimPlaybackParms aparms(x4_cueAnimId, -1, 1.f, true); + data.SetAnimation(aparms, false); + x0_delay = 0.f; + x4_cueAnimId = -1; + } + } + else if (!data.IsAnimTimeRemaining(0.001f, "Whole Body")) + { + switch (x8_loopState) + { + case 0: + SetAnim(data, xc_gunId, x10_setId, 1, mgr, 0.f); + break; + case 2: + x8_loopState = -1; + return true; + default: + break; + } + } return false; } -u32 CGSFreeLook::SetAnim(CAnimData&, s32, s32, s32, CStateManager&, float) +s32 CGSFreeLook::SetAnim(CAnimData& data, s32 gunId, s32 setId, s32 loopState, CStateManager& mgr, float delay) { - return 0; + s32 useLoopState = 1; + if (!x14_idle) + useLoopState = loopState; + x14_idle = false; + const CPASDatabase& pas = data.GetCharacterInfo().GetPASDatabase(); + CPASAnimParmData parms(3, CPASAnimParm::FromInt32(gunId), + CPASAnimParm::FromInt32(setId), CPASAnimParm::FromEnum(useLoopState)); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + xc_gunId = gunId; + x10_setId = pas.GetAnimState(3)->GetAnimParmData(anim.second, 1).GetInt32Value(); + x8_loopState = useLoopState; + if (delay != 0.f) + { + x0_delay = delay; + x4_cueAnimId = anim.second; + } + else + { + data.EnableLooping(loopState == 1); + CAnimPlaybackParms aparms(anim.second, -1, 1.f, true); + data.SetAnimation(aparms, false); + } + return anim.second; } + } diff --git a/Runtime/Weapon/CGSFreeLook.hpp b/Runtime/Weapon/CGSFreeLook.hpp index 4d622e234..625098dc3 100644 --- a/Runtime/Weapon/CGSFreeLook.hpp +++ b/Runtime/Weapon/CGSFreeLook.hpp @@ -10,20 +10,20 @@ class CAnimData; class CStateManager; class CGSFreeLook { - friend class CGunController; - float x0_ = 0.f; - s32 x4_ = -1; - u32 x8_ = -1; - u32 xc_ = 0; - u32 x10_ = -1; - bool x14_ = false; + float x0_delay = 0.f; + s32 x4_cueAnimId = -1; + s32 x8_loopState = -1; // In, loop, out + s32 xc_gunId = 0; + s32 x10_setId = -1; + bool x14_idle = false; public: - s32 GetSetId() const; - void SetLoopState(s32); - s32 GetLoopState() const; - s32 GetGunId() const; - bool Update(CAnimData&, float, CStateManager&); - u32 SetAnim(CAnimData&, s32, s32, s32, CStateManager&, float); + s32 GetSetId() const { return x10_setId; } + void SetLoopState(s32 l) { x8_loopState = l; } + s32 GetLoopState() const { return x8_loopState; } + void SetIdle(bool l) { x14_idle = l; } + s32 GetGunId() const { return xc_gunId; } + bool Update(CAnimData& data, float dt, CStateManager& mgr); + s32 SetAnim(CAnimData& data, s32 gunId, s32 setId, s32 loopState, CStateManager& mgr, float delay); }; diff --git a/Runtime/Weapon/CGrappleArm.cpp b/Runtime/Weapon/CGrappleArm.cpp index fbc6ea1e9..7e9883ec7 100644 --- a/Runtime/Weapon/CGrappleArm.cpp +++ b/Runtime/Weapon/CGrappleArm.cpp @@ -41,6 +41,11 @@ void CGrappleArm::TouchModel(const CStateManager& mgr) const } +void CGrappleArm::Update(float grappleSwingT, float dt, CStateManager& mgr) +{ + +} + void CGrappleArm::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) { @@ -56,4 +61,9 @@ void CGrappleArm::EnterIdle(CStateManager& mgr) } +void CGrappleArm::ReturnToDefault(CStateManager& mgr, float f1, bool b1) +{ + +} + } diff --git a/Runtime/Weapon/CGrappleArm.hpp b/Runtime/Weapon/CGrappleArm.hpp index 34eca7ad8..504e0dd6b 100644 --- a/Runtime/Weapon/CGrappleArm.hpp +++ b/Runtime/Weapon/CGrappleArm.hpp @@ -5,6 +5,7 @@ #include "zeus/CVector3f.hpp" #include "Character/CModelData.hpp" #include "CStateManager.hpp" +#include "CGunController.hpp" namespace urde { @@ -29,14 +30,17 @@ public: private: CModelData x0_modelData; zeus::CTransform x220_xf; + std::unique_ptr x328_gunController; EArmState x334_animState; union { struct { - bool x3b2_24_inGrappleCycle : 1; + bool x3b2_24_active : 1; bool x3b2_25_beamActive : 1; bool x3b2_27_armMoving : 1; + bool x3b2_28_isGrappling : 1; + bool x3b2_29_suitLoading : 1; }; u32 _dummy = 0; }; @@ -48,17 +52,22 @@ public: const zeus::CTransform& GetTransform() const { return x220_xf; } void SetAnimState(EArmState state); EArmState GetAnimState() const { return x334_animState; } - bool InGrappleCycle() const { return x3b2_24_inGrappleCycle; } + bool GetActive() const { return x3b2_24_active; } bool BeamActive() const { return x3b2_25_beamActive; } bool IsArmMoving() const { return x3b2_27_armMoving; } + bool IsGrappling() const { return x3b2_28_isGrappling; } + bool IsSuitLoading() const { return x3b2_29_suitLoading; } void Activate(bool); void GrappleBeamDisconnected(); void GrappleBeamConnected(); void RenderGrappleBeam(const CStateManager& mgr, const zeus::CVector3f& pos); void TouchModel(const CStateManager& mgr) const; + void Update(float grappleSwingT, float dt, CStateManager& mgr); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void EnterStruck(CStateManager& mgr, float angle, bool attack, bool b2); void EnterIdle(CStateManager& mgr); + void ReturnToDefault(CStateManager& mgr, float f1, bool b1); + CGunController* GunController() { return x328_gunController.get(); } }; } diff --git a/Runtime/Weapon/CGunController.cpp b/Runtime/Weapon/CGunController.cpp index e811c93e9..198665318 100644 --- a/Runtime/Weapon/CGunController.cpp +++ b/Runtime/Weapon/CGunController.cpp @@ -6,54 +6,94 @@ namespace urde { -void CGunController::UnLoadFidget() +void CGunController::LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 parm1, s32 parm2) { - + x30_fidget.LoadAnimAsync(*x0_modelData.AnimationData(), type, parm1, parm2, mgr); } -void CGunController::LoadFidgetAnimAsync(CStateManager &, s32, s32, s32) +void CGunController::EnterFidget(CStateManager& mgr, s32 type, s32 parm1, s32 parm2) { - + x54_curAnimId = x30_fidget.SetAnim(*x0_modelData.AnimationData(), type, parm1, parm2, mgr); + x50_gunState = EGunState::Fidget; } -void CGunController::GetFreeLookSetId() const +void CGunController::EnterFreeLook(CStateManager& mgr, s32 gunId, s32 setId) { - + if (x50_gunState != EGunState::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()); + x50_gunState = EGunState::FreeLook; } -bool CGunController::IsFidgetLoaded() const +void CGunController::EnterComboFire(CStateManager& mgr, s32 gunId) { - return false; + if (x50_gunState != EGunState::FreeLook) + x54_curAnimId = x1c_comboFire.SetAnim(*x0_modelData.AnimationData(), gunId, 0, mgr, 0.f); + else + x1c_comboFire.SetLoopState(x4_freeLook.GetLoopState()); + x50_gunState = EGunState::ComboFire; + x58_25_enteredComboFire = true; } -bool CGunController::IsComboOver() const +void CGunController::EnterStruck(CStateManager& mgr, float angle, bool bigStrike, bool b2) { - return true; + switch (x50_gunState) + { + case EGunState::Default: + case EGunState::ComboFire: + case EGunState::Idle: + case EGunState::Strike: + case EGunState::BigStrike: + return; + case EGunState::FreeLook: + x4_freeLook.SetIdle(true); + break; + default: + break; + } + + const CPASDatabase& pasDatabase = x0_modelData.AnimationData()->GetCharacterInfo().GetPASDatabase(); + CPASAnimParmData parms(2, CPASAnimParm::FromInt32(x4_freeLook.GetGunId()), + CPASAnimParm::FromReal32(angle), CPASAnimParm::FromBool(bigStrike), + CPASAnimParm::FromBool(b2)); + std::pair anim = + pasDatabase.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + x0_modelData.AnimationData()->EnableLooping(false); + CAnimPlaybackParms aparms(anim.second, -1, 1.f, true); + x0_modelData.AnimationData()->SetAnimation(aparms, false); + x54_curAnimId = anim.second; + x58_25_enteredComboFire = false; + x50_gunState = bigStrike ? EGunState::BigStrike : EGunState::Strike; } -void CGunController::EnterFreeLook(CStateManager &, s32, s32) -{ - -} - -void CGunController::EnterComboFire(CStateManager &, s32) -{ - -} - -void CGunController::EnterFidget(CStateManager &, s32, s32, s32) -{ - -} - -void CGunController::EnterStruck(CStateManager &, float) -{ - -} - -void CGunController::EnterIdle(CStateManager &) +void CGunController::EnterIdle(CStateManager& mgr) { + CPASAnimParm parm = CPASAnimParm::NoParameter(); + switch (x50_gunState) + { + case EGunState::FreeLook: + parm = CPASAnimParm::FromEnum(1); + x4_freeLook.SetIdle(true); + break; + case EGunState::ComboFire: + parm = CPASAnimParm::FromEnum(1); + x1c_comboFire.SetIdle(true); + break; + default: + return; + } + const CPASDatabase& pasDatabase = x0_modelData.AnimationData()->GetCharacterInfo().GetPASDatabase(); + CPASAnimParmData parms(5, parm); + std::pair anim = + pasDatabase.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + x0_modelData.AnimationData()->EnableLooping(false); + CAnimPlaybackParms aparms(anim.second, -1, 1.f, true); + x0_modelData.AnimationData()->SetAnimation(aparms, false); + x54_curAnimId = anim.second; + x50_gunState = EGunState::Idle; + x58_25_enteredComboFire = false; } bool CGunController::Update(float dt, CStateManager& mgr) @@ -63,60 +103,93 @@ bool CGunController::Update(float dt, CStateManager& mgr) { case EGunState::FreeLook: { - x58_24_ = x4_freeLook.Update(animData, dt, mgr); - if (!x58_24_ || !x58_25_) + x58_24_animDone = x4_freeLook.Update(animData, dt, mgr); + if (!x58_24_animDone || !x58_25_enteredComboFire) break; - EnterComboFire(mgr, x4_freeLook.xc_); - x58_24_ = false; + EnterComboFire(mgr, x4_freeLook.GetGunId()); + x58_24_animDone = false; break; } case EGunState::ComboFire: - x58_24_ = x1c_comboFire.Update(animData, dt, mgr); + x58_24_animDone = x1c_comboFire.Update(animData, dt, mgr); break; case EGunState::Fidget: - x58_24_ = x30_fidget.Update(animData, dt, mgr); + x58_24_animDone = x30_fidget.Update(animData, dt, mgr); break; - case EGunState::Six: + case EGunState::Strike: { if (animData.IsAnimTimeRemaining(0.001f, "Whole Body")) break; - x54_ = x4_freeLook.SetAnim(animData, x4_freeLook.xc_, x4_freeLook.x10_, 0, mgr, 0.f); + x54_curAnimId = x4_freeLook.SetAnim(animData, x4_freeLook.GetGunId(), x4_freeLook.GetSetId(), 0, mgr, 0.f); x50_gunState = EGunState::FreeLook; break; } - case EGunState::Seven: - x58_24_ = !animData.IsAnimTimeRemaining(0.001f, "Whole Body"); + case EGunState::BigStrike: + x58_24_animDone = !animData.IsAnimTimeRemaining(0.001f, "Whole Body"); break; default: break; } - if (!x58_24_) + if (!x58_24_animDone) return false; - x50_gunState = EGunState::Zero; - x58_25_ = false; + x50_gunState = EGunState::Inactive; + x58_25_enteredComboFire = false; return true; } -void CGunController::ReturnToDefault(CStateManager &, float) +void CGunController::ReturnToDefault(CStateManager& mgr, float dt, bool setState) { + CAnimData& animData = *x0_modelData.AnimationData(); + switch (x50_gunState) + { + case EGunState::Strike: + x50_gunState = EGunState::FreeLook; + case EGunState::Idle: + x4_freeLook.SetIdle(false); + case EGunState::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 EGunState::ComboFire: + x54_curAnimId = x1c_comboFire.SetAnim(animData, x1c_comboFire.GetGunId(), 2, mgr, dt); + break; + case EGunState::Fidget: + ReturnToBasePosition(mgr, dt); + break; + case EGunState::BigStrike: + x4_freeLook.SetIdle(false); + break; + default: + break; + } + + if (setState) + x50_gunState = EGunState::Default; } void CGunController::ReturnToBasePosition(CStateManager& mgr, float) { const CPASDatabase& pasDatabase = x0_modelData.AnimationData()->GetCharacterInfo().GetPASDatabase(); std::pair anim = - pasDatabase.FindBestAnimation(CPASAnimParmData::NoParameters(6), *mgr.GetActiveRandom(), -1); + pasDatabase.FindBestAnimation(CPASAnimParmData(6), *mgr.GetActiveRandom(), -1); + x0_modelData.AnimationData()->EnableLooping(false); + CAnimPlaybackParms parms(anim.second, -1, 1.f, true); + x0_modelData.AnimationData()->SetAnimation(parms, false); + x54_curAnimId = anim.second; + x58_25_enteredComboFire = false; } void CGunController::Reset() { - x58_24_ = true; - x58_25_ = false; - x50_gunState = EGunState::Zero; + x58_24_animDone = true; + x58_25_enteredComboFire = false; + x50_gunState = EGunState::Inactive; } } diff --git a/Runtime/Weapon/CGunController.hpp b/Runtime/Weapon/CGunController.hpp index 43eaadf3a..e77d4e6cd 100644 --- a/Runtime/Weapon/CGunController.hpp +++ b/Runtime/Weapon/CGunController.hpp @@ -10,14 +10,14 @@ namespace urde { enum class EGunState { - Zero, - One, + Inactive, + Default, FreeLook, ComboFire, - Four, + Idle, Fidget, - Six, - Seven + Strike, + BigStrike }; class CGunController @@ -26,37 +26,31 @@ class CGunController CGSFreeLook x4_freeLook; CGSComboFire x1c_comboFire; CGSFidget x30_fidget; - EGunState x50_gunState = EGunState::Zero; - u32 x54_ = -1; - - union { - struct - { - bool x58_24_ : 1; - bool x58_25_ : 1; - }; - u8 _dummy = 0; - }; + EGunState x50_gunState = EGunState::Inactive; + s32 x54_curAnimId = -1; + bool x58_24_animDone : 1; + bool x58_25_enteredComboFire : 1; public: CGunController(CModelData& modelData) : x0_modelData(modelData) { - x58_24_ = true; + x58_24_animDone = true; + x58_25_enteredComboFire = false; } - void UnLoadFidget(); - void LoadFidgetAnimAsync(CStateManager&, s32, s32, s32); - void GetFreeLookSetId() const; - bool IsFidgetLoaded() const; - bool IsComboOver() const; - void EnterFreeLook(CStateManager&, s32, s32); - void EnterComboFire(CStateManager&, s32); - void EnterFidget(CStateManager&, s32, s32, s32); - void EnterStruck(CStateManager&, float); - void EnterIdle(CStateManager&); - bool Update(float, CStateManager&); - void ReturnToDefault(CStateManager&, float); + void UnLoadFidget() { x30_fidget.UnLoadAnim(); } + void LoadFidgetAnimAsync(CStateManager& mgr, s32 type, s32 parm1, s32 parm2); + void EnterFidget(CStateManager& mgr, s32 type, s32 parm1, s32 parm2); + bool IsFidgetLoaded() const { return x30_fidget.IsAnimLoaded(); } + s32 GetFreeLookSetId() const { return x4_freeLook.GetSetId(); } + bool IsComboOver() const { return x1c_comboFire.IsComboOver(); } + void EnterFreeLook(CStateManager& mgr, s32 gunId, s32 setId); + void EnterComboFire(CStateManager& mgr, s32 gunId); + void EnterStruck(CStateManager& mgr, float angle, bool bigStrike, bool b2); + void EnterIdle(CStateManager& mgr); + bool Update(float dt, CStateManager& mgr); + void ReturnToDefault(CStateManager& mgr, float dt, bool setState); void ReturnToBasePosition(CStateManager&, float); void Reset(); }; diff --git a/Runtime/Weapon/CGunMotion.cpp b/Runtime/Weapon/CGunMotion.cpp index aa495baa7..77beb6b48 100644 --- a/Runtime/Weapon/CGunMotion.cpp +++ b/Runtime/Weapon/CGunMotion.cpp @@ -1,16 +1,104 @@ #include "CGunMotion.hpp" +#include "WeaponCommon.hpp" +#include "CStateManager.hpp" +#include "Character/CPASAnimParmData.hpp" namespace urde { -CGunMotion::CGunMotion(CAssetId, const zeus::CVector3f& vec) +CGunMotion::CGunMotion(CAssetId ancsId, const zeus::CVector3f& scale) +: x0_modelData(CAnimRes(ancsId, 0, scale, 0, false), 1), + x4c_gunController(x0_modelData) { - + xb8_24_inFidget = false; + LoadAnimations(); } -void CGunMotion::PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle, bool attack) +void CGunMotion::LoadAnimations() { + NWeaponTypes::get_token_vector(*x0_modelData.AnimationData(), 0, 14, xa8_anims, true); +} +bool CGunMotion::PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle, bool bigStrike) +{ + const CPASDatabase& pas = x0_modelData.GetAnimationData()->GetCharacterInfo().GetPASDatabase(); + + s32 animId = -1; + bool loop = true; + switch (state) + { + case SamusGun::EAnimationState::Wander: + { + CPASAnimParmData parms((s32(state))); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + animId = anim.second; + break; + } + case SamusGun::EAnimationState::Idle: + { + CPASAnimParmData parms(s32(state), CPASAnimParm::FromEnum(0)); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + animId = anim.second; + break; + } + case SamusGun::EAnimationState::Struck: + { + CPASAnimParmData parms(s32(state), CPASAnimParm::FromInt32(0), CPASAnimParm::FromReal32(angle), + CPASAnimParm::FromBool(bigStrike), CPASAnimParm::FromBool(false)); + auto anim = pas.FindBestAnimation(parms, *mgr.GetActiveRandom(), -1); + animId = anim.second; + loop = false; + break; + } + case SamusGun::EAnimationState::FreeLook: + x4c_gunController.EnterFreeLook(mgr, 0, -1); + break; + case SamusGun::EAnimationState::ComboFire: + x4c_gunController.EnterComboFire(mgr, 0); + break; + default: + break; + } + + if (animId != -1) + { + x0_modelData.AnimationData()->EnableLooping(loop); + CAnimPlaybackParms aparms(animId, -1, 1.f, true); + x0_modelData.AnimationData()->SetAnimation(aparms, false); + } + + return loop; +} + +void CGunMotion::ReturnToDefault(CStateManager& mgr, bool setState) +{ + x4c_gunController.ReturnToDefault(mgr, 0.f, setState); +} + +void CGunMotion::BasePosition(bool bigStrikeReset) +{ + x0_modelData.AnimationData()->EnableLooping(false); + CAnimPlaybackParms aparms(bigStrikeReset ? 6 : 0, -1, 1.f, true); + x0_modelData.AnimationData()->SetAnimation(aparms, false); +} + +void CGunMotion::EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2) +{ + xb8_24_inFidget = true; + x4c_gunController.EnterFidget(mgr, s32(type), 0, parm2); +} + +void CGunMotion::Update(float dt, CStateManager& mgr) +{ + x0_modelData.AdvanceAnimation(dt, mgr, kInvalidAreaId, true); + if (x4c_gunController.Update(dt, mgr)) + xb8_24_inFidget = false; +} + +void CGunMotion::Draw(const CStateManager& mgr, const zeus::CTransform& xf) const +{ + CModelFlags flags(0, 0, 3, zeus::CColor::skWhite); + x0_modelData.Render(mgr, xf, nullptr, flags); } } diff --git a/Runtime/Weapon/CGunMotion.hpp b/Runtime/Weapon/CGunMotion.hpp index 1987d17eb..932832d5f 100644 --- a/Runtime/Weapon/CGunMotion.hpp +++ b/Runtime/Weapon/CGunMotion.hpp @@ -4,6 +4,7 @@ #include "RetroTypes.hpp" #include "zeus/CVector3f.hpp" #include "Character/CModelData.hpp" +#include "CGunController.hpp" namespace urde { @@ -12,20 +13,40 @@ namespace SamusGun { enum class EAnimationState { - Zero, - One, - Two + Wander, + Fidget, + Struck, + FreeLook, + ComboFire, + Idle, + BasePosition +}; +enum class EFidgetType +{ + Zero }; } class CGunMotion { CModelData x0_modelData; + CGunController x4c_gunController; + std::vector xa8_anims; + bool xb8_24_inFidget : 1; + + void LoadAnimations(); public: - CGunMotion(CAssetId, const zeus::CVector3f& vec); + CGunMotion(CAssetId ancsId, const zeus::CVector3f& scale); const CModelData& GetModelData() const { return x0_modelData; } - void PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle, bool attack); + bool PlayPasAnim(SamusGun::EAnimationState state, CStateManager& mgr, float angle, bool bigStrike); + void ReturnToDefault(CStateManager& mgr, bool setState); + void BasePosition(bool bigStrikeReset); + void EnterFidget(CStateManager& mgr, SamusGun::EFidgetType type, s32 parm2); + void Update(float dt, CStateManager& mgr); + void Draw(const CStateManager& mgr, const zeus::CTransform& xf) const; + s32 GetFreeLookSetId() const { return x4c_gunController.GetFreeLookSetId(); } + CGunController& GunController() { return x4c_gunController; } }; } diff --git a/Runtime/Weapon/CGunWeapon.cpp b/Runtime/Weapon/CGunWeapon.cpp index 7c38fdce2..feeee24b9 100644 --- a/Runtime/Weapon/CGunWeapon.cpp +++ b/Runtime/Weapon/CGunWeapon.cpp @@ -55,6 +55,32 @@ void CGunWeapon::AsyncLoadSuitArm(CStateManager& mgr) { } +void CGunWeapon::BuildSecondaryEffect(ESecondaryFxType type) +{ + switch (type) + { + case ESecondaryFxType::Two: + if (x204_secondaryEffectType == ESecondaryFxType::Two) + break; + x1b8_secondaryEffect = std::make_unique(x188_secondaryEffects[1], + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x1b8_secondaryEffect->SetGlobalScale(x4_scale); + break; + case ESecondaryFxType::One: + if (x204_secondaryEffectType == ESecondaryFxType::One) + break; + x1b8_secondaryEffect = std::make_unique(x188_secondaryEffects[0], + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); + x1b8_secondaryEffect->SetGlobalScale(x4_scale); + break; + default: + break; + } + x204_secondaryEffectType = type; +} + void CGunWeapon::ActivateCharge(bool b1, bool b2) { } @@ -69,4 +95,21 @@ void CGunWeapon::TouchHolo(const CStateManager& mgr) } +void CGunWeapon::UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting) +{ + +} + +const SWeaponInfo& CGunWeapon::GetWeaponInfo() const +{ + return g_tweakPlayerGun->GetBeamInfo(s32(x200_beamId)); +} + +zeus::CAABox CGunWeapon::GetBounds() const +{ + if (x10_solidModelData) + return x10_solidModelData->GetBounds(); + return zeus::CAABox::skNullBox; +} + } diff --git a/Runtime/Weapon/CGunWeapon.hpp b/Runtime/Weapon/CGunWeapon.hpp index 190ce7d47..6be5b5281 100644 --- a/Runtime/Weapon/CGunWeapon.hpp +++ b/Runtime/Weapon/CGunWeapon.hpp @@ -10,31 +10,18 @@ #include "Particle/CElementGen.hpp" #include "CToken.hpp" #include "CStateManager.hpp" +#include "CGunController.hpp" +#include "WeaponCommon.hpp" namespace urde { -namespace NWeaponTypes -{ -enum class EGunAnimType -{ - Zero, - One, - Two, - Three, - Four, - FromMissile, - ToMissile, - Seven, - MissileReload, - FromBeam -}; -} class CActorLights; -class CGunController; struct CModelFlags; class CWeaponDescription; +using SWeaponInfo = DataSpec::SWeaponInfo; + class CVelocityInfo { friend class CGunWeapon; @@ -61,6 +48,10 @@ protected: static const char* skDependencyNames[5]; static const char* skSuitArmNames[8]; zeus::CVector3f x4_scale; + std::experimental::optional x10_solidModelData; + std::experimental::optional x60_; + std::experimental::optional xb0_; + std::unique_ptr x100_gunController; TToken x104_gunCharacter; TToken x13c_armCharacter; rstl::reserved_vector, 2> x144_weapons; @@ -68,26 +59,46 @@ protected: rstl::reserved_vector, 2> x16c_muzzleEffects; rstl::reserved_vector, 2> x188_secondaryEffects; rstl::reserved_vector, 2> x1a4_muzzleGenerators; - u32 x1b8_ = 0; + std::unique_ptr x1b8_secondaryEffect; CRainSplashGenerator* x1bc_rainSplashGenerator = nullptr; EWeaponType x1c0_weaponType; TUniqueId x1c4_playerId; EMaterialTypes x1c8_playerMaterial; CVelocityInfo x1d0_velInfo; CPlayerState::EBeamId x200_beamId; + ESecondaryFxType x204_secondaryEffectType = ESecondaryFxType::Zero; + u32 x208_ = 0; + CPlayerState::EBeamId x20c_; + u32 x210_ = 0; + CAssetId x214_ancsId; + union + { + struct + { + bool x218_24 : 1; + bool x218_25 : 1; + bool x218_26 : 1; + bool x218_27 : 1; + bool x218_28 : 1; + bool x218_29_leavingBeam : 1; + }; + u32 _dummy = 0; + }; + public: CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes, const zeus::CVector3f& scale); void AsyncLoadSuitArm(CStateManager& mgr); void AllocResPools(CPlayerState::EBeamId); virtual void Reset(CStateManager&) {} - virtual void PlayAnim(NWeaponTypes::EGunAnimType, bool) {} + virtual void PlayAnim(NWeaponTypes::EGunAnimType type, bool loop) {} virtual void PreRenderGunFx(const CStateManager&, const zeus::CTransform&) {} virtual void PostRenderGunFx(const CStateManager&, const zeus::CTransform&) {} virtual void UpdateGunFx(bool, float, const CStateManager&, const zeus::CTransform&) {} virtual void Fire(bool, float, CPlayerState::EChargeState, const zeus::CTransform&, CStateManager&, TUniqueId) {} virtual void EnableFx(bool) {} virtual void EnableSecondaryFx(ESecondaryFxType) {} + void BuildSecondaryEffect(ESecondaryFxType type); void ActivateCharge(bool b1, bool b2); void Touch(const CStateManager& mgr); void TouchHolo(const CStateManager& mgr); @@ -98,9 +109,16 @@ public: virtual void Load(CStateManager& mgr, bool) {} virtual void Unload(CStateManager&) {} virtual bool IsLoaded() const {return false;} + void UpdateMuzzleFx(float dt, const zeus::CVector3f& scale, const zeus::CVector3f& pos, bool emitting); const CVelocityInfo& GetVelocityInfo() const { return x1d0_velInfo; } void SetRainSplashGenerator(CRainSplashGenerator* g) { x1bc_rainSplashGenerator = g; } CElementGen* GetChargeMuzzleFx() const { return x1a4_muzzleGenerators[1].get(); } + void ReturnToDefault(CStateManager& mgr) {} + void UnLoadFidget() {} + CModelData& GetSolidModelData() { return *x10_solidModelData; } + const SWeaponInfo& GetWeaponInfo() const; + zeus::CAABox GetBounds() const; + void SetLeavingBeam() { x218_29_leavingBeam = true; } }; } diff --git a/Runtime/Weapon/CMakeLists.txt b/Runtime/Weapon/CMakeLists.txt index 224232902..e917766ed 100644 --- a/Runtime/Weapon/CMakeLists.txt +++ b/Runtime/Weapon/CMakeLists.txt @@ -1,5 +1,5 @@ set(WEAPON_SOURCES - WeaponCommon.hpp + WeaponCommon.hpp WeaponCommon.cpp CWeaponMgr.hpp CWeaponMgr.cpp CGunController.hpp CGunController.cpp CGunMotion.hpp CGunMotion.cpp diff --git a/Runtime/Weapon/CPhazonBeam.cpp b/Runtime/Weapon/CPhazonBeam.cpp index 2056cea26..828b87b7f 100644 --- a/Runtime/Weapon/CPhazonBeam.cpp +++ b/Runtime/Weapon/CPhazonBeam.cpp @@ -26,4 +26,9 @@ void CPhazonBeam::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager } +void CPhazonBeam::StopBeam(CStateManager& mgr, bool b1) +{ + +} + } \ No newline at end of file diff --git a/Runtime/Weapon/CPhazonBeam.hpp b/Runtime/Weapon/CPhazonBeam.hpp index 538a29310..94004db0a 100644 --- a/Runtime/Weapon/CPhazonBeam.hpp +++ b/Runtime/Weapon/CPhazonBeam.hpp @@ -28,6 +28,7 @@ public: bool IsFiring() const { return x278_ < 1.f / 6.f; } void SetX274_25(bool b) { x274_25 = b; } void SetX274_26(bool b) { x274_26 = b; } + void StopBeam(CStateManager& mgr, bool b1); }; } diff --git a/Runtime/Weapon/CPlasmaBeam.hpp b/Runtime/Weapon/CPlasmaBeam.hpp index ad49d1e7b..c23332e35 100644 --- a/Runtime/Weapon/CPlasmaBeam.hpp +++ b/Runtime/Weapon/CPlasmaBeam.hpp @@ -20,6 +20,8 @@ public: CPlasmaBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, const zeus::CVector3f& scale); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); + bool IsFiring() const { return x234_ > 0.f; } + void StopBeam(CStateManager& mgr, bool b1) {} }; } diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index ac55a2887..dd00a6727 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -131,11 +131,11 @@ void CPlayerGun::LoadHandAnimTokens() CAnimData::PrimitiveSetToTokenVector(prims, x540_handAnimTokens, true); } -void CPlayerGun::TakeDamage(bool attack, bool notFromMetroid, CStateManager& mgr) +void CPlayerGun::TakeDamage(bool bigStrike, bool notFromMetroid, CStateManager& mgr) { bool hasAngle = false; float angle = 0.f; - if (x398_damageAmt >= 10.f && !attack && (x2f8_ & 0x10) != 0x10 && !x832_26_ && x384_ <= 0.f) + if (x398_damageAmt >= 10.f && !bigStrike && (x2f8_ & 0x10) != 0x10 && !x832_26_ && x384_ <= 0.f) { x384_ = 20.f; x364_ = 0.75f; @@ -147,13 +147,13 @@ void CPlayerGun::TakeDamage(bool attack, bool notFromMetroid, CStateManager& mgr } } - if (hasAngle || attack) + if (hasAngle || bigStrike) { if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan) { - x73c_gunMotion->PlayPasAnim(SamusGun::EAnimationState::Two, mgr, angle, attack); - if ((attack && notFromMetroid) || x833_31_) - x740_grappleArm->EnterStruck(mgr, angle, attack, !x833_31_); + x73c_gunMotion->PlayPasAnim(SamusGun::EAnimationState::Struck, mgr, angle, bigStrike); + if ((bigStrike && notFromMetroid) || x833_31_) + x740_grappleArm->EnterStruck(mgr, angle, bigStrike, !x833_31_); } } @@ -180,6 +180,11 @@ void CPlayerGun::DeleteGunLight(CStateManager& mgr) x53c_lightId = kInvalidUniqueId; } +void CPlayerGun::UpdateGunLight(const zeus::CTransform& pos, CStateManager& mgr) +{ + +} + void CPlayerGun::SetGunLightActive(bool active, CStateManager& mgr) { if (x53c_lightId == kInvalidUniqueId) @@ -277,15 +282,15 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt break; case EScriptObjectMessage::Damage: { - bool attackDamage = false; + bool bigStrike = false; bool metroidAttached = false; if (TCastToConstPtr proj = mgr.GetObjectById(sender)) { - if ((proj->GetAttribField() & CGameProjectile::EProjectileAttrib::Twelve) != + if ((proj->GetAttribField() & CGameProjectile::EProjectileAttrib::BigStrike) != CGameProjectile::EProjectileAttrib::None) { x394_damageTimer = proj->GetDamageDuration(); - attackDamage = true; + bigStrike = true; } } else if (TCastToConstPtr ai = mgr.GetObjectById(sender)) @@ -293,33 +298,33 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt if (ai->GetX402_28()) { x394_damageTimer = ai->GetDamageDuration(); - attackDamage = true; + bigStrike = true; if (player.GetAttachedActor() != kInvalidUniqueId) metroidAttached = CPatterned::CastTo( mgr.GetObjectById(player.GetAttachedActor())) != nullptr; } } - if (!x834_30_damaged) + if (!x834_30_inBigStrike) { - if (attackDamage) + if (bigStrike) { x834_31_ = false; CancelFiring(mgr); } - TakeDamage(attackDamage, !metroidAttached, mgr); - x834_30_damaged = attackDamage; + TakeDamage(bigStrike, !metroidAttached, mgr); + x834_30_inBigStrike = bigStrike; } break; } case EScriptObjectMessage::OnFloor: - if (player.GetControlsFrozen() && !x834_30_damaged) + if (player.GetControlsFrozen() && !x834_30_inBigStrike) { x2f4_ = 0; x2ec_firing = 0; CancelFiring(mgr); TakeDamage(true, false, mgr); x394_damageTimer = 0.75f; - x834_30_damaged = true; + x834_30_inBigStrike = true; } break; default: @@ -378,14 +383,132 @@ void CPlayerGun::DamageRumble(const zeus::CVector3f& location, float damage, con x3dc_damageLocation = location; } +void CPlayerGun::StopChargeSound(CStateManager& mgr) +{ + if (x2e0_chargeSfx) + { + CSfxManager::SfxStop(x2e0_chargeSfx); + x2e0_chargeSfx.reset(); + } + if (x830_chargeRumbleHandle != -1) + { + mgr.GetRumbleManager().StopRumble(x830_chargeRumbleHandle); + x830_chargeRumbleHandle = -1; + } +} + void CPlayerGun::ResetCharge(CStateManager& mgr, bool b1) { + if (x32c_) + StopChargeSound(mgr); + if ((x2f8_ & 0x8) != 0x8 && (x2f8_ & 0x10) != 0x10) + { + bool r30 = !(mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed && !b1); + if (x832_27_ || r30) + PlayAnim(NWeaponTypes::EGunAnimType::Zero, false); + if (r30) + x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::Zero); + if ((x2f8_ & 0x2) != 0x2 || x330_chargeWeaponIdx != 0) + { + if ((x2f8_ & 0x8) != 0x8) + { + x2f8_ |= 0x1; + x2f8_ &= 0xFFE9; + } + x318_ = 0; + x31c_missileMode = EMissleMode::Inactive; + } + } + + x32c_ = 0; + x330_chargeWeaponIdx = 0; + x320_ = x310_selectedBeam; + x833_30_ = true; + x832_27_ = false; + x832_26_ = false; + x344_ = 0.f; } +bool CPlayerGun::ExitMissile() +{ + if ((x2f8_ & 0x1) == 0x1) + return true; + if ((x2f8_ & 0x10) == 0x10 || x338_ == 2) + return false; + x338_ = 2; + PlayAnim(NWeaponTypes::EGunAnimType::FromMissile, false); + return false; +} + +static const CPlayerState::EItemType skBeamArr[] = +{ + CPlayerState::EItemType::PowerBeam, + CPlayerState::EItemType::IceBeam, + CPlayerState::EItemType::WaveBeam, + CPlayerState::EItemType::PlasmaBeam +}; + +static const ControlMapper::ECommands mBeamCtrlCmd[] = +{ + ControlMapper::ECommands::PowerBeam, + ControlMapper::ECommands::IceBeam, + ControlMapper::ECommands::WaveBeam, + ControlMapper::ECommands::PlasmaBeam, +}; + void CPlayerGun::HandleBeamChange(const CFinalInput& input, CStateManager& mgr) { + CPlayerState& playerState = *mgr.GetPlayerState(); + float maxBeamInput = 0.f; + int selectBeam = -1; + for (int i=0 ; i<4 ; ++i) + { + if (playerState.HasPowerUp(skBeamArr[i])) + { + float inputVal = ControlMapper::GetAnalogInput(mBeamCtrlCmd[i], input); + if (inputVal > 0.65f && inputVal > maxBeamInput) + { + maxBeamInput = inputVal; + selectBeam = i; + } + } + } + if (selectBeam < 0) + return; + + x833_25_ = true; + if (x310_selectedBeam != selectBeam && playerState.HasPowerUp(skBeamArr[selectBeam])) + { + x314_pendingSelectedBeam = u32(selectBeam); + u32 flags = 0; + if ((x2f8_ & 0x10) == 0x10) + flags = 0x10; + flags |= 0x8; + x2f8_ = flags; + PlayAnim(NWeaponTypes::EGunAnimType::FromBeam, false); + if (x833_31_ || x744_auxWeapon->IsComboFxActive(mgr) || x832_26_) + { + x832_30_ = true; + x740_grappleArm->EnterIdle(mgr); + } + x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::Zero); + x338_ = 5; + x2e4_invalidSfx.reset(); + } + else if (playerState.HasPowerUp(skBeamArr[selectBeam])) + { + if (ExitMissile()) + { + if (!CSfxManager::IsPlaying(x2e4_invalidSfx)) + x2e4_invalidSfx = PlaySfx(1763, x834_27_underwater, false, 0.165f); + } + else + { + x2e4_invalidSfx.reset(); + } + } } void CPlayerGun::SetPhazonBeamMorph(bool intoPhazonBeam) @@ -437,22 +560,23 @@ void CPlayerGun::ResetBeamParams(CStateManager& mgr, const CPlayerState& playerS x833_30_ = true; } -void CPlayerGun::PlaySfx(u16 sfx, bool underwater, bool looped, float pan) +CSfxHandle CPlayerGun::PlaySfx(u16 sfx, bool underwater, bool looped, float pan) { CSfxHandle hnd = CSfxManager::SfxStart(sfx, 1.f, pan, true, 0x7f, looped, kInvalidAreaId); CSfxManager::SfxSpan(hnd, 0.f); if (underwater) CSfxManager::PitchBend(hnd, -1.f); + return hnd; } static const u16 skFromMissileSound[] = { 1824, 1849, 1851, 1853 }; static const u16 skFromBeamSound[] = { 0, 1822, 1828, 1826 }; static const u16 skToMissileSound[] = { 1823, 1829, 1850, 1852 }; -void CPlayerGun::PlayAnim(NWeaponTypes::EGunAnimType type, bool b1) +void CPlayerGun::PlayAnim(NWeaponTypes::EGunAnimType type, bool loop) { if (x338_ != 5) - x72c_currentBeam->PlayAnim(type, b1); + x72c_currentBeam->PlayAnim(type, loop); u16 sfx = 0xffff; switch (type) @@ -555,7 +679,7 @@ void CPlayerGun::HandleWeaponChange(const CFinalInput& input, CStateManager& mgr void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) { CPlayerState& state = *mgr.GetPlayerState(); - bool damageNotMorphed = (x834_30_damaged && + bool damageNotMorphed = (x834_30_inBigStrike && mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed); if (x832_24_ || damageNotMorphed || (x2f8_ & 0x8) == 0x8) return; @@ -584,14 +708,80 @@ void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) } } +void CPlayerGun::UnLoadFidget() +{ + if ((x2fc_ & 0x1) == 0x1) + x73c_gunMotion->GunController().UnLoadFidget(); + if ((x2fc_ & 0x2) == 0x2) + x72c_currentBeam->UnLoadFidget(); + if ((x2fc_ & 0x4) == 0x4) + if (CGunController* gc = x740_grappleArm->GunController()) + gc->UnLoadFidget(); + x2fc_ = 0; +} + +void CPlayerGun::ReturnArmAndGunToDefault(CStateManager& mgr, bool b1) +{ + if (b1 || !x833_31_) + { + x73c_gunMotion->ReturnToDefault(mgr, false); + x740_grappleArm->ReturnToDefault(mgr, 0.f, false); + } + if (!x834_25_) + x72c_currentBeam->ReturnToDefault(mgr); + x834_25_ = false; +} + +void CPlayerGun::ReturnToRestPose() +{ + if (x832_31_) + return; + if ((x2f8_ & 0x1) == 0x1) + PlayAnim(NWeaponTypes::EGunAnimType::Zero, false); + else if ((x2f8_ & 0x4) == 0x4) + PlayAnim(NWeaponTypes::EGunAnimType::ToMissile, false); + x832_31_ = true; +} + void CPlayerGun::ResetIdle(CStateManager& mgr) { - + x550_camBob.SetState(CPlayerCameraBob::ECameraBobState::GunFireNoBob, mgr); + if (x3a4_fidget.GetState() != CFidget::EState::Zero) + { + if (x3a4_fidget.GetState() == CFidget::EState::Seven) + UnLoadFidget(); + ReturnArmAndGunToDefault(mgr, true); + } + x3a4_fidget.ResetAll(); + ReturnToRestPose(); + if (x324_ != 0) + x324_ = 0; + if (!x740_grappleArm->GetActive()) + x834_26_ = false; } void CPlayerGun::CancelFiring(CStateManager& mgr) { - + if (x32c_ == 8) + ReturnArmAndGunToDefault(mgr, true); + if ((x2f8_ & 0x10) == 0x10) + { + StopContinuousBeam(mgr, true); + if ((x2f8_ & 0x8) == 0x8) + { + x2f8_ |= 0x1; + x2f8_ &= 0xFFE9; + } + x318_ = 0; + x31c_missileMode = EMissleMode::Inactive; + } + if (x32c_ != 0) + { + x72c_currentBeam->ActivateCharge(false, false); + SetGunLightActive(false, mgr); + ResetCharge(mgr, true); + } + Reset(mgr, (x2f8_ & 0x2) == 0x2); } float CPlayerGun::GetBeamVelocity() const @@ -602,15 +792,413 @@ float CPlayerGun::GetBeamVelocity() const } void CPlayerGun::StopContinuousBeam(CStateManager& mgr, bool b1) +{ + if ((x2f8_ & 0x10) == 0x10) + { + ReturnArmAndGunToDefault(mgr, false); + x744_auxWeapon->StopComboFx(mgr, b1); + switch (x310_selectedBeam) + { + case 0: + case 2: + case 3: + // All except ice + if (x310_selectedBeam != 0 || x833_28_phazonBeamActive) + { + x72c_currentBeam->EnableSecondaryFx( + b1 ? CGunWeapon::ESecondaryFxType::Zero : CGunWeapon::ESecondaryFxType::Three); + } + break; + default: + break; + } + } + else if (x833_28_phazonBeamActive) + { + if (static_cast(x72c_currentBeam)->IsFiring()) + static_cast(x72c_currentBeam)->StopBeam(mgr, b1); + } + else if (x310_selectedBeam == 3) // Plasma + { + if (static_cast(x72c_currentBeam)->IsFiring()) + static_cast(x72c_currentBeam)->StopBeam(mgr, b1); + } +} + +void CPlayerGun::CMotionState::Update(bool b1, float dt, zeus::CTransform& xf, CStateManager& mgr) { } -void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateManager& mgr) +void CPlayerGun::ChangeWeapon(const CPlayerState& playerState, CStateManager& mgr) { } +void CPlayerGun::GetLctrWithShake(zeus::CTransform& xfOut, const CModelData& mData, const std::string& lctrName, + bool b1, bool b2) +{ + +} + +void CPlayerGun::UpdateLeftArmTransform(const CModelData& mData, const CStateManager& mgr) +{ + +} + +void CPlayerGun::ProcessGunMorph(float dt, CStateManager& mgr) +{ + +} + +void CPlayerGun::ProcessPhazonGunMorph(float dt, CStateManager& mgr) +{ + +} + +void CPlayerGun::UpdateChargeState(float dt, CStateManager& mgr) +{ + +} + +void CPlayerGun::UpdateAuxWeapons(float dt, const zeus::CTransform& targetXf, CStateManager& mgr) +{ + +} + +void CPlayerGun::DoUserAnimEvents(float dt, CStateManager& mgr) +{ + +} + +TUniqueId CPlayerGun::GetTargetId(CStateManager& mgr) const +{ + return {}; +} + +void CPlayerGun::CancelLockOn() +{ + +} + +void CPlayerGun::UpdateWeaponFire(float dt, const CPlayerState& playerState, CStateManager& mgr) +{ + +} + +void CPlayerGun::UpdateGunIdle(bool b1, float camBobT, float dt, CStateManager& mgr) +{ + +} + +static const float chargeShakeTbl[] = { -0.001f, 0.f, 0.001f }; +static const CMaterialFilter sAimFilter = + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough}); + +void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateManager& mgr) +{ + CPlayer& player = mgr.GetPlayer(); + CPlayerState& playerState = *mgr.GetPlayerState(); + bool isUnmorphed = player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed; + + bool becameFrozen; + if (isUnmorphed) + becameFrozen = !x834_29_frozen && player.GetFrozenState(); + else + becameFrozen = false; + + bool becameThawed; + if (isUnmorphed) + becameThawed = x834_29_frozen && !player.GetFrozenState(); + else + becameThawed = false; + + x834_29_frozen = isUnmorphed && player.GetFrozenState(); + float advDt; + if (x834_29_frozen) + advDt = 0.f; + else + advDt = dt; + + bool r23 = x678_morph.GetGunState() != CGunMorph::EGunState::One; + if (mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay || r23) + x6e0_rightHandModel.AdvanceAnimation(advDt, mgr, kInvalidAreaId, true); + if (r23 && x734_ != 0 && x734_ != x72c_currentBeam) + { + x744_auxWeapon->LoadIdle(); + x734_->Update(advDt, mgr); + } + if (!x744_auxWeapon->IsLoaded()) + x744_auxWeapon->LoadIdle(); + + if (becameFrozen) + { + x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::Zero); + x72c_currentBeam->BuildSecondaryEffect(CGunWeapon::ESecondaryFxType::One); + } + else if (becameThawed) + { + x72c_currentBeam->BuildSecondaryEffect(CGunWeapon::ESecondaryFxType::Two); + } + + if (becameFrozen || becameThawed) + { + x2f4_ = 0; + x2ec_firing = 0; + CancelFiring(mgr); + } + + x72c_currentBeam->Update(advDt, mgr); + x73c_gunMotion->Update(advDt * x370_gunMotionSpeedMult, mgr); + x740_grappleArm->Update(grappleSwingT, advDt, mgr); + + if (x338_ != 0) + { + if (x678_morph.GetGunState() == CGunMorph::EGunState::Zero) + { + if (x338_ == 5) + { + ChangeWeapon(playerState, mgr); + x338_ = 0; + } + } + else if (!x72c_currentBeam->GetSolidModelData().GetAnimationData()->IsAnimTimeRemaining(0.001f, "Whole Body") || + x832_30_) + { + bool r24 = true; + switch (x338_) + { + case 1: + x2f8_ &= 0x1; + x2f8_ |= 0x6; + x318_ = 1; + x31c_missileMode = EMissleMode::Active; + break; + case 2: + if ((x2f8_ & 0x8) != 0x8) + { + x2f8_ |= 0x1; + x2f8_ &= 0xFFE9; + } + x318_ = 0; + x31c_missileMode = EMissleMode::Inactive; + x390_cooldown = x72c_currentBeam->GetWeaponInfo().x0_coolDown; + break; + case 4: + PlayAnim(NWeaponTypes::EGunAnimType::MissileReload, false); + x338_ = 3; + r24 = false; + break; + case 3: + x2f8_ |= 0x4; + break; + case 5: + ChangeWeapon(playerState, mgr); + break; + case 6: + x390_cooldown = x72c_currentBeam->GetWeaponInfo().x0_coolDown; + x2f8_ &= ~0x8; + if ((x2f8_ & 0x8) != 0x8) + { + x2f8_ |= 0x1; + x2f8_ &= 0xFFE9; + } + x318_ = 0; + x31c_missileMode = EMissleMode::Inactive; + break; + case 8: + if (x75c_phazonBeam->IsLoaded()) + break; + x72c_currentBeam->SetLeavingBeam(); + x75c_phazonBeam->Load(mgr, false); + x33c_gunOverrideMode = EGunOverrideMode::One; + break; + case 9: + if (x738_nextBeam->IsLoaded()) + break; + x72c_currentBeam->SetLeavingBeam(); + x738_nextBeam->Load(mgr, false); + x33c_gunOverrideMode = EGunOverrideMode::Two; + break; + default: + break; + } + + if (r24) + x338_ = 0; + } + } + + if (x37c_ < 0.2f) + { + x37c_ += advDt; + } + else + { + x37c_ = 0.f; + if (x30c_ > 0) + x30c_ -= 1; + } + + if (x32c_ != 0 && !player.GetFrozenState()) + { + x34c_shakeX = chargeShakeTbl[mgr.GetActiveRandom()->Next() % 3] * x340_chargeBeamFactor; + x350_shakeZ = chargeShakeTbl[mgr.GetActiveRandom()->Next() % 3] * x340_chargeBeamFactor; + } + + if (!x72c_currentBeam->IsLoaded()) + return; + + GetLctrWithShake(x4d8_gunLocalXf, x73c_gunMotion->GetModelData(), "GBSE_SDK", true, true); + GetLctrWithShake(x418_beamLocalXf, x72c_currentBeam->GetSolidModelData(), "LBEAM", false, true); + GetLctrWithShake(x508_elbowLocalXf, x72c_currentBeam->GetSolidModelData(), "elbow", false, false); + x4a8_gunWorldXf = x3e8_xf * x4d8_gunLocalXf * x550_camBob.GetCameraBobTransformation(); + + if (x740_grappleArm->GetActive() && !x740_grappleArm->IsGrappling()) + UpdateLeftArmTransform(x72c_currentBeam->GetSolidModelData(), mgr); + + x6a0_motionState.Update(x2f0_ != 0 && x832_28_ && x32c_ < 2 && !player.IsInFreeLook(), advDt, x4a8_gunWorldXf, mgr); + + x72c_currentBeam->GetSolidModelData().AdvanceParticles(x4a8_gunWorldXf, advDt, mgr); + x72c_currentBeam->UpdateGunFx(x380_ > 2.f && x378_ > 0.15f, dt, mgr, x508_elbowLocalXf); + + zeus::CTransform beamWorldXf = x4a8_gunWorldXf * x418_beamLocalXf; + + if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed && + !mgr.GetCameraManager()->IsInCinematicCamera()) + { + rstl::reserved_vector nearList; + zeus::CAABox aabb = x72c_currentBeam->GetBounds().getTransformedAABox(x4a8_gunWorldXf); + mgr.BuildNearList(nearList, aabb, sAimFilter, &player); + TUniqueId bestId = kInvalidUniqueId; + zeus::CVector3f dir = x4a8_gunWorldXf.basis[1].normalized(); + zeus::CVector3f pos = dir * -0.5f + x4a8_gunWorldXf.origin; + CRayCastResult result = mgr.RayWorldIntersection(bestId, pos, dir, 3.5f, sAimFilter, nearList); + x833_29_pointBlankWorldSurface = result.IsValid(); + if (result.IsValid()) + { + x448_elbowWorldXf = x4a8_gunWorldXf * x508_elbowLocalXf; + x448_elbowWorldXf.origin += dir * -0.5f; + beamWorldXf.origin = result.GetPoint(); + } + } + else + { + x833_29_pointBlankWorldSurface = false; + } + + zeus::CTransform beamTargetXf = x833_29_pointBlankWorldSurface ? x448_elbowWorldXf : beamWorldXf; + + zeus::CVector3f camTrans = mgr.GetCameraManager()->GetGlobalCameraTranslation(mgr); + beamWorldXf.origin += camTrans; + beamTargetXf.origin += camTrans; + + if (x832_25_) + { + bool emitting = x833_30_ ? x344_ < 1.f : false; + zeus::CVector3f scale((emitting && x832_26_) ? (1.f - x344_) * 2.f : 2.f); + x72c_currentBeam->UpdateMuzzleFx(advDt, scale, x418_beamLocalXf.origin, emitting); + CElementGen& gen = *x800_auxMuzzleGenerators[x320_]; + gen.SetGlobalOrientAndTrans(x418_beamLocalXf); + gen.SetGlobalScale(scale); + gen.SetParticleEmission(emitting); + gen.Update(advDt); + } + + if (x748_rainSplashGenerator) + x748_rainSplashGenerator->Update(advDt, mgr); + + UpdateGunLight(beamWorldXf, mgr); + ProcessGunMorph(advDt, mgr); + if (x835_26_phazonBeamMorphing) + ProcessPhazonGunMorph(advDt, mgr); + + if (x832_26_ && x77c_) + { + x77c_->SetGlobalTranslation(x418_beamLocalXf.origin); + x77c_->SetGlobalOrientation(x418_beamLocalXf.getRotation()); + x77c_->Update(advDt); + x344_ += advDt * 4.f; + } + + if (x35c_bombTime > 0.f) + { + x35c_bombTime -= advDt; + if (x35c_bombTime <= 0.f) + x308_bombCount = 3; + } + + if (playerState.ItemEnabled(CPlayerState::EItemType::ChargeBeam) && x32c_ != 0) + { + UpdateChargeState(advDt, mgr); + } + else + { + x340_chargeBeamFactor -= advDt; + if (x340_chargeBeamFactor < 0.f) + x340_chargeBeamFactor = 0.f; + } + + UpdateAuxWeapons(advDt, beamTargetXf, mgr); + DoUserAnimEvents(advDt, mgr); + + if (x304_ == 1 && GetTargetId(mgr) != kInvalidUniqueId) + { + if (!x832_29_ && !x832_26_ && (x2f8_ & 0x10) != 0x10) + { + x832_29_ = true; + x6a0_motionState.SetState(CMotionState::EMotionState::Two); + ReturnArmAndGunToDefault(mgr, true); + } + } + else + { + CancelLockOn(); + } + + UpdateWeaponFire(advDt, playerState, mgr); + UpdateGunIdle(x364_ > 0.f, cameraBobT, advDt, mgr); + + if ((x2ec_firing & 0x1) == 0x1) + { + x378_ = 0.f; + } + else if (x378_ < 2.f) + { + x378_ += advDt; + if (x378_ > 1.f) + { + x30c_ = 0; + x380_ = 0.f; + } + } + + if (x38c_ > 0.f) + x38c_ -= advDt; + + if (x30c_ > 5 && x380_ < 2.f) + x380_ += advDt; + + if (x384_ > 0.f) + x384_ -= advDt; + + if (x364_ > 0.f) + { + x2f4_ = 0; + x364_ -= advDt; + } + + if (isUnmorphed && (x2f8_ & 0x4) == 0x4) + { + x3a0_ -= advDt; + if (x3a0_ < 0.f) + { + x3a0_ = 0.f; + ExitMissile(); + } + } +} + void CPlayerGun::PreRender(const CStateManager& mgr, const zeus::CFrustum& frustum, const zeus::CVector3f& camPos) { diff --git a/Runtime/Weapon/CPlayerGun.hpp b/Runtime/Weapon/CPlayerGun.hpp index 752444b30..075f5c455 100644 --- a/Runtime/Weapon/CPlayerGun.hpp +++ b/Runtime/Weapon/CPlayerGun.hpp @@ -83,14 +83,35 @@ private: class CMotionState { + public: + enum class EMotionState + { + Zero, + One, + Two + }; + private: static float gGunExtendDistance; + bool x0_24_ = true; + float x4_ = 0.f; + float x8_ = 0.f; + float xc_ = 0.f; + float x10_ = 0.f; + float x14_ = 0.f; + float x18_ = 0.f; + float x1c_ = 0.f; + EMotionState x20_state = EMotionState::Zero; + u32 x24_ = 0; public: static void SetExtendDistance(float d) { gGunExtendDistance = d; } + void SetState(EMotionState state) { x20_state = state; } + void Update(bool b1, float dt, zeus::CTransform& xf, CStateManager& mgr); + }; CActorLights x0_lights; - u32 x2e0_ = 0; - u32 x2e4_ = 0; + CSfxHandle x2e0_chargeSfx; + CSfxHandle x2e4_invalidSfx; u32 x2e8_ = 0; u32 x2ec_firing = 0; u32 x2f0_ = 0; @@ -116,8 +137,8 @@ private: float x340_chargeBeamFactor = 0.f; float x344_ = 0.f; float x348_ = 0.f; - float x34c_ = 0.f; - float x350_ = 0.f; + float x34c_shakeX = 0.f; + float x350_shakeZ = 0.f; float x354_bombFuseTime; float x358_bombDropDelayTime; float x35c_bombTime = 0.f; @@ -125,7 +146,7 @@ private: float x364_ = 0.f; float x368_ = 0.f; float x36c_ = 1.f; - float x370_ = 1.f; + float x370_gunMotionSpeedMult = 1.f; float x374_ = 0.f; float x378_ = 0.f; float x37c_ = 0.f; @@ -133,7 +154,7 @@ private: float x384_ = 0.f; float x388_ = 0.f; float x38c_ = 0.f; - float x390_ = 0.f; + float x390_cooldown = 0.f; float x394_damageTimer = 0.f; float x398_damageAmt = 0.f; float x39c_ = 0.f; @@ -141,12 +162,12 @@ private: CFidget x3a4_fidget; zeus::CVector3f x3dc_damageLocation; zeus::CTransform x3e8_xf; - zeus::CTransform x418_; - zeus::CTransform x448_; + zeus::CTransform x418_beamLocalXf; + zeus::CTransform x448_elbowWorldXf; zeus::CTransform x478_assistAimXf; - zeus::CTransform x4a8_; - zeus::CTransform x4d8_; - zeus::CTransform x508_; + zeus::CTransform x4a8_gunWorldXf; + zeus::CTransform x4d8_gunLocalXf; + zeus::CTransform x508_elbowLocalXf; TUniqueId x538_playerId; TUniqueId x53a_ = kInvalidUniqueId; TUniqueId x53c_lightId = kInvalidUniqueId; @@ -161,16 +182,7 @@ private: TUniqueId x670_ = kInvalidUniqueId; u32 x674_ = 0; CGunMorph x678_morph; - bool x6a0_24_ = true; - float x6a4_ = 0.f; - float x6a8_ = 0.f; - float x6ac_ = 0.f; - float x6b0_ = 0.f; - float x6b4_ = 0.f; - float x6b8_ = 0.f; - float x6bc_ = 0.f; - u32 x6c0_ = 0; - u32 x6c4_ = 0; + CMotionState x6a0_motionState; zeus::CAABox x6c8_; CModelData x6e0_rightHandModel; CGunWeapon* x72c_currentBeam = nullptr; @@ -188,12 +200,12 @@ private: std::unique_ptr x75c_phazonBeam; CGunWeapon* x760_selectableBeams[4] = {}; // Used to be reserved_vector std::unique_ptr x774_holoTransitionGen; - std::unique_ptr x77c_; + std::unique_ptr x77c_; rstl::reserved_vector, 2>, 2> x784_bombEffects; rstl::reserved_vector, 5> x7c0_auxMuzzleEffects; rstl::reserved_vector, 5> x800_auxMuzzleGenerators; std::unique_ptr x82c_shadow; - s16 x830 = -1; + s16 x830_chargeRumbleHandle = -1; union { @@ -213,7 +225,7 @@ private: bool x833_26_ : 1; bool x833_27_ : 1; bool x833_28_phazonBeamActive : 1; - bool x833_29_ : 1; + bool x833_29_pointBlankWorldSurface : 1; bool x833_30_ : 1; bool x833_31_ : 1; @@ -222,8 +234,8 @@ private: bool x834_26_ : 1; bool x834_27_underwater : 1; bool x834_28_ : 1; - bool x834_29_ : 1; - bool x834_30_damaged : 1; + bool x834_29_frozen : 1; + bool x834_30_inBigStrike : 1; bool x834_31_ : 1; bool x835_24_canFirePhazon : 1; @@ -245,17 +257,36 @@ private: void LoadHandAnimTokens(); void CreateGunLight(CStateManager& mgr); void DeleteGunLight(CStateManager& mgr); + void UpdateGunLight(const zeus::CTransform& pos, CStateManager& mgr); void SetGunLightActive(bool active, CStateManager& mgr); void SetPhazonBeamMorph(bool intoPhazonBeam); void Reset(CStateManager& mgr, bool b1); void ResetBeamParams(CStateManager& mgr, const CPlayerState& playerState, bool playSelectionSfx); - void PlaySfx(u16 sfx, bool underwater, bool looped, float pan); - void PlayAnim(NWeaponTypes::EGunAnimType type, bool b1); + CSfxHandle PlaySfx(u16 sfx, bool underwater, bool looped, float pan); + void PlayAnim(NWeaponTypes::EGunAnimType type, bool loop); void CancelCharge(CStateManager& mgr, bool withEffect); + bool ExitMissile(); + void StopChargeSound(CStateManager& mgr); + void UnLoadFidget(); + void ReturnArmAndGunToDefault(CStateManager& mgr, bool b1); + void ReturnToRestPose(); + void ChangeWeapon(const CPlayerState& playerState, CStateManager& mgr); + void GetLctrWithShake(zeus::CTransform& xfOut, const CModelData& mData, const std::string& lctrName, + bool b1, bool b2); + void UpdateLeftArmTransform(const CModelData& mData, const CStateManager& mgr); + void ProcessGunMorph(float dt, CStateManager& mgr); + void ProcessPhazonGunMorph(float dt, CStateManager& mgr); + void UpdateChargeState(float dt, CStateManager& mgr); + void UpdateAuxWeapons(float dt, const zeus::CTransform& targetXf, CStateManager& mgr); + void DoUserAnimEvents(float dt, CStateManager& mgr); + TUniqueId GetTargetId(CStateManager& mgr) const; + void CancelLockOn(); + void UpdateWeaponFire(float dt, const CPlayerState& playerState, CStateManager& mgr); + void UpdateGunIdle(bool b1, float camBobT, float dt, CStateManager& mgr); public: explicit CPlayerGun(TUniqueId playerId); - void TakeDamage(bool attack, bool notFromMetroid, CStateManager& mgr); + void TakeDamage(bool bigStrike, bool notFromMetroid, CStateManager& mgr); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void AsyncLoadSuit(CStateManager& mgr); void TouchModel(const CStateManager& stateMgr); diff --git a/Runtime/Weapon/CWeapon.hpp b/Runtime/Weapon/CWeapon.hpp index 5eec33da9..c8efd9caf 100644 --- a/Runtime/Weapon/CWeapon.hpp +++ b/Runtime/Weapon/CWeapon.hpp @@ -21,7 +21,7 @@ public: Unknown1 = (1 << 7), Bombs = (1 << 8), PowerBombs = (1 << 9), - Twelve = (1 << 12), + BigStrike = (1 << 12), StaticInterference = (1 << 14), }; diff --git a/Runtime/Weapon/WeaponCommon.cpp b/Runtime/Weapon/WeaponCommon.cpp new file mode 100644 index 000000000..f99ec1d16 --- /dev/null +++ b/Runtime/Weapon/WeaponCommon.cpp @@ -0,0 +1,82 @@ +#include "WeaponCommon.hpp" +#include "Character/CAnimData.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "Character/CPrimitive.hpp" + +namespace urde +{ +namespace NWeaponTypes +{ + +void primitive_set_to_token_vector(const CAnimData& animData, const std::set& primSet, + std::vector& tokensOut, bool preLock) +{ + int eventCount = 0; + for (const CPrimitive& prim : primSet) + if (animData.GetEventResourceIdForAnimResourceId(prim.GetAnimResId()).IsValid()) + ++eventCount; + + tokensOut.clear(); + tokensOut.reserve(primSet.size() + eventCount); + + SObjectTag atag{FOURCC('ANIM'), 0}; + SObjectTag etag{FOURCC('EVNT'), 0}; + for (const CPrimitive& prim : primSet) + { + CAssetId eId = animData.GetEventResourceIdForAnimResourceId(prim.GetAnimResId()); + if (eId.IsValid()) + { + etag.id = prim.GetAnimResId(); + tokensOut.push_back(g_SimplePool->GetObj(etag)); + if (preLock) + tokensOut.back().Lock(); + } + atag.id = prim.GetAnimResId(); + tokensOut.push_back(g_SimplePool->GetObj(atag)); + if (preLock) + tokensOut.back().Lock(); + } +} + +void unlock_tokens(std::vector& anims) +{ + for (CToken& tok : anims) + tok.Unlock(); +} + +void lock_tokens(std::vector& anims) +{ + for (CToken& tok : anims) + tok.Lock(); +} + +bool are_tokens_ready(const std::vector& anims) +{ + for (const CToken& tok : anims) + if (!tok.IsLoaded()) + return false; + return true; +} + +void get_token_vector(CAnimData& animData, int begin, int end, std::vector& tokensOut, bool preLock) +{ + std::set prims; + for (int i=begin ; i& tokensOut, bool preLock) +{ + std::set prims; + CAnimPlaybackParms parms(animIdx, -1, 1.f, true); + animData.GetAnimationPrimitives(parms, prims); + primitive_set_to_token_vector(animData, prims, tokensOut, preLock); +} + +} +} diff --git a/Runtime/Weapon/WeaponCommon.hpp b/Runtime/Weapon/WeaponCommon.hpp index 9cdd03228..521c1a4e0 100644 --- a/Runtime/Weapon/WeaponCommon.hpp +++ b/Runtime/Weapon/WeaponCommon.hpp @@ -3,9 +3,13 @@ #include "RetroTypes.hpp" #include "DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp" +#include namespace urde { +class CAnimData; +class CToken; +class CPrimitive; enum class EWeaponType { None = -1, @@ -25,5 +29,33 @@ enum class EWeaponType Unused1 = 13, OrangePhazon = 14 }; + +namespace NWeaponTypes +{ + +enum class EGunAnimType +{ + Zero, + One, + Two, + Three, + Four, + FromMissile, + ToMissile, + Seven, + MissileReload, + FromBeam +}; + +void primitive_set_to_token_vector(const CAnimData& animData, const std::set& primSet, + std::vector& tokensOut, bool preLock); +void unlock_tokens(std::vector& anims); +void lock_tokens(std::vector& anims); +bool are_tokens_ready(const std::vector& anims); +void get_token_vector(CAnimData& animData, int begin, int end, std::vector& tokensOut, bool preLock); +void get_token_vector(CAnimData& animData, int animIdx, std::vector& tokensOut, bool preLock); + +} + } #endif // __URDE_WEAPONCOMMON_HPP__ diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index 6c4cb5c18..486e03bf1 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -1309,7 +1309,7 @@ void CPlayer::RenderGun(const CStateManager& mgr, const zeus::CVector3f& pos) co if (mgr.GetCameraManager()->IsInCinematicCamera()) return; - if (x490_gun->GetGrappleArm().InGrappleCycle() && + if (x490_gun->GetGrappleArm().GetActive() && x490_gun->GetGrappleArm().GetAnimState() != CGrappleArm::EArmState::Ten) x490_gun->GetGrappleArm().RenderGrappleBeam(mgr, pos);