mirror of https://github.com/AxioDL/metaforce.git
Lots of CParasite implementations
This commit is contained in:
parent
94333e4726
commit
bf3636a16e
|
@ -202,7 +202,7 @@ private:
|
|||
EThermalDrawFlag xf34_thermalFlag = EThermalDrawFlag::Bypass;
|
||||
TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId;
|
||||
std::list<u32> xf3c_;
|
||||
std::list<u32> xf54_;
|
||||
std::list<TUniqueId> xf54_parasiteTelegraphs;
|
||||
TUniqueId xf6c_playerActorHead = kInvalidUniqueId;
|
||||
u32 xf70_ = 0;
|
||||
|
||||
|
@ -470,6 +470,7 @@ public:
|
|||
}
|
||||
TUniqueId GetPlayerActorHead() const { return xf6c_playerActorHead; }
|
||||
void SetPlayerActorHead(TUniqueId id) { xf6c_playerActorHead = id; }
|
||||
std::list<TUniqueId>& GetParasiteTelegraphs() { return xf54_parasiteTelegraphs; }
|
||||
std::shared_ptr<CWorldLayerState>& WorldLayerStateNC() { return x8c8_worldLayerState; }
|
||||
static float g_EscapeShakeCountdown;
|
||||
static bool g_EscapeShakeCountdownInit;
|
||||
|
|
|
@ -88,8 +88,9 @@ class CBCGenerateCmd : public CBodyStateCmd
|
|||
bool x1c_25_overrideAnim : 1;
|
||||
public:
|
||||
CBCGenerateCmd() : CBodyStateCmd(EBodyStateCmd::Generate) { x1c_24_targetTransform = false; x1c_25_overrideAnim = false; }
|
||||
CBCGenerateCmd(pas::EGenerateType type, int i)
|
||||
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type) { x1c_24_targetTransform = false; x1c_25_overrideAnim = false; }
|
||||
CBCGenerateCmd(pas::EGenerateType type, s32 animId = -1)
|
||||
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), x18_animId(animId)
|
||||
{ x1c_24_targetTransform = false; x1c_25_overrideAnim = false; }
|
||||
CBCGenerateCmd(pas::EGenerateType type, const zeus::CVector3f& vec)
|
||||
: CBodyStateCmd(EBodyStateCmd::Generate), x8_type(type), xc_targetPos(vec)
|
||||
{ x1c_24_targetTransform = false; x1c_25_overrideAnim = false; }
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace urde
|
|||
|
||||
CParticleDatabase::CParticleDatabase()
|
||||
{
|
||||
xb4_24_active = true;
|
||||
xb4_24_updatesEnabled = true;
|
||||
xb4_25_anySystemsDrawnWithModel = false;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p
|
|||
void CParticleDatabase::Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
|
||||
const zeus::CTransform& xf, const zeus::CVector3f& scale, CStateManager& stateMgr)
|
||||
{
|
||||
if (!xb4_24_active)
|
||||
if (!xb4_24_updatesEnabled)
|
||||
return;
|
||||
|
||||
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x3c_rendererDrawLoop, true);
|
||||
|
|
|
@ -25,7 +25,7 @@ class CParticleDatabase
|
|||
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x78_rendererDraw;
|
||||
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x8c_firstDraw;
|
||||
std::map<std::string, std::unique_ptr<CParticleGenInfo>> xa0_lastDraw;
|
||||
bool xb4_24_active : 1;
|
||||
bool xb4_24_updatesEnabled : 1;
|
||||
bool xb4_25_anySystemsDrawnWithModel : 1;
|
||||
|
||||
static void SetModulationColorAllActiveEffectsForParticleDB(const zeus::CColor& color,
|
||||
|
@ -69,6 +69,7 @@ public:
|
|||
void InsertParticleGen(bool oneShot, int flags, std::string_view name,
|
||||
std::unique_ptr<CParticleGenInfo>&& gen);
|
||||
bool AreAnySystemsDrawnWithModel() const { return xb4_25_anySystemsDrawnWithModel; }
|
||||
void SetUpdatesEnabled(bool active) { xb4_24_updatesEnabled = active; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,111 @@
|
|||
namespace urde
|
||||
{
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Flee(const CPhysicsActor& actor,
|
||||
const zeus::CVector3f& v0) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Seek(const CPhysicsActor& actor,
|
||||
const zeus::CVector3f& v0) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Arrival(const CPhysicsActor& actor,
|
||||
const zeus::CVector3f& v0, float f1) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Pursuit(const CPhysicsActor& actor,
|
||||
const zeus::CVector3f& v0, const zeus::CVector3f& v1) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Separation(const CPhysicsActor& actor,
|
||||
const zeus::CVector3f& v0, float f1) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Alignment(const CPhysicsActor& actor,
|
||||
rstl::reserved_vector<TUniqueId, 1024>& list, const CStateManager& mgr) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Cohesion(const CPhysicsActor& actor,
|
||||
rstl::reserved_vector<TUniqueId, 1024>& list, float f1, const CStateManager& mgr) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Flee2D(const CPhysicsActor& actor,
|
||||
const zeus::CVector2f& v0) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::Arrival2D(const CPhysicsActor& actor,
|
||||
const zeus::CVector2f& v0, float f1) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CSteeringBehaviors::SolveQuadratic(float f30, float f31, float f3, float f4, float& out1, float& out2)
|
||||
{
|
||||
float f1 = f31 * f31 - 4.f * f30 * f3;
|
||||
if (f1 > FLT_EPSILON && std::fabs(f1) < FLT_EPSILON)
|
||||
return false;
|
||||
|
||||
out1 = -f31 + std::sqrt(f1) / 2.f * f30;
|
||||
out2 = -f31 - std::sqrt(f1) / 2.f * f30;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSteeringBehaviors::SolveCubic(
|
||||
const rstl::reserved_vector<float, 4>& in, rstl::reserved_vector<float, 4>& out)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSteeringBehaviors::SolveQuartic(
|
||||
const rstl::reserved_vector<float, 5>& in, rstl::reserved_vector<float, 4>& out)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::ProjectLinearIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, zeus::CVector3f& v3)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::ProjectLinearIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, zeus::CVector3f& v4)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::ProjectOrbitalIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, zeus::CVector3f& v4)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f CSteeringBehaviors::ProjectOrbitalIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
const zeus::CVector3f& v4, zeus::CVector3f& v5)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
zeus::CVector3f
|
||||
CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
|
||||
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt)
|
||||
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt)
|
||||
{
|
||||
zeus::CVector3f usePos = pos;
|
||||
if (vel.canBeNormalized())
|
||||
|
@ -35,15 +137,4 @@ CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeu
|
|||
return usePos;
|
||||
}
|
||||
|
||||
bool CSteeringBehaviors::SolveQuadratic(float f30, float f31, float f3, float f4, float& out1, float& out2)
|
||||
{
|
||||
float f1 = f31 * f31 - 4.f * f30 * f3;
|
||||
if (f1 > FLT_EPSILON && std::fabs(f1) < FLT_EPSILON)
|
||||
return false;
|
||||
|
||||
out1 = -f31 + std::sqrt(f1) / 2.f * f30;
|
||||
out2 = -f31 - std::sqrt(f1) / 2.f * f30;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,14 +5,40 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
class CPhysicsActor;
|
||||
class CStateManager;
|
||||
|
||||
class CSteeringBehaviors
|
||||
{
|
||||
float x0_ = M_PIF / 2.f;
|
||||
public:
|
||||
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
|
||||
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt);
|
||||
zeus::CVector3f Flee(const CPhysicsActor& actor, const zeus::CVector3f& v0) const;
|
||||
zeus::CVector3f Seek(const CPhysicsActor& actor, const zeus::CVector3f& v0) const;
|
||||
zeus::CVector3f Arrival(const CPhysicsActor& actor, const zeus::CVector3f& v0, float f1) const;
|
||||
zeus::CVector3f Pursuit(const CPhysicsActor& actor, const zeus::CVector3f& v0, const zeus::CVector3f& v1) const;
|
||||
zeus::CVector3f Separation(const CPhysicsActor& actor, const zeus::CVector3f& v0, float f1) const;
|
||||
zeus::CVector3f Alignment(const CPhysicsActor& actor, rstl::reserved_vector<TUniqueId, 1024>& list,
|
||||
const CStateManager& mgr) const;
|
||||
zeus::CVector3f Cohesion(const CPhysicsActor& actor, rstl::reserved_vector<TUniqueId, 1024>& list,
|
||||
float f1, const CStateManager& mgr) const;
|
||||
zeus::CVector3f Flee2D(const CPhysicsActor& actor, const zeus::CVector2f& v0) const;
|
||||
zeus::CVector3f Arrival2D(const CPhysicsActor& actor, const zeus::CVector2f& v0, float f1) const;
|
||||
static bool SolveQuadratic(float, float, float, float, float&, float&);
|
||||
static bool SolveCubic(const rstl::reserved_vector<float, 4>& in, rstl::reserved_vector<float, 4>& out);
|
||||
static bool SolveQuartic(const rstl::reserved_vector<float, 5>& in, rstl::reserved_vector<float, 4>& out);
|
||||
static zeus::CVector3f ProjectLinearIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, zeus::CVector3f& v3);
|
||||
static zeus::CVector3f ProjectLinearIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
zeus::CVector3f& v4);
|
||||
static zeus::CVector3f ProjectOrbitalIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
zeus::CVector3f& v4);
|
||||
static zeus::CVector3f ProjectOrbitalIntersection(const zeus::CVector3f& v0, float f1,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
||||
const zeus::CVector3f& v4, zeus::CVector3f& v5);
|
||||
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
|
||||
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -166,7 +166,9 @@ enum class ELoopAttackType
|
|||
|
||||
enum class EGenerateType
|
||||
{
|
||||
Invalid = -1
|
||||
Invalid = -1,
|
||||
Zero,
|
||||
One
|
||||
};
|
||||
|
||||
enum class ESlideType
|
||||
|
|
|
@ -208,13 +208,6 @@ CCollidableSphere::CCollidableSphere(const zeus::CSphere& sphere, const CMateria
|
|||
{
|
||||
}
|
||||
|
||||
const zeus::CSphere& CCollidableSphere::GetSphere() const { return x10_sphere; }
|
||||
|
||||
void CCollidableSphere::SetSphereCenter(const zeus::CVector3f& center)
|
||||
{
|
||||
x10_sphere.position = center;
|
||||
}
|
||||
|
||||
zeus::CSphere CCollidableSphere::Transform(const zeus::CTransform& xf) const
|
||||
{
|
||||
return zeus::CSphere(xf * x10_sphere.position, x10_sphere.radius);
|
||||
|
@ -257,10 +250,6 @@ CRayCastResult CCollidableSphere::CastRayInternal(const CInternalRayCastStructur
|
|||
return {};
|
||||
}
|
||||
|
||||
const CCollisionPrimitive::Type& CCollidableSphere::GetType() { return sType; }
|
||||
|
||||
void CCollidableSphere::SetStaticTableIndex(u32 index) { sTableIndex = index; }
|
||||
|
||||
bool CCollidableSphere::CollideMovingAABox(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir,
|
||||
double& dOut, CCollisionInfo& infoOut)
|
||||
{
|
||||
|
|
|
@ -22,8 +22,8 @@ class CCollidableSphere : public CCollisionPrimitive
|
|||
public:
|
||||
CCollidableSphere(const zeus::CSphere&, const CMaterialList&);
|
||||
|
||||
const zeus::CSphere& GetSphere() const;
|
||||
void SetSphereCenter(const zeus::CVector3f& center);
|
||||
const zeus::CSphere& GetSphere() const { return x10_sphere; }
|
||||
void SetSphereCenter(const zeus::CVector3f& center) { x10_sphere.position = center; }
|
||||
zeus::CSphere Transform(const zeus::CTransform& xf) const;
|
||||
|
||||
virtual u32 GetTableIndex() const;
|
||||
|
@ -32,8 +32,8 @@ public:
|
|||
virtual FourCC GetPrimType() const;
|
||||
virtual CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const;
|
||||
|
||||
static const Type& GetType();
|
||||
static void SetStaticTableIndex(u32 index);
|
||||
static const Type& GetType() { return sType; }
|
||||
static void SetStaticTableIndex(u32 index) { sTableIndex = index; }
|
||||
static bool CollideMovingAABox(const CInternalCollisionStructure&, const zeus::CVector3f&, double&,
|
||||
CCollisionInfo&);
|
||||
static bool CollideMovingSphere(const CInternalCollisionStructure&, const zeus::CVector3f&, double&,
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
void MorphVertices(std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn,
|
||||
const float* magnitudes, const TLockedToken<CSkinRules>& skinRules,
|
||||
const CPoseAsTransforms& pose) const;
|
||||
|
||||
void Reset(const zeus::CVector3f& dir, const zeus::CVector3f& pos, float duration) {}
|
||||
void Update(float) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,8 +5,13 @@
|
|||
#include "World/CWorld.hpp"
|
||||
#include "World/CGameArea.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "World/CScriptWaypoint.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "Graphics/CSkinnedModel.hpp"
|
||||
#include "Collision/CGameCollision.hpp"
|
||||
|
||||
namespace urde::MP1
|
||||
{
|
||||
|
@ -21,10 +26,10 @@ CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, c
|
|||
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)
|
||||
bool b1, EWalkerType wType, const CDamageVulnerability& dVuln,const CDamageInfo& parInfo, u16 sfxId1,
|
||||
u16 sfxId2, u16 sfxId3, CAssetId modelRes, CAssetId skinRes, 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)
|
||||
EColliderType::Zero, bodyType, aParams, f7, f4, EKnockBackVariant::Small, f2, wType, f17, b1)
|
||||
, x64c_(dVuln)
|
||||
, x6b4_(parInfo)
|
||||
, x6d0_(f1)
|
||||
|
@ -43,28 +48,38 @@ CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, c
|
|||
, x708_(pInfo.GetHeight() * 0.5f)
|
||||
, x710_(f18)
|
||||
, x714_(f19)
|
||||
, x73c_(CSfxManager::TranslateSFXID(sfxId1))
|
||||
, x73e_(CSfxManager::TranslateSFXID(sfxId2))
|
||||
, x740_(CSfxManager::TranslateSFXID(sfxId3))
|
||||
, x73c_haltSfx(CSfxManager::TranslateSFXID(sfxId1))
|
||||
, x73e_getUpSfx(CSfxManager::TranslateSFXID(sfxId2))
|
||||
, x740_crouchSfx(CSfxManager::TranslateSFXID(sfxId3))
|
||||
{
|
||||
x742_28_ = true;
|
||||
x742_30_ = true;
|
||||
x742_28_onGround = true;
|
||||
x742_30_attackOver = true;
|
||||
|
||||
switch(x5d0_)
|
||||
switch (x5d0_walkerType)
|
||||
{
|
||||
case 2:
|
||||
case EWalkerType::Geemer:
|
||||
x460_knockBackController.SetEnableFreeze(false);
|
||||
case 1:
|
||||
case EWalkerType::Oculus:
|
||||
x460_knockBackController.SetAutoResetImpulse(false);
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case EWalkerType::IceZoomer:
|
||||
{
|
||||
TLockedToken<CModel> model = g_SimplePool->GetObj({FOURCC('CMDL'), modelRes});
|
||||
TLockedToken<CModel> skin = g_SimplePool->GetObj({FOURCC('CSKR'), skinRes});
|
||||
x624_extraModel = CToken(
|
||||
TObjOwnerDerivedFromIObj<CSkinnedModel>::GetNewDerivedObject(std::make_unique<CSkinnedModel>(
|
||||
model, skin, x64_modelData->AnimationData()->GetModelData()->GetLayoutInfo(), 1, 1)));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (x5d0_ == 1)
|
||||
if (x5d0_walkerType == EWalkerType::Oculus)
|
||||
{
|
||||
|
||||
x460_knockBackController.SetEnableShock(false);
|
||||
x460_knockBackController.SetEnableBurn(false);
|
||||
x460_knockBackController.SetEnableBurnDeath(false);
|
||||
x460_knockBackController.SetEnableExplodeDeath(false);
|
||||
x460_knockBackController.SetX82_24(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,18 +96,18 @@ void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
|||
else if (msg == EScriptObjectMessage::Deleted)
|
||||
{
|
||||
//mgr.xf54_.sub80125d88(GetUniqueId());
|
||||
if (x5d0_ != 3)
|
||||
if (x5d0_walkerType != EWalkerType::IceZoomer)
|
||||
DestroyActorManager(mgr);
|
||||
}
|
||||
else if (msg == EScriptObjectMessage::Jumped && x742_25_)
|
||||
else if (msg == EScriptObjectMessage::Jumped && x742_25_jumpVelDirty)
|
||||
{
|
||||
UpdateJumpVelocity();
|
||||
x742_25_ = false;
|
||||
x742_25_jumpVelDirty = false;
|
||||
}
|
||||
else if (msg == EScriptObjectMessage::Activate)
|
||||
{
|
||||
x5d6_27_ = false;
|
||||
if (x5d0_ != 0)
|
||||
if (x5d0_walkerType != EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
}
|
||||
else if (msg == EScriptObjectMessage::SuspendedMove)
|
||||
|
@ -103,7 +118,7 @@ void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
|||
void CParasite::PreThink(float dt, CStateManager& mgr)
|
||||
{
|
||||
CWallWalker::PreThink(dt, mgr);
|
||||
x743_26_ = false;
|
||||
x743_26_oculusShotAt = false;
|
||||
}
|
||||
|
||||
void CParasite::Think(float dt, CStateManager& mgr)
|
||||
|
@ -112,7 +127,7 @@ void CParasite::Think(float dt, CStateManager& mgr)
|
|||
return;
|
||||
|
||||
++x5d4_;
|
||||
if (x5d0_ == 3)
|
||||
if (x5d0_walkerType == EWalkerType::IceZoomer)
|
||||
UpdateCollisionActors(mgr);
|
||||
|
||||
x5d6_26_ = false;
|
||||
|
@ -167,7 +182,7 @@ void CParasite::Think(float dt, CStateManager& mgr)
|
|||
{
|
||||
CPlayer* pl = mgr.Player();
|
||||
float radius;
|
||||
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_)
|
||||
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_attackOver)
|
||||
radius = x590_colSphere.GetSphere().radius;
|
||||
else
|
||||
radius = x708_;
|
||||
|
@ -177,10 +192,10 @@ void CParasite::Think(float dt, CStateManager& mgr)
|
|||
|
||||
if (plBox && plBox->intersects(aabox))
|
||||
{
|
||||
if (!x742_30_)
|
||||
if (!x742_30_attackOver)
|
||||
{
|
||||
x742_30_ = true;
|
||||
x742_27_ = false;
|
||||
x742_30_attackOver = true;
|
||||
x742_27_landed = false;
|
||||
}
|
||||
|
||||
if (x420_curDamageRemTime <= 0.f)
|
||||
|
@ -204,7 +219,628 @@ void CParasite::Think(float dt, CStateManager& mgr)
|
|||
if (x5d6_24_)
|
||||
AlignToFloor(mgr, x590_colSphere.GetSphere().radius, GetTranslation() + 2.f * dt * x138_velocity, dt);
|
||||
|
||||
x742_27_ = false;
|
||||
x742_27_landed = false;
|
||||
}
|
||||
|
||||
void CParasite::Render(const CStateManager& mgr) const
|
||||
{
|
||||
CWallWalker::Render(mgr);
|
||||
}
|
||||
|
||||
const CDamageVulnerability* CParasite::GetDamageVulnerability() const
|
||||
{
|
||||
switch (x5d0_walkerType)
|
||||
{
|
||||
case EWalkerType::Oculus:
|
||||
if (x743_24_)
|
||||
return &x64c_;
|
||||
break;
|
||||
case EWalkerType::IceZoomer:
|
||||
if (!x743_25_)
|
||||
return &CDamageVulnerability::ImmuneVulnerabilty();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return CAi::GetDamageVulnerability();
|
||||
}
|
||||
|
||||
void CParasite::Touch(CActor& actor, CStateManager& mgr)
|
||||
{
|
||||
CPatterned::Touch(actor, mgr);
|
||||
}
|
||||
|
||||
zeus::CVector3f CParasite::GetAimPosition(const CStateManager&, float) const
|
||||
{
|
||||
return GetTranslation();
|
||||
}
|
||||
|
||||
void CParasite::CollidedWith(TUniqueId uid, const CCollisionInfoList& list, CStateManager&)
|
||||
{
|
||||
static CMaterialList testList(EMaterialTypes::Character, EMaterialTypes::Player);
|
||||
if (x743_27_inJump)
|
||||
{
|
||||
for (const auto& info : list)
|
||||
{
|
||||
if (!x5d6_24_ && info.GetMaterialLeft().Intersection(testList) == 0)
|
||||
{
|
||||
OrientToSurfaceNormal(info.GetNormalLeft(), 360.f);
|
||||
CPhysicsActor::Stop();
|
||||
SetVelocityWR(zeus::CVector3f::skZero);
|
||||
x742_27_landed = true;
|
||||
x742_28_onGround = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state)
|
||||
{
|
||||
CPhysicsActor::Stop();
|
||||
TelegraphAttack(mgr, EStateMsg::Activate, 0.f);
|
||||
SetMomentumWR({0.f, 0.f, -GetWeight()});
|
||||
CPatterned::Death(mgr, direction, state);
|
||||
}
|
||||
|
||||
void CParasite::Patrol(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x742_26_ = true;
|
||||
x5d6_24_ = true;
|
||||
if (!x5d6_27_ && x5d0_walkerType == EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
SetMomentumWR(zeus::CVector3f::skZero);
|
||||
x5d6_25_ = false;
|
||||
xf8_24_movable = false;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
if (x5bc_ > 0.f)
|
||||
{
|
||||
x5bc_ -= dt;
|
||||
if (x5bc_ <= 0.f)
|
||||
{
|
||||
if (x5d0_walkerType == EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
x5bc_ = 0.f;
|
||||
}
|
||||
}
|
||||
GotoNextWaypoint(mgr);
|
||||
if (x5bc_ <= 0.f && !x5d6_27_)
|
||||
DoFlockingBehavior(mgr);
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
x5d6_24_ = false;
|
||||
xf8_24_movable = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::UpdatePFDestination(CStateManager& mgr)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void CParasite::DoFlockingBehavior(CStateManager& mgr)
|
||||
{
|
||||
zeus::CVector3f upVec = x34_transform.basis[2];
|
||||
rstl::reserved_vector<TUniqueId, 1024> _834;
|
||||
zeus::CAABox aabb(GetTranslation() - x6e4_, GetTranslation() + x6e4_);
|
||||
if (x5d4_ % 6 == 0)
|
||||
{
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
static CMaterialFilter filter = CMaterialFilter::MakeInclude(EMaterialTypes::Character);
|
||||
CParasite* closestParasite = nullptr;
|
||||
float minDistSq = 2.f + x6e8_ * x6e8_;
|
||||
mgr.BuildNearList(nearList, aabb, filter, nullptr);
|
||||
for (TUniqueId id : nearList)
|
||||
{
|
||||
if (CParasite* parasite = CPatterned::CastTo<CParasite>(mgr.ObjectById(id)))
|
||||
{
|
||||
if (parasite != this && parasite->IsAlive())
|
||||
{
|
||||
_834.push_back(parasite->GetUniqueId());
|
||||
float distSq = (parasite->GetTranslation() - GetTranslation()).magSquared();
|
||||
if (distSq < minDistSq)
|
||||
{
|
||||
minDistSq = distSq;
|
||||
closestParasite = parasite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closestParasite && x6ec_ > 0.f && x6e8_ > 0.f)
|
||||
x628_ = x45c_steeringBehaviors.Separation(*this, closestParasite->GetTranslation(), x6e8_) * x604_;
|
||||
else
|
||||
x628_ = zeus::CVector3f::skZero;
|
||||
x634_ = x45c_steeringBehaviors.Cohesion(*this, _834, 0.6f, mgr) * x604_;
|
||||
x640_ = x45c_steeringBehaviors.Alignment(*this, _834, mgr) * x604_;
|
||||
}
|
||||
|
||||
if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x700_ * x700_)
|
||||
{
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
|
||||
x45c_steeringBehaviors.Separation(*this, mgr.GetPlayer().GetTranslation(), x700_), upVec) * x604_,
|
||||
zeus::CVector3f::skZero, x704_));
|
||||
}
|
||||
|
||||
if (x628_ != zeus::CVector3f::skZero)
|
||||
{
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
|
||||
x628_, upVec), zeus::CVector3f::skZero, x6ec_));
|
||||
}
|
||||
|
||||
for (const auto& r : x5d8_doorRepulsors)
|
||||
{
|
||||
if ((r.GetVector() - GetTranslation()).magSquared() < r.GetFloat() * r.GetFloat())
|
||||
{
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
|
||||
x45c_steeringBehaviors.Separation(*this, r.GetVector(), r.GetFloat()) * x604_, upVec),
|
||||
zeus::CVector3f::skZero, 1.f));
|
||||
}
|
||||
}
|
||||
|
||||
if (x608_ <= 0.f)
|
||||
{
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
|
||||
x634_, upVec), zeus::CVector3f::skZero, x6f4_));
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
|
||||
x640_, upVec), zeus::CVector3f::skZero, x6f0_));
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(
|
||||
ProjectVectorToPlane(ProjectVectorToPlane(
|
||||
x45c_steeringBehaviors.Seek(*this, x2e0_destPos), upVec) * x604_, upVec),
|
||||
zeus::CVector3f::skZero, x6f8_));
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(
|
||||
x34_transform.basis[1] * x604_, zeus::CVector3f::skZero, x6fc_));
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::PathFind(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x742_26_ = true;
|
||||
x5d6_24_ = true;
|
||||
if (x5d0_walkerType == EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||
SetMomentumWR(zeus::CVector3f::skZero);
|
||||
xf8_24_movable = false;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
UpdatePFDestination(mgr);
|
||||
DoFlockingBehavior(mgr);
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
xf8_24_movable = true;
|
||||
x5d6_24_ = false;
|
||||
x742_26_ = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x5f8_ = mgr.GetPlayer().GetTranslation() + zeus::CVector3f(0.f, 0.f, 1.5f);
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
x450_bodyController->FaceDirection3D(
|
||||
ProjectVectorToPlane(x5f8_ - GetTranslation(), x34_transform.basis[2]),
|
||||
x34_transform.basis[1], 2.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TUniqueId CParasite::RecursiveFindClosestWayPoint(CStateManager& mgr, TUniqueId id, float& dist)
|
||||
{
|
||||
TUniqueId ret = id;
|
||||
TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(id);
|
||||
if (!wp)
|
||||
return ret;
|
||||
wp->SetActive(false);
|
||||
dist = (wp->GetTranslation() - GetTranslation()).magSquared();
|
||||
for (const auto& conn : wp->GetConnectionList())
|
||||
{
|
||||
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next)
|
||||
{
|
||||
TUniqueId nextId = mgr.GetIdForScript(conn.x8_objId);
|
||||
if (nextId != kInvalidUniqueId)
|
||||
{
|
||||
if (TCastToConstPtr<CScriptWaypoint> wp2 = mgr.GetObjectById(nextId))
|
||||
{
|
||||
if (wp2->GetActive())
|
||||
{
|
||||
float nextDist;
|
||||
TUniqueId closestWp = RecursiveFindClosestWayPoint(mgr, nextId, nextDist);
|
||||
if (nextDist < dist)
|
||||
{
|
||||
dist = nextDist;
|
||||
ret = closestWp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
wp->SetActive(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
TUniqueId CParasite::GetClosestWaypointForState(EScriptObjectState state, CStateManager& mgr)
|
||||
{
|
||||
float minDist = FLT_MAX;
|
||||
TUniqueId ret = kInvalidUniqueId;
|
||||
for (const auto& conn : GetConnectionList())
|
||||
{
|
||||
if (conn.x0_state == state && conn.x4_msg == EScriptObjectMessage::Follow)
|
||||
{
|
||||
TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
|
||||
float dist;
|
||||
TUniqueId closestWp = RecursiveFindClosestWayPoint(mgr, id, dist);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
ret = closestWp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CParasite::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
SetMomentumWR(zeus::CVector3f::skZero);
|
||||
TUniqueId wpId = GetClosestWaypointForState(EScriptObjectState::Patrol, mgr);
|
||||
if (wpId != kInvalidUniqueId)
|
||||
x2dc_destObj = wpId;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Halt(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x330_stateMachineState.SetDelay(x710_);
|
||||
x32c_animState = EAnimState::One;
|
||||
x743_24_ = true;
|
||||
x5d6_24_ = true;
|
||||
if (x5d0_walkerType == EWalkerType::Geemer)
|
||||
CSfxManager::AddEmitter(x73c_haltSfx, GetTranslation(), zeus::CVector3f::skZero,
|
||||
true, false, 0x7f, kInvalidAreaId);
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
TryCommand(mgr, pas::EAnimationState::LoopReaction, &CPatterned::TryLoopReaction, 1);
|
||||
x400_24_hitByPlayerProjectile = false;
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
|
||||
x32c_animState = EAnimState::Zero;
|
||||
x743_24_ = false;
|
||||
x5d6_24_ = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Run(CStateManager&, EStateMsg, float)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void CParasite::Generate(CStateManager&, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x5e8_ = 0;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
switch (x5e8_)
|
||||
{
|
||||
case 0:
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
|
||||
x5e8_ = 1;
|
||||
else
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero));
|
||||
break;
|
||||
case 1:
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
|
||||
x5e8_ = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Deactivate(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x5e8_ = 0;
|
||||
SendScriptMsgs(EScriptObjectState::UNKS2, mgr, EScriptObjectMessage::None);
|
||||
mgr.FreeScriptObject(GetUniqueId());
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
if (x5e8_ == 0)
|
||||
{
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
|
||||
x5e8_ = 1;
|
||||
else
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::One));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Attack(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
x608_ = 0.f;
|
||||
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed)
|
||||
{
|
||||
float rz = mgr.GetActiveRandom()->Float();
|
||||
float ry = mgr.GetActiveRandom()->Float();
|
||||
float rx = mgr.GetActiveRandom()->Float();
|
||||
x5f8_ = (zeus::CVector3f(rx, ry, rz) - 0.5f) * 0.5f + mgr.GetPlayer().GetTranslation();
|
||||
}
|
||||
else
|
||||
{
|
||||
float rz = mgr.GetActiveRandom()->Float();
|
||||
float ry = mgr.GetActiveRandom()->Float();
|
||||
float rx = mgr.GetActiveRandom()->Float();
|
||||
x5f8_ = (zeus::CVector3f(rx, ry, rz) + mgr.GetPlayer().GetTranslation() - GetTranslation())
|
||||
.normalized() * 15.f + GetTranslation();
|
||||
}
|
||||
FaceTarget(x5f8_);
|
||||
x5e8_ = 0;
|
||||
x742_30_attackOver = false;
|
||||
x742_24_ = false;
|
||||
x742_28_onGround = false;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
switch (x5e8_)
|
||||
{
|
||||
case 0:
|
||||
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Jump)
|
||||
{
|
||||
x5e8_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x742_25_jumpVelDirty = true;
|
||||
FaceTarget(x5f8_);
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_, pas::EJumpType::Normal));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
x742_28_onGround = true;
|
||||
x742_30_attackOver = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Crouch(CStateManager&, EStateMsg msg, float)
|
||||
{
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
|
||||
if (x5d0_walkerType == EWalkerType::Geemer)
|
||||
CSfxManager::AddEmitter(x740_crouchSfx, GetTranslation(), zeus::CVector3f::skZero,
|
||||
true, false, 0x7f, kInvalidAreaId);
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::GetUp(CStateManager&, EStateMsg msg, float)
|
||||
{
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
if (x5d0_walkerType == EWalkerType::Geemer)
|
||||
CSfxManager::AddEmitter(x73e_getUpSfx, GetTranslation(), zeus::CVector3f::skZero,
|
||||
true, false, 0x7f, kInvalidAreaId);
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
for (auto it = mgr.GetParasiteTelegraphs().begin(); it != mgr.GetParasiteTelegraphs().end();)
|
||||
{
|
||||
CParasite* other = CPatterned::CastTo<CParasite>(mgr.ObjectById(*it));
|
||||
if (!other)
|
||||
{
|
||||
it = mgr.GetParasiteTelegraphs().erase(it);
|
||||
continue;
|
||||
}
|
||||
if (other != this && other->IsAlive() &&
|
||||
(other->GetTranslation() - GetTranslation()).magSquared() < x6d0_ * x6d0_)
|
||||
{
|
||||
other->x742_24_ = true;
|
||||
other->x608_ = mgr.GetActiveRandom()->Float() * 0.5f + 0.5f;
|
||||
other->x5f8_ = GetTranslation();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
x400_24_hitByPlayerProjectile = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::Jump(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
AddMaterial(EMaterialTypes::GroundCollider, mgr);
|
||||
SetMomentumWR({0.f, 0.f, -GetWeight()});
|
||||
x742_28_onGround = false;
|
||||
x5d6_24_ = false;
|
||||
x742_27_landed = false;
|
||||
x743_27_inJump = true;
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
SetMomentumWR({0.f, 0.f, -GetWeight()});
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
RemoveMaterial(EMaterialTypes::GroundCollider, mgr);
|
||||
SetMomentumWR(zeus::CVector3f::skZero);
|
||||
x742_28_onGround = true;
|
||||
x742_27_landed = false;
|
||||
x743_27_inJump = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CParasite::FaceTarget(const zeus::CVector3f& target)
|
||||
{
|
||||
zeus::CQuaternion q =
|
||||
zeus::CQuaternion::lookAt(zeus::CTransform::Identity().basis[1],
|
||||
target - GetTranslation(), zeus::degToRad(360.f));
|
||||
SetTransform(q.toTransform(GetTranslation()));
|
||||
}
|
||||
|
||||
void CParasite::Retreat(CStateManager& mgr, EStateMsg msg, float)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EStateMsg::Activate:
|
||||
{
|
||||
zeus::CVector3f dir = mgr.GetPlayer().GetTranslation() - GetTranslation();
|
||||
dir.z = 0.f;
|
||||
if (dir.canBeNormalized())
|
||||
dir.normalize();
|
||||
else
|
||||
dir = mgr.GetPlayer().GetTransform().basis[1];
|
||||
x5f8_ = GetTranslation() - dir * 3.f;
|
||||
FaceTarget(x5f8_);
|
||||
x5e8_ = 0;
|
||||
x742_27_landed = false;
|
||||
x742_28_onGround = false;
|
||||
x742_25_jumpVelDirty = true;
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_, pas::EJumpType::One));
|
||||
break;
|
||||
}
|
||||
case EStateMsg::Update:
|
||||
x3b4_speed = 1.f;
|
||||
break;
|
||||
case EStateMsg::Deactivate:
|
||||
x742_28_onGround = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CParasite::AnimOver(CStateManager&, float)
|
||||
{
|
||||
return x5e8_ == 2;
|
||||
}
|
||||
|
||||
bool CParasite::ShouldAttack(CStateManager& mgr, float arg)
|
||||
{
|
||||
bool shouldAttack = false;
|
||||
if (x742_24_ && x608_ > 0.1f)
|
||||
shouldAttack = true;
|
||||
if (!TooClose(mgr, arg) && InMaxRange(mgr, arg))
|
||||
return shouldAttack || InDetectionRange(mgr, 0.f);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CParasite::CloseToWall(CStateManager& mgr)
|
||||
{
|
||||
static CMaterialFilter filter = CMaterialFilter::MakeInclude(EMaterialTypes::Solid);
|
||||
zeus::CAABox aabb = CPhysicsActor::GetBoundingBox();
|
||||
float margin = x590_colSphere.GetSphere().radius + x5b0_collisionCloseMargin;
|
||||
aabb.min -= zeus::CVector3f(margin);
|
||||
aabb.max += zeus::CVector3f(margin);
|
||||
CCollidableAABox cAABB(aabb, x68_material);
|
||||
return CGameCollision::DetectStaticCollisionBoolean(mgr, cAABB, {}, filter);
|
||||
}
|
||||
|
||||
bool CParasite::HitSomething(CStateManager& mgr, float)
|
||||
{
|
||||
if (x5d4_ & 0x1)
|
||||
return true;
|
||||
return x5b8_ < 270.f && CloseToWall(mgr);
|
||||
}
|
||||
|
||||
bool CParasite::Stuck(CStateManager&, float)
|
||||
{
|
||||
return x60c_ > x6e0_;
|
||||
}
|
||||
|
||||
bool CParasite::Landed(CStateManager&, float)
|
||||
{
|
||||
return x742_27_landed;
|
||||
}
|
||||
|
||||
bool CParasite::AttackOver(CStateManager&, float)
|
||||
{
|
||||
return x742_30_attackOver;
|
||||
}
|
||||
|
||||
bool CParasite::ShotAt(CStateManager&, float)
|
||||
{
|
||||
if (x5d0_walkerType != EWalkerType::Oculus)
|
||||
return x400_24_hitByPlayerProjectile;
|
||||
return x743_26_oculusShotAt;
|
||||
}
|
||||
|
||||
void CParasite::MassiveDeath(CStateManager& mgr)
|
||||
{
|
||||
CPatterned::MassiveDeath(mgr);
|
||||
}
|
||||
|
||||
void CParasite::MassiveFrozenDeath(CStateManager& mgr)
|
||||
{
|
||||
CPatterned::MassiveFrozenDeath(mgr);
|
||||
}
|
||||
|
||||
void CParasite::ThinkAboutMove(float dt)
|
||||
{
|
||||
if (!x68_material.HasMaterial(EMaterialTypes::GroundCollider))
|
||||
CPatterned::ThinkAboutMove(dt);
|
||||
}
|
||||
|
||||
bool CParasite::IsOnGround() const
|
||||
{
|
||||
return x742_28_onGround;
|
||||
}
|
||||
|
||||
void CParasite::UpdateWalkerAnimation(CStateManager& mgr, float dt)
|
||||
{
|
||||
CActor::UpdateAnimation(dt, mgr, true);
|
||||
}
|
||||
|
||||
void CParasite::DestroyActorManager(CStateManager& mgr)
|
||||
|
@ -214,12 +850,10 @@ void CParasite::DestroyActorManager(CStateManager& mgr)
|
|||
|
||||
void CParasite::UpdateJumpVelocity()
|
||||
{
|
||||
x150_momentum.x = 0;
|
||||
x150_momentum.y = 0;
|
||||
x150_momentum.z = -GetWeight();
|
||||
SetMomentumWR({0.f, 0.f, -GetWeight()});
|
||||
zeus::CVector3f vec;
|
||||
|
||||
if (!x742_30_)
|
||||
if (!x742_30_attackOver)
|
||||
{
|
||||
vec = skAttackVelocity * GetTransform().frontVector();
|
||||
vec.z = 0.5f * skRetreatVelocity;
|
||||
|
@ -231,10 +865,8 @@ void CParasite::UpdateJumpVelocity()
|
|||
}
|
||||
|
||||
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;
|
||||
float f31 = x5f8_.z - GetTranslation().z;
|
||||
zeus::CVector3f vec2 = x5f8_ - GetTranslation();
|
||||
vec2.z = 0.f;
|
||||
float f29 = vec2.magnitude();
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ class CParasite : public CWallWalker
|
|||
{
|
||||
class CRepulsor
|
||||
{
|
||||
zeus::CVector3f x0_v;
|
||||
float xc_f;
|
||||
public:
|
||||
CRepulsor(const zeus::CVector3f& v, float f) : x0_v(v), xc_f(f) {}
|
||||
const zeus::CVector3f& GetVector() const { return x0_v; }
|
||||
float GetFloat() const { return xc_f; }
|
||||
};
|
||||
static const float flt_805A8FB0;
|
||||
static const float skAttackVelocity;
|
||||
|
@ -24,23 +30,16 @@ class CParasite : public CWallWalker
|
|||
float x5ec_ = 0.f;
|
||||
float x5f0_ = 0.f;
|
||||
float x5f4_ = 0.f;
|
||||
float x5f8_ = 0.f;
|
||||
float x5fc_ = 0.f;
|
||||
float x600_ = 0.f;
|
||||
zeus::CVector3f x5f8_;
|
||||
float x604_ = 1.f;
|
||||
float x608_ = 0.f;
|
||||
float x60c_ = 0.f;
|
||||
zeus::CVector3f x614_;
|
||||
std::unique_ptr<CCollisionActorManager> x620_ = 0;
|
||||
u32 x624_ = 0;
|
||||
float x628_ = 0.f;
|
||||
float x62c_ = 0.f;
|
||||
float x630_ = 0.f;
|
||||
float x634_ = 0.f;
|
||||
float x638_ = 0.f;
|
||||
float x640_ = 0.f;
|
||||
float x644_ = 0.f;
|
||||
float x648_ = 0.f;
|
||||
TLockedToken<CSkinnedModel> x624_extraModel;
|
||||
zeus::CVector3f x628_;
|
||||
zeus::CVector3f x634_;
|
||||
zeus::CVector3f x640_;
|
||||
CDamageVulnerability x64c_;
|
||||
CDamageInfo x6b4_;
|
||||
float x6d0_;
|
||||
|
@ -68,46 +67,85 @@ class CParasite : public CWallWalker
|
|||
float x730_ = 0.f;
|
||||
float x734_ = 0.f;
|
||||
float x738_ = 0.f;
|
||||
s16 x73c_;
|
||||
s16 x73e_;
|
||||
s16 x740_;
|
||||
u16 x73c_haltSfx;
|
||||
u16 x73e_getUpSfx;
|
||||
u16 x740_crouchSfx;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x742_24_ : 1;
|
||||
bool x742_25_ : 1;
|
||||
bool x742_25_jumpVelDirty : 1;
|
||||
bool x742_26_ : 1;
|
||||
bool x742_27_ : 1;
|
||||
bool x742_28_ : 1;
|
||||
bool x742_27_landed : 1;
|
||||
bool x742_28_onGround : 1;
|
||||
bool x742_29_ : 1;
|
||||
bool x742_30_ : 1;
|
||||
bool x742_30_attackOver : 1;
|
||||
bool x742_31_ : 1;
|
||||
bool x743_24_ : 1;
|
||||
bool x743_25_ : 1;
|
||||
bool x743_26_ : 1;
|
||||
bool x743_27_ : 1;
|
||||
bool x743_26_oculusShotAt : 1;
|
||||
bool x743_27_inJump : 1;
|
||||
};
|
||||
u16 _dummy = 0;
|
||||
};
|
||||
bool CloseToWall(CStateManager& mgr);
|
||||
void FaceTarget(const zeus::CVector3f& target);
|
||||
TUniqueId RecursiveFindClosestWayPoint(CStateManager& mgr, TUniqueId id, float& dist);
|
||||
TUniqueId GetClosestWaypointForState(EScriptObjectState state, CStateManager& mgr);
|
||||
void UpdatePFDestination(CStateManager& mgr);
|
||||
void DoFlockingBehavior(CStateManager& mgr);
|
||||
public:
|
||||
DEFINE_PATTERNED(Parasite)
|
||||
CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
|
||||
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo&, EBodyType, float, float, float,
|
||||
float, float, float, float, float, float, float, float, float, float, float, float, float, float, float,
|
||||
bool, u32, const CDamageVulnerability&, const CDamageInfo&, u16, u16, u16, u32, u32, float,
|
||||
bool, EWalkerType wType, const CDamageVulnerability&, const CDamageInfo&, u16, u16, u16, CAssetId, CAssetId, float,
|
||||
const CActorParameters&);
|
||||
|
||||
void Accept(IVisitor&);
|
||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||
void PreThink(float, CStateManager&);
|
||||
void Think(float dt, CStateManager& mgr);
|
||||
void Render(const CStateManager&) const;
|
||||
const CDamageVulnerability* GetDamageVulnerability() const;
|
||||
void Touch(CActor& actor, CStateManager&);
|
||||
zeus::CVector3f GetAimPosition(const CStateManager&, float) const;
|
||||
void CollidedWith(TUniqueId uid, const CCollisionInfoList&, CStateManager&);
|
||||
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state);
|
||||
void Patrol(CStateManager&, EStateMsg msg, float dt);
|
||||
void PathFind(CStateManager&, EStateMsg msg, float dt);
|
||||
void TargetPlayer(CStateManager&, EStateMsg msg, float dt);
|
||||
void TargetPatrol(CStateManager&, EStateMsg msg, float dt);
|
||||
void Halt(CStateManager&, EStateMsg, float);
|
||||
void Run(CStateManager&, EStateMsg, float);
|
||||
void Generate(CStateManager&, EStateMsg, float);
|
||||
void Deactivate(CStateManager&, EStateMsg, float);
|
||||
void Attack(CStateManager&, EStateMsg, float);
|
||||
void Crouch(CStateManager&, EStateMsg, float);
|
||||
void GetUp(CStateManager&, EStateMsg, float);
|
||||
void TelegraphAttack(CStateManager&, EStateMsg, float);
|
||||
void Jump(CStateManager&, EStateMsg, float);
|
||||
void Retreat(CStateManager&, EStateMsg, float);
|
||||
bool AnimOver(CStateManager&, float);
|
||||
bool ShouldAttack(CStateManager&, float);
|
||||
bool HitSomething(CStateManager&, float);
|
||||
bool Stuck(CStateManager&, float);
|
||||
bool Landed(CStateManager&, float);
|
||||
bool AttackOver(CStateManager&, float);
|
||||
bool ShotAt(CStateManager&, float);
|
||||
void MassiveDeath(CStateManager&);
|
||||
void MassiveFrozenDeath(CStateManager&);
|
||||
void ThinkAboutMove(float);
|
||||
bool IsOnGround() const;
|
||||
virtual void UpdateWalkerAnimation(CStateManager&, float);
|
||||
|
||||
void DestroyActorManager(CStateManager& mgr);
|
||||
void UpdateJumpVelocity();
|
||||
void UpdateCollisionActors(CStateManager&) {}
|
||||
CDamageInfo GetContactDamage() const
|
||||
{
|
||||
if (x5d0_ == 1 && x743_24_)
|
||||
if (x5d0_walkerType == EWalkerType::Oculus && x743_24_)
|
||||
return x6b4_;
|
||||
return CPatterned::GetContactDamage();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ CSeedling::CSeedling(TUniqueId uid, std::string_view name, const CEntityInfo& in
|
|||
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, float f1, float f2, float f3, float f4)
|
||||
: CWallWalker(ECharacter::Seedling, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Ground, EColliderType::Zero, EBodyType::WallWalker, actParms, f1, f2,
|
||||
EKnockBackVariant::Small, f3, 4, f4, false)
|
||||
EKnockBackVariant::Small, f3, EWalkerType::Seedling, f4, false)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ public:
|
|||
virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info,
|
||||
EKnockBackType type, bool inDeferred, float magnitude)=0;
|
||||
virtual const CDamageVulnerability* GetDamageVulnerability() const { return &x260_damageVulnerability; }
|
||||
virtual const CDamageVulnerability* GetDamageVulnerability() { return &x260_damageVulnerability; }
|
||||
virtual void TakeDamage(const zeus::CVector3f& direction, float magnitude) {}
|
||||
virtual bool CanBeShot(const CStateManager&, int) { return true; }
|
||||
virtual bool IsListening() const { return false; }
|
||||
|
|
|
@ -485,7 +485,7 @@ void CKnockBackController::ValidateState(CPatterned& parent)
|
|||
if (disableFollowup)
|
||||
{
|
||||
x4_activeParms.x4_animFollowup = EKnockBackAnimationFollowUp::None;
|
||||
x4_activeParms.x8_followupMagnitude = 0.f;
|
||||
x4_activeParms.x8_followupDuration = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,8 @@ public:
|
|||
{
|
||||
EKnockBackAnimationState x0_animState;
|
||||
EKnockBackAnimationFollowUp x4_animFollowup;
|
||||
float x8_followupMagnitude;
|
||||
float xc_;
|
||||
float x8_followupDuration;
|
||||
float xc_intoFreezeDur;
|
||||
};
|
||||
private:
|
||||
friend class CPatterned;
|
||||
|
@ -149,6 +149,12 @@ public:
|
|||
void KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, CPatterned& parent,
|
||||
const CDamageInfo& info, EKnockBackType type, float magnitude);
|
||||
void SetEnableFreeze(bool b) { x81_25_enableFreeze = b; }
|
||||
void SetEnableShock(bool b) { x81_26_enableShock = b; }
|
||||
void SetEnableBurn(bool b) { x81_27_enableBurn = b; }
|
||||
void SetEnableBurnDeath(bool b) { x81_28_enableBurnDeath = b; }
|
||||
void SetEnableExplodeDeath(bool b) { x81_29_enableExplodeDeath = b; }
|
||||
void SetEnableLaggedBurnDeath(bool b) { x81_30_enableLaggedBurnDeath = b; }
|
||||
void SetX82_24(bool b) { x82_24_ = b; }
|
||||
const KnockBackParms& GetActiveParms() const { return x4_activeParms; }
|
||||
EKnockBackVariant GetVariant() const { return x0_variant; }
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Character/CAnimData.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "MP1/World/CSpacePirate.hpp"
|
||||
#include "MP1/World/CMetroid.hpp"
|
||||
#include "World/CStateMachine.hpp"
|
||||
#include "CExplosion.hpp"
|
||||
#include "Graphics/CSkinnedModel.hpp"
|
||||
|
@ -419,6 +420,17 @@ zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float
|
|||
return offset + GetBoundingBox().center();
|
||||
}
|
||||
|
||||
zeus::CTransform CPatterned::GetLctrTransform(std::string_view name) const
|
||||
{
|
||||
return x34_transform * GetScaledLocatorTransform(name);
|
||||
}
|
||||
|
||||
zeus::CTransform CPatterned::GetLctrTransform(CSegId id) const
|
||||
{
|
||||
zeus::CTransform xf = x64_modelData->GetAnimationData()->GetLocatorTransform(id, nullptr);
|
||||
return x34_transform * zeus::CTransform(xf.buildMatrix3f(), x64_modelData->GetScale() * xf.origin);
|
||||
}
|
||||
|
||||
void CPatterned::DeathDelete(CStateManager& mgr)
|
||||
{
|
||||
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
|
||||
|
@ -487,27 +499,27 @@ void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, c
|
|||
if (!x401_27_phazingOut && !x401_28_burning && hInfo)
|
||||
{
|
||||
x460_knockBackController.KnockBack(backVec, mgr, *this, info, type, magnitude);
|
||||
if (x450_bodyController->IsFrozen() && x460_knockBackController.GetActiveParms().xc_ >= 0.f)
|
||||
if (x450_bodyController->IsFrozen() && x460_knockBackController.GetActiveParms().xc_intoFreezeDur >= 0.f)
|
||||
x450_bodyController->FrozenBreakout();
|
||||
switch (x460_knockBackController.GetActiveParms().x4_animFollowup)
|
||||
{
|
||||
case EKnockBackAnimationFollowUp::Freeze:
|
||||
Freeze(mgr, zeus::CVector3f::skZero, zeus::CUnitVector3f(x34_transform.transposeRotate(backVec)),
|
||||
x460_knockBackController.GetActiveParms().x8_followupMagnitude);
|
||||
x460_knockBackController.GetActiveParms().x8_followupDuration);
|
||||
break;
|
||||
case EKnockBackAnimationFollowUp::PhazeOut:
|
||||
PhazeOut(mgr);
|
||||
break;
|
||||
case EKnockBackAnimationFollowUp::Shock:
|
||||
Shock(x460_knockBackController.GetActiveParms().x8_followupMagnitude, -1.f);
|
||||
Shock(x460_knockBackController.GetActiveParms().x8_followupDuration, -1.f);
|
||||
break;
|
||||
case EKnockBackAnimationFollowUp::Burn:
|
||||
Burn(x460_knockBackController.GetActiveParms().x8_followupMagnitude, 0.25f);
|
||||
Burn(x460_knockBackController.GetActiveParms().x8_followupDuration, 0.25f);
|
||||
break;
|
||||
case EKnockBackAnimationFollowUp::LaggedBurnDeath:
|
||||
x401_29_laggedBurnDeath = true;
|
||||
case EKnockBackAnimationFollowUp::BurnDeath:
|
||||
Burn(x460_knockBackController.GetActiveParms().x8_followupMagnitude, -1.f);
|
||||
Burn(x460_knockBackController.GetActiveParms().x8_followupDuration, -1.f);
|
||||
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
|
||||
x400_28_pendingMassiveDeath = x400_29_pendingMassiveFrozenDeath = false;
|
||||
x400_27_fadeToDeath = x401_28_burning = true;
|
||||
|
@ -561,7 +573,7 @@ bool CPatterned::Random(CStateManager&, float arg)
|
|||
|
||||
bool CPatterned::CodeTrigger(CStateManager&, float arg)
|
||||
{
|
||||
return x330_stateMachineState.x18_24_;
|
||||
return x330_stateMachineState.x18_24_codeTrigger;
|
||||
}
|
||||
|
||||
bool CPatterned::FixedDelay(CStateManager&, float arg)
|
||||
|
@ -779,7 +791,7 @@ bool CPatterned::OffLine(CStateManager&, float arg)
|
|||
return distSq > arg * arg;
|
||||
}
|
||||
|
||||
void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
if (CPathFindSearch* search = GetSearchPath())
|
||||
{
|
||||
|
@ -826,7 +838,7 @@ void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::Dead(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::Dead(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
|
@ -852,7 +864,7 @@ void CPatterned::Dead(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
|
@ -863,7 +875,7 @@ void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::TargetPatrol(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
if (msg == EStateMsg::Activate)
|
||||
{
|
||||
|
@ -875,7 +887,7 @@ void CPatterned::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
|
@ -923,7 +935,7 @@ void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||
void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float dt)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
|
@ -992,6 +1004,22 @@ void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float arg)
|
|||
}
|
||||
}
|
||||
|
||||
void CPatterned::TryCommand(CStateManager& mgr, pas::EAnimationState state,
|
||||
CPatternedTryFunc func, int arg)
|
||||
{
|
||||
if (state == x450_bodyController->GetCurrentStateId())
|
||||
x32c_animState = EAnimState::Repeat;
|
||||
else if (x32c_animState == EAnimState::One)
|
||||
(this->*func)(mgr, arg);
|
||||
else
|
||||
x32c_animState = EAnimState::Over;
|
||||
}
|
||||
|
||||
void CPatterned::TryLoopReaction(CStateManager& mgr, int arg)
|
||||
{
|
||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLoopReactionCmd(pas::EReactionType(arg)));
|
||||
}
|
||||
|
||||
void CPatterned::BuildBodyController(EBodyType bodyType)
|
||||
{
|
||||
if (x450_bodyController)
|
||||
|
@ -1067,6 +1095,75 @@ void CPatterned::MassiveFrozenDeath(CStateManager& mgr)
|
|||
x400_28_pendingMassiveDeath = x400_29_pendingMassiveFrozenDeath = false;
|
||||
}
|
||||
|
||||
void CPatterned::Burn(float duration, float damage)
|
||||
{
|
||||
switch (GetDamageVulnerability()->GetVulnerability(CWeaponMode(EWeaponType::Plasma), false))
|
||||
{
|
||||
case EVulnerability::DoubleDamage:
|
||||
x450_bodyController->SetOnFire(1.5f * duration);
|
||||
x3ec_pendingFireDamage = 1.5f * damage;
|
||||
break;
|
||||
case EVulnerability::Normal:
|
||||
x450_bodyController->SetOnFire(duration);
|
||||
x3ec_pendingFireDamage = damage;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CPatterned::Shock(float duration, float damage)
|
||||
{
|
||||
switch (GetDamageVulnerability()->GetVulnerability(CWeaponMode(EWeaponType::Wave), false))
|
||||
{
|
||||
case EVulnerability::DoubleDamage:
|
||||
x450_bodyController->SetElectrocuting(1.5f * duration);
|
||||
x3f0_pendingShockDamage = 1.5f * damage;
|
||||
break;
|
||||
case EVulnerability::Normal:
|
||||
x450_bodyController->SetElectrocuting(duration);
|
||||
x3f0_pendingShockDamage = damage;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CPatterned::Freeze(CStateManager& mgr, const zeus::CVector3f& pos,
|
||||
const zeus::CUnitVector3f& dir, float frozenDur)
|
||||
{
|
||||
if (x402_25_lostMassiveFrozenHP)
|
||||
x402_26_dieIf80PercFrozen = true;
|
||||
bool playSfx = false;
|
||||
if (x450_bodyController->IsFrozen())
|
||||
{
|
||||
x450_bodyController->Freeze(x460_knockBackController.GetActiveParms().xc_intoFreezeDur,
|
||||
frozenDur, x4f8_outofFreezeDur);
|
||||
mgr.GetActorModelParticles()->EnsureElectricLoaded(*this);
|
||||
playSfx = true;
|
||||
}
|
||||
else if (!x450_bodyController->IsElectrocuting() &&
|
||||
!x450_bodyController->IsOnFire())
|
||||
{
|
||||
x450_bodyController->Freeze(x4f4_intoFreezeDur, frozenDur, x4f8_outofFreezeDur);
|
||||
if (x510_vertexMorph)
|
||||
x510_vertexMorph->Reset(dir, pos, x4f4_intoFreezeDur);
|
||||
playSfx = true;
|
||||
}
|
||||
|
||||
if (playSfx)
|
||||
{
|
||||
u16 sfx;
|
||||
if (x460_knockBackController.GetVariant() != EKnockBackVariant::Small &&
|
||||
CPatterned::CastTo<MP1::CMetroid>(mgr.GetObjectById(GetUniqueId())))
|
||||
sfx = SFXsfx0701;
|
||||
else
|
||||
sfx = SFXsfx0708;
|
||||
CSfxManager::AddEmitter(sfx, GetTranslation(), zeus::CVector3f::skZero,
|
||||
true, false, 0x7f, kInvalidAreaId);
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CVector3f CPatterned::GetGunEyePos() const
|
||||
{
|
||||
zeus::CVector3f origin = GetOrigin();
|
||||
|
@ -1684,4 +1781,13 @@ void CPatterned::ThinkAboutMove(float dt)
|
|||
|
||||
RotateToOR(x440_rotDelta, dt);
|
||||
}
|
||||
|
||||
void CPatterned::PhazeOut(CStateManager& mgr)
|
||||
{
|
||||
if (!x400_27_fadeToDeath)
|
||||
SendScriptMsgs(EScriptObjectState::DeathRattle, mgr, EScriptObjectMessage::None);
|
||||
x401_27_phazingOut = true;
|
||||
x450_bodyController->SetPlaybackRate(0.f);
|
||||
x64_modelData->AnimationData()->GetParticleDB().SetUpdatesEnabled(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace urde
|
|||
class CPatternedInfo;
|
||||
class CProjectileInfo;
|
||||
class CPathFindSearch;
|
||||
typedef void (CPatterned::*CPatternedTryFunc)(CStateManager&, int);
|
||||
|
||||
class CPatterned : public CAi
|
||||
{
|
||||
|
@ -133,7 +134,7 @@ public:
|
|||
{
|
||||
Zero,
|
||||
One,
|
||||
Two,
|
||||
Repeat,
|
||||
Over
|
||||
};
|
||||
class CPatternNode
|
||||
|
@ -327,6 +328,8 @@ public:
|
|||
return GetAimPosition(mgr, 0.f);
|
||||
}
|
||||
zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const;
|
||||
zeus::CTransform GetLctrTransform(std::string_view name) const;
|
||||
zeus::CTransform GetLctrTransform(CSegId id) const;
|
||||
|
||||
void DeathDelete(CStateManager& mgr);
|
||||
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state);
|
||||
|
@ -363,21 +366,24 @@ public:
|
|||
bool InRange(CStateManager&, float arg);
|
||||
bool OffLine(CStateManager&, float arg);
|
||||
bool Default(CStateManager&, float arg) { return true; }
|
||||
void PathFind(CStateManager&, EStateMsg msg, float arg);
|
||||
void Dead(CStateManager&, EStateMsg msg, float arg);
|
||||
void TargetPlayer(CStateManager&, EStateMsg msg, float arg);
|
||||
void TargetPatrol(CStateManager&, EStateMsg msg, float arg);
|
||||
void FollowPattern(CStateManager&, EStateMsg msg, float arg);
|
||||
void Patrol(CStateManager&, EStateMsg msg, float arg);
|
||||
void Start(CStateManager&, EStateMsg msg, float arg) {}
|
||||
void PathFind(CStateManager&, EStateMsg msg, float dt);
|
||||
void Dead(CStateManager&, EStateMsg msg, float dt);
|
||||
void TargetPlayer(CStateManager&, EStateMsg msg, float dt);
|
||||
void TargetPatrol(CStateManager&, EStateMsg msg, float dt);
|
||||
void FollowPattern(CStateManager&, EStateMsg msg, float dt);
|
||||
void Patrol(CStateManager&, EStateMsg msg, float dt);
|
||||
void Start(CStateManager&, EStateMsg msg, float dt) {}
|
||||
|
||||
void TryCommand(CStateManager& mgr, pas::EAnimationState state, CPatternedTryFunc func, int arg);
|
||||
void TryLoopReaction(CStateManager& mgr, int arg);
|
||||
|
||||
virtual bool KnockbackWhenFrozen() const { return true; }
|
||||
virtual void MassiveDeath(CStateManager& mgr);
|
||||
virtual void MassiveFrozenDeath(CStateManager& mgr);
|
||||
virtual void Burn(float, float) {}
|
||||
virtual void Shock(float, float) {}
|
||||
virtual void Burn(float, float);
|
||||
virtual void Shock(float, float);
|
||||
virtual void Freeze(CStateManager& mgr, const zeus::CVector3f& pos,
|
||||
const zeus::CUnitVector3f& dir, float magnitude) {}
|
||||
const zeus::CUnitVector3f& dir, float frozenDur);
|
||||
virtual void ThinkAboutMove(float);
|
||||
virtual CPathFindSearch* GetSearchPath() { return nullptr; }
|
||||
virtual CDamageInfo GetContactDamage() const { return x404_contactDamage; }
|
||||
|
@ -385,7 +391,7 @@ public:
|
|||
virtual bool IsOnGround() const { return x328_27_onGround; }
|
||||
virtual float GetGravityConstant() const { return 24.525002f; }
|
||||
virtual CProjectileInfo* GetProjectileInfo() { return nullptr; }
|
||||
virtual void PhazeOut(CStateManager&) {}
|
||||
virtual void PhazeOut(CStateManager&);
|
||||
virtual const std::experimental::optional<TLockedToken<CGenDescription>>&
|
||||
GetDeathExplosionParticle() const { return x520_deathExplosionParticle; }
|
||||
float GetDamageDuration() const { return x504_damageDur; }
|
||||
|
|
|
@ -61,7 +61,7 @@ CStateMachine::CStateMachine(CInputStream& in)
|
|||
|
||||
s32 CStateMachine::GetStateIndex(std::string_view state) const
|
||||
{
|
||||
auto it = std::find_if(x0_states.begin(), x0_states.end(), [&state](const CAiState& st) {
|
||||
auto it = std::find_if(x0_states.begin(), x0_states.end(), [state](const CAiState& st) {
|
||||
return (strncmp(st.GetName(), state.data(), 31) == 0);
|
||||
});
|
||||
if (it == x0_states.end())
|
||||
|
@ -96,7 +96,7 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta)
|
|||
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
|
||||
x4_state = state;
|
||||
x8_time = 0.f;
|
||||
x18_24_ = false;
|
||||
x18_24_codeTrigger = false;
|
||||
xc_random = mgr.GetActiveRandom()->Float();
|
||||
x4_state->CallFunc(mgr, ai, EStateMsg::Activate, delta);
|
||||
return;
|
||||
|
@ -115,7 +115,7 @@ void CStateMachineState::SetState(CStateManager& mgr, CAi& ai, s32 idx)
|
|||
x4_state = state;
|
||||
x8_time = 0.f;
|
||||
xc_random = mgr.GetActiveRandom()->Float();
|
||||
x18_24_ = false;
|
||||
x18_24_codeTrigger = false;
|
||||
x4_state->CallFunc(mgr, ai, EStateMsg::Activate, 0.f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,14 +51,14 @@ class CAiState
|
|||
{
|
||||
friend class CStateMachineState;
|
||||
CAiStateFunc x0_func;
|
||||
char xc_name[32];
|
||||
char xc_name[32] = {};
|
||||
u32 x2c_numTriggers;
|
||||
CAiTrigger* x30_firstTrigger;
|
||||
public:
|
||||
CAiState(CAiStateFunc func, const char* name)
|
||||
{
|
||||
x0_func = func;
|
||||
strncpy(xc_name, name, 32);
|
||||
strncpy(xc_name, name, 31);
|
||||
}
|
||||
|
||||
s32 GetNumTriggers() const { return x2c_numTriggers; }
|
||||
|
@ -97,7 +97,7 @@ class CStateMachineState
|
|||
{
|
||||
struct
|
||||
{
|
||||
bool x18_24_ : 1;
|
||||
bool x18_24_codeTrigger : 1;
|
||||
};
|
||||
u32 dummy = 0;
|
||||
};
|
||||
|
|
|
@ -9,16 +9,16 @@ namespace urde
|
|||
CWallWalker::CWallWalker(ECharacter chr, TUniqueId uid, std::string_view name, EFlavorType flavType,
|
||||
const CEntityInfo& eInfo, const zeus::CTransform& xf,
|
||||
CModelData&& mData, const CPatternedInfo& pInfo, EMovementType mType,
|
||||
EColliderType colType, EBodyType bType, const CActorParameters& aParms, float f1, float f2,
|
||||
EKnockBackVariant w1, float f3, u32 w2, float f4, bool b1)
|
||||
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, w1)
|
||||
EColliderType colType, EBodyType bType, const CActorParameters& aParms,
|
||||
float f1, float f2, EKnockBackVariant kbVariant, float f3, EWalkerType wType, float f4, bool b1)
|
||||
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, kbVariant)
|
||||
, x590_colSphere(zeus::CSphere(zeus::CVector3f::skZero, pInfo.GetHalfExtent()), x68_material)
|
||||
, x5b0_(f1)
|
||||
, x5b0_collisionCloseMargin(f1)
|
||||
, x5b4_(f2)
|
||||
, x5c0_advanceWpRadius(f3)
|
||||
, x5c4_(f4)
|
||||
, x5cc_bendingHackAnim(GetModelData()->GetAnimationData()->GetCharacterInfo().GetAnimationIndex("BendingAnimationHack"sv))
|
||||
, x5d0_(w2)
|
||||
, x5d0_walkerType(wType)
|
||||
, x5d6_24_(false)
|
||||
, x5d6_25_(false)
|
||||
, x5d6_26_(false)
|
||||
|
@ -28,6 +28,37 @@ CWallWalker::CWallWalker(ECharacter chr, TUniqueId uid, std::string_view name, E
|
|||
{
|
||||
}
|
||||
|
||||
void CWallWalker::OrientToSurfaceNormal(const zeus::CVector3f& normal, float clampAngle)
|
||||
{
|
||||
float dot = x34_transform.basis[2].dot(normal);
|
||||
if (zeus::close_enough(dot, 1.f) || dot < -0.999f)
|
||||
return;
|
||||
zeus::CQuaternion q =
|
||||
zeus::CQuaternion::clampedRotateTo(x34_transform.basis[2], normal, zeus::degToRad(clampAngle));
|
||||
q.setImaginary(x34_transform.transposeRotate(q.getImaginary()));
|
||||
SetTransform((zeus::CQuaternion(x34_transform.basis) * q).normalized().toTransform(GetTranslation()));
|
||||
}
|
||||
|
||||
void CWallWalker::GotoNextWaypoint(CStateManager& mgr)
|
||||
{
|
||||
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x2dc_destObj))
|
||||
{
|
||||
zeus::CVector3f wpPos = wp->GetTranslation();
|
||||
if ((wpPos - GetTranslation()).magSquared() < x5c0_advanceWpRadius * x5c0_advanceWpRadius)
|
||||
{
|
||||
x2dc_destObj = wp->NextWaypoint(mgr);
|
||||
if (!zeus::close_enough(wp->GetPause(), 0.f))
|
||||
{
|
||||
x5bc_ = wp->GetPause();
|
||||
if (x5d0_walkerType == EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
}
|
||||
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
|
||||
}
|
||||
SetDestPos(wpPos);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallWalker::PreThink(float dt, CStateManager& mgr)
|
||||
{
|
||||
CPatterned::PreThink(dt, mgr);
|
||||
|
@ -45,11 +76,9 @@ void CWallWalker::PreThink(float dt, CStateManager& mgr)
|
|||
SetTranslation(GetTranslation() * (1.f - futureDt) +
|
||||
(((GetTranslation() - ((plane.vec.dot(GetTranslation())) - plane.d) -
|
||||
x590_colSphere.GetSphere().radius - 0.1f) * plane.vec) * futureDt));
|
||||
|
||||
}
|
||||
else
|
||||
MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
|
||||
}
|
||||
|
||||
void CWallWalker::Think(float dt, CStateManager& mgr)
|
||||
|
@ -92,6 +121,11 @@ void CWallWalker::Think(float dt, CStateManager& mgr)
|
|||
}
|
||||
}
|
||||
|
||||
void CWallWalker::Render(const CStateManager& mgr) const
|
||||
{
|
||||
CPatterned::Render(mgr);
|
||||
}
|
||||
|
||||
void CWallWalker::UpdateWPDestination(CStateManager& mgr)
|
||||
{
|
||||
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x2dc_destObj))
|
||||
|
@ -103,7 +137,7 @@ void CWallWalker::UpdateWPDestination(CStateManager& mgr)
|
|||
if (std::fabs(wp->GetPause()) > 0.00001f)
|
||||
{
|
||||
x5bc_ = wp->GetPause();
|
||||
if (x5d0_ == 0)
|
||||
if (x5d0_walkerType == EWalkerType::Parasite)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,21 @@ namespace urde
|
|||
{
|
||||
class CWallWalker : public CPatterned
|
||||
{
|
||||
public:
|
||||
enum class EWalkerType
|
||||
{
|
||||
Parasite = 0,
|
||||
Oculus = 1,
|
||||
Geemer = 2,
|
||||
IceZoomer = 3,
|
||||
Seedling = 4
|
||||
};
|
||||
protected:
|
||||
CCollisionSurface x568_ = CCollisionSurface(zeus::CVector3f(),
|
||||
zeus::CVector3f::skForward,
|
||||
zeus::CVector3f::skRight, -1);
|
||||
CCollidableSphere x590_colSphere;
|
||||
float x5b0_;
|
||||
float x5b0_collisionCloseMargin;
|
||||
float x5b4_;
|
||||
float x5b8_ = 0.f;
|
||||
float x5bc_ = 0.f;
|
||||
|
@ -21,7 +30,7 @@ protected:
|
|||
float x5c4_;
|
||||
float x5c8_bendingHackWeight = 0.f;
|
||||
s32 x5cc_bendingHackAnim;
|
||||
u32 x5d0_;
|
||||
EWalkerType x5d0_walkerType;
|
||||
s16 x5d4_ = 0;
|
||||
bool x5d6_24_ : 1;
|
||||
bool x5d6_25_ : 1;
|
||||
|
@ -29,13 +38,20 @@ protected:
|
|||
bool x5d6_27_ : 1;
|
||||
bool x5d6_28_addBendingWeight : 1;
|
||||
bool x5d6_29_applyBendingHack : 1;
|
||||
static zeus::CVector3f ProjectVectorToPlane(const zeus::CVector3f& v0, const zeus::CVector3f& v1)
|
||||
{
|
||||
return v0 - v1 * v0.dot(v1);
|
||||
}
|
||||
void OrientToSurfaceNormal(const zeus::CVector3f& normal, float clampAngle);
|
||||
void GotoNextWaypoint(CStateManager& mgr);
|
||||
public:
|
||||
CWallWalker(ECharacter, TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&,
|
||||
CModelData&&, const CPatternedInfo&, EMovementType, EColliderType, EBodyType,
|
||||
const CActorParameters&, float, float, EKnockBackVariant, float, u32, float, bool);
|
||||
const CActorParameters&, float, float, EKnockBackVariant, float, EWalkerType wType, float, bool);
|
||||
|
||||
void PreThink(float, CStateManager&);
|
||||
void Think(float, CStateManager&);
|
||||
void Render(const CStateManager&) const;
|
||||
const CCollisionPrimitive* GetCollisionPrimitive() const { return &x590_colSphere; }
|
||||
void UpdateWPDestination(CStateManager&);
|
||||
};
|
||||
|
|
|
@ -1924,8 +1924,9 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr
|
|||
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
|
||||
return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo,
|
||||
EBodyType::WallWalker, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
|
||||
f16, f17, 0.f, b1, 0, CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(),
|
||||
-1, -1, -1, -1, -1, 0.f, aParms);
|
||||
f16, f17, 0.f, b1, CWallWalker::EWalkerType::Parasite,
|
||||
CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(),
|
||||
-1, -1, -1, {}, {}, 0.f, aParms);
|
||||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadPlayerHint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||
|
@ -2970,7 +2971,7 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop
|
|||
return new MP1::CParasite(mgr.AllocateUniqueId(), actHead.x0_name, CPatterned::EFlavorType::Zero, info,
|
||||
actHead.x10_transform, std::move(mData), pInfo, EBodyType::WallWalker, 0.f, f1, f2, f3,
|
||||
f4, 0.2f, 0.4f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f, f5, f6, false, 2,
|
||||
0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f, f5, f6, false, CWallWalker::EWalkerType::Geemer,
|
||||
CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(), sId1, sId2, sId3, -1,
|
||||
-1, 0.f, actParms);
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ enum class EScriptObjectState
|
|||
CameraTarget = 16,
|
||||
UNKS2 = 17,
|
||||
Play = 18,
|
||||
MassiveDeath = 19,
|
||||
MassiveDeath = 19,
|
||||
DeathRattle = 20,
|
||||
AboutToMassivelyDie = 21,
|
||||
Damage = 22,
|
||||
|
|
Loading…
Reference in New Issue