mirror of https://github.com/AxioDL/metaforce.git
271 lines
7.4 KiB
C++
271 lines
7.4 KiB
C++
#include "CParasite.hpp"
|
|
#include "Character/CModelData.hpp"
|
|
#include "World/CActorParameters.hpp"
|
|
#include "World/CPatternedInfo.hpp"
|
|
#include "World/CWorld.hpp"
|
|
#include "World/CGameArea.hpp"
|
|
#include "World/CPlayer.hpp"
|
|
#include "CStateManager.hpp"
|
|
#include "TCastTo.hpp"
|
|
|
|
namespace urde::MP1
|
|
{
|
|
|
|
const float CParasite::flt_805A8FB0 = 2.f * std::sqrt(2.5f / 24.525002f);
|
|
const float CParasite::skAttackVelocity = 15.f / 2.f * (std::sqrt(2.5f / 24.525002f));
|
|
short CParasite::word_805A8FC0 = 0;
|
|
const float CParasite::flt_805A8FB8 = 2.f * std::sqrt(2.5f / 24.525002f);
|
|
const float CParasite::skRetreatVelocity = 3.f / 2.f * std::sqrt(2.5f / 24.525002f);
|
|
|
|
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo &info,
|
|
const zeus::CTransform &xf, CModelData &&mData, const CPatternedInfo &pInfo, EBodyType bodyType,
|
|
float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9,
|
|
float f10, float f11, float f12, float f13, float f14, float f15, float f16, float f17, float f18,
|
|
bool b1, u32 w1, const CDamageVulnerability& dVuln,const CDamageInfo& parInfo, u16 sfxId1,
|
|
u16 sfxId2, u16 sfxId3, u32 w2, u32 w3, float f19, const CActorParameters &aParams)
|
|
: CWallWalker(ECharacter::Parasite, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
|
|
EColliderType::Zero, bodyType, aParams, f7, f4, EKnockBackVariant::Small, f2, w1, f17, b1)
|
|
, x64c_(dVuln)
|
|
, x6b4_(parInfo)
|
|
, x6d0_(f1)
|
|
, x6d4_(f3)
|
|
, x6dc_(f5)
|
|
, x6e0_(f6)
|
|
, x6e4_(f8)
|
|
, x6e8_(f9)
|
|
, x6ec_(f10)
|
|
, x6f0_(f11)
|
|
, x6f4_(f12)
|
|
, x6f8_(f13)
|
|
, x6fc_(f14)
|
|
, x700_(f15)
|
|
, x704_(f16)
|
|
, x708_(pInfo.GetHeight() * 0.5f)
|
|
, x710_(f18)
|
|
, x714_(f19)
|
|
, x73c_(CSfxManager::TranslateSFXID(sfxId1))
|
|
, x73e_(CSfxManager::TranslateSFXID(sfxId2))
|
|
, x740_(CSfxManager::TranslateSFXID(sfxId3))
|
|
{
|
|
x742_28_ = true;
|
|
x742_30_ = true;
|
|
|
|
switch(x5d0_)
|
|
{
|
|
case 2:
|
|
x460_knockBackController.SetEnableFreeze(false);
|
|
case 1:
|
|
x460_knockBackController.SetAutoResetImpulse(false);
|
|
break;
|
|
case 3:
|
|
|
|
default:
|
|
break;
|
|
}
|
|
if (x5d0_ == 1)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void CParasite::Accept(IVisitor &visitor) { visitor.Visit(this); }
|
|
|
|
void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
|
{
|
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
|
if (msg == EScriptObjectMessage::Registered)
|
|
{
|
|
x450_bodyController->Activate(mgr);
|
|
/* TODO: Finish 8015A0E8*/
|
|
}
|
|
else if (msg == EScriptObjectMessage::Deleted)
|
|
{
|
|
//mgr.xf54_.sub80125d88(GetUniqueId());
|
|
if (x5d0_ != 3)
|
|
DestroyActorManager(mgr);
|
|
}
|
|
else if (msg == EScriptObjectMessage::Jumped && x742_25_)
|
|
{
|
|
UpdateJumpVelocity();
|
|
x742_25_ = false;
|
|
}
|
|
else if (msg == EScriptObjectMessage::Activate)
|
|
{
|
|
x5d6_27_ = false;
|
|
if (x5d0_ != 0)
|
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
|
}
|
|
else if (msg == EScriptObjectMessage::SuspendedMove)
|
|
{
|
|
}
|
|
}
|
|
|
|
void CParasite::PreThink(float dt, CStateManager& mgr)
|
|
{
|
|
CWallWalker::PreThink(dt, mgr);
|
|
x743_26_ = false;
|
|
}
|
|
|
|
void CParasite::Think(float dt, CStateManager& mgr)
|
|
{
|
|
if (!GetActive())
|
|
return;
|
|
|
|
++x5d4_;
|
|
if (x5d0_ == 3)
|
|
UpdateCollisionActors(mgr);
|
|
|
|
x5d6_26_ = false;
|
|
CGameArea* area = mgr.WorldNC()->GetArea(GetAreaIdAlways());
|
|
|
|
CGameArea::EOcclusionState r6 = CGameArea::EOcclusionState::Occluded;
|
|
if (area->IsPostConstructed())
|
|
r6 = area->GetPostConstructed()->x10dc_occlusionState;
|
|
if (r6 != CGameArea::EOcclusionState::Visible)
|
|
x5d6_26_ = true;
|
|
|
|
if (!x5d6_26_)
|
|
{
|
|
zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation();
|
|
float distance = (GetTranslation() - plVec).magnitude() ;
|
|
|
|
if (distance > x5c4_)
|
|
{
|
|
CRayCastResult res = mgr.RayStaticIntersection(plVec, (GetTranslation() - plVec).normalized(), distance,
|
|
CMaterialFilter::skPassEverything);
|
|
if (res.IsValid())
|
|
x5d6_26_ = true;
|
|
}
|
|
}
|
|
|
|
if (x5d6_26_)
|
|
{
|
|
xf8_24_movable = x5d6_26_;
|
|
return;
|
|
}
|
|
|
|
xf8_24_movable = !xf8_24_movable;
|
|
|
|
if (!x5d6_27_)
|
|
{
|
|
if (x450_bodyController->IsFrozen())
|
|
{
|
|
if ((GetTranslation() - x614_).magSquared() < 0.3f /* <- Used to be a static variable */ * dt)
|
|
x60c_ += dt;
|
|
else
|
|
x60c_ = 0.f;
|
|
|
|
x614_ = GetTranslation();
|
|
if (x608_ > 0.f)
|
|
x608_ -= dt;
|
|
else
|
|
x608_ = 0.f;
|
|
}
|
|
}
|
|
|
|
if (x400_25_alive)
|
|
{
|
|
CPlayer* pl = mgr.Player();
|
|
float radius;
|
|
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_)
|
|
radius = x590_colSphere.GetSphere().radius;
|
|
else
|
|
radius = x708_;
|
|
|
|
zeus::CAABox aabox{GetTranslation() - radius, GetTranslation() + radius};
|
|
auto plBox = pl->GetTouchBounds();
|
|
|
|
if (plBox && plBox->intersects(aabox))
|
|
{
|
|
if (!x742_30_)
|
|
{
|
|
x742_30_ = true;
|
|
x742_27_ = false;
|
|
}
|
|
|
|
if (x420_curDamageRemTime <= 0.f)
|
|
{
|
|
mgr.ApplyDamage(GetUniqueId(), pl->GetUniqueId(), GetUniqueId(), GetContactDamage(),
|
|
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
|
|
x420_curDamageRemTime = x424_damageWaitTime;
|
|
}
|
|
}
|
|
}
|
|
|
|
CWallWalker::Think(dt, mgr);
|
|
|
|
if (x5d6_27_)
|
|
return;
|
|
|
|
if (x450_bodyController->IsFrozen())
|
|
return;
|
|
|
|
x3b4_speed = x604_;
|
|
if (x5d6_24_)
|
|
AlignToFloor(mgr, x590_colSphere.GetSphere().radius, GetTranslation() + 2.f * dt * x138_velocity, dt);
|
|
|
|
x742_27_ = false;
|
|
}
|
|
|
|
void CParasite::DestroyActorManager(CStateManager& mgr)
|
|
{
|
|
//x620_->Destroy(mgr);
|
|
}
|
|
|
|
void CParasite::UpdateJumpVelocity()
|
|
{
|
|
x150_momentum.x = 0;
|
|
x150_momentum.y = 0;
|
|
x150_momentum.z = -GetWeight();
|
|
zeus::CVector3f vec;
|
|
|
|
if (!x742_30_)
|
|
{
|
|
vec = skAttackVelocity * GetTransform().frontVector();
|
|
vec.z = 0.5f * skRetreatVelocity;
|
|
}
|
|
else
|
|
{
|
|
vec = skRetreatVelocity * GetTransform().frontVector();
|
|
vec.z = 0.5f * skAttackVelocity;
|
|
}
|
|
|
|
float f30 = x150_momentum.z / xe8_mass;
|
|
float f31 = x600_ - GetTranslation().z;
|
|
zeus::CVector3f vec2;
|
|
vec2.x = x5f8_ - GetTranslation().x;
|
|
vec2.y = x5fc_ * GetTranslation().y;
|
|
vec2.z = 0.f;
|
|
float f29 = vec2.magnitude();
|
|
|
|
if (f29 > FLT_EPSILON)
|
|
{
|
|
vec2 *= zeus::CVector3f{1.f / f29};
|
|
float f28 = vec2.dot(vec);
|
|
if (f28 > FLT_EPSILON)
|
|
{
|
|
float f27 = 0.f;
|
|
bool isNeg = f31 < 0.f;
|
|
float out1, out2;
|
|
if (CSteeringBehaviors::SolveQuadratic(f30, vec.z, -f31, vec2.y, out1, out2))
|
|
f27 = isNeg ? out1 : out2;
|
|
|
|
if (!isNeg)
|
|
f27 = f27 * f29 / f28;
|
|
|
|
if (f27 < 10.f)
|
|
{
|
|
vec = f29 / f27 * vec2;
|
|
vec.z = (0.5f * f30 * f27 + f31 / f27);
|
|
}
|
|
}
|
|
}
|
|
SetVelocityWR(vec);
|
|
}
|
|
|
|
void CParasite::AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float)
|
|
{
|
|
}
|
|
|
|
} // namespace urde::MP1
|