diff --git a/asm/MetroidPrime/BodyState/CBSLieOnGround.s b/asm/MetroidPrime/BodyState/CBSLieOnGround.s index ced79a07..39197987 100644 --- a/asm/MetroidPrime/BodyState/CBSLieOnGround.s +++ b/asm/MetroidPrime/BodyState/CBSLieOnGround.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E1488 -lbl_803E1488: +.global __vt__14CBSLieOnGround +__vt__14CBSLieOnGround: # ROM: 0x3DE488 .4byte 0 .4byte 0 @@ -31,8 +31,8 @@ __dt__14CBSLieOnGroundFv: /* 801367D8 00133738 93 E1 00 0C */ stw r31, 0xc(r1) /* 801367DC 0013373C 7C 7F 1B 79 */ or. r31, r3, r3 /* 801367E0 00133740 41 82 00 30 */ beq lbl_80136810 -/* 801367E4 00133744 3C 60 80 3E */ lis r3, lbl_803E1488@ha -/* 801367E8 00133748 38 03 14 88 */ addi r0, r3, lbl_803E1488@l +/* 801367E4 00133744 3C 60 80 3E */ lis r3, __vt__14CBSLieOnGround@ha +/* 801367E8 00133748 38 03 14 88 */ addi r0, r3, __vt__14CBSLieOnGround@l /* 801367EC 0013374C 90 1F 00 00 */ stw r0, 0(r31) /* 801367F0 00133750 41 82 00 10 */ beq lbl_80136800 /* 801367F4 00133754 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha @@ -252,10 +252,10 @@ __ct__14CBSLieOnGroundFRC6CActor: /* 80136ADC 00133A3C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80136AE0 00133A40 7C 08 02 A6 */ mflr r0 /* 80136AE4 00133A44 3C C0 80 3E */ lis r6, __vt__10CBodyState@ha -/* 80136AE8 00133A48 3C A0 80 3E */ lis r5, lbl_803E1488@ha +/* 80136AE8 00133A48 3C A0 80 3E */ lis r5, __vt__14CBSLieOnGround@ha /* 80136AEC 00133A4C 90 01 00 14 */ stw r0, 0x14(r1) /* 80136AF0 00133A50 38 C6 13 18 */ addi r6, r6, __vt__10CBodyState@l -/* 80136AF4 00133A54 38 05 14 88 */ addi r0, r5, lbl_803E1488@l +/* 80136AF4 00133A54 38 05 14 88 */ addi r0, r5, __vt__14CBSLieOnGround@l /* 80136AF8 00133A58 93 E1 00 0C */ stw r31, 0xc(r1) /* 80136AFC 00133A5C 7C 7F 1B 78 */ mr r31, r3 /* 80136B00 00133A60 38 60 00 00 */ li r3, 0 diff --git a/configure.py b/configure.py index 5eb25bce..b74cae55 100755 --- a/configure.py +++ b/configure.py @@ -189,7 +189,7 @@ LIBS = [ "MetroidPrime/BodyState/CBSFall", ["MetroidPrime/BodyState/CBSGetup", True], "MetroidPrime/BodyState/CBSKnockBack", - "MetroidPrime/BodyState/CBSLieOnGround", + ["MetroidPrime/BodyState/CBSLieOnGround", True], "MetroidPrime/BodyState/CBSLocomotion", "MetroidPrime/BodyState/CBSStep", "MetroidPrime/BodyState/CBSTurn", diff --git a/include/Kyoto/Animation/CPASDatabase.hpp b/include/Kyoto/Animation/CPASDatabase.hpp index 978da51f..1547de98 100644 --- a/include/Kyoto/Animation/CPASDatabase.hpp +++ b/include/Kyoto/Animation/CPASDatabase.hpp @@ -14,6 +14,7 @@ class CRandom16; class CPASDatabase { public: + bool HasState(int id) const; const CPASAnimState* GetAnimState(int) const; rstl::pair< float, int > FindBestAnimation(const CPASAnimParmData&, CRandom16&, int) const; diff --git a/include/MetroidPrime/BodyState/CBSLieOnGround.hpp b/include/MetroidPrime/BodyState/CBSLieOnGround.hpp new file mode 100644 index 00000000..0172205e --- /dev/null +++ b/include/MetroidPrime/BodyState/CBSLieOnGround.hpp @@ -0,0 +1,23 @@ +#ifndef _CBSLIEONGROUND +#define _CBSLIEONGROUND + +#include "MetroidPrime/BodyState/CBodyState.hpp" + +class CActor; + +class CBSLieOnGround : public CBodyState { +public: + explicit CBSLieOnGround(const CActor& actor); + ~CBSLieOnGround(); + + void Start(CBodyController& bc, CStateManager& mgr) override; + pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override; + void Shutdown(CBodyController& bc) override; + +private: + uint x4_24_hasGroundHit : 1; + + pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); +}; + +#endif // _CBSLIEONGROUND diff --git a/obj_files.mk b/obj_files.mk index 8e48a48a..de3554d0 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -154,7 +154,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSFall.o\ $(BUILD_DIR)/src/MetroidPrime/BodyState/CBSGetup.o\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSKnockBack.o\ - $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSLieOnGround.o\ + $(BUILD_DIR)/src/MetroidPrime/BodyState/CBSLieOnGround.o\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSLocomotion.o\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSStep.o\ $(BUILD_DIR)/asm/MetroidPrime/BodyState/CBSTurn.o\ diff --git a/src/MetroidPrime/BodyState/CBSLieOnGround.cpp b/src/MetroidPrime/BodyState/CBSLieOnGround.cpp new file mode 100644 index 00000000..ac56cb56 --- /dev/null +++ b/src/MetroidPrime/BodyState/CBSLieOnGround.cpp @@ -0,0 +1,53 @@ +#include "MetroidPrime/BodyState/CBSLieOnGround.hpp" + +#include "MetroidPrime/BodyState/CBodyController.hpp" +#include "MetroidPrime/BodyState/CBodyStateCmdMgr.hpp" +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/CAnimData.hpp" +#include "MetroidPrime/CModelData.hpp" +#include "MetroidPrime/CStateManager.hpp" + +#include "Kyoto/Animation/CPASAnimParmData.hpp" + +CBSLieOnGround::CBSLieOnGround(const CActor& actor) : x4_24_hasGroundHit(false) { + x4_24_hasGroundHit = + actor.GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().HasState( + pas::kAS_GroundHit); +} + +void CBSLieOnGround::Start(CBodyController& bc, CStateManager& mgr) { + int fallState = bc.GetFallState(); + const CPASDatabase& db = bc.GetPASDatabase(); + + const CPASAnimParmData parms(pas::kAS_LieOnGround, CPASAnimParm::FromEnum(fallState)); + const rstl::pair< float, int > best = db.FindBestAnimation(parms, *mgr.Random(), -1); + if (best.first > 0.f) { + const CAnimPlaybackParms playParms(best.second, -1, 1.f, true); + bc.SetCurrentAnimation(playParms, true, false); + } else { + bc.EnableAnimation(false); + } +} + +pas::EAnimationState CBSLieOnGround::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { + return GetBodyStateTransition(dt, bc); +} + +void CBSLieOnGround::Shutdown(CBodyController& bc) { bc.EnableAnimation(true); } + +pas::EAnimationState CBSLieOnGround::GetBodyStateTransition(float dt, CBodyController& bc) { + CBodyStateCmdMgr& commandMgr = bc.CommandMgr(); + + if (commandMgr.GetCmd(kBSC_Die)) { + return pas::kAS_Death; + } + if (x4_24_hasGroundHit && commandMgr.GetCmd(kBSC_KnockBack)) { + return pas::kAS_GroundHit; + } + if (!commandMgr.GetCmd(kBSC_Locomotion) && commandMgr.GetCmd(kBSC_Getup)) { + return pas::kAS_Getup; + } + return pas::kAS_Invalid; +} + +CBSLieOnGround::~CBSLieOnGround() {}