prime/src/MetroidPrime/ScriptObjects/CScriptActorKeyframe.cpp
Luke Street 7e364e92a5 rs_new migration & link CScriptCameraWaypoint, CScriptActorKeyframe
Former-commit-id: 6f33908f35925bdf5807507701c717c5ad69e046
2023-10-12 17:52:29 -04:00

136 lines
5.1 KiB
C++

#include "MetroidPrime/ScriptObjects/CScriptActorKeyframe.hpp"
#include "MetroidPrime/BodyState/CBodyController.hpp"
#include "MetroidPrime/BodyState/CBodyStateInfo.hpp"
#include "MetroidPrime/CAnimData.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "MetroidPrime/Enemies/CPatterned.hpp"
#include "MetroidPrime/ScriptObjects/CScriptActor.hpp"
#include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp"
CScriptActorKeyframe::CScriptActorKeyframe(TUniqueId uid, const rstl::string& name,
const CEntityInfo& info, int animId, bool looping,
float lifetime, bool isPassive, int fadeOut, bool active,
float totalPlayback)
: CEntity(uid, info, active, name)
, x34_animationId(animId)
, x38_initialLifetime(lifetime)
, x3c_playbackRate(totalPlayback)
, x40_lifetime(lifetime)
, x44_24_isLooped(looping)
, x44_25_isPassive(isPassive)
, x44_26_fadeOut((fadeOut << 5) & 0x20)
, x44_27_timedLoop((fadeOut << 3) & 0x10)
, x44_28_playing(false) {}
void CScriptActorKeyframe::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
CStateManager& mgr) {
switch (msg) {
case kSM_Action:
if (GetActive()) {
if (!x44_25_isPassive) {
rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin();
for (; conn != GetConnectionList().end(); ++conn) {
if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Play) {
continue;
}
CStateManager::TIdListResult search = mgr.GetIdListForScript(conn->x8_objId);
for (CStateManager::TIdList::const_iterator it = search.first; it != search.second;
++it) {
UpdateEntity(it->second, mgr);
}
}
}
x44_28_playing = true;
x40_lifetime = x38_initialLifetime;
SendScriptMsgs(kSS_Play, mgr, kSM_None);
}
break;
case kSM_InitializedInArea:
if (x34_animationId == -1)
x34_animationId = 0;
break;
default:
break;
}
CEntity::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptActorKeyframe::Accept(IVisitor& visitor) { visitor.Visit(*this); }
void CScriptActorKeyframe::UpdateEntity(TUniqueId uid, CStateManager& mgr) {
CEntity* ent = mgr.ObjectById(uid);
CActor* act = TCastToPtr< CScriptActor >(ent);
if (!act) {
act = TCastToPtr< CScriptPlatform >(ent);
}
if (act) {
if (!act->GetActive()) {
mgr.SendScriptMsg(act, GetUniqueId(), kSM_Activate);
}
act->SetModelFlags(CModelFlags::Normal());
if (act->HasAnimation()) {
if (act->AnimationData()->IsAdditiveAnimation(x34_animationId)) {
act->AnimationData()->AddAdditiveAnimation(x34_animationId, 1.f, x44_24_isLooped,
x44_26_fadeOut);
} else {
act->AnimationData()->SetAnimation(CAnimPlaybackParms(x34_animationId, -1, 1.f, true),
false);
act->ModelData()->EnableLooping(x44_24_isLooped);
act->AnimationData()->MultiplyPlaybackRate(x3c_playbackRate);
}
}
} else if (CPatterned* ai = TCastToPtr< CPatterned >(ent)) {
if (ai->AnimationData()->IsAdditiveAnimation(x34_animationId)) {
ai->AnimationData()->AddAdditiveAnimation(x34_animationId, 1.f, x44_24_isLooped,
x44_26_fadeOut);
} else {
CBodyStateCmdMgr& cmdMgr = ai->BodyCtrl()->CommandMgr();
cmdMgr.DeliverCmd(
CBCScriptedCmd(x34_animationId, x44_24_isLooped, x44_27_timedLoop, x38_initialLifetime));
}
}
}
void CScriptActorKeyframe::Think(float dt, CStateManager& mgr) {
if (!x44_25_isPassive && x44_24_isLooped && x44_27_timedLoop && x44_28_playing &&
x40_lifetime > 0.f) {
x40_lifetime -= dt;
if (x40_lifetime <= 0.f) {
x44_28_playing = false;
rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin();
for (; conn != GetConnectionList().end(); ++conn) {
if (conn->x0_state != kSS_Play || conn->x4_msg != kSM_Play) {
continue;
}
TUniqueId uid = mgr.GetIdForScript(conn->x8_objId);
CEntity* ent = mgr.ObjectById(uid);
if (CScriptActor* act = TCastToPtr< CScriptActor >(ent)) {
if (act->HasAnimation()) {
if (act->AnimationData()->IsAdditiveAnimation(x34_animationId)) {
act->AnimationData()->DelAdditiveAnimation(x34_animationId);
} else if (act->AnimationData()->GetCurrentAnimation() == x34_animationId) {
act->ModelData()->EnableLooping(false);
}
}
} else if (CPatterned* ai = TCastToPtr< CPatterned >(ent)) {
if (ai->AnimationData()->IsAdditiveAnimation(x34_animationId)) {
ai->AnimationData()->DelAdditiveAnimation(x34_animationId);
} else if (ai->BodyCtrl()->GetBodyStateInfo().GetCurrentStateId() == pas::kAS_Scripted &&
ai->AnimationData()->GetCurrentAnimation() == x34_animationId) {
ai->BodyCtrl()->CommandMgr().DeliverCmd(CBodyStateCmd(kBSC_ExitState));
}
}
}
}
}
CEntity::Think(dt, mgr);
}