mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-07-24 21:35:34 +00:00
92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
#include "MetroidPrime/BodyState/CABSReaction.hpp"
|
|
|
|
#include "MetroidPrime/BodyState/CBodyController.hpp"
|
|
#include "MetroidPrime/CActor.hpp"
|
|
#include "MetroidPrime/CAnimData.hpp"
|
|
#include "MetroidPrime/CModelData.hpp"
|
|
#include "MetroidPrime/CStateManager.hpp"
|
|
|
|
#include "Kyoto/Animation/CAnimTreeNode.hpp"
|
|
#include "Kyoto/Animation/CPASAnimParmData.hpp"
|
|
#include "Kyoto/Math/CloseEnough.hpp"
|
|
|
|
|
|
CABSReaction::CABSReaction()
|
|
: x4_weight(1.f), x8_anim(-1), xc_type(pas::kART_Invalid), x10_active(false) {}
|
|
|
|
void CABSReaction::Start(CBodyController& bc, CStateManager& mgr) {
|
|
const CBCAdditiveReactionCmd* cmd =
|
|
static_cast< const CBCAdditiveReactionCmd* >(bc.CommandMgr().GetCmd(kBSC_AdditiveReaction));
|
|
x4_weight = cmd->GetWeight();
|
|
xc_type = cmd->GetType();
|
|
x10_active = cmd->GetIsActive();
|
|
|
|
CPASAnimParmData parms(pas::kAS_AdditiveReaction, CPASAnimParm::FromEnum(xc_type));
|
|
rstl::pair< float, int > best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.Random(), -1);
|
|
x8_anim = best.second;
|
|
|
|
if (x8_anim != -1) {
|
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
|
animData.AddAdditiveAnimation(x8_anim, GetWeight(), IsActive(), false);
|
|
}
|
|
}
|
|
|
|
pas::EAnimationState CABSReaction::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) {
|
|
pas::EAnimationState st = GetBodyStateTransition(dt, bc);
|
|
if (st == pas::kAS_Invalid) {
|
|
if (x8_anim == -1)
|
|
return pas::kAS_AdditiveIdle;
|
|
|
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
|
if (x10_active) {
|
|
if (bc.CommandMgr().GetCmd(kBSC_StopReaction)) {
|
|
StopAnimation(bc);
|
|
st = pas::kAS_AdditiveIdle;
|
|
bc.GetOwner().RemoveEmitter();
|
|
}
|
|
} else {
|
|
if (animData.IsAdditiveAnimationAdded(x8_anim)) {
|
|
CCharAnimTime rem = animData.GetAdditiveAnimationTree(x8_anim)->VGetTimeRemaining();
|
|
if (close_enough(rem.GetSeconds(), 0.0f)) {
|
|
StopAnimation(bc);
|
|
st = pas::kAS_AdditiveIdle;
|
|
}
|
|
} else {
|
|
st = pas::kAS_AdditiveIdle;
|
|
}
|
|
}
|
|
}
|
|
return st;
|
|
}
|
|
|
|
void CABSReaction::Shutdown(CBodyController& bc) { StopAnimation(bc); }
|
|
|
|
bool CBodyController::HasIceBreakoutState() {
|
|
// Inline function that ends here?
|
|
CPASAnimParmData parms(pas::kAS_AdditiveReaction, CPASAnimParm::FromEnum(pas::kART_IceBreakout));
|
|
const CPASDatabase& db = GetPASDatabase();
|
|
rstl::pair< float, int > best = db.FindBestAnimation(parms, -1);
|
|
return best.first > 0.f;
|
|
}
|
|
|
|
pas::EAnimationState CABSReaction::GetBodyStateTransition(float dt, CBodyController& bc) {
|
|
CBodyStateCmdMgr& commandMgr = bc.CommandMgr();
|
|
|
|
const CBCAdditiveReactionCmd* cmd =
|
|
static_cast< const CBCAdditiveReactionCmd* >(bc.CommandMgr().GetCmd(kBSC_AdditiveReaction));
|
|
if (cmd != nullptr && cmd->GetType() == pas::kART_IceBreakout)
|
|
return pas::kAS_AdditiveReaction;
|
|
|
|
return pas::kAS_Invalid;
|
|
}
|
|
|
|
void CABSReaction::StopAnimation(CBodyController& bc) {
|
|
if (x8_anim != -1) {
|
|
CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData();
|
|
animData.DelAdditiveAnimation(x8_anim);
|
|
x8_anim = -1;
|
|
}
|
|
}
|
|
|
|
CABSReaction::~CABSReaction() {}
|