Add CBSCover

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-11 14:55:40 +02:00
parent 816451423a
commit a63276e51d
No known key found for this signature in database
GPG Key ID: E224F951761145F8
8 changed files with 158 additions and 11 deletions

View File

@ -3,8 +3,8 @@
.section .data .section .data
.balign 8 .balign 8
.global lbl_803E3E48 .global __vt__8CBSCover
lbl_803E3E48: __vt__8CBSCover:
# ROM: 0x3E0E48 # ROM: 0x3E0E48
.4byte 0 .4byte 0
.4byte 0 .4byte 0
@ -31,8 +31,8 @@ __dt__8CBSCoverFv:
/* 80175CE4 00172C44 93 E1 00 0C */ stw r31, 0xc(r1) /* 80175CE4 00172C44 93 E1 00 0C */ stw r31, 0xc(r1)
/* 80175CE8 00172C48 7C 7F 1B 79 */ or. r31, r3, r3 /* 80175CE8 00172C48 7C 7F 1B 79 */ or. r31, r3, r3
/* 80175CEC 00172C4C 41 82 00 30 */ beq lbl_80175D1C /* 80175CEC 00172C4C 41 82 00 30 */ beq lbl_80175D1C
/* 80175CF0 00172C50 3C 60 80 3E */ lis r3, lbl_803E3E48@ha /* 80175CF0 00172C50 3C 60 80 3E */ lis r3, __vt__8CBSCover@ha
/* 80175CF4 00172C54 38 03 3E 48 */ addi r0, r3, lbl_803E3E48@l /* 80175CF4 00172C54 38 03 3E 48 */ addi r0, r3, __vt__8CBSCover@l
/* 80175CF8 00172C58 90 1F 00 00 */ stw r0, 0(r31) /* 80175CF8 00172C58 90 1F 00 00 */ stw r0, 0(r31)
/* 80175CFC 00172C5C 41 82 00 10 */ beq lbl_80175D0C /* 80175CFC 00172C5C 41 82 00 10 */ beq lbl_80175D0C
/* 80175D00 00172C60 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha /* 80175D00 00172C60 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
@ -273,7 +273,6 @@ lbl_80175FEC:
/* 80176024 00172F84 48 16 D0 59 */ bl NoParameter__12CPASAnimParmFv /* 80176024 00172F84 48 16 D0 59 */ bl NoParameter__12CPASAnimParmFv
/* 80176028 00172F88 38 61 00 78 */ addi r3, r1, 0x78 /* 80176028 00172F88 38 61 00 78 */ addi r3, r1, 0x78
/* 8017602C 00172F8C 48 16 D0 51 */ bl NoParameter__12CPASAnimParmFv /* 8017602C 00172F8C 48 16 D0 51 */ bl NoParameter__12CPASAnimParmFv
.global lbl_80176030
lbl_80176030: lbl_80176030:
/* 80176030 00172F90 7F 64 DB 78 */ mr r4, r27 /* 80176030 00172F90 7F 64 DB 78 */ mr r4, r27
/* 80176034 00172F94 38 61 00 80 */ addi r3, r1, 0x80 /* 80176034 00172F94 38 61 00 80 */ addi r3, r1, 0x80
@ -581,11 +580,11 @@ lbl_80176484:
.global __ct__8CBSCoverFv .global __ct__8CBSCoverFv
__ct__8CBSCoverFv: __ct__8CBSCoverFv:
/* 80176498 001733F8 3C C0 80 3E */ lis r6, __vt__10CBodyState@ha /* 80176498 001733F8 3C C0 80 3E */ lis r6, __vt__10CBodyState@ha
/* 8017649C 001733FC 3C A0 80 3E */ lis r5, lbl_803E3E48@ha /* 8017649C 001733FC 3C A0 80 3E */ lis r5, __vt__8CBSCover@ha
/* 801764A0 00173400 38 06 13 18 */ addi r0, r6, __vt__10CBodyState@l /* 801764A0 00173400 38 06 13 18 */ addi r0, r6, __vt__10CBodyState@l
/* 801764A4 00173404 38 80 FF FF */ li r4, -1 /* 801764A4 00173404 38 80 FF FF */ li r4, -1
/* 801764A8 00173408 90 03 00 00 */ stw r0, 0(r3) /* 801764A8 00173408 90 03 00 00 */ stw r0, 0(r3)
/* 801764AC 0017340C 38 A5 3E 48 */ addi r5, r5, lbl_803E3E48@l /* 801764AC 0017340C 38 A5 3E 48 */ addi r5, r5, __vt__8CBSCover@l
/* 801764B0 00173410 38 00 00 00 */ li r0, 0 /* 801764B0 00173410 38 00 00 00 */ li r0, 0
/* 801764B4 00173414 90 A3 00 00 */ stw r5, 0(r3) /* 801764B4 00173414 90 A3 00 00 */ stw r5, 0(r3)
/* 801764B8 00173418 90 83 00 04 */ stw r4, 4(r3) /* 801764B8 00173418 90 83 00 04 */ stw r4, 4(r3)

