metaforce/Runtime/World/CAmbientAI.cpp

148 lines
4.9 KiB
C++
Raw Normal View History

#include "Runtime/World/CAmbientAI.hpp"
#include "Runtime/CStateManager.hpp"
#include "Runtime/World/CPlayer.hpp"
#include "TCastTo.hpp" // Generated file, do not modify include path
2018-06-04 12:30:04 -07:00
2021-04-10 01:42:06 -07:00
namespace metaforce {
2018-06-04 12:30:04 -07:00
CAmbientAI::CAmbientAI(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const zeus::CAABox& aabox, const CMaterialList& matList, float mass,
2018-12-07 21:30:43 -08:00
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, const CActorParameters& aParms,
float alertRange, float impactRange, s32 alertAnim, s32 impactAnim, bool active)
2018-06-04 12:30:04 -07:00
: CPhysicsActor(uid, active, name, info, xf, std::move(mData), matList, aabox, SMoverData(mass), aParms, 0.3f, 0.1f)
, x258_initialHealthInfo(hInfo)
, x260_healthInfo(hInfo)
, x268_dVuln(dVuln)
, x2d4_alertRange(alertRange)
, x2d8_impactRange(impactRange)
, x2dc_defaultAnim(GetModelData()->GetAnimationData()->GetDefaultAnimation())
, x2e0_alertAnim(alertAnim)
, x2e4_impactAnim(impactAnim) {
GetModelData()->GetAnimationData()->EnableLooping(true);
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
void CAmbientAI::Accept(IVisitor& visitor) { visitor.Visit(this); }
2018-06-04 12:30:04 -07:00
2018-12-07 21:30:43 -08:00
void CAmbientAI::Think(float dt, CStateManager& mgr) {
if (!GetActive())
return;
2018-06-04 12:30:04 -07:00
2022-10-20 09:39:16 -07:00
if (GetModelData() && GetModelData()->GetAnimationData() != nullptr) {
bool hasAnimTime = GetModelData()->GetAnimationData()->IsAnimTimeRemaining(
dt - FLT_EPSILON, "Whole Body"sv);
2018-12-07 21:30:43 -08:00
bool isLooping = GetModelData()->GetIsLoop();
2018-06-04 12:30:04 -07:00
2018-12-07 21:30:43 -08:00
if (hasAnimTime || isLooping) {
x2e8_25_animating = true;
2022-10-20 09:39:16 -07:00
SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
2018-12-07 21:30:43 -08:00
MoveToOR(deltas.x0_posDelta, dt);
RotateToOR(deltas.xc_rotDelta, dt);
}
2018-06-04 12:30:04 -07:00
2022-10-20 09:39:16 -07:00
if (hasAnimTime) {
} else if (x2e8_25_animating && !isLooping) {
2018-12-07 21:30:43 -08:00
SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None);
x2e8_25_animating = false;
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
}
2018-06-04 12:30:04 -07:00
2022-10-20 09:39:16 -07:00
bool inAlertRange =
(mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude() < x2d4_alertRange;
bool inImpactRange =
(mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude() < x2d8_impactRange;
2018-06-04 12:30:04 -07:00
2018-12-07 21:30:43 -08:00
switch (x2d0_animState) {
case EAnimationState::Ready: {
if (inAlertRange) {
x2d0_animState = EAnimationState::Alert;
2022-10-20 09:39:16 -07:00
GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2e0_alertAnim, -1, 1.f, true),
false);
GetModelData()->EnableLooping(true);
2018-12-07 21:30:43 -08:00
RandomizePlaybackRate(mgr);
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
break;
}
case EAnimationState::Alert: {
if (!inAlertRange) {
x2d0_animState = EAnimationState::Ready;
2022-10-20 09:39:16 -07:00
GetModelData()->GetAnimationData()->SetAnimation(
CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
GetModelData()->EnableLooping(true);
2018-12-07 21:30:43 -08:00
RandomizePlaybackRate(mgr);
} else if (inImpactRange) {
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
2022-10-20 09:39:16 -07:00
RemoveEmitter();
2018-12-07 21:30:43 -08:00
SetActive(false);
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
break;
}
case EAnimationState::Impact: {
if (!x2e8_25_animating) {
x2d0_animState = EAnimationState::Ready;
2022-10-20 09:39:16 -07:00
GetModelData()->GetAnimationData()->SetAnimation(
CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
GetModelData()->EnableLooping(true);
2018-12-07 21:30:43 -08:00
RandomizePlaybackRate(mgr);
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
break;
}
}
2018-06-04 12:30:04 -07:00
2022-10-20 09:39:16 -07:00
if (x2e8_24_dead) {
return;
}
CHealthInfo* hInfo = HealthInfo(mgr);
if (hInfo->GetHP() <= 0.f) {
x2e8_24_dead = true;
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
RemoveEmitter();
SetActive(false);
2018-12-07 21:30:43 -08:00
}
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
void CAmbientAI::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
switch (msg) {
case EScriptObjectMessage::Reset: {
if (!GetActive())
SetActive(true);
x2d0_animState = EAnimationState::Ready;
GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
GetModelData()->GetAnimationData()->EnableLooping(true);
2018-12-07 21:30:43 -08:00
RandomizePlaybackRate(mgr);
x2e8_24_dead = false;
x260_healthInfo = x258_initialHealthInfo;
break;
}
2022-10-20 09:39:16 -07:00
case EScriptObjectMessage::InitializedInArea:
RandomizePlaybackRate(mgr);
break;
2018-12-07 21:30:43 -08:00
case EScriptObjectMessage::Damage: {
if (GetActive()) {
x2d0_animState = EAnimationState::Impact;
GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2e4_impactAnim, -1, 1.f, true), false);
GetModelData()->GetAnimationData()->EnableLooping(false);
2018-12-07 21:30:43 -08:00
RandomizePlaybackRate(mgr);
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
break;
}
default:
break;
}
CPhysicsActor::AcceptScriptMsg(msg, uid, mgr);
2018-06-04 12:30:04 -07:00
}
std::optional<zeus::CAABox> CAmbientAI::GetTouchBounds() const {
if (GetActive()) {
2018-12-07 21:30:43 -08:00
return {GetBoundingBox()};
}
return std::nullopt;
2018-06-04 12:30:04 -07:00
}
2018-12-07 21:30:43 -08:00
void CAmbientAI::RandomizePlaybackRate(CStateManager& mgr) {
GetModelData()->GetAnimationData()->MultiplyPlaybackRate(0.4f * mgr.GetActiveRandom()->Float() + 0.8f);
2018-06-04 12:30:04 -07:00
}
2021-04-10 01:42:06 -07:00
} // namespace metaforce