mirror of https://github.com/PrimeDecomp/prime.git
Add CBSTurn
This commit is contained in:
parent
3a425ceeff
commit
29457d953c
|
@ -3,8 +3,8 @@
|
|||
.section .data
|
||||
.balign 8
|
||||
|
||||
.global lbl_803E1750
|
||||
lbl_803E1750:
|
||||
.global __vt__12CBSFlyerTurn
|
||||
__vt__12CBSFlyerTurn:
|
||||
# ROM: 0x3DE750
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -22,8 +22,8 @@ lbl_803E1750:
|
|||
.4byte Shutdown__7CBSTurnFR15CBodyController
|
||||
.4byte GetBodyStateTransition__7CBSTurnFfR15CBodyController
|
||||
|
||||
.global lbl_803E178C
|
||||
lbl_803E178C:
|
||||
.global __vt__7CBSTurn
|
||||
__vt__7CBSTurn:
|
||||
# ROM: 0x3DE78C
|
||||
.4byte 0
|
||||
.4byte 0
|
||||
|
@ -51,12 +51,12 @@ __dt__12CBSFlyerTurnFv:
|
|||
/* 801391D0 00136130 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 801391D4 00136134 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 801391D8 00136138 41 82 00 40 */ beq lbl_80139218
|
||||
/* 801391DC 0013613C 3C 60 80 3E */ lis r3, lbl_803E1750@ha
|
||||
/* 801391E0 00136140 38 03 17 50 */ addi r0, r3, lbl_803E1750@l
|
||||
/* 801391DC 0013613C 3C 60 80 3E */ lis r3, __vt__12CBSFlyerTurn@ha
|
||||
/* 801391E0 00136140 38 03 17 50 */ addi r0, r3, __vt__12CBSFlyerTurn@l
|
||||
/* 801391E4 00136144 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 801391E8 00136148 41 82 00 20 */ beq lbl_80139208
|
||||
/* 801391EC 0013614C 3C 60 80 3E */ lis r3, lbl_803E178C@ha
|
||||
/* 801391F0 00136150 38 03 17 8C */ addi r0, r3, lbl_803E178C@l
|
||||
/* 801391EC 0013614C 3C 60 80 3E */ lis r3, __vt__7CBSTurn@ha
|
||||
/* 801391F0 00136150 38 03 17 8C */ addi r0, r3, __vt__7CBSTurn@l
|
||||
/* 801391F4 00136154 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 801391F8 00136158 41 82 00 10 */ beq lbl_80139208
|
||||
/* 801391FC 0013615C 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -361,9 +361,9 @@ __ct__12CBSFlyerTurnFv:
|
|||
/* 80139630 00136590 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 80139634 00136594 7C 7F 1B 78 */ mr r31, r3
|
||||
/* 80139638 00136598 48 00 06 A9 */ bl __ct__7CBSTurnFv
|
||||
/* 8013963C 0013659C 3C 80 80 3E */ lis r4, lbl_803E1750@ha
|
||||
/* 8013963C 0013659C 3C 80 80 3E */ lis r4, __vt__12CBSFlyerTurn@ha
|
||||
/* 80139640 001365A0 7F E3 FB 78 */ mr r3, r31
|
||||
/* 80139644 001365A4 38 04 17 50 */ addi r0, r4, lbl_803E1750@l
|
||||
/* 80139644 001365A4 38 04 17 50 */ addi r0, r4, __vt__12CBSFlyerTurn@l
|
||||
/* 80139648 001365A8 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 8013964C 001365AC 83 E1 00 0C */ lwz r31, 0xc(r1)
|
||||
/* 80139650 001365B0 80 01 00 14 */ lwz r0, 0x14(r1)
|
||||
|
@ -379,8 +379,8 @@ __dt__7CBSTurnFv:
|
|||
/* 8013966C 001365CC 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 80139670 001365D0 7C 7F 1B 79 */ or. r31, r3, r3
|
||||
/* 80139674 001365D4 41 82 00 30 */ beq lbl_801396A4
|
||||
/* 80139678 001365D8 3C 60 80 3E */ lis r3, lbl_803E178C@ha
|
||||
/* 8013967C 001365DC 38 03 17 8C */ addi r0, r3, lbl_803E178C@l
|
||||
/* 80139678 001365D8 3C 60 80 3E */ lis r3, __vt__7CBSTurn@ha
|
||||
/* 8013967C 001365DC 38 03 17 8C */ addi r0, r3, __vt__7CBSTurn@l
|
||||
/* 80139680 001365E0 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 80139684 001365E4 41 82 00 10 */ beq lbl_80139694
|
||||
/* 80139688 001365E8 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
|
||||
|
@ -851,9 +851,9 @@ __ct__7CBSTurnFv:
|
|||
/* 80139CF8 00136C58 FC 40 08 90 */ fmr f2, f1
|
||||
/* 80139CFC 00136C5C 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 80139D00 00136C60 7C 7F 1B 78 */ mr r31, r3
|
||||
/* 80139D04 00136C64 3C 60 80 3E */ lis r3, lbl_803E178C@ha
|
||||
/* 80139D04 00136C64 3C 60 80 3E */ lis r3, __vt__7CBSTurn@ha
|
||||
/* 80139D08 00136C68 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 80139D0C 00136C6C 38 03 17 8C */ addi r0, r3, lbl_803E178C@l
|
||||
/* 80139D0C 00136C6C 38 03 17 8C */ addi r0, r3, __vt__7CBSTurn@l
|
||||
/* 80139D10 00136C70 38 7F 00 08 */ addi r3, r31, 8
|
||||
/* 80139D14 00136C74 90 1F 00 00 */ stw r0, 0(r31)
|
||||
/* 80139D18 00136C78 D0 3F 00 04 */ stfs f1, 4(r31)
|
||||
|
|
|
@ -192,7 +192,7 @@ LIBS = [
|
|||
["MetroidPrime/BodyState/CBSLieOnGround", True],
|
||||
"MetroidPrime/BodyState/CBSLocomotion",
|
||||
["MetroidPrime/BodyState/CBSStep", True],
|
||||
"MetroidPrime/BodyState/CBSTurn",
|
||||
["MetroidPrime/BodyState/CBSTurn", False],
|
||||
"MetroidPrime/BodyState/CBodyController",
|
||||
["MetroidPrime/BodyState/CBSLoopAttack", False],
|
||||
["MetroidPrime/Weapons/CTargetableProjectile", False],
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
CPASAnimParm GetAnimParmData(int, unsigned int) const;
|
||||
|
||||
pas::EAnimationState GetStateId() const { return x0_id; }
|
||||
bool HasAnims() const { return static_cast<uint>(x14_anims.size()) != 0; }
|
||||
|
||||
private:
|
||||
pas::EAnimationState x0_id;
|
||||
|
|
|
@ -98,6 +98,10 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
CVector2f ToVec2f() const {
|
||||
return CVector2f(mX, mY);
|
||||
}
|
||||
|
||||
static float Dot(const CVector3f& a, const CVector3f& b) {
|
||||
return (a.GetX() * b.GetX()) + (a.GetY() * b.GetY()) + (a.GetZ() * b.GetZ());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _CBSTURN
|
||||
#define _CBSTURN
|
||||
|
||||
#include "MetroidPrime/BodyState/CBodyState.hpp"
|
||||
|
||||
#include "Kyoto/Math/CVector2f.hpp"
|
||||
|
||||
class CBSTurn : public CBodyState {
|
||||
public:
|
||||
CBSTurn();
|
||||
~CBSTurn() override {}
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
float x4_rotateSpeed;
|
||||
CVector2f x8_dest;
|
||||
pas::ETurnDirection x10_turnDir;
|
||||
|
||||
virtual pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
|
||||
|
||||
bool FacingDest(CBodyController& bc) const;
|
||||
};
|
||||
|
||||
class CBSFlyerTurn : public CBSTurn {
|
||||
public:
|
||||
CBSFlyerTurn();
|
||||
void Start(CBodyController& bc, CStateManager& mgr) override;
|
||||
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
|
||||
};
|
||||
|
||||
#endif // _CBSTURN
|
|
@ -0,0 +1,171 @@
|
|||
#include "MetroidPrime/BodyState/CBSTurn.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/CVector3f.hpp"
|
||||
|
||||
inline CVector2f FlipCenterColumn(const CTransform4f& m) {
|
||||
CVector2f v = m.GetColumn(kDY).ToVec2f();
|
||||
return CVector2f(v.GetY(), -v.GetX());
|
||||
}
|
||||
|
||||
CBSTurn::CBSTurn() : x4_rotateSpeed(0.f), x8_dest(0.0f, 0.0f), x10_turnDir(pas::kTD_Invalid) {}
|
||||
|
||||
void CBSTurn::Start(CBodyController& bc, CStateManager& mgr) {
|
||||
const CVector3f& lookDir = bc.GetOwner().GetTransform().GetColumn(kDY);
|
||||
const CVector2f lookDir2d(lookDir.GetX(), lookDir.GetY());
|
||||
|
||||
x8_dest = bc.GetCommandMgr().GetFaceVector().ToVec2f();
|
||||
|
||||
const float deltaAngle = CMath::Rad2Deg(CVector2f::GetAngleDiff(lookDir2d, x8_dest));
|
||||
|
||||
const CVector2f lookDir2dInv(lookDir2d.GetY(), -lookDir2d.GetX());
|
||||
float dot = CVector2f::Dot(CVector2f(lookDir2dInv), x8_dest);
|
||||
x10_turnDir = dot > 0.f ? pas::kTD_Left : pas::kTD_Right;
|
||||
|
||||
const CPASDatabase& db = bc.GetPASDatabase();
|
||||
|
||||
const CPASAnimParmData parms(pas::kAS_Turn, CPASAnimParm::FromEnum(x10_turnDir),
|
||||
CPASAnimParm::FromReal32(deltaAngle),
|
||||
CPASAnimParm::FromEnum(bc.GetLocomotionType()));
|
||||
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 CPASAnimParm& animAngle = db.GetAnimState(pas::kAS_Turn)->GetAnimParmData(best.second, 1);
|
||||
|
||||
x4_rotateSpeed =
|
||||
CMath::Deg2Rad((x10_turnDir == pas::kTD_Left) ? animAngle.GetReal32Value() - deltaAngle
|
||||
: deltaAngle - animAngle.GetReal32Value());
|
||||
const float timeRem = bc.GetAnimTimeRemaining();
|
||||
if (timeRem > 0.f) {
|
||||
x4_rotateSpeed /= timeRem;
|
||||
}
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSTurn::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
|
||||
const pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
if (st == pas::kAS_Invalid) {
|
||||
bc.SetDeltaRotation(CQuaternion::ZRotation(CRelAngle::FromRadians(x4_rotateSpeed * dt)));
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
void CBSTurn::Shutdown(CBodyController&) {}
|
||||
|
||||
bool CBSTurn::FacingDest(CBodyController& bc) const {
|
||||
const CVector2f leftDir = FlipCenterColumn(bc.GetOwner().GetTransform());
|
||||
|
||||
if (x10_turnDir == pas::kTD_Left) {
|
||||
if (CVector2f::Dot(leftDir, x8_dest) < 0.f) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (CVector2f::Dot(leftDir, x8_dest) > 0.f) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSTurn::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 (cmdMgr.GetCmd(kBSC_Generate)) {
|
||||
return pas::kAS_Generate;
|
||||
}
|
||||
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_LoopReaction)) {
|
||||
return pas::kAS_LoopReaction;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_Jump)) {
|
||||
return pas::kAS_Jump;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_Step)) {
|
||||
return pas::kAS_Step;
|
||||
}
|
||||
if (cmdMgr.GetCmd(kBSC_Scripted)) {
|
||||
return pas::kAS_Scripted;
|
||||
}
|
||||
if (bc.IsAnimationOver() || FacingDest(bc) || cmdMgr.GetMoveVector().IsNonZero()) {
|
||||
return pas::kAS_Locomotion;
|
||||
}
|
||||
return pas::kAS_Invalid;
|
||||
}
|
||||
|
||||
CBSFlyerTurn::CBSFlyerTurn() {}
|
||||
|
||||
void CBSFlyerTurn::Start(CBodyController& bc, CStateManager& mgr) {
|
||||
const CPASDatabase& db = bc.GetPASDatabase();
|
||||
if (db.GetAnimState(pas::kAS_Turn)->HasAnims()) {
|
||||
CBSTurn::Start(bc, mgr);
|
||||
} else {
|
||||
x8_dest = bc.GetCommandMgr().GetFaceVector().ToVec2f();
|
||||
|
||||
const CVector2f& lookDir2dInv = FlipCenterColumn(bc.GetOwner().GetTransform());
|
||||
|
||||
float dot = CVector2f::Dot(CVector2f(lookDir2dInv), x8_dest);
|
||||
x10_turnDir = dot > 0.f ? pas::kTD_Left : pas::kTD_Right;
|
||||
|
||||
const CPASAnimParmData parms(pas::kAS_Locomotion, CPASAnimParm::FromEnum(0),
|
||||
CPASAnimParm::FromEnum(bc.GetLocomotionType()));
|
||||
|
||||
const rstl::pair< float, int > best = db.FindBestAnimation(parms, *mgr.Random(), -1);
|
||||
if (best.second != bc.GetCurrentAnimId()) {
|
||||
const CAnimPlaybackParms playParms(best.second, -1, 1.f, true);
|
||||
bc.SetCurrentAnimation(playParms, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pas::EAnimationState CBSFlyerTurn::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
|
||||
if (bc.GetPASDatabase().GetAnimState(pas::kAS_Turn)->HasAnims()) {
|
||||
return CBSTurn::UpdateBody(dt, bc, mgr);
|
||||
}
|
||||
|
||||
const pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
||||
if (st == pas::kAS_Invalid) {
|
||||
CBodyStateCmdMgr& cmdMgr = bc.CommandMgr();
|
||||
CVector3f faceVec = cmdMgr.GetFaceVector();
|
||||
if (faceVec.IsNonZero()) {
|
||||
x8_dest = faceVec.ToVec2f();
|
||||
|
||||
const CVector2f& lookDir2dInv = FlipCenterColumn(bc.GetOwner().GetTransform());
|
||||
|
||||
float dot = CVector2f::Dot(CVector2f(lookDir2dInv), x8_dest);
|
||||
x10_turnDir = dot > 0.f ? pas::kTD_Left : pas::kTD_Right;
|
||||
}
|
||||
bc.FaceDirection(CVector3f(x8_dest.GetX(), x8_dest.GetY(), 0.f), dt);
|
||||
}
|
||||
return st;
|
||||
}
|
Loading…
Reference in New Issue