View File

@ -237,7 +237,7 @@ LIBS = [
["MetroidPrime/ScriptObjects/CScriptRipple", False], ["MetroidPrime/ScriptObjects/CScriptRipple", False],
"MetroidPrime/CBoneTracking", "MetroidPrime/CBoneTracking",
["MetroidPrime/Player/CFaceplateDecoration", False], ["MetroidPrime/Player/CFaceplateDecoration", False],
"MetroidPrime/BodyState/CBSCover", ["MetroidPrime/BodyState/CBSCover", False],
["MetroidPrime/ScriptObjects/CScriptBallTrigger", True], ["MetroidPrime/ScriptObjects/CScriptBallTrigger", True],
"MetroidPrime/Weapons/CPlasmaProjectile", "MetroidPrime/Weapons/CPlasmaProjectile",
"MetroidPrime/Player/CPlayerOrbit", "MetroidPrime/Player/CPlayerOrbit",

View File

@ -33,6 +33,7 @@ public:
// Slerp__11CQuaternionFRC11CQuaternionRC11CQuaternionf // Slerp__11CQuaternionFRC11CQuaternionRC11CQuaternionf
// ShortestRotationArc__11CQuaternionFRC9CVector3fRC9CVector3f // ShortestRotationArc__11CQuaternionFRC9CVector3fRC9CVector3f
// LookAt__11CQuaternionFRC13CUnitVector3fRC13CUnitVector3fRC9CRelAngle // LookAt__11CQuaternionFRC13CUnitVector3fRC13CUnitVector3fRC9CRelAngle
static CQuaternion LookAt(const CUnitVector3f&, const CUnitVector3f&, const CRelAngle&);
// normalize_angle__Ff // normalize_angle__Ff
// IsValidQuaternion__11CQuaternionCFf // IsValidQuaternion__11CQuaternionCFf
// SlerpLocal__11CQuaternionFRC11CQuaternionRC11CQuaternionf // SlerpLocal__11CQuaternionFRC11CQuaternionRC11CQuaternionf

View File

@ -16,8 +16,14 @@ public:
Normalize(); Normalize();
} }
} }
CUnitVector3f(const CVector3f& vec); // : CVector3f(vec) { Normalize(); } CUnitVector3f(
const CVector3f& vec); // : CVector3f(vec.IsNonZero() ? vec.AsNormalized() : Zero()) {}
// TODO // TODO
static CUnitVector3f Forward() {
return CUnitVector3f(CVector3f::Forward().GetX(), CVector3f::Forward().GetY(),
CVector3f::Forward().GetZ(), kN_No);
}
}; };
CHECK_SIZEOF(CUnitVector3f, 0xc) CHECK_SIZEOF(CUnitVector3f, 0xc)

View File

@ -0,0 +1,27 @@
#ifndef _CBSCOVER
#define _CBSCOVER
#include "MetroidPrime/BodyState/CBodyState.hpp"
class CBSCover : public CBodyState {
public:
CBSCover();
bool IsMoving() const override { return true; }
bool ApplyHeadTracking() const override { return false; }
bool CanShoot() const override;
void Start(CBodyController& bc, CStateManager& mgr) override;
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
void Shutdown(CBodyController&) override;
pas::ECoverDirection GetCoverDirection() const { return x8_coverDirection; }
bool GetNeedsExit() const { return xc_needsExit; }
private:
pas::ECoverState x4_state;
pas::ECoverDirection x8_coverDirection;
bool xc_needsExit;
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
};
#endif // _CBSCOVER

View File

@ -26,6 +26,7 @@ public:
void FaceDirection(const CVector3f& v0, float dt); void FaceDirection(const CVector3f& v0, float dt);
void EnableAnimation(bool enable); void EnableAnimation(bool enable);
void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r); void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r);
void LoopBestAnimation(const CPASAnimParmData& parms, CRandom16& r);
bool HasIceBreakoutState(); bool HasIceBreakoutState();
void Activate(CStateManager& mgr); void Activate(CStateManager& mgr);
void SetLocomotionType(pas::ELocomotionType type); void SetLocomotionType(pas::ELocomotionType type);

View File

