mirror of https://github.com/PrimeDecomp/prime.git
Add CBSFall
This commit is contained in:
parent
a7e2bdf73f
commit
4e55f8c7dd
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E13E0
|
||||
lbl_803E13E0:
|
||||
.global __vt__7CBSFall
|
||||
__vt__7CBSFall:
|
||||
# ROM: 0x3DE3E0
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -31,8 +31,8 @@ __dt__7CBSFallFv:
|
|||
/* 80135944 001328A4 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 80135948 001328A8 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 8013594C 001328AC 41 82 00 30 */ beq lbl_8013597C
|
||||
/* 80135950 001328B0 3C 60 80 3E */ lis r3, lbl_803E13E0@ha
|
||||
/* 80135954 001328B4 38 03 13 E0 */ addi r0, r3, lbl_803E13E0@l
|
||||
/* 80135950 001328B0 3C 60 80 3E */ lis r3, __vt__7CBSFall@ha
|
||||
/* 80135954 001328B4 38 03 13 E0 */ addi r0, r3, __vt__7CBSFall@l
|
||||
/* 80135958 001328B8 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 8013595C 001328BC 41 82 00 10 */ beq lbl_8013596C
|
||||
/* 80135960 001328C0 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -388,11 +388,11 @@ lbl_80135E3C:
|
|||
.global __ct__7CBSFallFv
|
||||
__ct__7CBSFallFv:
|
||||
/* 80135E58 00132DB8 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
||||
/* 80135E5C 00132DBC 3C 80 80 3E */ lis r4, lbl_803E13E0@ha
|
||||
/* 80135E5C 00132DBC 3C 80 80 3E */ lis r4, __vt__7CBSFall@ha
|
||||
/* 80135E60 00132DC0 38 05 13 18 */ addi r0, r5, __vt__10CBodyState@l
|
||||
/* 80135E64 00132DC4 C0 02 99 C0 */ lfs f0, lbl_805AB6E0@sda21(r2)
|
||||
/* 80135E68 00132DC8 90 03 00 00 */ stw r0, 0(r3)
|
||||
/* 80135E6C 00132DCC 38 84 13 E0 */ addi r4, r4, lbl_803E13E0@l
|
||||
/* 80135E6C 00132DCC 38 84 13 E0 */ addi r4, r4, __vt__7CBSFall@l
|
||||
/* 80135E70 00132DD0 38 00 FF FF */ li r0, -1
|
||||
/* 80135E74 00132DD4 90 83 00 00 */ stw r4, 0(r3)
|
||||
/* 80135E78 00132DD8 D0 03 00 04 */ stfs f0, 4(r3)
|
||||
|
|
|
@ -186,7 +186,7 @@ LIBS = [
|
|||
["MetroidPrime/BodyState/CBodyStateInfo", False],
|
||||
"MetroidPrime/BodyState/CBSAttack",
|
||||
["MetroidPrime/BodyState/CBSDie", True],
|
||||
"MetroidPrime/BodyState/CBSFall",
|
||||
["MetroidPrime/BodyState/CBSFall", False],
|
||||
["MetroidPrime/BodyState/CBSGetup", True],
|
||||
"MetroidPrime/BodyState/CBSKnockBack",
|
||||
["MetroidPrime/BodyState/CBSLieOnGround", True],
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
int GetEnumValue() const; // { return x0_value.m_int; }
|
||||
int GetInt32Value() const;
|
||||
float GetReal32Value() const;
|
||||
bool GetBoolValue() const;
|
||||
|
||||
private:
|
||||
UParmValue x0_value;
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _CBSFALL
|
||||
#define _CBSFALL
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||
|
||||
class CBSFall : public CBodyState {
|
||||
public:
|
||||
CBSFall();
|
||||
~CBSFall();
|
||||
|
||||
void Start(CBodyController& bc, CStateManager& mgr) override;
|
||||
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
|
||||
void Shutdown(CBodyController& bc) override;
|
||||
|
||||
private:
|
||||
float x4_rotateSpeed;
|
||||
float x8_remTime;
|
||||
pas::EFallState xc_fallState;
|
||||
|
||||
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||
};
|
||||
|
||||
#endif // _CBSFALL
|
|
@ -168,6 +168,24 @@ private:
|
|||
|
||||
//
|
||||
|
||||
class CBCKnockDownCmd : public CBodyStateCmd {
|
||||
public:
|
||||
explicit CBCKnockDownCmd()
|
||||
: CBodyStateCmd(kBSC_KnockDown), x8_dir(0.f, 0.f, 0.f), x14_severity(pas::kS_Invalid) {}
|
||||
|
||||
explicit CBCKnockDownCmd(const CVector3f& vec, pas::ESeverity severity)
|
||||
: CBodyStateCmd(kBSC_KnockDown), x8_dir(vec), x14_severity(severity) {}
|
||||
|
||||
const CVector3f& GetHitDirection() const { return x8_dir; }
|
||||
pas::ESeverity GetHitSeverity() const { return x14_severity; }
|
||||
|
||||
private:
|
||||
CVector3f x8_dir;
|
||||
pas::ESeverity x14_severity;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CBodyStateCmdMgr {
|
||||
public:
|
||||
CBodyStateCmd* GetCmd(EBodyStateCmd cmd);
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#include "MetroidPrime/BodyState/CBSFall.hpp"
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyController.hpp"
|
||||
#include "MetroidPrime/CActor.hpp"
|
||||
#include "MetroidPrime/CAnimPlaybackParms.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
|
||||
#include "Kyoto/Animation/CPASAnimParmData.hpp"
|
||||
#include "Kyoto/Animation/CPASDatabase.hpp"
|
||||
#include "Kyoto/Math/CRelAngle.hpp"
|
||||
#include "Kyoto/Math/CAbsAngle.hpp"
|
||||
|
||||
#include "math.h"
|
||||
#include "rstl/math.hpp"
|
||||
|
||||
|
||||
CBSFall::CBSFall() : x4_rotateSpeed(0.f), x8_remTime(0.f), xc_fallState(pas::kFS_Invalid) {}
|
||||
|
||||
void CBSFall::Start(CBodyController& bc, CStateManager& mgr) {
|
||||
const CBCKnockDownCmd* cmd =
|
||||
static_cast< const CBCKnockDownCmd* >(bc.CommandMgr().GetCmd(kBSC_KnockDown));
|
||||
CVector3f localDir = bc.GetOwner().GetTransform().TransposeRotate(cmd->GetHitDirection());
|
||||
CAbsAngle angle = CAbsAngle::FromRadians(atan2(localDir.GetY(), localDir.GetZ()));
|
||||
|
||||
const CPASDatabase& db = bc.GetPASDatabase();
|
||||
const CPASAnimParmData parms(pas::kAS_Fall, CPASAnimParm::FromReal32(angle.AsDegrees()),
|
||||
CPASAnimParm::FromEnum(cmd->GetHitSeverity()));
|
||||
const rstl::pair< float, int > best = db.FindBestAnimation(parms, *mgr.Random(), -1);
|
||||
const CAnimPlaybackParms playParms(best.second, -1, 1.f, true);
|
||||
bc.SetCurrentAnimation(playParms, false, false);
|
||||
|
||||
const CPASAnimState* knockdownState = db.GetAnimState(pas::kAS_Fall);
|
||||
CPASAnimParm knockdownParm2(knockdownState->GetAnimParmData(best.second, 2));
|
||||
if (!knockdownParm2.GetBoolValue()) {
|
||||
CPASAnimParm knockdownParm0(knockdownState->GetAnimParmData(best.second, 0));
|
||||
float knockdownAngle = knockdownParm0.GetReal32Value();
|
||||
float delta1 = CAbsAngle::FromRadians(angle.AsRadians() - CRelAngle::FromDegrees(knockdownAngle).AsRadians()).AsRadians();
|
||||
float delta2 = CAbsAngle::FromRadians(CRelAngle::FromDegrees(knockdownAngle).AsRadians() - angle.AsRadians()).AsRadians();
|
||||
float minAngle = rstl::min_val(delta1, delta2);
|
||||
// There's a missing `if (delta1 < 0) { delta1 += M_2PIF; }` here
|
||||
// But it's not exactly delta1, but a temporary from inside the FromRadians call?!
|
||||
const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle;
|
||||
x8_remTime = 0.15f * bc.GetAnimTimeRemaining();
|
||||
x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle;
|
||||
} else {
|
||||
x8_remTime = 0.f;
|
||||
x4_rotateSpeed = 0.f;
|
||||
}
|
||||
|
||||
CPASAnimParm knockdownParm3(knockdownState->GetAnimParmData(best.second, 3));
|
||||
xc_fallState = pas::EFallState(knockdownParm3.GetEnumValue());
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSFall::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
|
||||
const pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
if (st == pas::kAS_Invalid && x8_remTime > 0.f) {
|
||||
bc.SetDeltaRotation(CQuaternion::ZRotation(CRelAngle::FromRadians(x4_rotateSpeed * dt)));
|
||||
x8_remTime -= dt;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void CBSFall::Shutdown(CBodyController& bc) { bc.SetFallState(xc_fallState); }
|
||||
|
||||
pas::EAnimationState CBSFall::GetBodyStateTransition(float dt, CBodyController& bc) {
|
||||
if (bc.IsAnimationOver()) {
|
||||
return pas::kAS_LieOnGround;
|
||||
}
|
||||
return pas::kAS_Invalid;
|
||||
}
|
||||
|
||||
CBSFall::~CBSFall() {}
|
Loading…
Reference in New Issue