mirror of https://github.com/AxioDL/metaforce.git
CMetroid: More function implementations
This commit is contained in:
parent
78b364a445
commit
e8ce4c2e27
|
@ -94,7 +94,7 @@ enum class EGetupType { Invalid = -1, Zero = 0, One = 1, Two = 2 };
|
||||||
|
|
||||||
enum class ELoopState { Invalid = -1, Begin, Loop, End };
|
enum class ELoopState { Invalid = -1, Begin, Loop, End };
|
||||||
|
|
||||||
enum class ELoopAttackType { Invalid = -1 };
|
enum class ELoopAttackType { Invalid = -1, Zero, One, Two, Three };
|
||||||
|
|
||||||
enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four, Five };
|
enum class EGenerateType { Invalid = -1, Zero, One, Two, Three, Four, Five };
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#include "Runtime/CStateManager.hpp"
|
#include "Runtime/CStateManager.hpp"
|
||||||
#include "Runtime/Character/CPASAnimParmData.hpp"
|
#include "Runtime/Character/CPASAnimParmData.hpp"
|
||||||
|
#include "Runtime/Collision/CGameCollision.hpp"
|
||||||
#include "Runtime/Weapon/CGameProjectile.hpp"
|
#include "Runtime/Weapon/CGameProjectile.hpp"
|
||||||
|
#include "Runtime/World/CPlayer.hpp"
|
||||||
#include "Runtime/World/CTeamAiMgr.hpp"
|
#include "Runtime/World/CTeamAiMgr.hpp"
|
||||||
#include "Runtime/World/CWorld.hpp"
|
#include "Runtime/World/CWorld.hpp"
|
||||||
#include "Runtime/World/ScriptLoader.hpp"
|
#include "Runtime/World/ScriptLoader.hpp"
|
||||||
|
@ -43,17 +45,19 @@ constexpr CDamageVulnerability skNormalDamageVulnerability{
|
||||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
|
||||||
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None,
|
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto skPirateSuckJoint = "Head_1"sv;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CMetroidData::CMetroidData(CInputStream& in)
|
CMetroidData::CMetroidData(CInputStream& in)
|
||||||
: x0_frozenVulnerability(in)
|
: x0_frozenVulnerability(in)
|
||||||
, x68_energyDrainVulnerability(in)
|
, x68_energyDrainVulnerability(in)
|
||||||
, xd0_(in.readFloatBig())
|
, xd0_(in.readFloatBig())
|
||||||
, xd4_(in.readFloatBig())
|
, xd4_maxEnergyDrainAllowed(in.readFloatBig())
|
||||||
, xd8_(in.readFloatBig())
|
, xd8_(in.readFloatBig())
|
||||||
, xdc_(in.readFloatBig())
|
, xdc_stage2GrowthScale(in.readFloatBig())
|
||||||
, xe0_(in.readFloatBig())
|
, xe0_stage2GrowthEnergy(in.readFloatBig())
|
||||||
, xe4_(in.readFloatBig()) {
|
, xe4_explosionGrowthEnergy(in.readFloatBig()) {
|
||||||
xe8_animParms1 = ScriptLoader::LoadAnimationParameters(in);
|
xe8_animParms1 = ScriptLoader::LoadAnimationParameters(in);
|
||||||
xf8_animParms2 = ScriptLoader::LoadAnimationParameters(in);
|
xf8_animParms2 = ScriptLoader::LoadAnimationParameters(in);
|
||||||
x108_animParms3 = ScriptLoader::LoadAnimationParameters(in);
|
x108_animParms3 = ScriptLoader::LoadAnimationParameters(in);
|
||||||
|
@ -186,4 +190,579 @@ const CDamageVulnerability* CMetroid::GetDamageVulnerability() const {
|
||||||
return CAi::GetDamageVulnerability();
|
return CAi::GetDamageVulnerability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CMetroid::GetOrigin(const CStateManager& mgr, const CTeamAiRole& role,
|
||||||
|
const zeus::CVector3f& aimPos) const {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
float range = 0.5f * (x2fc_minAttackRange + x300_maxAttackRange);
|
||||||
|
const zeus::CVector3f& pos = GetTranslation();
|
||||||
|
TUniqueId target = x7b0_attackTarget;
|
||||||
|
if (target == player.GetUniqueId()) {
|
||||||
|
const zeus::CVector3f& playerPos = player.GetTranslation();
|
||||||
|
const zeus::CVector3f& playerFace = player.GetTransform().frontVector();
|
||||||
|
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||||
|
zeus::CVector3f face = playerPos - pos;
|
||||||
|
face.z() = 0.f;
|
||||||
|
if (face.canBeNormalized()) {
|
||||||
|
face.normalize();
|
||||||
|
} else {
|
||||||
|
face = playerFace;
|
||||||
|
}
|
||||||
|
return playerPos + zeus::CVector3f{range * face.x(), range * face.y(), 0.5f};
|
||||||
|
}
|
||||||
|
return aimPos + zeus::CVector3f{range * playerFace.x(), range * playerFace.y(), 0.5f};
|
||||||
|
}
|
||||||
|
if (TCastToConstPtr<CActor> actor = mgr.GetObjectById(target)) {
|
||||||
|
const zeus::CVector3f& actorPos = actor->GetTranslation();
|
||||||
|
zeus::CVector3f face = pos - actorPos;
|
||||||
|
face.z() = 0.f;
|
||||||
|
if (face.canBeNormalized()) {
|
||||||
|
face.normalize();
|
||||||
|
} else {
|
||||||
|
face = actor->GetTransform().frontVector();
|
||||||
|
}
|
||||||
|
return actorPos + zeus::CVector3f{range * face.x(), range * face.y(), 0.5f};
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x568_state = x9bf_27_ ? EState::Over : EState::One;
|
||||||
|
if (x7b0_attackTarget == kInvalidUniqueId) {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
const zeus::CVector3f& pos = GetTranslation();
|
||||||
|
float playerDistSq = (player.GetTranslation() - pos).magSquared();
|
||||||
|
x7b0_attackTarget = player.GetUniqueId();
|
||||||
|
if (!x450_bodyController->HasBeenFrozen()) {
|
||||||
|
float range = std::max(x3bc_detectionRange, std::sqrt(playerDistSq));
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||||
|
mgr.BuildNearList(nearList, zeus::CAABox{pos - range, pos + range},
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Character}), nullptr);
|
||||||
|
CSpacePirate* closestPirate = nullptr;
|
||||||
|
for (const auto id : nearList) {
|
||||||
|
if (auto* pirate = CPatterned::CastTo<CSpacePirate>(mgr.ObjectById(id))) {
|
||||||
|
if (IsPirateValidTarget(pirate, mgr)) {
|
||||||
|
float distSq = (pirate->GetTranslation() - pos).magSquared();
|
||||||
|
if (distSq < playerDistSq) {
|
||||||
|
closestPirate = pirate;
|
||||||
|
playerDistSq = distSq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (closestPirate != nullptr) {
|
||||||
|
x7b0_attackTarget = closestPirate->GetUniqueId();
|
||||||
|
closestPirate->SetAttackTarget(GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto* pirate = CPatterned::CastTo<CSpacePirate>(mgr.ObjectById(x7b0_attackTarget))) {
|
||||||
|
mgr.SendScriptMsg(pirate, GetUniqueId(), EScriptObjectMessage::Alert);
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x568_state == EState::One) {
|
||||||
|
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) {
|
||||||
|
x568_state = EState::Two;
|
||||||
|
} else {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Three, zeus::skZero3f));
|
||||||
|
}
|
||||||
|
} else if (x568_state == EState::Two) {
|
||||||
|
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate) {
|
||||||
|
if (x7b0_attackTarget != kInvalidUniqueId) {
|
||||||
|
if (TCastToConstPtr<CActor> actor = mgr.GetObjectById(x7b0_attackTarget)) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverTargetVector(actor->GetTranslation() - GetTranslation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x568_state = EState::Over;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::Touch(CActor& act, CStateManager& mgr) {
|
||||||
|
if (IsAlive()) {
|
||||||
|
if (TCastToPtr<CGameProjectile> proj = act) {
|
||||||
|
if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId() && x3fc_flavor != CPatterned::EFlavorType::Two &&
|
||||||
|
proj->HasAttrib(EProjectileAttrib::Ice)) {
|
||||||
|
if (GetDamageVulnerability()->WeaponHits(CWeaponMode{EWeaponType::Ice, false}, false)) {
|
||||||
|
float timeScale = proj->HasAttrib(EProjectileAttrib::Charged) ? 2.f : 1.f;
|
||||||
|
const zeus::CVector3f& projPos = proj->GetTranslation();
|
||||||
|
Freeze(mgr, projPos - GetTranslation(), x34_transform.transposeRotate(projPos - proj->GetPreviousPos()),
|
||||||
|
timeScale * x4fc_freezeDur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x9bf_26_shotAt = true;
|
||||||
|
}
|
||||||
|
CPatterned::Touch(act, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::IsPirateValidTarget(CSpacePirate* target, CStateManager& mgr) {
|
||||||
|
if (target->GetAttachedActor() == kInvalidUniqueId && target->IsTrooper()) {
|
||||||
|
const CHealthInfo* healthInfo = target->GetHealthInfo(mgr);
|
||||||
|
if (healthInfo != nullptr && healthInfo->GetHP() > 0.f) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::UpdateAttackChance(CStateManager& mgr, float dt) {
|
||||||
|
if (IsAttackInProgress(mgr)) {
|
||||||
|
x7b4_attackChance = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime;
|
||||||
|
} else if (x7b4_attackChance > 0.f) {
|
||||||
|
float delta = dt;
|
||||||
|
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||||
|
delta = 2.f * dt;
|
||||||
|
}
|
||||||
|
x7b4_attackChance -= delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::IsAttackInProgress(CStateManager& mgr) {
|
||||||
|
if (TCastToConstPtr<CActor> actor = mgr.GetObjectById(x7b0_attackTarget)) {
|
||||||
|
if (x7b0_attackTarget == mgr.GetPlayer().GetUniqueId()) {
|
||||||
|
const TUniqueId attachedActor = mgr.GetPlayer().GetAttachedActor();
|
||||||
|
if (attachedActor != kInvalidUniqueId && attachedActor != GetUniqueId()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (const auto* pirate = CPatterned::CastTo<CSpacePirate>(actor.GetPtr())) {
|
||||||
|
const TUniqueId attachedActor = pirate->GetAttachedActor();
|
||||||
|
if (attachedActor != kInvalidUniqueId && attachedActor != GetUniqueId()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SuckEnergyFromTarget(CStateManager& mgr, float dt) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::RestoreSolidCollision(CStateManager& mgr) {
|
||||||
|
constexpr auto filter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid, EMaterialTypes::AIBlock});
|
||||||
|
const zeus::CVector3f& pos = GetTranslation();
|
||||||
|
if (x9bf_30_ && !CGameCollision::DetectStaticCollisionBoolean(mgr, x6a0_collisionPrimitive, GetTransform(), filter)) {
|
||||||
|
bool add = true;
|
||||||
|
if (!x80c_.isZero()) {
|
||||||
|
const zeus::CVector3f dir = pos - x80c_;
|
||||||
|
float mag = dir.magnitude();
|
||||||
|
if (mag > 0.f) {
|
||||||
|
// TODO double check bool
|
||||||
|
add = mgr.RayStaticIntersection(x80c_, (1.f / mag) * dir, mag, filter).IsInvalid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
AddMaterial(EMaterialTypes::Solid, mgr);
|
||||||
|
x9bf_30_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x9bf_31_) {
|
||||||
|
constexpr auto nearFilter =
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid, EMaterialTypes::Player, EMaterialTypes::Character});
|
||||||
|
float radius = x808_loopAttackDistance * GetModelData()->GetScale().y();
|
||||||
|
const zeus::CAABox box{pos - radius, pos + radius};
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||||
|
mgr.BuildNearList(nearList, box, nearFilter, this);
|
||||||
|
if (!CGameCollision::DetectDynamicCollisionBoolean(x6a0_collisionPrimitive, GetTransform(), nearList, mgr)) {
|
||||||
|
x9bf_31_ = false;
|
||||||
|
CMaterialFilter matFilter = GetMaterialFilter();
|
||||||
|
matFilter.ExcludeList().Remove({EMaterialTypes::Character, EMaterialTypes::Player});
|
||||||
|
SetMaterialFilter(matFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::PreventWorldCollisions(CStateManager& mgr, float dt) {
|
||||||
|
float size = 2.f * x6a0_collisionPrimitive.GetSphere().radius;
|
||||||
|
if (IsSuckingEnergy()) {
|
||||||
|
if (x7b0_attackTarget == mgr.GetPlayer().GetUniqueId()) {
|
||||||
|
if (TCastToPtr<CPhysicsActor> actor = mgr.ObjectById(x7b0_attackTarget)) {
|
||||||
|
// why not use mgr.GetPlayer()? :thonking:
|
||||||
|
float mass = 300.f;
|
||||||
|
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed) {
|
||||||
|
float scale = std::min(1.f, 1.33f * x7c0_);
|
||||||
|
mass = 300.f * (1.f - scale) + 7500.f * scale;
|
||||||
|
}
|
||||||
|
CGameCollision::AvoidStaticCollisionWithinRadius(mgr, *actor, 8, dt, 0.25f, size, mass, 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x7c4_ = 0.f;
|
||||||
|
} else if (!x9bf_30_ && !x9bf_31_) {
|
||||||
|
x7c4_ = 0.f;
|
||||||
|
} else {
|
||||||
|
x7c4_ += dt;
|
||||||
|
if (x7c4_ <= 6.f) {
|
||||||
|
if (x9bf_30_ && 0.25f < x7c4_) {
|
||||||
|
RemoveMaterial(EMaterialTypes::Solid, mgr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MassiveDeath(mgr);
|
||||||
|
}
|
||||||
|
CGameCollision::AvoidStaticCollisionWithinRadius(mgr, *this, 8, dt, 0.25f, size, 15000.f, 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SwarmRemove(CStateManager& mgr) {
|
||||||
|
if (x698_teamAiMgrId == kInvalidUniqueId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TCastToPtr<CTeamAiMgr> aiMgr = mgr.ObjectById(x698_teamAiMgrId)) {
|
||||||
|
if (aiMgr->IsPartOfTeam(GetUniqueId())) {
|
||||||
|
aiMgr->RemoveTeamAiRole(GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SwarmAdd(CStateManager& mgr) {
|
||||||
|
if (x698_teamAiMgrId == kInvalidUniqueId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TCastToPtr<CTeamAiMgr> aiMgr = mgr.ObjectById(x698_teamAiMgrId)) {
|
||||||
|
if (!aiMgr->IsPartOfTeam(GetUniqueId())) {
|
||||||
|
aiMgr->AssignTeamAiRole(*this, CTeamAiRole::ETeamAiRole::Melee, CTeamAiRole::ETeamAiRole::Invalid,
|
||||||
|
CTeamAiRole::ETeamAiRole::Invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::ApplyGrowth(float arg) {
|
||||||
|
x7f8_ += arg;
|
||||||
|
const float energy = std::clamp(x7f8_ / x56c_data.GetStage2GrowthEnergy(), 0.f, 1.f);
|
||||||
|
const float scale = x56c_data.GetStage2GrowthScale() - x7e8_scale3.y();
|
||||||
|
x7d0_scale1 = zeus::CVector3f{energy * scale + x7e8_scale3.y()};
|
||||||
|
TakeDamage(zeus::skZero3f, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::IsSuckingEnergy() const { return x7c8_ == EUnknown::Two && !x450_bodyController->IsFrozen(); }
|
||||||
|
|
||||||
|
void CMetroid::UpdateVolume() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::UpdateTouchBounds() {
|
||||||
|
const zeus::CTransform& locXf = GetLocatorTransform("lockon_target_LCTR"sv);
|
||||||
|
x6a0_collisionPrimitive.SetSphereCenter(locXf * GetModelData()->GetScale());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::Attack(CStateManager& mgr, EStateMsg msg, float dt) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
if (AttachToTarget(mgr)) {
|
||||||
|
x568_state = EState::One;
|
||||||
|
x7bc_ = 0.f;
|
||||||
|
x7c8_ = EUnknown::One;
|
||||||
|
x9bf_29_isAttacking = true;
|
||||||
|
RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||||
|
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
|
||||||
|
DisableSolidCollision(this);
|
||||||
|
AddMaterial(EMaterialTypes::Trigger, mgr);
|
||||||
|
} else {
|
||||||
|
x568_state = EState::Over;
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x568_state == EState::One) {
|
||||||
|
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::LoopAttack) {
|
||||||
|
x568_state = EState::Two;
|
||||||
|
} else {
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLoopAttackCmd(pas::ELoopAttackType::Three));
|
||||||
|
}
|
||||||
|
} else if (x568_state == EState::Two) {
|
||||||
|
if (GetModelData()->GetAnimationData()->GetIsLoop()) {
|
||||||
|
x7c8_ = EUnknown::Two;
|
||||||
|
}
|
||||||
|
const CPlayer& player = mgr.GetPlayer();
|
||||||
|
if (x7b0_attackTarget == player.GetUniqueId() && player.GetAttachedActor() == GetUniqueId() &&
|
||||||
|
player.GetAreaIdAlways() != GetAreaIdAlways()) {
|
||||||
|
DetachFromTarget(mgr);
|
||||||
|
x401_30_pendingDeath = true;
|
||||||
|
} else if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::LoopAttack) {
|
||||||
|
if (ShouldReleaseFromTarget(mgr)) {
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
|
||||||
|
DetachFromTarget(mgr);
|
||||||
|
x7c8_ = EUnknown::Three;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x568_state = EState::Over;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
CTeamAiMgr::ResetTeamAiRole(CTeamAiMgr::EAttackType::Melee, mgr, x698_teamAiMgrId, GetUniqueId(), false);
|
||||||
|
x7b4_attackChance = x308_attackTimeVariation * mgr.GetActiveRandom()->Float() + x304_averageAttackTime;
|
||||||
|
x7c8_ = EUnknown::Zero;
|
||||||
|
DetachFromTarget(mgr);
|
||||||
|
x9bf_29_isAttacking = false;
|
||||||
|
SetTransform({zeus::CQuaternion::fromAxisAngle({0.f, 0.f, 1.f}, GetYaw()), GetTranslation()});
|
||||||
|
AddMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||||
|
RemoveMaterial(EMaterialTypes::Trigger, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::AttachToTarget(CStateManager& mgr) {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
if (x7b0_attackTarget == player.GetUniqueId()) {
|
||||||
|
if (player.AttachActorToPlayer(GetUniqueId(), false)) {
|
||||||
|
player.GetEnergyDrain().AddEnergyDrainSource(GetUniqueId(), 1.f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return PreDamageSpacePirate(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::DetachFromTarget(CStateManager& mgr) {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
CActor* target = nullptr;
|
||||||
|
zeus::CVector3f vec;
|
||||||
|
zeus::CTransform xf;
|
||||||
|
if (x7b0_attackTarget == player.GetUniqueId()) {
|
||||||
|
if (player.GetAttachedActor() == GetUniqueId()) {
|
||||||
|
player.DetachActorFromPlayer();
|
||||||
|
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||||
|
const auto q1 = zeus::CQuaternion::fromAxisAngle({0.f, 0.f, 1.f}, M_PI);
|
||||||
|
const auto q2 = zeus::CQuaternion::fromAxisAngle({0.f, 0.f, 1.f}, GetYaw());
|
||||||
|
const auto mat = zeus::CMatrix3f{q2 * q1};
|
||||||
|
vec = mat * zeus::skForward;
|
||||||
|
xf = zeus::CTransform{mat, player.GetTranslation()};
|
||||||
|
} else {
|
||||||
|
vec = player.GetTransform().frontVector();
|
||||||
|
xf = player.GetTransform();
|
||||||
|
}
|
||||||
|
mgr.GetPlayer().GetEnergyDrain().RemoveEnergyDrainSource(GetUniqueId());
|
||||||
|
x80c_ = player.GetAimPosition(mgr, 0.f);
|
||||||
|
target = &player;
|
||||||
|
}
|
||||||
|
} else if (x7b0_attackTarget != kInvalidUniqueId) {
|
||||||
|
if (auto* pirate = CPatterned::CastTo<CSpacePirate>(mgr.ObjectById(x7b0_attackTarget))) {
|
||||||
|
if (pirate->GetAttachedActor() == GetUniqueId()) {
|
||||||
|
pirate->DetachActorFromPirate();
|
||||||
|
vec = pirate->GetTransform().frontVector();
|
||||||
|
xf = pirate->GetTransform();
|
||||||
|
x80c_ = GetTranslation();
|
||||||
|
target = pirate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetupExitFaceHugDirection(target, mgr, vec, xf);
|
||||||
|
x9bf_31_ = true;
|
||||||
|
x9bf_30_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::ShouldReleaseFromTarget(CStateManager& mgr) {
|
||||||
|
if (x450_bodyController->IsFrozen()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
if (x7b0_attackTarget == GetUniqueId()) {
|
||||||
|
if (x7bc_ >= x56c_data.GetMaxEnergyDrainAllowed() * GetDamageMultiplier() || IsPlayerUnderwater(mgr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Unmorphed) {
|
||||||
|
return IsHunterAttacking(mgr);
|
||||||
|
}
|
||||||
|
} else if (x7b0_attackTarget != kInvalidUniqueId) {
|
||||||
|
if (const auto* pirate = CPatterned::CastTo<CSpacePirate>(mgr.GetObjectById(x7b0_attackTarget))) {
|
||||||
|
if (!pirate->AllEnergyDrained() && !pirate->GetBodyController()->GetBodyStateInfo().GetCurrentState()->IsDead()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::DisableSolidCollision(CMetroid* target) {
|
||||||
|
CMaterialFilter filter = target->GetMaterialFilter();
|
||||||
|
filter.ExcludeList().Add({EMaterialTypes::Character, EMaterialTypes::Player});
|
||||||
|
target->SetMaterialFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SetupExitFaceHugDirection(CActor* actor, CStateManager& mgr, const zeus::CVector3f& vec,
|
||||||
|
const zeus::CTransform& xf) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::PreDamageSpacePirate(CStateManager& mgr) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::IsPlayerUnderwater(CStateManager& mgr) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::IsHunterAttacking(CStateManager& mgr) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CMetroid::GetGrowthStage() {
|
||||||
|
const float energy = x7f8_;
|
||||||
|
const float stage2GrowthEnergy = x56c_data.GetStage2GrowthEnergy();
|
||||||
|
if (energy < stage2GrowthEnergy) {
|
||||||
|
return 1.f + energy / stage2GrowthEnergy;
|
||||||
|
}
|
||||||
|
const float explosionGrowthEnergy = x56c_data.GetExplosionGrowthEnergy();
|
||||||
|
if (energy < explosionGrowthEnergy) {
|
||||||
|
return 2.f + (energy - stage2GrowthEnergy) / (explosionGrowthEnergy - stage2GrowthEnergy);
|
||||||
|
}
|
||||||
|
return 3.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::ShouldAttack(CStateManager& mgr, float arg) {
|
||||||
|
if (!CanAttack(mgr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (TCastToPtr<CTeamAiMgr> aiMgr = mgr.ObjectById(x698_teamAiMgrId)) {
|
||||||
|
return aiMgr->AddMeleeAttacker(GetUniqueId());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::CanAttack(CStateManager& mgr) {
|
||||||
|
if (x7b4_attackChance <= 0.f) {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
if (x7b0_attackTarget == player.GetUniqueId()) {
|
||||||
|
if (IsPlayerUnderwater(mgr) ||
|
||||||
|
(player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
|
||||||
|
player.GetMorphBall()->GetSpiderBallState() == CMorphBall::ESpiderBallState::Active)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed && IsHunterAttacking(mgr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const CEntity* target = mgr.GetObjectById(x7b0_attackTarget);
|
||||||
|
if (target != nullptr && target->GetAreaIdAlways() == GetAreaIdAlways()) {
|
||||||
|
return !IsAttackInProgress(mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::PathFind(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||||
|
GetBodyController()->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed);
|
||||||
|
GetBodyController()->GetCommandMgr().SetSteeringSpeedRange(1.f, 1.f);
|
||||||
|
SetUpPathFindBehavior(mgr);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
const auto* searchPath = GetSearchPath();
|
||||||
|
if (searchPath == nullptr || PathShagged(mgr, 0.f) || PathOver(mgr, 0.f)) {
|
||||||
|
const auto* aiRole = CTeamAiMgr::GetTeamAiRole(mgr, x698_teamAiMgrId, GetUniqueId());
|
||||||
|
if (aiRole == nullptr) {
|
||||||
|
x7a4_ = GetOrigin(mgr, CTeamAiRole{GetUniqueId()}, GetAttackTargetPos(mgr));
|
||||||
|
} else {
|
||||||
|
x7a4_ = aiRole->GetTeamPosition();
|
||||||
|
}
|
||||||
|
ApplyForwardSteering(mgr, x7a4_);
|
||||||
|
} else {
|
||||||
|
CPatterned::PathFind(mgr, msg, arg);
|
||||||
|
}
|
||||||
|
ApplySeparationBehavior(mgr, 9.f);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
GetBodyController()->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::ApplyForwardSteering(CStateManager& mgr, const zeus::CVector3f& vec) {
|
||||||
|
if ((vec - GetTranslation()).magSquared() <= 4.f) {
|
||||||
|
if (ShouldTurn(mgr, 0.f) && x7b0_attackTarget != kInvalidUniqueId) {
|
||||||
|
if (TCastToConstPtr<CActor> actor = mgr.GetObjectById(x7b0_attackTarget)) {
|
||||||
|
const zeus::CVector3f dir = actor->GetTranslation() - GetTranslation();
|
||||||
|
if (dir.canBeNormalized()) {
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd{zeus::skZero3f, dir.normalized(), 1.f});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const zeus::CVector3f arrival = x45c_steeringBehaviors.Arrival(*this, GetTranslation().toVec2f(), 0.5f);
|
||||||
|
if (arrival.magSquared() > 0.01f) {
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(arrival, zeus::skZero3f, 3.f));
|
||||||
|
}
|
||||||
|
if (TCastToConstPtr<CPhysicsActor> actor = mgr.GetObjectById(x7b0_attackTarget)) {
|
||||||
|
const auto move = x45c_steeringBehaviors.Pursuit(*this, vec, actor->GetVelocity());
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||||
|
} else {
|
||||||
|
const auto move = x45c_steeringBehaviors.Seek(*this, vec);
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(move, zeus::skZero3f, 1.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::ApplySeparationBehavior(CStateManager& mgr, float arg) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetroid::SetUpPathFindBehavior(CStateManager& mgr) {
|
||||||
|
x9bf_28_ = false;
|
||||||
|
if (GetSearchPath() == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (const auto* role = CTeamAiMgr::GetTeamAiRole(mgr, x698_teamAiMgrId, GetUniqueId())) {
|
||||||
|
SetDestPos(role->GetTeamPosition());
|
||||||
|
} else {
|
||||||
|
SetDestPos(GetOrigin(mgr, CTeamAiRole{GetUniqueId()}, mgr.GetPlayer().GetTranslation()));
|
||||||
|
}
|
||||||
|
const zeus::CVector3f targetPos = GetAttackTargetPos(mgr);
|
||||||
|
const zeus::CVector3f dir = GetDestPos() - targetPos;
|
||||||
|
if (dir.canBeNormalized()) {
|
||||||
|
constexpr auto filter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid, EMaterialTypes::AIBlock});
|
||||||
|
float mag = dir.magnitude();
|
||||||
|
const zeus::CVector3f dirScaled = (1.f / mag) * dir;
|
||||||
|
const auto result = mgr.RayStaticIntersection(targetPos, dirScaled, mag, filter);
|
||||||
|
if (result.IsValid()) {
|
||||||
|
SetDestPos(targetPos + 0.5f * result.GetT() * dirScaled);
|
||||||
|
x9bf_28_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x7a4_ = GetDestPos();
|
||||||
|
CPatterned::PathFind(mgr, EStateMsg::Activate, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CMetroid::GetAttackTargetPos(CStateManager& mgr) {
|
||||||
|
const TUniqueId targetId = x7b0_attackTarget;
|
||||||
|
if (targetId != kInvalidUniqueId) {
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
if (targetId == player.GetUniqueId()) {
|
||||||
|
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||||
|
return player.GetMorphBall()->GetBallToWorld().origin;
|
||||||
|
}
|
||||||
|
return player.GetTranslation() + zeus::CVector3f{0.f, 0.f, -0.6f + player.GetEyeHeight()};
|
||||||
|
}
|
||||||
|
if (TCastToConstPtr<CActor> actor = mgr.GetObjectById(targetId)) {
|
||||||
|
const auto locXf = actor->GetLocatorTransform(skPirateSuckJoint);
|
||||||
|
return actor->GetTranslation() +
|
||||||
|
zeus::CVector3f{0.f, 0.f, locXf.origin.z() * actor->GetModelData()->GetScale().z() + 0.4f};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroid::AggressionCheck(CStateManager& mgr, float arg) {
|
||||||
|
if (x7b0_attackTarget != kInvalidUniqueId) {
|
||||||
|
CEntity* target = mgr.ObjectById(x7b0_attackTarget);
|
||||||
|
if (auto* pirate = CPatterned::CastTo<CSpacePirate>(target)) {
|
||||||
|
if (!IsPirateValidTarget(pirate, mgr)) {
|
||||||
|
x7b0_attackTarget = kInvalidUniqueId;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TCastToPtr<CActor> actor = target) {
|
||||||
|
const zeus::CVector3f dir = actor->GetTranslation() - GetTranslation();
|
||||||
|
if (x3bc_detectionRange * x3bc_detectionRange > dir.magSquared()) {
|
||||||
|
if (x3c0_detectionHeightRange > 0.f) {
|
||||||
|
return dir.z() * dir.z() < x3c0_detectionHeightRange * x3c0_detectionHeightRange;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x7b0_attackTarget = kInvalidUniqueId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
||||||
|
|
|
@ -19,11 +19,11 @@ private:
|
||||||
CDamageVulnerability x0_frozenVulnerability;
|
CDamageVulnerability x0_frozenVulnerability;
|
||||||
CDamageVulnerability x68_energyDrainVulnerability;
|
CDamageVulnerability x68_energyDrainVulnerability;
|
||||||
float xd0_;
|
float xd0_;
|
||||||
float xd4_;
|
float xd4_maxEnergyDrainAllowed;
|
||||||
float xd8_;
|
float xd8_;
|
||||||
float xdc_;
|
float xdc_stage2GrowthScale;
|
||||||
float xe0_;
|
float xe0_stage2GrowthEnergy;
|
||||||
float xe4_;
|
float xe4_explosionGrowthEnergy;
|
||||||
std::optional<CAnimationParameters> xe8_animParms1;
|
std::optional<CAnimationParameters> xe8_animParms1;
|
||||||
std::optional<CAnimationParameters> xf8_animParms2;
|
std::optional<CAnimationParameters> xf8_animParms2;
|
||||||
std::optional<CAnimationParameters> x108_animParms3;
|
std::optional<CAnimationParameters> x108_animParms3;
|
||||||
|
@ -35,7 +35,11 @@ public:
|
||||||
static u32 GetNumProperties() { return skNumProperties; }
|
static u32 GetNumProperties() { return skNumProperties; }
|
||||||
const CDamageVulnerability& GetFrozenVulnerability() const { return x0_frozenVulnerability; }
|
const CDamageVulnerability& GetFrozenVulnerability() const { return x0_frozenVulnerability; }
|
||||||
const CDamageVulnerability& GetEnergyDrainVulnerability() const { return x68_energyDrainVulnerability; }
|
const CDamageVulnerability& GetEnergyDrainVulnerability() const { return x68_energyDrainVulnerability; }
|
||||||
bool GetStartsInWall() { return x128_24_startsInWall; }
|
float GetMaxEnergyDrainAllowed() const { return xd4_maxEnergyDrainAllowed; }
|
||||||
|
float GetStage2GrowthScale() const { return xdc_stage2GrowthScale; }
|
||||||
|
float GetStage2GrowthEnergy() const { return xe0_stage2GrowthEnergy; }
|
||||||
|
float GetExplosionGrowthEnergy() const { return xe4_explosionGrowthEnergy; }
|
||||||
|
bool GetStartsInWall() const { return x128_24_startsInWall; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMetroid : public CPatterned {
|
class CMetroid : public CPatterned {
|
||||||
|
@ -128,36 +132,37 @@ public:
|
||||||
void Touch(CActor& act, CStateManager& mgr) override;
|
void Touch(CActor& act, CStateManager& mgr) override;
|
||||||
|
|
||||||
void Attack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
void Attack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
void Dodge(CStateManager& mgr, EStateMsg msg, float dt) override;
|
// void Dodge(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override;
|
// void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override;
|
||||||
void Generate(CStateManager& mgr, EStateMsg msg, float arg) override;
|
// void Generate(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred,
|
// void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool
|
||||||
float magnitude) override;
|
// inDeferred,
|
||||||
|
// float magnitude) override;
|
||||||
void PathFind(CStateManager& mgr, EStateMsg msg, float arg) override;
|
void PathFind(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
void Patrol(CStateManager& mgr, EStateMsg msg, float arg) override;
|
// void Patrol(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
void TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) override;
|
// void TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
void TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
// void TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
void TurnAround(CStateManager& mgr, EStateMsg msg, float dt) override;
|
// void TurnAround(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
void WallHang(CStateManager& mgr, EStateMsg msg, float dt) override;
|
// void WallHang(CStateManager& mgr, EStateMsg msg, float dt) override;
|
||||||
|
|
||||||
bool AnimOver(CStateManager&, float arg) override { return x568_state == EState::Over; }
|
bool AnimOver(CStateManager&, float arg) override { return x568_state == EState::Over; }
|
||||||
bool AggressionCheck(CStateManager& mgr, float arg) override;
|
bool AggressionCheck(CStateManager& mgr, float arg) override;
|
||||||
bool Attacked(CStateManager& mgr, float arg) override;
|
// bool Attacked(CStateManager& mgr, float arg) override;
|
||||||
bool AttackOver(CStateManager& mgr, float arg) override;
|
// bool AttackOver(CStateManager& mgr, float arg) override;
|
||||||
bool InAttackPosition(CStateManager& mgr, float arg) override;
|
// bool InAttackPosition(CStateManager& mgr, float arg) override;
|
||||||
bool InDetectionRange(CStateManager& mgr, float arg) override;
|
// bool InDetectionRange(CStateManager& mgr, float arg) override;
|
||||||
bool InPosition(CStateManager& mgr, float arg) override;
|
// bool InPosition(CStateManager& mgr, float arg) override;
|
||||||
bool InRange(CStateManager& mgr, float arg) override;
|
// bool InRange(CStateManager& mgr, float arg) override;
|
||||||
bool Inside(CStateManager& mgr, float arg) override;
|
// bool Inside(CStateManager& mgr, float arg) override;
|
||||||
bool Leash(CStateManager& mgr, float arg) override;
|
// bool Leash(CStateManager& mgr, float arg) override;
|
||||||
bool LostInterest(CStateManager& mgr, float arg) override;
|
// bool LostInterest(CStateManager& mgr, float arg) override;
|
||||||
bool PatternShagged(CStateManager& mgr, float arg) override;
|
// bool PatternShagged(CStateManager& mgr, float arg) override;
|
||||||
bool ShotAt(CStateManager& mgr, float arg) override { return x9bf_26_shotAt; }
|
bool ShotAt(CStateManager& mgr, float arg) override { return x9bf_26_shotAt; }
|
||||||
bool ShouldAttack(CStateManager& mgr, float arg) override;
|
bool ShouldAttack(CStateManager& mgr, float arg) override;
|
||||||
bool ShouldDodge(CStateManager& mgr, float arg) override;
|
// bool ShouldDodge(CStateManager& mgr, float arg) override;
|
||||||
bool ShouldTurn(CStateManager& mgr, float arg) override;
|
// bool ShouldTurn(CStateManager& mgr, float arg) override;
|
||||||
bool ShouldWallHang(CStateManager& mgr, float arg) override { return x56c_data.GetStartsInWall(); }
|
bool ShouldWallHang(CStateManager& mgr, float arg) override { return x56c_data.GetStartsInWall(); }
|
||||||
bool SpotPlayer(CStateManager& mgr, float arg) override;
|
// bool SpotPlayer(CStateManager& mgr, float arg) override;
|
||||||
|
|
||||||
bool IsAttacking() const { return x9bf_29_isAttacking; }
|
bool IsAttacking() const { return x9bf_29_isAttacking; }
|
||||||
|
|
||||||
|
@ -181,7 +186,7 @@ private:
|
||||||
void DisableSolidCollision(CMetroid* target);
|
void DisableSolidCollision(CMetroid* target);
|
||||||
void RestoreSolidCollision(CStateManager& mgr);
|
void RestoreSolidCollision(CStateManager& mgr);
|
||||||
void PreventWorldCollisions(CStateManager& mgr, float dt);
|
void PreventWorldCollisions(CStateManager& mgr, float dt);
|
||||||
void SetupExitFaceHugDirection(CActor& actor, CStateManager& mgr, const zeus::CVector3f& vec,
|
void SetupExitFaceHugDirection(CActor* actor, CStateManager& mgr, const zeus::CVector3f& vec,
|
||||||
const zeus::CTransform& xf);
|
const zeus::CTransform& xf);
|
||||||
void DetachFromTarget(CStateManager& mgr);
|
void DetachFromTarget(CStateManager& mgr);
|
||||||
bool AttachToTarget(CStateManager& mgr);
|
bool AttachToTarget(CStateManager& mgr);
|
||||||
|
|
|
@ -330,5 +330,7 @@ public:
|
||||||
CProjectileInfo* GetProjectileInfo() override;
|
CProjectileInfo* GetProjectileInfo() override;
|
||||||
bool GetEnableAim() const { return x637_25_enableAim; }
|
bool GetEnableAim() const { return x637_25_enableAim; }
|
||||||
bool AllEnergyDrained() const { return x638_30_allEnergyDrained; }
|
bool AllEnergyDrained() const { return x638_30_allEnergyDrained; }
|
||||||
|
TUniqueId GetAttachedActor() const { return x7b4_attachedActor; }
|
||||||
|
bool IsTrooper() const { return x636_24_trooper; }
|
||||||
};
|
};
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
||||||
|
|
|
@ -73,7 +73,7 @@ CPatterned::CPatterned(ECharacter character, TUniqueId uid, std::string_view nam
|
||||||
x458_iceShatterSfx = pInfo.x134_iceShatterSfx;
|
x458_iceShatterSfx = pInfo.x134_iceShatterSfx;
|
||||||
x4f4_intoFreezeDur = pInfo.x100_intoFreezeDur;
|
x4f4_intoFreezeDur = pInfo.x100_intoFreezeDur;
|
||||||
x4f8_outofFreezeDur = pInfo.x104_outofFreezeDur;
|
x4f8_outofFreezeDur = pInfo.x104_outofFreezeDur;
|
||||||
x4fc_ = pInfo.x108_;
|
x4fc_freezeDur = pInfo.x108_freezeDur;
|
||||||
x508_colliderType = colliderType;
|
x508_colliderType = colliderType;
|
||||||
x50c_baseDamageMag = actorParms.GetThermalMag();
|
x50c_baseDamageMag = actorParms.GetThermalMag();
|
||||||
x514_deathExplosionOffset = pInfo.x110_particle1Scale;
|
x514_deathExplosionOffset = pInfo.x110_particle1Scale;
|
||||||
|
|
|
@ -214,7 +214,7 @@ protected:
|
||||||
float x4f0_predictedLeashTime = 0.f;
|
float x4f0_predictedLeashTime = 0.f;
|
||||||
float x4f4_intoFreezeDur;
|
float x4f4_intoFreezeDur;
|
||||||
float x4f8_outofFreezeDur;
|
float x4f8_outofFreezeDur;
|
||||||
float x4fc_;
|
float x4fc_freezeDur;
|
||||||
float x500_preThinkDt = 0.f;
|
float x500_preThinkDt = 0.f;
|
||||||
float x504_damageDur = 0.f;
|
float x504_damageDur = 0.f;
|
||||||
EColliderType x508_colliderType;
|
EColliderType x508_colliderType;
|
||||||
|
|
|
@ -35,7 +35,7 @@ CPatternedInfo::CPatternedInfo(CInputStream& in, u32 pcount)
|
||||||
, xfc_stateMachineId(in.readUint32Big())
|
, xfc_stateMachineId(in.readUint32Big())
|
||||||
, x100_intoFreezeDur(in.readFloatBig())
|
, x100_intoFreezeDur(in.readFloatBig())
|
||||||
, x104_outofFreezeDur(in.readFloatBig())
|
, x104_outofFreezeDur(in.readFloatBig())
|
||||||
, x108_(in.readFloatBig())
|
, x108_freezeDur(in.readFloatBig())
|
||||||
, x10c_pathfindingIndex(in.readUint32Big())
|
, x10c_pathfindingIndex(in.readUint32Big())
|
||||||
, x110_particle1Scale(zeus::CVector3f::ReadBig(in))
|
, x110_particle1Scale(zeus::CVector3f::ReadBig(in))
|
||||||
, x11c_particle1(in)
|
, x11c_particle1(in)
|
||||||
|
|
|
@ -42,7 +42,7 @@ class CPatternedInfo {
|
||||||
CAssetId xfc_stateMachineId;
|
CAssetId xfc_stateMachineId;
|
||||||
float x100_intoFreezeDur;
|
float x100_intoFreezeDur;
|
||||||
float x104_outofFreezeDur;
|
float x104_outofFreezeDur;
|
||||||
float x108_;
|
float x108_freezeDur;
|
||||||
|
|
||||||
u32 x10c_pathfindingIndex;
|
u32 x10c_pathfindingIndex;
|
||||||
|
|
||||||
|
|
|
@ -584,6 +584,7 @@ public:
|
||||||
float GetStaticTimer() const { return x740_staticTimer; }
|
float GetStaticTimer() const { return x740_staticTimer; }
|
||||||
float GetDeathTime() const { return x9f4_deathTime; }
|
float GetDeathTime() const { return x9f4_deathTime; }
|
||||||
const CPlayerEnergyDrain& GetEnergyDrain() const { return x274_energyDrain; }
|
const CPlayerEnergyDrain& GetEnergyDrain() const { return x274_energyDrain; }
|
||||||
|
CPlayerEnergyDrain& GetEnergyDrain() { return x274_energyDrain; }
|
||||||
EPlayerZoneInfo GetOrbitZone() const { return x330_orbitZoneMode; }
|
EPlayerZoneInfo GetOrbitZone() const { return x330_orbitZoneMode; }
|
||||||
EPlayerZoneType GetOrbitType() const { return x334_orbitType; }
|
EPlayerZoneType GetOrbitType() const { return x334_orbitType; }
|
||||||
const zeus::CTransform& GetFirstPersonCameraTransform(const CStateManager& mgr) const;
|
const zeus::CTransform& GetFirstPersonCameraTransform(const CStateManager& mgr) const;
|
||||||
|
|
|
@ -26,7 +26,8 @@ private:
|
||||||
zeus::CVector3f x1c_position;
|
zeus::CVector3f x1c_position;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTeamAiRole(TUniqueId ownerId, ETeamAiRole a, ETeamAiRole b, ETeamAiRole c)
|
CTeamAiRole(TUniqueId ownerId, ETeamAiRole a = ETeamAiRole::Invalid, ETeamAiRole b = ETeamAiRole::Invalid,
|
||||||
|
ETeamAiRole c = ETeamAiRole::Invalid)
|
||||||
: x0_ownerId(ownerId), x4_roleA(a), x8_roleB(b), xc_roleC(c) {}
|
: x0_ownerId(ownerId), x4_roleA(a), x8_roleB(b), xc_roleC(c) {}
|
||||||
TUniqueId GetOwnerId() const { return x0_ownerId; }
|
TUniqueId GetOwnerId() const { return x0_ownerId; }
|
||||||
bool HasTeamAiRole() const { return false; }
|
bool HasTeamAiRole() const { return false; }
|
||||||
|
|
|
@ -2010,7 +2010,7 @@ CEntity* ScriptLoader::LoadDrone(CStateManager& mgr, CInputStream& in, int propC
|
||||||
CEntity* ScriptLoader::LoadMetroid(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
CEntity* ScriptLoader::LoadMetroid(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
|
||||||
if (!EnsurePropertyCount(propCount, MP1::CMetroidData::GetNumProperties(), "Metroid"))
|
if (!EnsurePropertyCount(propCount, MP1::CMetroidData::GetNumProperties(), "Metroid"))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#if 0
|
|
||||||
std::string name = mgr.HashInstanceName(in);
|
std::string name = mgr.HashInstanceName(in);
|
||||||
CPatterned::EFlavorType flavor = CPatterned::EFlavorType(in.readUint32Big());
|
CPatterned::EFlavorType flavor = CPatterned::EFlavorType(in.readUint32Big());
|
||||||
zeus::CTransform xf = LoadEditorTransform(in);
|
zeus::CTransform xf = LoadEditorTransform(in);
|
||||||
|
@ -2028,12 +2028,8 @@ CEntity* ScriptLoader::LoadMetroid(CStateManager& mgr, CInputStream& in, int pro
|
||||||
|
|
||||||
CModelData mData(
|
CModelData mData(
|
||||||
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
|
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
|
||||||
return new MP1::CMetroid(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, actParms,
|
return new MP1::CMetroid(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, actParms, metData,
|
||||||
metData,
|
kInvalidUniqueId);
|
||||||
kInvalidUniqueId);
|
|
||||||
#else
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadDebrisExtended(CStateManager& mgr, CInputStream& in, int propCount,
|
CEntity* ScriptLoader::LoadDebrisExtended(CStateManager& mgr, CInputStream& in, int propCount,
|
||||||
|
|
Loading…
Reference in New Issue