mirror of https://github.com/PrimeDecomp/prime.git
Add CBSGroundHit
This commit is contained in:
parent
4e55f8c7dd
commit
b8cdf8d847
|
@ -3,8 +3,8 @@
|
||||||
.section .data
|
.section .data
|
||||||
.balign 8
|
.balign 8
|
||||||
|
|
||||||
.global lbl_803E18B0
|
.global __vt__12CBSGroundHit
|
||||||
lbl_803E18B0:
|
__vt__12CBSGroundHit:
|
||||||
# ROM: 0x3DE8B0
|
# ROM: 0x3DE8B0
|
||||||
.4byte 0
|
.4byte 0
|
||||||
.4byte 0
|
.4byte 0
|
||||||
|
@ -31,8 +31,8 @@ __dt__12CBSGroundHitFv:
|
||||||
/* 8013ED68 0013BCC8 93 E1 00 0C */ stw r31, 0xc(r1)
|
/* 8013ED68 0013BCC8 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||||
/* 8013ED6C 0013BCCC 7C 7F 1B 79 */ or. r31, r3, r3
|
/* 8013ED6C 0013BCCC 7C 7F 1B 79 */ or. r31, r3, r3
|
||||||
/* 8013ED70 0013BCD0 41 82 00 30 */ beq lbl_8013EDA0
|
/* 8013ED70 0013BCD0 41 82 00 30 */ beq lbl_8013EDA0
|
||||||
/* 8013ED74 0013BCD4 3C 60 80 3E */ lis r3, lbl_803E18B0@ha
|
/* 8013ED74 0013BCD4 3C 60 80 3E */ lis r3, __vt__12CBSGroundHit@ha
|
||||||
/* 8013ED78 0013BCD8 38 03 18 B0 */ addi r0, r3, lbl_803E18B0@l
|
/* 8013ED78 0013BCD8 38 03 18 B0 */ addi r0, r3, __vt__12CBSGroundHit@l
|
||||||
/* 8013ED7C 0013BCDC 90 1F 00 00 */ stw r0, 0(r31)
|
/* 8013ED7C 0013BCDC 90 1F 00 00 */ stw r0, 0(r31)
|
||||||
/* 8013ED80 0013BCE0 41 82 00 10 */ beq lbl_8013ED90
|
/* 8013ED80 0013BCE0 41 82 00 10 */ beq lbl_8013ED90
|
||||||
/* 8013ED84 0013BCE4 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
/* 8013ED84 0013BCE4 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||||
|
@ -407,11 +407,11 @@ lbl_8013F2A4:
|
||||||
.global __ct__12CBSGroundHitFv
|
.global __ct__12CBSGroundHitFv
|
||||||
__ct__12CBSGroundHitFv:
|
__ct__12CBSGroundHitFv:
|
||||||
/* 8013F2C0 0013C220 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
/* 8013F2C0 0013C220 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
||||||
/* 8013F2C4 0013C224 3C 80 80 3E */ lis r4, lbl_803E18B0@ha
|
/* 8013F2C4 0013C224 3C 80 80 3E */ lis r4, __vt__12CBSGroundHit@ha
|
||||||
/* 8013F2C8 0013C228 38 05 13 18 */ addi r0, r5, __vt__10CBodyState@l
|
/* 8013F2C8 0013C228 38 05 13 18 */ addi r0, r5, __vt__10CBodyState@l
|
||||||
/* 8013F2CC 0013C22C C0 02 9B 28 */ lfs f0, lbl_805AB848@sda21(r2)
|
/* 8013F2CC 0013C22C C0 02 9B 28 */ lfs f0, lbl_805AB848@sda21(r2)
|
||||||
/* 8013F2D0 0013C230 90 03 00 00 */ stw r0, 0(r3)
|
/* 8013F2D0 0013C230 90 03 00 00 */ stw r0, 0(r3)
|
||||||
/* 8013F2D4 0013C234 38 84 18 B0 */ addi r4, r4, lbl_803E18B0@l
|
/* 8013F2D4 0013C234 38 84 18 B0 */ addi r4, r4, __vt__12CBSGroundHit@l
|
||||||
/* 8013F2D8 0013C238 38 00 FF FF */ li r0, -1
|
/* 8013F2D8 0013C238 38 00 FF FF */ li r0, -1
|
||||||
/* 8013F2DC 0013C23C 90 83 00 00 */ stw r4, 0(r3)
|
/* 8013F2DC 0013C23C 90 83 00 00 */ stw r4, 0(r3)
|
||||||
/* 8013F2E0 0013C240 D0 03 00 04 */ stfs f0, 4(r3)
|
/* 8013F2E0 0013C240 D0 03 00 04 */ stfs f0, 4(r3)
|
||||||
|
|
|
@ -198,7 +198,7 @@ LIBS = [
|
||||||
"MetroidPrime/Weapons/CTargetableProjectile",
|
"MetroidPrime/Weapons/CTargetableProjectile",
|
||||||
"MetroidPrime/BodyState/CBSLoopReaction",
|
"MetroidPrime/BodyState/CBSLoopReaction",
|
||||||
"MetroidPrime/CSteeringBehaviors",
|
"MetroidPrime/CSteeringBehaviors",
|
||||||
"MetroidPrime/BodyState/CBSGroundHit",
|
["MetroidPrime/BodyState/CBSGroundHit", False],
|
||||||
"MetroidPrime/Enemies/CChozoGhost",
|
"MetroidPrime/Enemies/CChozoGhost",
|
||||||
"MetroidPrime/Enemies/CFireFlea",
|
"MetroidPrime/Enemies/CFireFlea",
|
||||||
["MetroidPrime/BodyState/CBSSlide", False],
|
["MetroidPrime/BodyState/CBSSlide", False],
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef _CBSGROUNDHIT
|
||||||
|
#define _CBSGROUNDHIT
|
||||||
|
|
||||||
|
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||||
|
|
||||||
|
class CBSGroundHit : public CBodyState {
|
||||||
|
public:
|
||||||
|
CBSGroundHit();
|
||||||
|
~CBSGroundHit();
|
||||||
|
|
||||||
|
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 // _CBSGROUNDHIT
|
|
@ -186,6 +186,24 @@ private:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
class CBCKnockBackCmd : public CBodyStateCmd {
|
||||||
|
public:
|
||||||
|
explicit CBCKnockBackCmd()
|
||||||
|
: CBodyStateCmd(kBSC_KnockBack), x8_dir(0.f, 0.f, 0.f), x14_severity(pas::kS_Invalid) {}
|
||||||
|
|
||||||
|
explicit CBCKnockBackCmd(const CVector3f& vec, pas::ESeverity severity)
|
||||||
|
: CBodyStateCmd(kBSC_KnockBack), 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 {
|
class CBodyStateCmdMgr {
|
||||||
public:
|
public:
|
||||||
CBodyStateCmd* GetCmd(EBodyStateCmd cmd);
|
CBodyStateCmd* GetCmd(EBodyStateCmd cmd);
|
||||||
|
|
|
@ -7,20 +7,20 @@
|
||||||
|
|
||||||
#include "Kyoto/Animation/CPASAnimParmData.hpp"
|
#include "Kyoto/Animation/CPASAnimParmData.hpp"
|
||||||
#include "Kyoto/Animation/CPASDatabase.hpp"
|
#include "Kyoto/Animation/CPASDatabase.hpp"
|
||||||
#include "Kyoto/Math/CRelAngle.hpp"
|
|
||||||
#include "Kyoto/Math/CAbsAngle.hpp"
|
#include "Kyoto/Math/CAbsAngle.hpp"
|
||||||
|
#include "Kyoto/Math/CRelAngle.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "rstl/math.hpp"
|
#include "rstl/math.hpp"
|
||||||
|
|
||||||
|
|
||||||
CBSFall::CBSFall() : x4_rotateSpeed(0.f), x8_remTime(0.f), xc_fallState(pas::kFS_Invalid) {}
|
CBSFall::CBSFall() : x4_rotateSpeed(0.f), x8_remTime(0.f), xc_fallState(pas::kFS_Invalid) {}
|
||||||
|
|
||||||
void CBSFall::Start(CBodyController& bc, CStateManager& mgr) {
|
void CBSFall::Start(CBodyController& bc, CStateManager& mgr) {
|
||||||
const CBCKnockDownCmd* cmd =
|
const CBCKnockDownCmd* cmd =
|
||||||
static_cast< const CBCKnockDownCmd* >(bc.CommandMgr().GetCmd(kBSC_KnockDown));
|
static_cast< const CBCKnockDownCmd* >(bc.CommandMgr().GetCmd(kBSC_KnockDown));
|
||||||
CVector3f localDir = bc.GetOwner().GetTransform().TransposeRotate(cmd->GetHitDirection());
|
CVector3f localDir = bc.GetOwner().GetTransform().TransposeRotate(cmd->GetHitDirection());
|
||||||
CAbsAngle angle = CAbsAngle::FromRadians(atan2(localDir.GetY(), localDir.GetZ()));
|
CAbsAngle angle = CAbsAngle::FromRadians(atan2(localDir.GetY(), localDir.GetZ())); // TODO: x
|
||||||
|
|
||||||
const CPASDatabase& db = bc.GetPASDatabase();
|
const CPASDatabase& db = bc.GetPASDatabase();
|
||||||
const CPASAnimParmData parms(pas::kAS_Fall, CPASAnimParm::FromReal32(angle.AsDegrees()),
|
const CPASAnimParmData parms(pas::kAS_Fall, CPASAnimParm::FromReal32(angle.AsDegrees()),
|
||||||
|
@ -34,11 +34,16 @@ void CBSFall::Start(CBodyController& bc, CStateManager& mgr) {
|
||||||
if (!knockdownParm2.GetBoolValue()) {
|
if (!knockdownParm2.GetBoolValue()) {
|
||||||
CPASAnimParm knockdownParm0(knockdownState->GetAnimParmData(best.second, 0));
|
CPASAnimParm knockdownParm0(knockdownState->GetAnimParmData(best.second, 0));
|
||||||
float knockdownAngle = knockdownParm0.GetReal32Value();
|
float knockdownAngle = knockdownParm0.GetReal32Value();
|
||||||
float delta1 = CAbsAngle::FromRadians(angle.AsRadians() - CRelAngle::FromDegrees(knockdownAngle).AsRadians()).AsRadians();
|
float delta1 = CAbsAngle::FromRadians(angle.AsRadians() -
|
||||||
float delta2 = CAbsAngle::FromRadians(CRelAngle::FromDegrees(knockdownAngle).AsRadians() - angle.AsRadians()).AsRadians();
|
CRelAngle::FromDegrees(knockdownAngle).AsRadians())
|
||||||
|
.AsRadians();
|
||||||
|
float delta2 = CAbsAngle::FromRadians(CRelAngle::FromDegrees(knockdownAngle).AsRadians() -
|
||||||
|
angle.AsRadians())
|
||||||
|
.AsRadians();
|
||||||
float minAngle = rstl::min_val(delta1, delta2);
|
float minAngle = rstl::min_val(delta1, delta2);
|
||||||
// There's a missing `if (delta1 < 0) { delta1 += M_2PIF; }` here
|
// 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?!
|
// But it's not exactly delta1, but a temporary from inside the FromRadians call?!
|
||||||
|
// Same problem in CBSGroundHit
|
||||||
const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle;
|
const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle;
|
||||||
x8_remTime = 0.15f * bc.GetAnimTimeRemaining();
|
x8_remTime = 0.15f * bc.GetAnimTimeRemaining();
|
||||||
x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle;
|
x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle;
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "MetroidPrime/BodyState/CBSGroundHit.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/CAbsAngle.hpp"
|
||||||
|
#include "Kyoto/Math/CRelAngle.hpp"
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
#include "rstl/math.hpp"
|
||||||
|
|
||||||
|
CBSGroundHit::CBSGroundHit()
|
||||||
|
: x4_rotateSpeed(0.f), x8_remTime(0.f), xc_fallState(pas::kFS_Invalid) {}
|
||||||
|
|
||||||
|
void CBSGroundHit::Start(CBodyController& bc, CStateManager& mgr) {
|
||||||
|
const CBCKnockBackCmd* cmd =
|
||||||
|
static_cast< const CBCKnockBackCmd* >(bc.CommandMgr().GetCmd(kBSC_KnockBack));
|
||||||
|
|
||||||
|
CVector3f localDir = bc.GetOwner().GetTransform().TransposeRotate(cmd->GetHitDirection());
|
||||||
|
CAbsAngle angle = CAbsAngle::FromRadians(atan2(localDir.GetY(), localDir.GetX()));
|
||||||
|
|
||||||
|
int fallState = bc.GetFallState();
|
||||||
|
const CPASDatabase& db = bc.GetPASDatabase();
|
||||||
|
|
||||||
|
const CPASAnimParmData parms(pas::kAS_GroundHit, CPASAnimParm::FromEnum(fallState),
|
||||||
|
CPASAnimParm::FromReal32(angle.AsDegrees()));
|
||||||
|
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* groundHitState = db.GetAnimState(pas::kAS_GroundHit);
|
||||||
|
CPASAnimParm parm2(groundHitState->GetAnimParmData(best.second, 2));
|
||||||
|
if (!parm2.GetBoolValue()) {
|
||||||
|
CPASAnimParm parm1(groundHitState->GetAnimParmData(best.second, 1));
|
||||||
|
float knockdownAngle = parm1.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 missing code here. Same problem in CBSFall, see there for details
|
||||||
|
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 parm3(groundHitState->GetAnimParmData(best.second, 3));
|
||||||
|
xc_fallState = pas::EFallState(parm3.GetEnumValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
pas::EAnimationState CBSGroundHit::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 CBSGroundHit::Shutdown(CBodyController& bc) { bc.SetFallState(xc_fallState); }
|
||||||
|
|
||||||
|
pas::EAnimationState CBSGroundHit::GetBodyStateTransition(float dt, CBodyController& bc) {
|
||||||
|
CBodyStateCmdMgr& cmdMgr = bc.CommandMgr();
|
||||||
|
if (bc.IsAnimationOver()) {
|
||||||
|
if (cmdMgr.GetCmd(kBSC_Die)) {
|
||||||
|
return pas::kAS_Death;
|
||||||
|
}
|
||||||
|
return pas::kAS_LieOnGround;
|
||||||
|
}
|
||||||
|
return pas::kAS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBSGroundHit::~CBSGroundHit() {}
|
Loading…
Reference in New Issue