mirror of https://github.com/PrimeDecomp/prime.git
Add CBSLoopReaction
This commit is contained in:
parent
286180ee0c
commit
36653c19b0
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E1878
|
||||
lbl_803E1878:
|
||||
.global __vt__15CBSLoopReaction
|
||||
__vt__15CBSLoopReaction:
|
||||
# ROM: 0x3DE878
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -31,8 +31,8 @@ __dt__15CBSLoopReactionFv:
|
|||
/* 8013C054 00138FB4 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 8013C058 00138FB8 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 8013C05C 00138FBC 41 82 00 30 */ beq lbl_8013C08C
|
||||
/* 8013C060 00138FC0 3C 60 80 3E */ lis r3, lbl_803E1878@ha
|
||||
/* 8013C064 00138FC4 38 03 18 78 */ addi r0, r3, lbl_803E1878@l
|
||||
/* 8013C060 00138FC0 3C 60 80 3E */ lis r3, __vt__15CBSLoopReaction@ha
|
||||
/* 8013C064 00138FC4 38 03 18 78 */ addi r0, r3, __vt__15CBSLoopReaction@l
|
||||
/* 8013C068 00138FC8 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 8013C06C 00138FCC 41 82 00 10 */ beq lbl_8013C07C
|
||||
/* 8013C070 00138FD0 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -734,11 +734,11 @@ lbl_8013CA00:
|
|||
.global __ct__15CBSLoopReactionFv
|
||||
__ct__15CBSLoopReactionFv:
|
||||
/* 8013CA20 00139980 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
||||
/* 8013CA24 00139984 3C 80 80 3E */ lis r4, lbl_803E1878@ha
|
||||
/* 8013CA24 00139984 3C 80 80 3E */ lis r4, __vt__15CBSLoopReaction@ha
|
||||
/* 8013CA28 00139988 38 C5 13 18 */ addi r6, r5, __vt__10CBodyState@l
|
||||
/* 8013CA2C 0013998C 38 00 FF FF */ li r0, -1
|
||||
/* 8013CA30 00139990 90 C3 00 00 */ stw r6, 0(r3)
|
||||
/* 8013CA34 00139994 38 A4 18 78 */ addi r5, r4, lbl_803E1878@l
|
||||
/* 8013CA34 00139994 38 A4 18 78 */ addi r5, r4, __vt__15CBSLoopReaction@l
|
||||
/* 8013CA38 00139998 38 80 00 00 */ li r4, 0
|
||||
/* 8013CA3C 0013999C 90 A3 00 00 */ stw r5, 0(r3)
|
||||
/* 8013CA40 001399A0 90 03 00 04 */ stw r0, 4(r3)
|
||||
|
|
|
@ -196,7 +196,7 @@ LIBS = [
|
|||
"MetroidPrime/BodyState/CBodyController",
|
||||
["MetroidPrime/BodyState/CBSLoopAttack", False],
|
||||
["MetroidPrime/Weapons/CTargetableProjectile", False],
|
||||
"MetroidPrime/BodyState/CBSLoopReaction",
|
||||
["MetroidPrime/BodyState/CBSLoopReaction", False],
|
||||
"MetroidPrime/CSteeringBehaviors",
|
||||
["MetroidPrime/BodyState/CBSGroundHit", False],
|
||||
"MetroidPrime/Enemies/CChozoGhost",
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _CBSLOOPREACTION
|
||||
#define _CBSLOOPREACTION
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||
|
||||
class CBSLoopReaction : public CBodyState {
|
||||
public:
|
||||
CBSLoopReaction();
|
||||
|
||||
void Start(CBodyController& bc, CStateManager& mgr) override;
|
||||
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
|
||||
void Shutdown(CBodyController&) override {}
|
||||
|
||||
private:
|
||||
pas::ELoopState x4_state;
|
||||
pas::EReactionType x8_reactionType;
|
||||
bool xc_24_loopHit : 1;
|
||||
|
||||
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||
bool PlayExitAnimation(CBodyController& bc, CStateManager& mgr) const;
|
||||
};
|
||||
|
||||
#endif // _CBSLOOPREACTION
|
|
@ -0,0 +1,143 @@
|
|||
#include "MetroidPrime/BodyState/CBSLoopReaction.hpp"
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyController.hpp"
|
||||
#include "MetroidPrime/CAnimPlaybackParms.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
|
||||
#include "Kyoto/Animation/CPASAnimParmData.hpp"
|
||||
#include "Kyoto/Animation/CPASDatabase.hpp"
|
||||
|
||||
CBSLoopReaction::CBSLoopReaction()
|
||||
: x4_state(pas::kLS_Invalid), x8_reactionType(pas::kRT_Invalid), xc_24_loopHit(false) {}
|
||||
|
||||
void CBSLoopReaction::Start(CBodyController& bc, CStateManager& mgr) {
|
||||
CBodyStateCmdMgr& commandMgr = bc.CommandMgr();
|
||||
|
||||
CBodyStateCmd* cmd = commandMgr.GetCmd(kBSC_LoopReaction);
|
||||
if (cmd) {
|
||||
x8_reactionType = static_cast< const CBCLoopReactionCmd* >(cmd)->GetReactionType();
|
||||
xc_24_loopHit = false;
|
||||
} else {
|
||||
cmd = commandMgr.GetCmd(kBSC_LoopHitReaction);
|
||||
x8_reactionType = static_cast< const CBCLoopHitReactionCmd* >(cmd)->GetReactionType();
|
||||
xc_24_loopHit = true;
|
||||
}
|
||||
|
||||
x4_state = pas::kLS_Begin;
|
||||
const CPASAnimParmData parms(pas::kAS_LoopReaction, CPASAnimParm::FromEnum(x8_reactionType),
|
||||
CPASAnimParm::FromEnum(x4_state));
|
||||
rstl::pair< float, int > best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.Random(), -1);
|
||||
|
||||
if (best.first > FLT_EPSILON) {
|
||||
const CAnimPlaybackParms playParms(best.second, -1, 1.f, true);
|
||||
bc.SetCurrentAnimation(playParms, false, false);
|
||||
} else {
|
||||
x4_state = pas::kLS_Loop;
|
||||
CPASAnimParmData loopParms(pas::kAS_LoopReaction, CPASAnimParm::FromEnum(x8_reactionType),
|
||||
CPASAnimParm::FromEnum(x4_state));
|
||||
bc.LoopBestAnimation(parms, *mgr.Random());
|
||||
}
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSLoopReaction::UpdateBody(float dt, CBodyController& bc,
|
||||
CStateManager& mgr) {
|
||||
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
if (st == pas::kAS_Invalid) {
|
||||
CBodyStateCmdMgr& commandMgr = bc.CommandMgr();
|
||||
|
||||
switch (x4_state) {
|
||||
case pas::kLS_Begin:
|
||||
if (commandMgr.GetCmd(kBSC_ExitState)) {
|
||||
if (PlayExitAnimation(bc, mgr)) {
|
||||
x4_state = pas::kLS_End;
|
||||
} else {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
}
|
||||
} else {
|
||||
if (bc.IsAnimationOver()) {
|
||||
const CPASAnimParmData parms(pas::kAS_LoopReaction,
|
||||
CPASAnimParm::FromEnum(s32(x8_reactionType)),
|
||||
CPASAnimParm::FromEnum(1));
|
||||
bc.LoopBestAnimation(parms, *mgr.Random());
|
||||
x4_state = pas::kLS_Loop;
|
||||
} else if (commandMgr.GetTargetVector().IsNonZero()) {
|
||||
bc.FaceDirection(commandMgr.GetTargetVector(), dt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pas::kLS_Loop:
|
||||
if (commandMgr.GetCmd(kBSC_ExitState)) {
|
||||
if (PlayExitAnimation(bc, mgr)) {
|
||||
x4_state = pas::kLS_End;
|
||||
} else {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
}
|
||||
} else if (commandMgr.GetTargetVector().IsNonZero()) {
|
||||
bc.FaceDirection(commandMgr.GetTargetVector(), dt);
|
||||
}
|
||||
break;
|
||||
case pas::kLS_End:
|
||||
if (bc.IsAnimationOver()) {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
bool CBSLoopReaction::PlayExitAnimation(CBodyController& bc, CStateManager& mgr) const {
|
||||
const CPASDatabase& db = bc.GetPASDatabase();
|
||||
|
||||
const CPASAnimParmData parms(pas::kAS_LoopReaction, CPASAnimParm::FromEnum(int(x8_reactionType)),
|
||||
CPASAnimParm::FromEnum(2));
|
||||
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, false, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
pas::EAnimationState CBSLoopReaction::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_KnockBack)) {
|
||||
return pas::kAS_KnockBack;
|
||||
}
|
||||
if (!xc_24_loopHit && commandMgr.GetCmd(kBSC_Locomotion)) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
|
||||
if (x4_state == pas::kLS_End) {
|
||||
if (commandMgr.GetCmd(kBSC_MeleeAttack)) {
|
||||
return pas::kAS_MeleeAttack;
|
||||
}
|
||||
if (commandMgr.GetCmd(kBSC_ProjectileAttack)) {
|
||||
return pas::kAS_ProjectileAttack;
|
||||
}
|
||||
if (commandMgr.GetCmd(kBSC_LoopAttack)) {
|
||||
return pas::kAS_LoopAttack;
|
||||
}
|
||||
if (commandMgr.GetCmd(kBSC_Step)) {
|
||||
return pas::kAS_Step;
|
||||
}
|
||||
if (commandMgr.GetMoveVector().IsNonZero()) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
if (commandMgr.GetFaceVector().IsNonZero()) {
|
||||
return pas::kAS_Turn;
|
||||
}
|
||||
}
|
||||
return pas::kAS_Invalid;
|
||||
}
|
Loading…
Reference in New Issue