mirror of https://github.com/PrimeDecomp/prime.git
Add almost matched CBSLoopAttack
This commit is contained in:
parent
50c6435c62
commit
64ec879441
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E17C8
|
||||
lbl_803E17C8:
|
||||
.global __vt__13CBSLoopAttack
|
||||
__vt__13CBSLoopAttack:
|
||||
# ROM: 0x3DE7C8
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -31,8 +31,8 @@ __dt__13CBSLoopAttackFv:
|
|||
/* 8013AED8 00137E38 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 8013AEDC 00137E3C 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 8013AEE0 00137E40 41 82 00 30 */ beq lbl_8013AF10
|
||||
/* 8013AEE4 00137E44 3C 60 80 3E */ lis r3, lbl_803E17C8@ha
|
||||
/* 8013AEE8 00137E48 38 03 17 C8 */ addi r0, r3, lbl_803E17C8@l
|
||||
/* 8013AEE4 00137E44 3C 60 80 3E */ lis r3, __vt__13CBSLoopAttack@ha
|
||||
/* 8013AEE8 00137E48 38 03 17 C8 */ addi r0, r3, __vt__13CBSLoopAttack@l
|
||||
/* 8013AEEC 00137E4C 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 8013AEF0 00137E50 41 82 00 10 */ beq lbl_8013AF00
|
||||
/* 8013AEF4 00137E54 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -701,11 +701,11 @@ lbl_8013B81C:
|
|||
.global __ct__13CBSLoopAttackFv
|
||||
__ct__13CBSLoopAttackFv:
|
||||
/* 8013B838 00138798 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
|
||||
/* 8013B83C 0013879C 3C 80 80 3E */ lis r4, lbl_803E17C8@ha
|
||||
/* 8013B83C 0013879C 3C 80 80 3E */ lis r4, __vt__13CBSLoopAttack@ha
|
||||
/* 8013B840 001387A0 38 C5 13 18 */ addi r6, r5, __vt__10CBodyState@l
|
||||
/* 8013B844 001387A4 38 00 FF FF */ li r0, -1
|
||||
/* 8013B848 001387A8 90 C3 00 00 */ stw r6, 0(r3)
|
||||
/* 8013B84C 001387AC 38 A4 17 C8 */ addi r5, r4, lbl_803E17C8@l
|
||||
/* 8013B84C 001387AC 38 A4 17 C8 */ addi r5, r4, __vt__13CBSLoopAttack@l
|
||||
/* 8013B850 001387B0 38 80 00 00 */ li r4, 0
|
||||
/* 8013B854 001387B4 90 A3 00 00 */ stw r5, 0(r3)
|
||||
/* 8013B858 001387B8 90 03 00 04 */ stw r0, 4(r3)
|
||||
|
|
|
@ -194,7 +194,7 @@ LIBS = [
|
|||
["MetroidPrime/BodyState/CBSStep", True],
|
||||
"MetroidPrime/BodyState/CBSTurn",
|
||||
"MetroidPrime/BodyState/CBodyController",
|
||||
"MetroidPrime/BodyState/CBSLoopAttack",
|
||||
["MetroidPrime/BodyState/CBSLoopAttack", False],
|
||||
["MetroidPrime/Weapons/CTargetableProjectile", False],
|
||||
"MetroidPrime/BodyState/CBSLoopReaction",
|
||||
"MetroidPrime/CSteeringBehaviors",
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _CBSLOOPATTACK
|
||||
#define _CBSLOOPATTACK
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||
|
||||
class CBSLoopAttack : public CBodyState {
|
||||
public:
|
||||
CBSLoopAttack();
|
||||
|
||||
bool CanShoot() const override { return true; }
|
||||
void Start(CBodyController& bc, CStateManager& mgr) override;
|
||||
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
|
||||
void Shutdown(CBodyController&) override;
|
||||
|
||||
pas::ELoopState GetState() const { return x4_state; }
|
||||
pas::ELoopAttackType GetAttackType() const { return x8_loopAttackType; }
|
||||
bool GetAdvance() const { return xc_25_advance; }
|
||||
|
||||
private:
|
||||
pas::ELoopState x4_state;
|
||||
pas::ELoopAttackType x8_loopAttackType;
|
||||
bool xc_24_waitForAnimOver : 1;
|
||||
bool xc_25_advance : 1;
|
||||
|
||||
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||
};
|
||||
|
||||
#endif // _CBSLOOPATTACK
|
|
@ -252,11 +252,11 @@ public:
|
|||
: CBodyStateCmd(kBSC_LoopAttack), x8_type(type), xc_waitForAnimOver(waitForAnimOver) {}
|
||||
|
||||
pas::ELoopAttackType GetAttackType() const { return x8_type; }
|
||||
bool WaitForAnimOver() const { return xc_waitForAnimOver; }
|
||||
int WaitForAnimOver() const { return xc_waitForAnimOver; }
|
||||
|
||||
private:
|
||||
pas::ELoopAttackType x8_type;
|
||||
bool xc_waitForAnimOver;
|
||||
int xc_waitForAnimOver;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -423,6 +423,7 @@ public:
|
|||
|
||||
CBodyStateCmd* GetCmd(EBodyStateCmd cmd);
|
||||
const CVector3f& GetMoveVector() const { return x0_move; }
|
||||
const CVector3f& GetFaceVector() const { return xc_face; }
|
||||
const CVector3f& GetTargetVector() const { return x18_target; }
|
||||
const CVector3f& GetAdditiveTargetVector() const { return x24_additiveTarget; }
|
||||
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#include "MetroidPrime/BodyState/CBSLoopAttack.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"
|
||||
|
||||
CBSLoopAttack::CBSLoopAttack()
|
||||
: x4_state(pas::kLS_Invalid)
|
||||
, x8_loopAttackType(pas::kLAT_Invalid)
|
||||
, xc_24_waitForAnimOver(false)
|
||||
, xc_25_advance(false)
|
||||
|
||||
{}
|
||||
|
||||
void CBSLoopAttack::Start(CBodyController& bc, CStateManager& mgr) {
|
||||
const CBCLoopAttackCmd* cmd =
|
||||
static_cast< const CBCLoopAttackCmd* >(bc.CommandMgr().GetCmd(kBSC_LoopAttack));
|
||||
|
||||
x8_loopAttackType = cmd->GetAttackType();
|
||||
xc_24_waitForAnimOver = cmd->WaitForAnimOver() == 1;
|
||||
xc_25_advance = false;
|
||||
|
||||
if (bc.GetLocomotionType() == pas::kLT_Crouch) {
|
||||
x4_state = pas::kLS_Loop;
|
||||
const CPASAnimParmData parms(pas::kAS_LoopAttack, CPASAnimParm::FromEnum(x4_state),
|
||||
CPASAnimParm::FromEnum(x8_loopAttackType));
|
||||
bc.LoopBestAnimation(parms, *mgr.Random());
|
||||
|
||||
} else {
|
||||
x4_state = pas::kLS_Begin;
|
||||
const CPASAnimParmData parms(pas::kAS_LoopAttack, CPASAnimParm::FromEnum(x4_state),
|
||||
CPASAnimParm::FromEnum(x8_loopAttackType));
|
||||
const 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;
|
||||
const CPASAnimParmData loopParms(pas::kAS_LoopAttack, CPASAnimParm::FromEnum(x4_state),
|
||||
CPASAnimParm::FromEnum(x8_loopAttackType));
|
||||
bc.LoopBestAnimation(loopParms, *mgr.Random());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSLoopAttack::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
|
||||
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
|
||||
if (st == pas::kAS_Invalid) {
|
||||
CBodyStateCmdMgr& commandMgr = bc.CommandMgr();
|
||||
CBodyStateCmd* cmd = commandMgr.GetCmd(kBSC_ExitState);
|
||||
xc_25_advance = ((GetAdvance() | cmd != nullptr) << 4) & 0x10;
|
||||
|
||||
switch (x4_state) {
|
||||
case pas::kLS_Begin:
|
||||
if (xc_25_advance && (!xc_24_waitForAnimOver || bc.IsAnimationOver())) {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
} else if (bc.IsAnimationOver()) {
|
||||
const CPASAnimParmData parms(pas::kAS_LoopAttack, CPASAnimParm::FromEnum(1),
|
||||
CPASAnimParm::FromEnum(x8_loopAttackType));
|
||||
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 (xc_25_advance && (!xc_24_waitForAnimOver || bc.IsAnimationOver())) {
|
||||
if (bc.GetLocomotionType() != pas::kLT_Crouch) {
|
||||
const CPASAnimParmData parms(pas::kAS_LoopAttack, CPASAnimParm::FromEnum(2),
|
||||
CPASAnimParm::FromEnum(x8_loopAttackType));
|
||||
bc.PlayBestAnimation(parms, *mgr.Random());
|
||||
x4_state = pas::kLS_End;
|
||||
} else {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case pas::kLS_End:
|
||||
if (bc.IsAnimationOver()) {
|
||||
x4_state = pas::kLS_Invalid;
|
||||
st = pas::kAS_Locomotion;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void CBSLoopAttack::Shutdown(CBodyController&) {}
|
||||
|
||||
pas::EAnimationState CBSLoopAttack::GetBodyStateTransition(float dt, CBodyController& bc) {
|
||||
CBodyStateCmdMgr& cmdMgr = bc.CommandMgr();
|
||||
if (cmdMgr.GetCmd(kBSC_Hurled)) {
|
||||
return pas::kAS_Hurled;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_KnockDown)) {
|
||||
return pas::kAS_Fall;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_LoopHitReaction)) {
|
||||
return pas::kAS_LoopReaction;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_KnockBack)) {
|
||||
return pas::kAS_KnockBack;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_Locomotion)) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
|
||||
if (x4_state == pas::kLS_End) {
|
||||
if (cmdMgr.GetCmd(kBSC_MeleeAttack)) {
|
||||
return pas::kAS_MeleeAttack;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_ProjectileAttack)) {
|
||||
return pas::kAS_ProjectileAttack;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_LoopAttack)) {
|
||||
return pas::kAS_LoopAttack;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_Step)) {
|
||||
return pas::kAS_Step;
|
||||
}
|
||||
if (cmdMgr.GetMoveVector().IsNonZero()) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
if (cmdMgr.GetFaceVector().IsNonZero()) {
|
||||
return pas::kAS_Turn;
|
||||
}
|
||||
}
|
||||
|
||||
return pas::kAS_Invalid;
|
||||
}
|
Loading…
Reference in New Issue