diff --git a/asm/MetroidPrime/Cameras/CCameraManager.s b/asm/MetroidPrime/Cameras/CCameraManager.s index 9553b17f..43b8eb0f 100644 --- a/asm/MetroidPrime/Cameras/CCameraManager.s +++ b/asm/MetroidPrime/Cameras/CCameraManager.s @@ -2133,8 +2133,8 @@ lbl_8000AD08: /* 8000AD24 00007C84 38 21 00 20 */ addi r1, r1, 0x20 /* 8000AD28 00007C88 4E 80 00 20 */ blr -.global sub_8000ad2c -sub_8000ad2c: +.global __dt__16CCameraShakeDataFv +__dt__16CCameraShakeDataFv: /* 8000AD2C 00007C8C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8000AD30 00007C90 7C 08 02 A6 */ mflr r0 /* 8000AD34 00007C94 90 01 00 14 */ stw r0, 0x14(r1) diff --git a/asm/MetroidPrime/Cameras/CCameraShakeData.s b/asm/MetroidPrime/Cameras/CCameraShakeData.s index b5bed57f..e7e21882 100644 --- a/asm/MetroidPrime/Cameras/CCameraShakeData.s +++ b/asm/MetroidPrime/Cameras/CCameraShakeData.s @@ -1487,9 +1487,9 @@ __sinit_CCameraShakeData_cpp: /* 8015DD80 0015ACE0 39 01 00 BC */ addi r8, r1, 0xbc /* 8015DD84 0015ACE4 38 80 00 00 */ li r4, 0 /* 8015DD88 0015ACE8 4B FF F1 11 */ bl __ct__16CCameraShakeDataFffiRC9CVector3fRC22CCameraShakerComponentRC22CCameraShakerComponentRC22CCameraShakerComponent -/* 8015DD8C 0015ACEC 3C 80 80 01 */ lis r4, sub_8000ad2c@ha +/* 8015DD8C 0015ACEC 3C 80 80 01 */ lis r4, __dt__16CCameraShakeDataFv@ha /* 8015DD90 0015ACF0 38 BF 00 60 */ addi r5, r31, 0x60 -/* 8015DD94 0015ACF4 38 84 AD 2C */ addi r4, r4, sub_8000ad2c@l +/* 8015DD94 0015ACF4 38 84 AD 2C */ addi r4, r4, __dt__16CCameraShakeDataFv@l /* 8015DD98 0015ACF8 48 22 B8 F5 */ bl __register_global_object /* 8015DD9C 0015ACFC 34 01 00 BC */ addic. r0, r1, 0xbc /* 8015DDA0 0015AD00 41 82 00 10 */ beq lbl_8015DDB0 @@ -1529,9 +1529,9 @@ lbl_8015DDD8: /* 8015DE1C 0015AD7C 39 01 00 08 */ addi r8, r1, 8 /* 8015DE20 0015AD80 38 80 00 00 */ li r4, 0 /* 8015DE24 0015AD84 4B FF F0 75 */ bl __ct__16CCameraShakeDataFffiRC9CVector3fRC22CCameraShakerComponentRC22CCameraShakerComponentRC22CCameraShakerComponent -/* 8015DE28 0015AD88 3C 80 80 01 */ lis r4, sub_8000ad2c@ha +/* 8015DE28 0015AD88 3C 80 80 01 */ lis r4, __dt__16CCameraShakeDataFv@ha /* 8015DE2C 0015AD8C 38 BF 00 6C */ addi r5, r31, 0x6c -/* 8015DE30 0015AD90 38 84 AD 2C */ addi r4, r4, sub_8000ad2c@l +/* 8015DE30 0015AD90 38 84 AD 2C */ addi r4, r4, __dt__16CCameraShakeDataFv@l /* 8015DE34 0015AD94 48 22 B8 59 */ bl __register_global_object /* 8015DE38 0015AD98 34 01 00 08 */ addic. r0, r1, 8 /* 8015DE3C 0015AD9C 41 82 00 10 */ beq lbl_8015DE4C diff --git a/asm/MetroidPrime/Weapons/CPlasmaBeam.s b/asm/MetroidPrime/Weapons/CPlasmaBeam.s index bdc52aae..f1f32e2d 100644 --- a/asm/MetroidPrime/Weapons/CPlasmaBeam.s +++ b/asm/MetroidPrime/Weapons/CPlasmaBeam.s @@ -7,8 +7,8 @@ lbl_ctor: .section .data .balign 8 -.global lbl_803DF710 -lbl_803DF710: +.global __vt__11CPlasmaBeam +__vt__11CPlasmaBeam: # ROM: 0x3DC710 .4byte 0 .4byte 0 @@ -18,13 +18,13 @@ lbl_803DF710: .4byte PreRenderGunFx__10CGunWeaponFRC13CStateManagerRC12CTransform4f .4byte PostRenderGunFx__11CPlasmaBeamFRC13CStateManagerRC12CTransform4f .4byte UpdateGunFx__11CPlasmaBeamFbfRC13CStateManagerRC12CTransform4f - .4byte Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId + .4byte Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff .4byte EnableFx__10CGunWeaponFb .4byte EnableSecondaryFx__11CPlasmaBeamFQ210CGunWeapon16ESecondaryFxType .4byte Draw__10CGunWeaponCFbRC13CStateManagerRC12CTransform4fRC11CModelFlagsPC12CActorLights .4byte DrawMuzzleFx__10CGunWeaponCFRC13CStateManager .4byte Update__11CPlasmaBeamFfR13CStateManager - .4byte Load__11CPlasmaBeamFb + .4byte Load__11CPlasmaBeamFR13CStateManagerb .4byte Unload__11CPlasmaBeamFR13CStateManager .4byte IsLoaded__11CPlasmaBeamCFv .4byte 0 @@ -43,7 +43,7 @@ lbl_805A7320: .balign 8 .lcomm lbl_8046C488, 0x10, 4 -.comm lbl_8056D420, 0xD4, 4 +.comm CameraShaker, 0xD4, 4 .section .sdata2, "a" .balign 8 @@ -339,8 +339,8 @@ Unload__11CPlasmaBeamFR13CStateManager: /* 800DEEA8 000DBE08 38 21 00 10 */ addi r1, r1, 0x10 /* 800DEEAC 000DBE0C 4E 80 00 20 */ blr -.global Load__11CPlasmaBeamFb -Load__11CPlasmaBeamFb: +.global Load__11CPlasmaBeamFR13CStateManagerb +Load__11CPlasmaBeamFR13CStateManagerb: /* 800DEEB0 000DBE10 94 21 FF F0 */ stwu r1, -0x10(r1) /* 800DEEB4 000DBE14 7C 08 02 A6 */ mflr r0 /* 800DEEB8 000DBE18 90 01 00 14 */ stw r0, 0x14(r1) @@ -407,8 +407,8 @@ StopBeam__11CPlasmaBeamFR13CStateManagerb: UpdateBeam__11CPlasmaBeamFfRC12CTransform4fRC9CVector3fR13CStateManager: /* 800DEF68 000DBEC8 4E 80 00 20 */ blr -.global Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId -Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId: +.global Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff +Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff: /* 800DEF6C 000DBECC 94 21 FF 90 */ stwu r1, -0x70(r1) /* 800DEF70 000DBED0 7C 08 02 A6 */ mflr r0 /* 800DEF74 000DBED4 90 01 00 74 */ stw r0, 0x74(r1) @@ -462,9 +462,9 @@ lbl_800DF028: /* 800DF030 000DBF90 C0 62 8F 38 */ lfs f3, lbl_805AAC58@sda21(r2) /* 800DF034 000DBF94 B0 01 00 08 */ sth r0, 8(r1) /* 800DF038 000DBF98 48 0D C8 51 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff -/* 800DF03C 000DBF9C 3C 80 80 57 */ lis r4, lbl_8056D420@ha +/* 800DF03C 000DBF9C 3C 80 80 57 */ lis r4, CameraShaker@ha /* 800DF040 000DBFA0 80 7E 08 70 */ lwz r3, 0x870(r30) -/* 800DF044 000DBFA4 38 84 D4 20 */ addi r4, r4, lbl_8056D420@l +/* 800DF044 000DBFA4 38 84 D4 20 */ addi r4, r4, CameraShaker@l /* 800DF048 000DBFA8 38 A0 00 00 */ li r5, 0 /* 800DF04C 000DBFAC 4B F2 B9 D5 */ bl AddCameraShaker__14CCameraManagerFRC16CCameraShakeDatab /* 800DF050 000DBFB0 C0 02 8F 44 */ lfs f0, lbl_805AAC64@sda21(r2) @@ -770,9 +770,6 @@ lbl_800DF468: /* 800DF484 000DC3E4 80 01 00 14 */ lwz r0, 0x14(r1) /* 800DF488 000DC3E8 7C 08 03 A6 */ mtlr r0 /* 800DF48C 000DC3EC 38 21 00 10 */ addi r1, r1, 0x10 - -.global sub_800df490 -sub_800df490: /* 800DF490 000DC3F0 4E 80 00 20 */ blr .global __dt__11CPlasmaBeamFv @@ -785,9 +782,9 @@ __dt__11CPlasmaBeamFv: /* 800DF4A8 000DC408 93 C1 00 08 */ stw r30, 8(r1) /* 800DF4AC 000DC40C 7C 7E 1B 79 */ or. r30, r3, r3 /* 800DF4B0 000DC410 41 82 00 70 */ beq lbl_800DF520 -/* 800DF4B4 000DC414 3C 60 80 3E */ lis r3, lbl_803DF710@ha +/* 800DF4B4 000DC414 3C 60 80 3E */ lis r3, __vt__11CPlasmaBeam@ha /* 800DF4B8 000DC418 34 1E 02 28 */ addic. r0, r30, 0x228 -/* 800DF4BC 000DC41C 38 03 F7 10 */ addi r0, r3, lbl_803DF710@l +/* 800DF4BC 000DC41C 38 03 F7 10 */ addi r0, r3, __vt__11CPlasmaBeam@l /* 800DF4C0 000DC420 90 1E 00 00 */ stw r0, 0(r30) /* 800DF4C4 000DC424 41 82 00 24 */ beq lbl_800DF4E8 /* 800DF4C8 000DC428 80 7E 02 28 */ lwz r3, 0x228(r30) @@ -835,9 +832,9 @@ __ct__11CPlasmaBeamFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f: /* 800DF558 000DC4B8 38 C1 00 08 */ addi r6, r1, 8 /* 800DF55C 000DC4BC B0 01 00 08 */ sth r0, 8(r1) /* 800DF560 000DC4C0 48 0D DC 51 */ bl __ct__10CGunWeaponFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f -/* 800DF564 000DC4C4 3C 60 80 3E */ lis r3, lbl_803DF710@ha +/* 800DF564 000DC4C4 3C 60 80 3E */ lis r3, __vt__11CPlasmaBeam@ha /* 800DF568 000DC4C8 3C 80 80 3D */ lis r4, lbl_803CE530@ha -/* 800DF56C 000DC4CC 38 03 F7 10 */ addi r0, r3, lbl_803DF710@l +/* 800DF56C 000DC4CC 38 03 F7 10 */ addi r0, r3, __vt__11CPlasmaBeam@l /* 800DF570 000DC4D0 38 61 00 0C */ addi r3, r1, 0xc /* 800DF574 000DC4D4 90 1F 00 00 */ stw r0, 0(r31) /* 800DF578 000DC4D8 38 84 E5 30 */ addi r4, r4, lbl_803CE530@l @@ -887,13 +884,13 @@ __sinit_CPlasmaBeam_cpp: /* 800DF61C 000DC57C 38 61 00 08 */ addi r3, r1, 8 /* 800DF620 000DC580 C0 42 8F 64 */ lfs f2, lbl_805AAC84@sda21(r2) /* 800DF624 000DC584 48 07 E2 0D */ bl __ct__16CCameraShakeDataFff -/* 800DF628 000DC588 3C 60 80 57 */ lis r3, lbl_8056D420@ha +/* 800DF628 000DC588 3C 60 80 57 */ lis r3, CameraShaker@ha /* 800DF62C 000DC58C 38 81 00 08 */ addi r4, r1, 8 -/* 800DF630 000DC590 38 63 D4 20 */ addi r3, r3, lbl_8056D420@l +/* 800DF630 000DC590 38 63 D4 20 */ addi r3, r3, CameraShaker@l /* 800DF634 000DC594 4B F2 B7 75 */ bl __ct__16CCameraShakeDataFRC16CCameraShakeData -/* 800DF638 000DC598 3C 80 80 01 */ lis r4, sub_8000ad2c@ha +/* 800DF638 000DC598 3C 80 80 01 */ lis r4, __dt__16CCameraShakeDataFv@ha /* 800DF63C 000DC59C 3C A0 80 47 */ lis r5, lbl_8046C488@ha -/* 800DF640 000DC5A0 38 84 AD 2C */ addi r4, r4, sub_8000ad2c@l +/* 800DF640 000DC5A0 38 84 AD 2C */ addi r4, r4, __dt__16CCameraShakeDataFv@l /* 800DF644 000DC5A4 38 A5 C4 88 */ addi r5, r5, lbl_8046C488@l /* 800DF648 000DC5A8 48 2A A0 45 */ bl __register_global_object /* 800DF64C 000DC5AC 34 81 00 88 */ addic. r4, r1, 0x88 diff --git a/configure.py b/configure.py index 132e8090..a0b50307 100755 --- a/configure.py +++ b/configure.py @@ -129,7 +129,7 @@ LIBS = [ ["MetroidPrime/ScriptLoader", False], "MetroidPrime/CSamusDoll", "MetroidPrime/Factories/CStateMachineFactory", - "MetroidPrime/Weapons/CPlasmaBeam", + ["MetroidPrime/Weapons/CPlasmaBeam", False], ["MetroidPrime/Weapons/CPowerBeam", False], "MetroidPrime/Weapons/CWaveBeam", ["MetroidPrime/Weapons/CIceBeam", False], @@ -268,7 +268,7 @@ LIBS = [ "MetroidPrime/Weapons/CIceImpact", ["MetroidPrime/GameObjectLists", True], "MetroidPrime/Weapons/CAuxWeapon", - "MetroidPrime/Weapons/CGunWeapon", + ["MetroidPrime/Weapons/CGunWeapon", False], ["MetroidPrime/ScriptObjects/CScriptAreaAttributes", False], "MetroidPrime/Weapons/CWaveBuster", ["MetroidPrime/Player/CStaticInterference", False], diff --git a/include/MetroidPrime/Cameras/CCameraShakeData.hpp b/include/MetroidPrime/Cameras/CCameraShakeData.hpp index 48d5f899..916a1ecb 100644 --- a/include/MetroidPrime/Cameras/CCameraShakeData.hpp +++ b/include/MetroidPrime/Cameras/CCameraShakeData.hpp @@ -12,11 +12,32 @@ struct SCameraShakePoint { float xc_attackTime; float x10_sustainTime; float x14_duration; + + SCameraShakePoint() + : x0_useEnvelope(false) + , x8_magnitude(0.f) + , xc_attackTime(0.f) + , x10_sustainTime(0.f) + , x14_duration(0.f) {} + + SCameraShakePoint(bool useEnvelope, float attackTime, float sustainTime, float duration, + float magnitude) + : x0_useEnvelope(useEnvelope) + , x8_magnitude(magnitude) + , xc_attackTime(attackTime) + , x10_sustainTime(sustainTime) + , x14_duration(duration) {} }; CHECK_SIZEOF(SCameraShakePoint, 0x18) class CCameraShakerComponent { public: + CCameraShakerComponent() : x4_useModulation(false), x38_value(0.f) {} + + CCameraShakerComponent(bool useModulation, const SCameraShakePoint& am, + const SCameraShakePoint& fm) + : x4_useModulation(useModulation), x8_am(am), x20_fm(fm) {} + virtual ~CCameraShakerComponent() {} private: @@ -30,14 +51,24 @@ CHECK_SIZEOF(CCameraShakerComponent, 0x3c) class CStateManager; class CCameraShakeData { public: + CCameraShakeData(float duration, float magnitude) + : x0_duration(duration) + , xd0_sfxDist(100.f) + , xc0_flags(0) + , xc4_sfxPos(CVector3f::Zero()) + , x8_shakerX() + , x44_shakerY() + , x80_shakerZ(true, SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude), + SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.f)) {} CCameraShakeData(const CCameraShakeData&); + void SetShakerId(int id) { xbc_shakerId = id; } int GetShakerId() const { return xbc_shakerId; } void Update(float dt, CStateManager& mgr); float GetDuration() const { return x0_duration; } float GetCurTime() const { return x4_curTime; } - const CVector3f& GetPoint() const;// { return xc4_sfxPos; } + const CVector3f& GetPoint() const; // { return xc4_sfxPos; } private: float x0_duration; diff --git a/include/MetroidPrime/Player/CPlayerGun.hpp b/include/MetroidPrime/Player/CPlayerGun.hpp index c55fedbd..26a3e851 100644 --- a/include/MetroidPrime/Player/CPlayerGun.hpp +++ b/include/MetroidPrime/Player/CPlayerGun.hpp @@ -180,6 +180,7 @@ public: int GetStateFlags() const { return x2f8_stateFlags; } void SetStateFlags(int flags) { x2f8_stateFlags = flags; } + bool IsCharging() const { return x834_24_charging; } private: class CGunMorph { diff --git a/include/MetroidPrime/Weapons/CGunWeapon.hpp b/include/MetroidPrime/Weapons/CGunWeapon.hpp index ceda8ed3..35aa1eb9 100644 --- a/include/MetroidPrime/Weapons/CGunWeapon.hpp +++ b/include/MetroidPrime/Weapons/CGunWeapon.hpp @@ -76,7 +76,7 @@ public: virtual void EnableFx(bool enable); virtual void EnableSecondaryFx(ESecondaryFxType type); virtual void Draw(bool drawSuitArm, const CStateManager& mgr, const CTransform4f& xf, - const CModelFlags& flags, const CActorLights* lights); + const CModelFlags& flags, const CActorLights* lights) const; virtual void DrawMuzzleFx(const CStateManager& mgr) const; virtual void Update(float dt, CStateManager& mgr); virtual void Load(CStateManager& mgr, bool subtypeBasePose); @@ -90,6 +90,7 @@ public: CAABox GetBounds() const; CAABox GetBounds(const CTransform4f& xf) const; const SWeaponInfo& GetWeaponInfo() const; + void ActivateCharge(bool enable, bool resetEffect); protected: // x0 is vtable diff --git a/include/MetroidPrime/Weapons/CPlasmaBeam.hpp b/include/MetroidPrime/Weapons/CPlasmaBeam.hpp index 7b422a00..282faa57 100644 --- a/include/MetroidPrime/Weapons/CPlasmaBeam.hpp +++ b/include/MetroidPrime/Weapons/CPlasmaBeam.hpp @@ -4,15 +4,48 @@ #include "types.h" #include "MetroidPrime/Weapons/CGunWeapon.hpp" +#include "MetroidPrime/CEntityInfo.hpp" class CPlasmaBeam : public CGunWeapon { public: CPlasmaBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, const CVector3f& scale); - ~CPlasmaBeam(); + + ~CPlasmaBeam() override; + + // CGunWeapon + void PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) override; + void UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, + const CTransform4f& xf) override; + void Update(float dt, CStateManager& mgr) override; + void Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState, + const CTransform4f& xf, CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, + float chargeFactor2) override; + + void Load(CStateManager& mgr, bool subtypeBasePose) override; + void Unload(CStateManager& mgr) override; + bool IsLoaded() const override; + void EnableSecondaryFx(ESecondaryFxType type) override; + + bool IsFiring(const CStateManager& mgr) const; + void StopBeam(CStateManager& mgr, bool b1); + void CreateBeam(CStateManager& mgr); + void UpdateBeam(float dt, const CTransform4f& targetXf, const CVector3f& localBeamPos, CStateManager& mgr); + void DeleteBeam(CStateManager& mgr); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); private: - uchar x21c_pad[0x24]; + TCachedToken< CGenDescription > x21c_plasma2nd1; + rstl::single_ptr< CElementGen > x228_chargeFx; + bool x22c_24_loaded : 1; + bool x22c_25_worldLighingDim : 1; + float x230_fireShotDelayTimer; + float x234_fireShotDelay; + float x238_lightingResetDelayTimer; + TAreaId x23c_stateArea; + + void ReInitVariables(); + void SetWorldLighting(CStateManager& mgr, TAreaId aid, float speed, float target); }; CHECK_SIZEOF(CPlasmaBeam, 0x240) diff --git a/src/MetroidPrime/Weapons/CGunWeapon.cpp b/src/MetroidPrime/Weapons/CGunWeapon.cpp new file mode 100644 index 00000000..27b0fe61 --- /dev/null +++ b/src/MetroidPrime/Weapons/CGunWeapon.cpp @@ -0,0 +1,4 @@ +#include "MetroidPrime/Weapons/CGunWeapon.hpp" + +void CGunWeapon::Draw(bool drawSuitArm, const CStateManager& mgr, const CTransform4f& xf, + const CModelFlags& flags, const CActorLights* lights) const {} diff --git a/src/MetroidPrime/Weapons/CPlasmaBeam.cpp b/src/MetroidPrime/Weapons/CPlasmaBeam.cpp new file mode 100644 index 00000000..e312b598 --- /dev/null +++ b/src/MetroidPrime/Weapons/CPlasmaBeam.cpp @@ -0,0 +1,188 @@ +#include "MetroidPrime/Weapons/CPlasmaBeam.hpp" + +#include "MetroidPrime/CGameArea.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/CWorld.hpp" +#include "MetroidPrime/Cameras/CCameraManager.hpp" +#include "MetroidPrime/Cameras/CCameraShakeData.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/Player/CPlayerGun.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" +#include "MetroidPrime/SFX/Weapons.h" + +#include "Kyoto/Particles/CElementGen.hpp" + +#include "rstl/math.hpp" + +static CCameraShakeData CameraShaker = CCameraShakeData(0.125f, 0.25f); +static ushort kSoundId[2] = {SFXwpn_fire_plasma_normal, SFXwpn_fire_plasma_charged}; + +CPlasmaBeam::CPlasmaBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, + EMaterialTypes playerMaterial, const CVector3f& scale) +: CGunWeapon(characterId, type, playerId, playerMaterial, scale) +, x21c_plasma2nd1(gpSimplePool->GetObj("Plasma2nd_1")) +, x22c_24_loaded(false) +, x22c_25_worldLighingDim(false) +, x230_fireShotDelayTimer(0.f) +, x234_fireShotDelay(0.f) +, x238_lightingResetDelayTimer(0.f) +, x23c_stateArea(kInvalidAreaId) {} + +CPlasmaBeam::~CPlasmaBeam() {} + +void CPlasmaBeam::ReInitVariables() { + x228_chargeFx = nullptr; + x22c_24_loaded = false; + x1cc_enabledSecondaryEffect = kSFT_None; +} + +bool CPlasmaBeam::IsFiring(const CStateManager& mgr) const { return x234_fireShotDelay > 0.f; } + +void CPlasmaBeam::PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) { + if (x228_chargeFx.get() && x1cc_enabledSecondaryEffect != kSFT_None) + x228_chargeFx->Render(); + CGunWeapon::PostRenderGunFx(mgr, xf); +} + +void CPlasmaBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, + const CTransform4f& xf) { + if (x228_chargeFx.get() && x1cc_enabledSecondaryEffect != kSFT_None) { + if (x228_chargeFx->IsSystemDeletable()) + x1cc_enabledSecondaryEffect = kSFT_None; + x228_chargeFx->SetTranslation(xf.GetTranslation()); + x228_chargeFx->SetOrientation(xf.GetRotation()); + x228_chargeFx->Update(dt); + } + CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf); +} + +void CPlasmaBeam::Update(float dt, CStateManager& mgr) { + CGunWeapon::Update(dt, mgr); + x230_fireShotDelayTimer -= dt; + x230_fireShotDelayTimer = rstl::max_val(0.f, x230_fireShotDelayTimer); + x238_lightingResetDelayTimer -= dt; + + if (mgr.GetPlayer()->GetPlayerGun()->GetChargeBeamFactor() > 0.5f) { + SetWorldLighting(mgr, mgr.GetPlayer()->GetCurrentAreaId(), 0.2f, 0.8f); + } else { + if (x238_lightingResetDelayTimer < 0.f && x22c_25_worldLighingDim) { + SetWorldLighting(mgr, mgr.GetPlayer()->GetCurrentAreaId(), 2.f, 1.f); + } + } + + if (IsLoaded()) + return; + + if (CGunWeapon::IsLoaded() && !x22c_24_loaded) { + x22c_24_loaded = x21c_plasma2nd1.IsLoaded(); + if (x22c_24_loaded) + CreateBeam(mgr); + } +} + +void CPlasmaBeam::Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState, + const CTransform4f& xf, CStateManager& mgr, TUniqueId homingTarget, + float chargeFactor1, float chargeFactor2) { + bool fired = false; + if (chargeState == CPlayerState::kCS_Normal) { + if (x230_fireShotDelayTimer < 0.01f) { + ActivateCharge(false, true); + CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1, + chargeFactor2); + x230_fireShotDelayTimer += 0.33f; + x234_fireShotDelay = 0.33f; + fired = true; + } + } else { + CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1, 1.f); + mgr.CameraManager()->AddCameraShaker(CameraShaker, false); + x238_lightingResetDelayTimer = 0.65f; + SetWorldLighting(mgr, mgr.GetPlayer()->GetCurrentAreaId(), 8.f, 0.7f); + fired = true; + } + + if (!fired) { + return; + } + + NWeaponTypes::play_sfx(kSoundId[chargeState], underwater, false, 0x4a); +} + +void CPlasmaBeam::UpdateBeam(float dt, const CTransform4f& targetXf, const CVector3f& localBeamPos, + CStateManager& mgr) {} + +void CPlasmaBeam::StopBeam(CStateManager& mgr, bool b1) {} + +void CPlasmaBeam::CreateBeam(CStateManager& mgr) {} + +void CPlasmaBeam::DeleteBeam(CStateManager& mgr) { + if (x22c_25_worldLighingDim) + SetWorldLighting(mgr, mgr.GetPlayer()->GetCurrentAreaId(), 2.f, 1.f); +} + +void CPlasmaBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { + switch (msg) { + case kSM_Deleted: + DeleteBeam(mgr); + break; + + case kSM_Registered: + default: + break; + } +} + + +void CPlasmaBeam::Load(CStateManager& mgr, bool subtypeBasePose) { + CGunWeapon::Load(mgr, subtypeBasePose); + x21c_plasma2nd1.Lock(); +} + +void CPlasmaBeam::Unload(CStateManager& mgr) { + CGunWeapon::Unload(mgr); + x21c_plasma2nd1.Unlock(); + DeleteBeam(mgr); + ReInitVariables(); +} + +bool CPlasmaBeam::IsLoaded() const { return CGunWeapon::IsLoaded() && x22c_24_loaded; } + +void CPlasmaBeam::EnableSecondaryFx(ESecondaryFxType type) { + switch (type) { + case kSFT_CancelCharge: + if (x1cc_enabledSecondaryEffect == kSFT_None) + return; + + if (!x228_chargeFx.null()) { + x228_chargeFx->SetParticleEmission(false); + break; + } else { + return; + } + + case kSFT_Charge: + x228_chargeFx = new CElementGen(x21c_plasma2nd1); + x228_chargeFx->SetGlobalScale(x4_scale); + + default: + break; + } + x1cc_enabledSecondaryEffect = type; +} + +void CPlasmaBeam::SetWorldLighting(CStateManager& mgr, TAreaId aid, float speed, float target) { + if (x22c_25_worldLighingDim && x23c_stateArea != aid && x23c_stateArea != kInvalidAreaId) { + CGameArea* area = mgr.World()->Area(x23c_stateArea); + if (area->IsLoaded()) + area->SetWeaponWorldLighting(2.f, 1.f); + } + + x23c_stateArea = aid; + x22c_25_worldLighingDim = target != 1.f; + + if (x23c_stateArea != kInvalidAreaId) { + CGameArea* area = mgr.World()->Area(x23c_stateArea); + if (area->IsLoaded()) + area->SetWeaponWorldLighting(speed, target); + } +}