mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-08-11 14:59:06 +00:00
This member function alters instance state in a few implementations, so it shouldn't be made const. The state manager parameter also shouldn't be const. Retrieved data from the post constructed instance is further modified in some implementations. This removes the constness on this parameter in order to fix more const_cast usages in a follow-up change.
164 lines
6.3 KiB
C++
164 lines
6.3 KiB
C++
#include "Runtime/MP1/World/CAtomicAlpha.hpp"
|
|
|
|
#include <array>
|
|
|
|
#include "Runtime/CStateManager.hpp"
|
|
#include "Runtime/Weapon/CPlayerGun.hpp"
|
|
#include "Runtime/World/CGameArea.hpp"
|
|
#include "Runtime/World/CPatternedInfo.hpp"
|
|
#include "Runtime/World/CPlayer.hpp"
|
|
#include "Runtime/World/CWorld.hpp"
|
|
|
|
namespace urde::MP1 {
|
|
constexpr std::array skBombLocators{
|
|
"bomb1_LCTR"sv,
|
|
"bomb2_LCTR"sv,
|
|
"bomb3_LCTR"sv,
|
|
"bomb4_LCTR"sv,
|
|
};
|
|
|
|
CAtomicAlpha::CAtomicAlpha(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
|
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
|
|
CAssetId bombWeapon, const CDamageInfo& bombDamage, float bombDropDelay, float f2, float f3,
|
|
CAssetId cmdl, bool invisible, bool b2)
|
|
: CPatterned(ECharacter::AtomicAlpha, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
|
EMovementType::Flyer, EColliderType::One, EBodyType::Flyer, actParms, EKnockBackVariant::Medium)
|
|
, x568_24_inRange(false)
|
|
, x568_25_invisible(invisible)
|
|
, x568_26_applyBeamAttraction(b2)
|
|
, x56c_bomdDropDelay(bombDropDelay)
|
|
, x570_bombReappearDelay(f2)
|
|
, x574_bombRappearTime(f3)
|
|
, x580_pathFind(nullptr, 3, pInfo.GetPathfindingIndex(), 1.f, 1.f)
|
|
, x668_bombProjectile(bombWeapon, bombDamage)
|
|
, x690_bombModel(CStaticRes(cmdl, GetModelData()->GetScale())) {
|
|
x668_bombProjectile.Token().Lock();
|
|
for (u32 i = 0; i < skBombCount; ++i) {
|
|
x6dc_bombLocators.emplace_back(skBombLocators[i], pas::ELocomotionType(u32(pas::ELocomotionType::Internal10) + i));
|
|
}
|
|
}
|
|
|
|
void CAtomicAlpha::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
|
if (msg == EScriptObjectMessage::InitializedInArea) {
|
|
x580_pathFind.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea);
|
|
} else if (msg == EScriptObjectMessage::Registered) {
|
|
x450_bodyController->Activate(mgr);
|
|
} else if (msg == EScriptObjectMessage::AddSplashInhabitant) {
|
|
if (x400_25_alive)
|
|
x401_30_pendingDeath = true;
|
|
}
|
|
}
|
|
|
|
void CAtomicAlpha::Render(const CStateManager& mgr) const {
|
|
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && x568_25_invisible)
|
|
return;
|
|
|
|
CPatterned::Render(mgr);
|
|
for (const SBomb& bomb : x6dc_bombLocators) {
|
|
zeus::CTransform locatorXf =
|
|
GetTransform() * GetScaledLocatorTransform(bomb.x0_locatorName) *
|
|
zeus::CTransform::Scale(
|
|
std::min(1.f, std::max(0.f, bomb.x14_scaleTime - x570_bombReappearDelay) / x570_bombReappearDelay));
|
|
CModelFlags flags;
|
|
flags.x2_flags = 1 | 2;
|
|
flags.x4_color = zeus::skWhite;
|
|
x690_bombModel.Render(mgr, locatorXf, x90_actorLights.get(), flags);
|
|
}
|
|
}
|
|
void CAtomicAlpha::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) {
|
|
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay && x568_25_invisible) {
|
|
return;
|
|
}
|
|
CPatterned::AddToRenderer(frustum, mgr);
|
|
}
|
|
|
|
void CAtomicAlpha::Think(float dt, CStateManager& mgr) {
|
|
CPatterned::Think(dt, mgr);
|
|
if (!GetActive())
|
|
return;
|
|
|
|
x578_bombTime += dt;
|
|
|
|
for (SBomb& bomb : x6dc_bombLocators) {
|
|
bomb.x14_scaleTime += dt;
|
|
}
|
|
}
|
|
|
|
void CAtomicAlpha::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
|
|
if (type == EUserEventType::Projectile) {
|
|
zeus::CVector3f origin = GetLctrTransform(node.GetLocatorName()).origin;
|
|
zeus::CTransform xf = zeus::lookAt(origin, origin + zeus::skDown, zeus::skUp);
|
|
LaunchProjectile(xf, mgr, 4, EProjectileAttrib::None, false, {}, 0xFFFF, false, zeus::CVector3f(1.f));
|
|
x578_bombTime = 0.f;
|
|
x57c_curBomb = (x57c_curBomb + 1) & (x6dc_bombLocators.size() - 1);
|
|
} else
|
|
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
|
|
}
|
|
|
|
bool CAtomicAlpha::Leash(CStateManager& mgr, float) {
|
|
if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() <=
|
|
x3cc_playerLeashRadius * x3cc_playerLeashRadius)
|
|
return false;
|
|
|
|
return x3d4_curPlayerLeashTime > x3d0_playerLeashTime;
|
|
}
|
|
|
|
bool CAtomicAlpha::AggressionCheck(CStateManager& mgr, float) {
|
|
const CPlayerGun* playerGun = mgr.GetPlayer().GetPlayerGun();
|
|
float factor = 0.f;
|
|
if (x568_26_applyBeamAttraction && playerGun->IsCharging())
|
|
factor = playerGun->GetChargeBeamFactor();
|
|
return factor > 0.1f;
|
|
}
|
|
|
|
void CAtomicAlpha::CollidedWith(TUniqueId uid, const CCollisionInfoList& list, CStateManager& mgr) {
|
|
if (IsAlive()) {
|
|
if (TCastToConstPtr<CPlayer> pl = mgr.GetObjectById(uid)) {
|
|
if (x420_curDamageRemTime <= 0.f) {
|
|
mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), 0.5f, 0.25f);
|
|
for (SBomb& bomb : x6dc_bombLocators) {
|
|
bomb.x14_scaleTime = 0.f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CPatterned::CollidedWith(uid, list, mgr);
|
|
}
|
|
|
|
void CAtomicAlpha::Patrol(CStateManager& mgr, EStateMsg msg, float arg) {
|
|
CPatterned::Patrol(mgr, msg, arg);
|
|
if (msg == EStateMsg::Activate) {
|
|
x578_bombTime = 0.f;
|
|
} else if (msg == EStateMsg::Update) {
|
|
if (x568_24_inRange) {
|
|
if (x578_bombTime >= x56c_bomdDropDelay &&
|
|
x6dc_bombLocators[0].x14_scaleTime > (x570_bombReappearDelay + x574_bombRappearTime)) {
|
|
x450_bodyController->SetLocomotionType(x6dc_bombLocators[x57c_curBomb].x10_locomotionType);
|
|
} else {
|
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
|
}
|
|
if (Leash(mgr, arg))
|
|
x568_24_inRange = false;
|
|
} else {
|
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
|
if (InMaxRange(mgr, arg))
|
|
x568_24_inRange = true;
|
|
}
|
|
} else if (msg == EStateMsg::Deactivate) {
|
|
x568_24_inRange = false;
|
|
}
|
|
}
|
|
|
|
void CAtomicAlpha::Attack(CStateManager& mgr, EStateMsg msg, float) {
|
|
if (msg == EStateMsg::Activate) {
|
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Internal8);
|
|
} else if (msg == EStateMsg::Update) {
|
|
zeus::CVector3f seekVec = x664_steeringBehaviors.Seek(*this, mgr.GetPlayer().GetEyePosition());
|
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(seekVec, {}, 1.f));
|
|
} else if (msg == EStateMsg::Deactivate) {
|
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
|
}
|
|
}
|
|
} // namespace urde::MP1
|