diff --git a/asm/MetroidPrime/BodyState/CBSScripted.s b/asm/MetroidPrime/BodyState/CBSScripted.s index 582a2d4d..eb742548 100644 --- a/asm/MetroidPrime/BodyState/CBSScripted.s +++ b/asm/MetroidPrime/BodyState/CBSScripted.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E24A8 -lbl_803E24A8: +.global __vt__11CBSScripted +__vt__11CBSScripted: # ROM: 0x3DF4A8 .4byte 0 .4byte 0 @@ -31,8 +31,8 @@ __dt__11CBSScriptedFv: /* 8014B0CC 0014802C 93 E1 00 0C */ stw r31, 0xc(r1) /* 8014B0D0 00148030 7C 7F 1B 79 */ or. r31, r3, r3 /* 8014B0D4 00148034 41 82 00 30 */ beq lbl_8014B104 -/* 8014B0D8 00148038 3C 60 80 3E */ lis r3, lbl_803E24A8@ha -/* 8014B0DC 0014803C 38 03 24 A8 */ addi r0, r3, lbl_803E24A8@l +/* 8014B0D8 00148038 3C 60 80 3E */ lis r3, __vt__11CBSScripted@ha +/* 8014B0DC 0014803C 38 03 24 A8 */ addi r0, r3, __vt__11CBSScripted@l /* 8014B0E0 00148040 90 1F 00 00 */ stw r0, 0(r31) /* 8014B0E4 00148044 41 82 00 10 */ beq lbl_8014B0F4 /* 8014B0E8 00148048 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha @@ -258,11 +258,11 @@ Start__11CBSScriptedFR15CBodyControllerR13CStateManager: .global __ct__11CBSScriptedFv __ct__11CBSScriptedFv: /* 8014B3E0 00148340 3C C0 80 3E */ lis r6, __vt__10CBodyState@ha -/* 8014B3E4 00148344 3C A0 80 3E */ lis r5, lbl_803E24A8@ha +/* 8014B3E4 00148344 3C A0 80 3E */ lis r5, __vt__11CBSScripted@ha /* 8014B3E8 00148348 38 C6 13 18 */ addi r6, r6, __vt__10CBodyState@l /* 8014B3EC 0014834C 38 80 00 00 */ li r4, 0 /* 8014B3F0 00148350 90 C3 00 00 */ stw r6, 0(r3) -/* 8014B3F4 00148354 38 05 24 A8 */ addi r0, r5, lbl_803E24A8@l +/* 8014B3F4 00148354 38 05 24 A8 */ addi r0, r5, __vt__11CBSScripted@l /* 8014B3F8 00148358 C0 02 9C E8 */ lfs f0, lbl_805ABA08@sda21(r2) /* 8014B3FC 0014835C 90 03 00 00 */ stw r0, 0(r3) /* 8014B400 00148360 88 03 00 04 */ lbz r0, 4(r3) diff --git a/configure.py b/configure.py index b74cae55..5f300a87 100755 --- a/configure.py +++ b/configure.py @@ -210,7 +210,7 @@ LIBS = [ "MetroidPrime/CSortedLists", ["MetroidPrime/ScriptObjects/CScriptDebugCameraWaypoint", True], ["MetroidPrime/ScriptObjects/CScriptSpiderBallAttractionSurface", False], - "MetroidPrime/BodyState/CBSScripted", + ["MetroidPrime/BodyState/CBSScripted", True], "MetroidPrime/Enemies/CPuddleToadGamma", ["MetroidPrime/ScriptObjects/CScriptDistanceFog", False], "MetroidPrime/BodyState/CBSProjectileAttack", diff --git a/include/MetroidPrime/BodyState/CBSScripted.hpp b/include/MetroidPrime/BodyState/CBSScripted.hpp new file mode 100644 index 00000000..1e9d2227 --- /dev/null +++ b/include/MetroidPrime/BodyState/CBSScripted.hpp @@ -0,0 +1,24 @@ +#ifndef _CBSSCRIPTED +#define _CBSSCRIPTED + +#include "MetroidPrime/BodyState/CBodyState.hpp" + +class CBSScripted : public CBodyState { +public: + CBSScripted(); + ~CBSScripted(); + + bool ApplyHeadTracking() const override; + void Start(CBodyController& bc, CStateManager& mgr) override; + pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override; + void Shutdown(CBodyController&) override; + +private: + bool x4_24_loopAnim : 1; + bool x4_25_timedLoop : 1; + float x8_remTime; + + pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); +}; + +#endif // _CBSSCRIPTED diff --git a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp index f3ac2323..30449d2c 100644 --- a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp +++ b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp @@ -47,7 +47,7 @@ public: , xc_targetPos(vec) , x1c_24_targetTransform(targetTransform) , x1c_25_overrideAnim(overrideAnim) {} - + pas::EGenerateType GetGenerateType() const { return x8_type; } const CVector3f& GetExitTargetPos() const { return xc_targetPos; } bool HasExitTargetPos() const { return x1c_24_targetTransform; } @@ -57,6 +57,35 @@ public: // +class CBCScriptedCmd : public CBodyStateCmd { + s32 x8_anim; + bool xc_24_loopAnim : 1; + bool xc_25_timedLoop : 1; + float x10_loopDur; + +public: + explicit CBCScriptedCmd() + : CBodyStateCmd(kBSC_Scripted) + , x8_anim(-1) + , xc_24_loopAnim(false) + , xc_25_timedLoop(false) + , x10_loopDur(0.f) {} + + explicit CBCScriptedCmd(int i, bool b1, bool b2, float f) + : CBodyStateCmd(kBSC_Scripted) + , x8_anim(i) + , xc_24_loopAnim(b1) + , xc_25_timedLoop(b2) + , x10_loopDur(f) {} + + int GetAnimId() const { return x8_anim; } + bool IsLooped() const { return xc_24_loopAnim; } + bool GetUseLoopDuration() const { return xc_25_timedLoop; } + float GetLoopDuration() const { return x10_loopDur; } +}; + +// + class CBCGetupCmd : public CBodyStateCmd { pas::EGetupType x8_type; diff --git a/obj_files.mk b/obj_files.mk index de3554d0..7b36097f 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -175,7 +175,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/CSortedLists.o\ $(BUILD_DIR)/src/MetroidPrime/ScriptObjects/CScriptDebugCameraWaypoint.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptSpiderBallAttractionSurface.o\ - $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSScripted.o\ + $(BUILD_DIR)/src/MetroidPrime/BodyState/CBSScripted.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CPuddleToadGamma.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptDistanceFog.o\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSProjectileAttack.o\ diff --git a/src/MetroidPrime/BodyState/CBSScripted.cpp b/src/MetroidPrime/BodyState/CBSScripted.cpp new file mode 100644 index 00000000..038c421e --- /dev/null +++ b/src/MetroidPrime/BodyState/CBSScripted.cpp @@ -0,0 +1,70 @@ +#include "MetroidPrime/BodyState/CBSScripted.hpp" + +#include "MetroidPrime/CAnimPlaybackParms.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/BodyState/CBodyController.hpp" + +#include "Kyoto/Animation/CPASAnimParmData.hpp" +#include "Kyoto/Animation/CPASDatabase.hpp" + +CBSScripted::CBSScripted() : x4_24_loopAnim(false), x4_25_timedLoop(false), x8_remTime(0.f) {} + +void CBSScripted::Start(CBodyController& bc, CStateManager& mgr) { + const CBCScriptedCmd* cmd = static_cast(bc.CommandMgr().GetCmd(kBSC_Scripted)); + x4_24_loopAnim = cmd->IsLooped(); + x4_25_timedLoop = cmd->GetUseLoopDuration(); + x8_remTime = cmd->GetLoopDuration(); + const CAnimPlaybackParms playParms(cmd->GetAnimId(), -1, 1.f, true); + bc.SetCurrentAnimation(playParms, cmd->IsLooped(), false); +} + +pas::EAnimationState CBSScripted::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { + pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::kAS_Invalid) { + CBodyStateCmdMgr& commandMgr = bc.CommandMgr(); + if (commandMgr.GetTargetVector().IsNonZero()) { + bc.FaceDirection(commandMgr.GetTargetVector(), dt); + } + if (x4_24_loopAnim && x4_25_timedLoop) { + x8_remTime -= dt; + if (x8_remTime <= 0.f) { + st = pas::kAS_Locomotion; + } + } + } + return st; +} + +void CBSScripted::Shutdown(CBodyController&) override {} + +pas::EAnimationState CBSScripted::GetBodyStateTransition(float dt, CBodyController& bc) { + CBodyStateCmdMgr& commandMgr = bc.CommandMgr(); + + if (commandMgr.GetCmd(kBSC_Hurled)) { + return pas::kAS_Hurled; + } + if (commandMgr.GetCmd(kBSC_KnockDown)) { + return pas::kAS_Fall; + } + if (commandMgr.GetCmd(kBSC_LoopHitReaction)) { + return pas::kAS_LoopReaction; + } + if (commandMgr.GetCmd(kBSC_KnockBack)) { + return pas::kAS_KnockBack; + } + if (commandMgr.GetCmd(kBSC_Scripted)) { + return pas::kAS_Scripted; + } + if (x4_24_loopAnim) { + if (commandMgr.GetCmd(kBSC_ExitState)) { + return pas::kAS_Locomotion; + } + } else if (bc.IsAnimationOver()) { + return pas::kAS_Locomotion; + } + return pas::kAS_Invalid; +} + +bool CBSScripted::ApplyHeadTracking() const override { return false; } + +CBSScripted::~CBSScripted() {}