From 68f99e4072442cc3268eceefff8b0ccf1a93d9c3 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Tue, 15 Nov 2022 22:06:18 +0200 Subject: [PATCH] Add CPowerBeam Former-commit-id: 0d1b469f91ac6e2034c172fb7d9e804c5656b288 --- asm/MetroidPrime/Weapons/CGunWeapon.s | 6 +- asm/MetroidPrime/Weapons/CIceBeam.s | 2 +- asm/MetroidPrime/Weapons/CPhazonBeam.s | 5 +- asm/MetroidPrime/Weapons/CPlasmaBeam.s | 4 +- asm/MetroidPrime/Weapons/CPowerBeam.s | 21 ++- asm/MetroidPrime/Weapons/CWaveBeam.s | 2 +- configure.py | 2 +- include/Kyoto/CToken.hpp | 3 + include/Kyoto/Particles/CElementGen.hpp | 3 + include/Kyoto/TToken.hpp | 17 ++ include/MetroidPrime/CModelData.hpp | 3 + include/MetroidPrime/Weapons/CGunWeapon.hpp | 14 +- include/MetroidPrime/Weapons/CPowerBeam.hpp | 25 ++- include/MetroidPrime/Weapons/WeaponCommon.hpp | 1 + src/MetroidPrime/Weapons/CPowerBeam.cpp | 155 ++++++++++++++++++ 15 files changed, 235 insertions(+), 28 deletions(-) create mode 100644 src/MetroidPrime/Weapons/CPowerBeam.cpp diff --git a/asm/MetroidPrime/Weapons/CGunWeapon.s b/asm/MetroidPrime/Weapons/CGunWeapon.s index ad65de7a..f30f90c2 100644 --- a/asm/MetroidPrime/Weapons/CGunWeapon.s +++ b/asm/MetroidPrime/Weapons/CGunWeapon.s @@ -14,7 +14,7 @@ lbl_803E52B0: .4byte PreRenderGunFx__10CGunWeaponFRC13CStateManagerRC12CTransform4f .4byte PostRenderGunFx__10CGunWeaponFRC13CStateManagerRC12CTransform4f .4byte UpdateGunFx__10CGunWeaponFbfRC13CStateManagerRC12CTransform4f - .4byte Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId + .4byte Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff .4byte EnableFx__10CGunWeaponFb .4byte EnableSecondaryFx__10CGunWeaponFQ210CGunWeapon16ESecondaryFxType .4byte Draw__10CGunWeaponCFbRC13CStateManagerRC12CTransform4fRC11CModelFlagsPC12CActorLights @@ -2036,8 +2036,8 @@ ReturnToDefault__10CGunWeaponFR13CStateManager: /* 801BB880 001B87E0 38 21 00 10 */ addi r1, r1, 0x10 /* 801BB884 001B87E4 4E 80 00 20 */ blr -.global Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId -Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId: +.global Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff +Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff: /* 801BB888 001B87E8 94 21 FE E0 */ stwu r1, -0x120(r1) /* 801BB88C 001B87EC 7C 08 02 A6 */ mflr r0 /* 801BB890 001B87F0 90 01 01 24 */ stw r0, 0x124(r1) diff --git a/asm/MetroidPrime/Weapons/CIceBeam.s b/asm/MetroidPrime/Weapons/CIceBeam.s index bc7e275d..e842b48f 100644 --- a/asm/MetroidPrime/Weapons/CIceBeam.s +++ b/asm/MetroidPrime/Weapons/CIceBeam.s @@ -283,7 +283,7 @@ Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager /* 800E1234 000DE194 A0 08 00 00 */ lhz r0, 0(r8) /* 800E1238 000DE198 39 01 00 08 */ addi r8, r1, 8 /* 800E123C 000DE19C B0 01 00 08 */ sth r0, 8(r1) -/* 800E1240 000DE1A0 48 0D A6 49 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 800E1240 000DE1A0 48 0D A6 49 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 800E1244 000DE1A4 57 E0 08 3C */ slwi r0, r31, 1 /* 800E1248 000DE1A8 38 62 8F A0 */ addi r3, r2, lbl_805AACC0@sda21 /* 800E124C 000DE1AC 7C 83 02 2E */ lhzx r4, r3, r0 diff --git a/asm/MetroidPrime/Weapons/CPhazonBeam.s b/asm/MetroidPrime/Weapons/CPhazonBeam.s index 5e640d16..6ff8b6ba 100644 --- a/asm/MetroidPrime/Weapons/CPhazonBeam.s +++ b/asm/MetroidPrime/Weapons/CPhazonBeam.s @@ -539,7 +539,7 @@ lbl_8018C918: /* 8018C944 001898A4 7F 46 D3 78 */ mr r6, r26 /* 8018C948 001898A8 7F 67 DB 78 */ mr r7, r27 /* 8018C94C 001898AC 39 01 00 0C */ addi r8, r1, 0xc -/* 8018C950 001898B0 48 02 EF 39 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 8018C950 001898B0 48 02 EF 39 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 8018C954 001898B4 80 7B 08 D8 */ lwz r3, 0x8d8(r27) /* 8018C958 001898B8 48 12 27 B1 */ bl SetGlobalSeed__17CProjectileWeaponFUs /* 8018C95C 001898BC 3B DE 03 E8 */ addi r30, r30, 0x3e8 @@ -555,7 +555,7 @@ lbl_8018C97C: /* 8018C97C 001898DC A0 1C 00 00 */ lhz r0, 0(r28) /* 8018C980 001898E0 39 01 00 08 */ addi r8, r1, 8 /* 8018C984 001898E4 B0 01 00 08 */ sth r0, 8(r1) -/* 8018C988 001898E8 48 02 EF 01 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 8018C988 001898E8 48 02 EF 01 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 8018C98C 001898EC 38 00 00 01 */ li r0, 1 lbl_8018C990: /* 8018C990 001898F0 54 00 06 3F */ clrlwi. r0, r0, 0x18 @@ -1325,4 +1325,3 @@ lbl_803D0912: .asciz "azon2nd_1" .balign 4 .4byte 0 - diff --git a/asm/MetroidPrime/Weapons/CPlasmaBeam.s b/asm/MetroidPrime/Weapons/CPlasmaBeam.s index 3ac8dc0d..bdc52aae 100644 --- a/asm/MetroidPrime/Weapons/CPlasmaBeam.s +++ b/asm/MetroidPrime/Weapons/CPlasmaBeam.s @@ -448,7 +448,7 @@ Fire__11CPlasmaBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateMan /* 800DEFFC 000DBF5C 7F A6 EB 78 */ mr r6, r29 /* 800DF000 000DBF60 7F C7 F3 78 */ mr r7, r30 /* 800DF004 000DBF64 39 01 00 0C */ addi r8, r1, 0xc -/* 800DF008 000DBF68 48 0D C8 81 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 800DF008 000DBF68 48 0D C8 81 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 800DF00C 000DBF6C C0 1A 02 30 */ lfs f0, 0x230(r26) /* 800DF010 000DBF70 38 00 00 01 */ li r0, 1 /* 800DF014 000DBF74 C0 22 8F 40 */ lfs f1, lbl_805AAC60@sda21(r2) @@ -461,7 +461,7 @@ lbl_800DF028: /* 800DF02C 000DBF8C 39 01 00 08 */ addi r8, r1, 8 /* 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__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 800DF038 000DBF98 48 0D C8 51 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 800DF03C 000DBF9C 3C 80 80 57 */ lis r4, lbl_8056D420@ha /* 800DF040 000DBFA0 80 7E 08 70 */ lwz r3, 0x870(r30) /* 800DF044 000DBFA4 38 84 D4 20 */ addi r4, r4, lbl_8056D420@l diff --git a/asm/MetroidPrime/Weapons/CPowerBeam.s b/asm/MetroidPrime/Weapons/CPowerBeam.s index 287e1a65..130ea116 100644 --- a/asm/MetroidPrime/Weapons/CPowerBeam.s +++ b/asm/MetroidPrime/Weapons/CPowerBeam.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803DF758 -lbl_803DF758: +.global __vt__10CPowerBeam +__vt__10CPowerBeam: # ROM: 0x3DC758 .4byte 0 .4byte 0 @@ -14,7 +14,7 @@ lbl_803DF758: .4byte PreRenderGunFx__10CPowerBeamFRC13CStateManagerRC12CTransform4f .4byte PostRenderGunFx__10CPowerBeamFRC13CStateManagerRC12CTransform4f .4byte UpdateGunFx__10CPowerBeamFbfRC13CStateManagerRC12CTransform4f - .4byte Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId + .4byte Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff .4byte EnableFx__10CGunWeaponFb .4byte EnableSecondaryFx__10CPowerBeamFQ210CGunWeapon16ESecondaryFxType .4byte Draw__10CGunWeaponCFbRC13CStateManagerRC12CTransform4fRC11CModelFlagsPC12CActorLights @@ -202,8 +202,8 @@ Load__10CPowerBeamFR13CStateManagerb: /* 800DF8AC 000DC80C 38 21 00 10 */ addi r1, r1, 0x10 /* 800DF8B0 000DC810 4E 80 00 20 */ blr -.global Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId -Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId: +.global Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff +Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff: /* 800DF8B4 000DC814 94 21 FF E0 */ stwu r1, -0x20(r1) /* 800DF8B8 000DC818 7C 08 02 A6 */ mflr r0 /* 800DF8BC 000DC81C 90 01 00 24 */ stw r0, 0x24(r1) @@ -214,7 +214,7 @@ Fire__10CPowerBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateMana /* 800DF8D0 000DC830 A0 08 00 00 */ lhz r0, 0(r8) /* 800DF8D4 000DC834 39 01 00 08 */ addi r8, r1, 8 /* 800DF8D8 000DC838 B0 01 00 08 */ sth r0, 8(r1) -/* 800DF8DC 000DC83C 48 0D BF AD */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 800DF8DC 000DC83C 48 0D BF AD */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 800DF8E0 000DC840 57 E0 08 3C */ slwi r0, r31, 1 /* 800DF8E4 000DC844 38 62 8F 68 */ addi r3, r2, lbl_805AAC88@sda21 /* 800DF8E8 000DC848 7C 83 02 2E */ lhzx r4, r3, r0 @@ -638,9 +638,9 @@ __dt__10CPowerBeamFv: /* 800DFEC8 000DCE28 93 C1 00 08 */ stw r30, 8(r1) /* 800DFECC 000DCE2C 7C 7E 1B 79 */ or. r30, r3, r3 /* 800DFED0 000DCE30 41 82 00 B4 */ beq lbl_800DFF84 -/* 800DFED4 000DCE34 3C 60 80 3E */ lis r3, lbl_803DF758@ha +/* 800DFED4 000DCE34 3C 60 80 3E */ lis r3, __vt__10CPowerBeam@ha /* 800DFED8 000DCE38 34 1E 02 38 */ addic. r0, r30, 0x238 -/* 800DFEDC 000DCE3C 38 03 F7 58 */ addi r0, r3, lbl_803DF758@l +/* 800DFEDC 000DCE3C 38 03 F7 58 */ addi r0, r3, __vt__10CPowerBeam@l /* 800DFEE0 000DCE40 90 1E 00 00 */ stw r0, 0(r30) /* 800DFEE4 000DCE44 41 82 00 24 */ beq lbl_800DFF08 /* 800DFEE8 000DCE48 80 7E 02 38 */ lwz r3, 0x238(r30) @@ -707,9 +707,9 @@ __ct__10CPowerBeamFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f: /* 800DFFBC 000DCF1C 38 C1 00 08 */ addi r6, r1, 8 /* 800DFFC0 000DCF20 B0 01 00 08 */ sth r0, 8(r1) /* 800DFFC4 000DCF24 48 0D D1 ED */ bl __ct__10CGunWeaponFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f -/* 800DFFC8 000DCF28 3C 60 80 3E */ lis r3, lbl_803DF758@ha +/* 800DFFC8 000DCF28 3C 60 80 3E */ lis r3, __vt__10CPowerBeam@ha /* 800DFFCC 000DCF2C 3C 80 80 3D */ lis r4, lbl_803CE548@ha -/* 800DFFD0 000DCF30 38 03 F7 58 */ addi r0, r3, lbl_803DF758@l +/* 800DFFD0 000DCF30 38 03 F7 58 */ addi r0, r3, __vt__10CPowerBeam@l /* 800DFFD4 000DCF34 38 61 00 14 */ addi r3, r1, 0x14 /* 800DFFD8 000DCF38 90 1F 00 00 */ stw r0, 0(r31) /* 800DFFDC 000DCF3C 38 84 E5 48 */ addi r4, r4, lbl_803CE548@l @@ -777,4 +777,3 @@ lbl_803CE548: .byte 0x50, 0x6F, 0x77 .asciz "er2nd_1" .4byte 0 - diff --git a/asm/MetroidPrime/Weapons/CWaveBeam.s b/asm/MetroidPrime/Weapons/CWaveBeam.s index 0c5e203d..0e570750 100644 --- a/asm/MetroidPrime/Weapons/CWaveBeam.s +++ b/asm/MetroidPrime/Weapons/CWaveBeam.s @@ -370,7 +370,7 @@ Fire__9CWaveBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManage /* 800E0498 000DD3F8 A0 18 00 00 */ lhz r0, 0(r24) /* 800E049C 000DD3FC 39 01 00 44 */ addi r8, r1, 0x44 /* 800E04A0 000DD400 B0 01 00 44 */ sth r0, 0x44(r1) -/* 800E04A4 000DD404 48 0D B3 E5 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId +/* 800E04A4 000DD404 48 0D B3 E5 */ bl Fire__10CGunWeaponFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff /* 800E04A8 000DD408 48 00 01 E4 */ b lbl_800E068C lbl_800E04AC: /* 800E04AC 000DD40C 80 77 09 00 */ lwz r3, 0x900(r23) diff --git a/configure.py b/configure.py index 05bd3417..163e14e5 100755 --- a/configure.py +++ b/configure.py @@ -130,7 +130,7 @@ LIBS = [ "MetroidPrime/CSamusDoll", "MetroidPrime/Factories/CStateMachineFactory", "MetroidPrime/Weapons/CPlasmaBeam", - "MetroidPrime/Weapons/CPowerBeam", + ["MetroidPrime/Weapons/CPowerBeam", False], "MetroidPrime/Weapons/CWaveBeam", "MetroidPrime/Weapons/CIceBeam", ["MetroidPrime/CScriptMailbox", False], diff --git a/include/Kyoto/CToken.hpp b/include/Kyoto/CToken.hpp index 5791d0b5..6ac6699a 100644 --- a/include/Kyoto/CToken.hpp +++ b/include/Kyoto/CToken.hpp @@ -24,6 +24,9 @@ public: void RemoveRef(); CToken& operator=(const CToken&); +protected: + bool HasLock() { return x4_lockHeld; } + private: CObjectReference* x0_objRef; bool x4_lockHeld; diff --git a/include/Kyoto/Particles/CElementGen.hpp b/include/Kyoto/Particles/CElementGen.hpp index e29942c1..a986397b 100644 --- a/include/Kyoto/Particles/CElementGen.hpp +++ b/include/Kyoto/Particles/CElementGen.hpp @@ -73,6 +73,7 @@ public: virtual uint Get4CharId() const override; int GetEmitterTime() const; + int GetSystemCount(); int GetCumulativeParticleCount() const { return x260_cumulativeParticles; } bool IsIndirectTextured() const; // { return x28_loadedGenDesc->x54_x40_TEXR && x28_loadedGenDesc->x58_x44_TIND; } @@ -81,6 +82,8 @@ public: static void Initialize(); static void ShutDown(); + void SetGlobalOrientAndTrans(const CTransform4f& xf); + public: TLockedToken< CGenDescription > x1c_genDesc; CGenDescription* x28_loadedGenDesc; diff --git a/include/Kyoto/TToken.hpp b/include/Kyoto/TToken.hpp index 7ea670b8..2b8f34d1 100644 --- a/include/Kyoto/TToken.hpp +++ b/include/Kyoto/TToken.hpp @@ -35,6 +35,23 @@ public: T* operator*() { return x8_item; } + bool IsLoaded() { + if (x8_item != nullptr) { + return true; + } + if (HasLock() && CToken::IsLoaded()) { + x8_item = GetT(); + return true; + } else { + return false; + } + } + + void Unlock() { + x8_item = nullptr; + TToken::Unlock(); + } + private: T* x8_item; }; diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index dae5e8bf..a7edfaf4 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -13,6 +13,7 @@ #include "rstl/auto_ptr.hpp" #include "rstl/optional_object.hpp" #include "rstl/pair.hpp" +#include "rstl/string.hpp" class CAABox; class CActorLights; @@ -82,6 +83,8 @@ public: CAABox GetBounds(const CTransform4f& xf) const; CAABox GetBounds() const; + CTransform4f GetScaledLocatorTransform(const rstl::string& name) const; + bool HasAnimation() const { return !xc_animData.null(); } bool IsNull() const { return xc_animData.null() && !x1c_normalModel; } diff --git a/include/MetroidPrime/Weapons/CGunWeapon.hpp b/include/MetroidPrime/Weapons/CGunWeapon.hpp index c22bb28f..ceda8ed3 100644 --- a/include/MetroidPrime/Weapons/CGunWeapon.hpp +++ b/include/MetroidPrime/Weapons/CGunWeapon.hpp @@ -3,10 +3,12 @@ #include "types.h" +#include "MetroidPrime/CModelData.hpp" #include "MetroidPrime/Player/CPlayerState.hpp" #include "MetroidPrime/Weapons/WeaponCommon.hpp" #include "MetroidPrime/Weapons/WeaponTypes.hpp" +#include "Kyoto/Math/CAABox.hpp" #include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/TToken.hpp" @@ -16,13 +18,16 @@ #include "rstl/reserved_vector.hpp" #include "rstl/single_ptr.hpp" -class CModelData; class CGenDescription; class CGunController; class CAnimCharacterSet; class CWeaponDescription; class CElementGen; class CRainSplashGenerator; +class CTransform4f; +class CModelFlags; +class CActorLights; +class SWeaponInfo; class CVelocityInfo { public: @@ -42,10 +47,9 @@ private: class CGunWeapon { public: - // TODO ctor - CGunWeapon(); + CGunWeapon(CAssetId ancsId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, + const CVector3f& scale); virtual ~CGunWeapon(); - // TODO other virtual methods enum ESecondaryFxType { kSFT_None, @@ -87,7 +91,7 @@ public: CAABox GetBounds(const CTransform4f& xf) const; const SWeaponInfo& GetWeaponInfo() const; -private: +protected: // x0 is vtable CVector3f x4_scale; rstl::optional_object< CModelData > x10_solidModelData; diff --git a/include/MetroidPrime/Weapons/CPowerBeam.hpp b/include/MetroidPrime/Weapons/CPowerBeam.hpp index ca621dfe..b8a0843d 100644 --- a/include/MetroidPrime/Weapons/CPowerBeam.hpp +++ b/include/MetroidPrime/Weapons/CPowerBeam.hpp @@ -5,14 +5,37 @@ #include "MetroidPrime/Weapons/CGunWeapon.hpp" +#include "rstl/single_ptr.hpp" + class CPowerBeam : public CGunWeapon { public: CPowerBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, EMaterialTypes playerMaterial, const CVector3f& scale); ~CPowerBeam(); + void PreRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) override; + void PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) override; + void UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, const CTransform4f& xf) override; + void Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState, const CTransform4f& xf, CStateManager& mgr, + TUniqueId homingTarget, float chargeFactor1, float chargeFactor2) override; + void EnableSecondaryFx(ESecondaryFxType type) override; + void Update(float dt, CStateManager& mgr) override; + void Load(CStateManager& mgr, bool subtypeBasePose) override; + void Unload(CStateManager& mgr) override; + bool IsLoaded() const override; + private: - uchar x21c_pad[0x2C]; + enum ESmokeState { kSS_Inactive, kSS_Active, kSS_Done }; + TCachedToken x21c_shotSmoke; + TCachedToken x228_power2nd1; + rstl::single_ptr x234_shotSmokeGen; + rstl::single_ptr x238_power2ndGen; + float x23c_smokeTimer; + ESmokeState x240_smokeState; + bool x244_24 : 1; + bool x244_25_loaded : 1; + + void ReInitVariables(); }; CHECK_SIZEOF(CPowerBeam, 0x248) diff --git a/include/MetroidPrime/Weapons/WeaponCommon.hpp b/include/MetroidPrime/Weapons/WeaponCommon.hpp index 44e8bc3e..cc12af67 100644 --- a/include/MetroidPrime/Weapons/WeaponCommon.hpp +++ b/include/MetroidPrime/Weapons/WeaponCommon.hpp @@ -5,6 +5,7 @@ class CToken; class CSfxHandle; +class CAnimData; namespace NWeaponTypes { diff --git a/src/MetroidPrime/Weapons/CPowerBeam.cpp b/src/MetroidPrime/Weapons/CPowerBeam.cpp new file mode 100644 index 00000000..b5dcc9dc --- /dev/null +++ b/src/MetroidPrime/Weapons/CPowerBeam.cpp @@ -0,0 +1,155 @@ +#include "MetroidPrime/Weapons/CPowerBeam.hpp" + +#include "MetroidPrime/SFX/Weapons.h" + +#include "MetaRender/CCubeRenderer.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Particles/CElementGen.hpp" +#include "Kyoto/Audio/CSfxHandle.hpp" + + +CPowerBeam::CPowerBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, + EMaterialTypes playerMaterial, const CVector3f& scale) +: CGunWeapon(characterId, type, playerId, playerMaterial, scale) +, x21c_shotSmoke(gpSimplePool->GetObj("ShotSmoke")) +, x228_power2nd1(gpSimplePool->GetObj("Power2nd_1")) +, x23c_smokeTimer(0.f) +, x240_smokeState(kSS_Inactive) +, x244_24(false) +, x244_25_loaded(false) { +} + +CPowerBeam::~CPowerBeam() {} + +void CPowerBeam::ReInitVariables() { + x234_shotSmokeGen = nullptr; + x238_power2ndGen = nullptr; + x23c_smokeTimer = 0.f; + x240_smokeState = kSS_Inactive; + x244_24 = false; + x244_25_loaded = false; + x1cc_enabledSecondaryEffect = kSFT_None; +} + +void CPowerBeam::PreRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) { + CTransform4f backupView = CGraphics::GetViewMatrix(); + + CGraphics::SetViewPointMatrix(xf.GetInverse() * backupView); + gpRender->SetModelMatrix(CTransform4f::Identity()); + if (!x234_shotSmokeGen.null() && x240_smokeState != kSS_Inactive) + x234_shotSmokeGen->Render(); + + CGraphics::SetViewPointMatrix(backupView); +} + +void CPowerBeam::PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) { + if (x1cc_enabledSecondaryEffect != kSFT_None && !x238_power2ndGen.null()) + x238_power2ndGen->Render(); + CGunWeapon::PostRenderGunFx(mgr, xf); +} + +static const char* kTransformName = "LBEAM"; + +void CPowerBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr, + const CTransform4f& xf) { + switch (x240_smokeState) { + case kSS_Inactive: + if (shotSmoke) { + if (!x234_shotSmokeGen.null()) + x234_shotSmokeGen->SetParticleEmission(true); + x23c_smokeTimer = 2.f; + x240_smokeState = kSS_Active; + } + break; + case kSS_Active: + if (x23c_smokeTimer > 0.f) { + x23c_smokeTimer -= dt; + } else { + if (!x234_shotSmokeGen.null()) + x234_shotSmokeGen->SetParticleEmission(false); + x240_smokeState = kSS_Done; + } + // [[fallthrough]]; + case kSS_Done: + if (!x234_shotSmokeGen.null()) { + CTransform4f locator = x10_solidModelData->GetScaledLocatorTransform(rstl::string_l(kTransformName)); + x234_shotSmokeGen->SetGlobalTranslation(locator.GetTranslation()); + x234_shotSmokeGen->Update(dt); + if (x240_smokeState == kSS_Done && x234_shotSmokeGen->GetSystemCount() == 0) + x240_smokeState = kSS_Inactive; + } else { + x240_smokeState = kSS_Inactive; + } + break; + } + + if (x1cc_enabledSecondaryEffect != kSFT_None && !x238_power2ndGen.null()) { + x238_power2ndGen->SetGlobalOrientAndTrans(xf); + x238_power2ndGen->Update(dt); + } + + CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf); +} + + +void CPowerBeam::Update(float dt, CStateManager& mgr) { + CGunWeapon::Update(dt, mgr); + if (IsLoaded()) + return; + + if (CGunWeapon::IsLoaded() && !x244_25_loaded) { + x244_25_loaded = x21c_shotSmoke.IsLoaded() && x228_power2nd1.IsLoaded(); + if (x244_25_loaded) { + x234_shotSmokeGen = new CElementGen (x21c_shotSmoke); + x234_shotSmokeGen->SetParticleEmission(false); + } + } +} + +void CPowerBeam::Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState, const CTransform4f& xf, + CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1, + float chargeFactor2) { + static ushort skSoundId[] = { + SFXwpn_fire_power_normal, + SFXwpn_fire_power_charged, + }; + + CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1, + chargeFactor2); + NWeaponTypes::play_sfx(skSoundId[size_t(chargeState)], underwater, false, 0x4a); +} + +void CPowerBeam::Load(CStateManager& mgr, bool subtypeBasePose) { + CGunWeapon::Load(mgr, subtypeBasePose); + x21c_shotSmoke.Lock(); + x228_power2nd1.Lock(); +} + + +void CPowerBeam::Unload(CStateManager& mgr) { + CGunWeapon::Unload(mgr); + x228_power2nd1.Unlock(); + x21c_shotSmoke.Unlock(); + ReInitVariables(); +} + +bool CPowerBeam::IsLoaded() const { return CGunWeapon::IsLoaded() && x244_25_loaded; } + +void CPowerBeam::EnableSecondaryFx(ESecondaryFxType type) { + switch (type) { + case kSFT_None: + case kSFT_ToCombo: + case kSFT_CancelCharge: + if (x1cc_enabledSecondaryEffect != kSFT_None && !x238_power2ndGen.null()) + x238_power2ndGen->SetParticleEmission(false); + x1cc_enabledSecondaryEffect = kSFT_None; + break; + case kSFT_Charge: + x238_power2ndGen = new CElementGen(x228_power2nd1); + x238_power2ndGen->SetGlobalScale(x4_scale); + x1cc_enabledSecondaryEffect = type; + break; + default: + break; + } +}