mirror of https://github.com/PrimeDecomp/prime.git
parent
a84a03d58a
commit
83055d527d
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E1450
|
||||
lbl_803E1450:
|
||||
.global __vt__12CBSKnockBack
|
||||
__vt__12CBSKnockBack:
|
||||
# ROM: 0x3DE450
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -31,8 +31,8 @@ __dt__12CBSKnockBackFv:
|
|||
/* 80136208 00133168 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 8013620C 0013316C 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 80136210 00133170 41 82 00 30 */ beq lbl_80136240
|
||||
/* 80136214 00133174 3C 60 80 3E */ lis r3, lbl_803E1450@ha
|
||||
/* 80136218 00133178 38 03 14 50 */ addi r0, r3, lbl_803E1450@l
|
||||
/* 80136214 00133174 3C 60 80 3E */ lis r3, __vt__12CBSKnockBack@ha
|
||||
/* 80136218 00133178 38 03 14 50 */ addi r0, r3, __vt__12CBSKnockBack@l
|
||||
/* 8013621C 0013317C 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 80136220 00133180 41 82 00 10 */ beq lbl_80136230
|
||||
/* 80136224 00133184 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -430,11 +430,11 @@ lbl_80136784:
|
|||
.global __ct__12CBSKnockBackFv
|
||||
__ct__12CBSKnockBackFv:
|
||||
/* 801367A0 00133700 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
||||
/* 801367A4 00133704 3C 80 80 3E */ lis r4, lbl_803E1450@ha
|
||||
/* 801367A4 00133704 3C 80 80 3E */ lis r4, __vt__12CBSKnockBack@ha
|
||||
/* 801367A8 00133708 38 A5 13 18 */ addi r5, r5, __vt__10CBodyState@l
|
||||
/* 801367AC 0013370C C0 02 99 FC */ lfs f0, lbl_805AB71C@sda21(r2)
|
||||
/* 801367B0 00133710 90 A3 00 00 */ stw r5, 0(r3)
|
||||
/* 801367B4 00133714 38 04 14 50 */ addi r0, r4, lbl_803E1450@l
|
||||
/* 801367B4 00133714 38 04 14 50 */ addi r0, r4, __vt__12CBSKnockBack@l
|
||||
/* 801367B8 00133718 90 03 00 00 */ stw r0, 0(r3)
|
||||
/* 801367BC 0013371C D0 03 00 04 */ stfs f0, 4(r3)
|
||||
/* 801367C0 00133720 D0 03 00 08 */ stfs f0, 8(r3)
|
||||
|
|
|
@ -188,7 +188,7 @@ LIBS = [
|
|||
["MetroidPrime/BodyState/CBSDie", True],
|
||||
["MetroidPrime/BodyState/CBSFall", False],
|
||||
["MetroidPrime/BodyState/CBSGetup", True],
|
||||
"MetroidPrime/BodyState/CBSKnockBack",
|
||||
["MetroidPrime/BodyState/CBSKnockBack", False],
|
||||
["MetroidPrime/BodyState/CBSLieOnGround", True],
|
||||
"MetroidPrime/BodyState/CBSLocomotion",
|
||||
["MetroidPrime/BodyState/CBSStep", True],
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _CBSKNOCKBACK
|
||||
#define _CBSKNOCKBACK
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||
|
||||
class CBSKnockBack : public CBodyState {
|
||||
public:
|
||||
CBSKnockBack();
|
||||
~CBSKnockBack();
|
||||
|
||||
void Start(CBodyController& bc, CStateManager& mgr) override;
|
||||
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
|
||||
void Shutdown(CBodyController&) override;
|
||||
bool IsMoving() const override;
|
||||
|
||||
private:
|
||||
float x4_curTime;
|
||||
float x8_rotateSpeed;
|
||||
float xc_remTime;
|
||||
|
||||
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||
};
|
||||
|
||||
#endif // _CBSKNOCKBACK
|
|
@ -10,7 +10,6 @@
|
|||
#include "Kyoto/Math/CAbsAngle.hpp"
|
||||
#include "Kyoto/Math/CRelAngle.hpp"
|
||||
|
||||
|
||||
#include "math.h"
|
||||
#include "rstl/math.hpp"
|
||||
|
||||
|
@ -43,7 +42,7 @@ void CBSFall::Start(CBodyController& bc, CStateManager& mgr) {
|
|||
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?!
|
||||
// Same problem in CBSGroundHit
|
||||
// Same problem in CBSGroundHit and CBSKnockBack
|
||||
const float flippedAngle = (delta1 > M_PIF) ? -minAngle : minAngle;
|
||||
x8_remTime = 0.15f * bc.GetAnimTimeRemaining();
|
||||
x4_rotateSpeed = (x8_remTime > FLT_EPSILON) ? flippedAngle / x8_remTime : flippedAngle;
|
||||
|
|
|
@ -32,10 +32,10 @@ void CBSGroundHit::Start(CBodyController& bc, CStateManager& mgr) {
|
|||
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));
|
||||
const CPASAnimState* animState = db.GetAnimState(pas::kAS_GroundHit);
|
||||
CPASAnimParm parm2(animState->GetAnimParmData(best.second, 2));
|
||||
if (!parm2.GetBoolValue()) {
|
||||
CPASAnimParm parm1(groundHitState->GetAnimParmData(best.second, 1));
|
||||
CPASAnimParm parm1(animState->GetAnimParmData(best.second, 1));
|
||||
float knockdownAngle = parm1.GetReal32Value();
|
||||
float delta1 = CAbsAngle::FromRadians(angle.AsRadians() -
|
||||
CRelAngle::FromDegrees(knockdownAngle).AsRadians())
|
||||
|
@ -52,7 +52,7 @@ void CBSGroundHit::Start(CBodyController& bc, CStateManager& mgr) {
|
|||
x8_remTime = 0.f;
|
||||
x4_rotateSpeed = 0.f;
|
||||
}
|
||||
CPASAnimParm parm3(groundHitState->GetAnimParmData(best.second, 3));
|
||||
CPASAnimParm parm3(animState->GetAnimParmData(best.second, 3));
|
||||
xc_fallState = pas::EFallState(parm3.GetEnumValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
#include "MetroidPrime/BodyState/CBSKnockBack.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"
|
||||
|
||||
CBSKnockBack::CBSKnockBack() : x4_curTime(0.f), x8_rotateSpeed(0.f), xc_remTime(0.f) {}
|
||||
|
||||
void CBSKnockBack::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()));
|
||||
|
||||
const CPASDatabase& db = bc.GetPASDatabase();
|
||||
|
||||
const CPASAnimParmData parms(pas::kAS_KnockBack, 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* animState = db.GetAnimState(pas::kAS_KnockBack);
|
||||
|
||||
CPASAnimParm parm2(animState->GetAnimParmData(best.second, 2));
|
||||
if (!parm2.GetBoolValue()) {
|
||||
CPASAnimParm parm0(animState->GetAnimParmData(best.second, 0));
|
||||
float knockdownAngle = parm0.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;
|
||||
xc_remTime = 0.15f * bc.GetAnimTimeRemaining();
|
||||
x8_rotateSpeed = (xc_remTime > FLT_EPSILON) ? flippedAngle / xc_remTime : flippedAngle;
|
||||
} else {
|
||||
xc_remTime = 0.f;
|
||||
x8_rotateSpeed = 0.f;
|
||||
}
|
||||
x4_curTime = 0.f;
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSKnockBack::UpdateBody(float dt, CBodyController& bc,
|
||||
CStateManager& mgr) override {
|
||||
const pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
if (st == pas::kAS_Invalid) {
|
||||
x4_curTime += dt;
|
||||
if (xc_remTime > 0.f) {
|
||||
bc.SetDeltaRotation(CQuaternion::ZRotation(CRelAngle::FromRadians(x8_rotateSpeed * dt)));
|
||||
xc_remTime -= dt;
|
||||
}
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void CBSKnockBack::Shutdown(CBodyController&) override {}
|
||||
|
||||
pas::EAnimationState CBSKnockBack::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) && x4_curTime > 0.2f) {
|
||||
return pas::kAS_KnockBack;
|
||||
}
|
||||
if (bc.IsAnimationOver()) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
return pas::kAS_Invalid;
|
||||
}
|
||||
|
||||
bool CBSKnockBack::IsMoving() const override { return true; }
|
||||
|
||||
CBSKnockBack::~CBSKnockBack() {}
|
Loading…
Reference in New Issue