@ -7,6 +7,7 @@
#include "Kyoto/Animation/CharacterCommon.hpp" #include "Kyoto/Animation/CharacterCommon.hpp"
#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/Math/CVector3f.hpp"
#include "Kyoto/Math/CUnitVector3f.hpp"
enum ESteeringBlendMode { enum ESteeringBlendMode {
kSBM_Normal, kSBM_Normal,
@ -341,12 +342,12 @@ public:
pas::ECoverDirection GetDirection() const { return x8_dir; } pas::ECoverDirection GetDirection() const { return x8_dir; }
const CVector3f& GetTarget() const { return xc_targetPos; } const CVector3f& GetTarget() const { return xc_targetPos; }
const CVector3f& GetAlignDirection() const { return x18_alignDir; } CUnitVector3f GetAlignDirection() const { return x18_alignDir; }
private: private:
pas::ECoverDirection x8_dir; pas::ECoverDirection x8_dir;
CVector3f xc_targetPos; CVector3f xc_targetPos;
CVector3f x18_alignDir; CUnitVector3f x18_alignDir;
}; };
// //

View File

@ -0,0 +1,112 @@
#include "MetroidPrime/BodyState/CBSCover.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/CUnitVector3f.hpp"
bool CBSCover::CanShoot() const { return x4_state == pas::kCS_Lean; }
CBSCover::CBSCover()
: x4_state(pas::kCS_Invalid), x8_coverDirection(pas::kCD_Invalid), xc_needsExit(false) {}
void CBSCover::Start(CBodyController& bc, CStateManager& mgr) {
const CBCCoverCmd* cmd = static_cast< const CBCCoverCmd* >(bc.CommandMgr().GetCmd(kBSC_Cover));
x8_coverDirection = cmd->GetDirection();
x4_state = pas::kCS_IntoCover;
const CPASAnimParmData parms(pas::kAS_Cover, CPASAnimParm::FromEnum(x4_state),
CPASAnimParm::FromEnum(GetCoverDirection()));
const rstl::pair< float, int > best =
bc.GetPASDatabase().FindBestAnimation(parms, *mgr.Random(), -1);
CVector3f scale = bc.GetOwner().GetModelData()->GetScale();
CRelAngle lookAtMaxAngle = CRelAngle::FromRadians(M_2PIF);
const CUnitVector3f& lookAtDest = cmd->GetAlignDirection();
const CQuaternion orientDelta = CQuaternion::LookAt(CUnitVector3f::Forward(), lookAtDest, lookAtMaxAngle);
const CAnimPlaybackParms playParms(best.second, &orientDelta, &cmd->GetTarget(),
&bc.GetOwner().GetTransform(), &scale, false);
bc.SetCurrentAnimation(playParms, false, false);
xc_needsExit = false;
if (bc.CommandMgr().GetCmd(kBSC_ExitState)) {
xc_needsExit = true;
}
}
pas::EAnimationState CBSCover::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
if (st == pas::kAS_Invalid) {
switch (x4_state) {
case pas::kCS_Lean:
case pas::kCS_IntoCover:
if (bc.IsAnimationOver()) {
x4_state = pas::kCS_Cover;
const CPASAnimParmData parms(pas::kAS_Cover, CPASAnimParm::FromEnum(x4_state),
CPASAnimParm::FromEnum(GetCoverDirection()));
bc.LoopBestAnimation(parms, *mgr.Random());
}
if (bc.CommandMgr().GetCmd(kBSC_ExitState)) {
xc_needsExit = true;
}
break;
case pas::kCS_Cover: {
CBodyStateCmdMgr& commandMgr = bc.CommandMgr();
if (commandMgr.GetTargetVector().IsNonZero()) {
bc.FaceDirection(commandMgr.GetTargetVector(), dt);
}
if (commandMgr.GetCmd(kBSC_ExitState) || GetNeedsExit()) {
xc_needsExit = false;
x4_state = pas::kCS_OutOfCover;
const CPASAnimParmData parms(pas::kAS_Cover, CPASAnimParm::FromEnum(x4_state),
CPASAnimParm::FromEnum(GetCoverDirection()));
bc.PlayBestAnimation(parms, *mgr.Random());
} else if (commandMgr.GetCmd(kBSC_LeanFromCover)) {
x4_state = pas::kCS_Lean;
const CPASAnimParmData parms(pas::kAS_Cover, CPASAnimParm::FromEnum(x4_state),
CPASAnimParm::FromEnum(GetCoverDirection()));
bc.PlayBestAnimation(parms, *mgr.Random());
}
break;
}
case pas::kCS_OutOfCover:
if (bc.IsAnimationOver()) {
x4_state = pas::kCS_Invalid;
st = pas::kAS_Locomotion;
}
break;
default:
break;
}
}
return st;
}
void CBSCover::Shutdown(CBodyController&) {}
pas::EAnimationState CBSCover::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;
}
return pas::kAS_Invalid;
}