Work on CParasite

This commit is contained in:
Jack Andersen 2018-11-12 23:20:11 -10:00
parent bf3636a16e
commit 660e7cd239
17 changed files with 755 additions and 358 deletions

View File

@ -17,24 +17,24 @@ struct Parasite : IScriptObject
Value<atVec3f> scale;
PatternedInfo patternedInfo;
ActorParameters actorParameters;
Value<float> unknown2;
Value<float> unknown3;
Value<float> maxTelegraphReactDist;
Value<float> advanceWpRadius;
Value<float> unknown4;
Value<float> unknown5;
Value<float> alignAngVel;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
Value<float> unknown11;
Value<float> unknown12;
Value<float> unknown13;
Value<float> unknown14;
Value<float> unknown15;
Value<float> unknown16;
Value<float> unknown17;
Value<float> unknown18;
Value<bool> unknown19;
Value<float> stuckTimeThreshold;
Value<float> collisionCloseMargin;
Value<float> parasiteSearchRadius;
Value<float> parasiteSeparationDist;
Value<float> parasiteSeparationWeight;
Value<float> parasiteAlignmentWeight;
Value<float> parasiteCohesionWeight;
Value<float> destinationSeekWeight;
Value<float> forwardMoveWeight;
Value<float> playerSeparationDist;
Value<float> playerSeparationWeight;
Value<float> playerObstructionMinDist;
Value<bool> disableMove;
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const
{

View File

@ -202,7 +202,7 @@ private:
EThermalDrawFlag xf34_thermalFlag = EThermalDrawFlag::Bypass;
TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId;
std::list<u32> xf3c_;
std::list<TUniqueId> xf54_parasiteTelegraphs;
std::list<TUniqueId> xf54_activeParasites;
TUniqueId xf6c_playerActorHead = kInvalidUniqueId;
u32 xf70_ = 0;
@ -470,7 +470,7 @@ public:
}
TUniqueId GetPlayerActorHead() const { return xf6c_playerActorHead; }
void SetPlayerActorHead(TUniqueId id) { xf6c_playerActorHead = id; }
std::list<TUniqueId>& GetParasiteTelegraphs() { return xf54_parasiteTelegraphs; }
std::list<TUniqueId>& GetActiveParasites() { return xf54_activeParasites; }
std::shared_ptr<CWorldLayerState>& WorldLayerStateNC() { return x8c8_worldLayerState; }
static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit;

View File

@ -284,8 +284,8 @@ class CBCLocomotionCmd
zeus::CVector3f xc_face;
float x18_weight;
public:
CBCLocomotionCmd(const zeus::CVector3f& v1, const zeus::CVector3f& v2, float f)
: x0_move(v1), xc_face(v2), x18_weight(f) {}
CBCLocomotionCmd(const zeus::CVector3f& move, const zeus::CVector3f& face, float weight)
: x0_move(move), xc_face(face), x18_weight(weight) {}
const zeus::CVector3f& GetMoveVector() const { return x0_move; }
const zeus::CVector3f& GetFaceVector() const { return xc_face; }
float GetWeight() const { return x18_weight; }

View File

@ -3,16 +3,125 @@
#include "World/CActor.hpp"
#include "CStateManager.hpp"
#include "CMaterialList.hpp"
#include "Collision/CCollisionActor.hpp"
namespace urde
{
CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId owner, TAreaId area,
const std::vector<CJointCollisionDescription>& descs, bool b1)
: x0_jointDescriptions(descs)
, x10_ownerId(owner)
, x12_(b1)
const std::vector<CJointCollisionDescription>& descs, bool active)
: x10_ownerId(owner)
, x12_active(active)
{
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(x10_ownerId))
{
zeus::CTransform xf = act->GetTransform();
const CAnimData* animData = act->GetModelData()->GetAnimationData();
zeus::CVector3f scale = act->GetModelData()->GetScale();
zeus::CTransform scaleXf = zeus::CTransform::Scale(scale);
x0_jointDescriptions.reserve(descs.size());
for (const CJointCollisionDescription& desc : descs)
{
CJointCollisionDescription modDesc = desc;
modDesc.ScaleAllBounds(scale);
zeus::CTransform locXf = GetWRLocatorTransform(*animData, modDesc.GetPivotId(), xf, scaleXf);
if (modDesc.GetNextId() != 0xff)
{
zeus::CTransform locXf2 = GetWRLocatorTransform(*animData, modDesc.GetNextId(), xf, scaleXf);
float dist = (locXf2.origin - locXf.origin).magnitude();
if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize)
{
if (dist <= FLT_EPSILON)
continue;
zeus::CVector3f bounds = modDesc.GetBounds();
bounds.y += dist;
CCollisionActor* newAct =
new CCollisionActor(mgr.AllocateUniqueId(), area, x10_ownerId, bounds,
zeus::CVector3f(0.f, 0.5f * dist, 0.f), active, modDesc.GetMass());
if (modDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero)
{
newAct->SetTransform(locXf);
}
else
{
zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized();
zeus::CVector3f upVector = locXf.basis[2];
if (zeus::close_enough(std::fabs(delta.dot(upVector)), 1.f))
upVector = locXf.basis[1];
newAct->SetTransform(zeus::lookAt(locXf.origin, locXf.origin + delta, upVector));
}
mgr.AddObject(newAct);
x0_jointDescriptions.push_back(desc);
}
else
{
TUniqueId newId = mgr.AllocateUniqueId();
CCollisionActor* newAct =
new CCollisionActor(newId, area, x10_ownerId,
active, modDesc.GetRadius(), modDesc.GetMass());
newAct->SetTransform(locXf);
mgr.AddObject(newAct);
x0_jointDescriptions.push_back(CJointCollisionDescription::
SphereCollision(modDesc.GetPivotId(), modDesc.GetRadius(), modDesc.GetName(), 0.001f));
x0_jointDescriptions.back().SetCollisionActorId(newId);
u32 numSeps = u32(dist / modDesc.GetMaxSeparation());
if (numSeps)
{
x0_jointDescriptions.reserve(x0_jointDescriptions.capacity() + numSeps);
float pitch = dist / float(numSeps + 1);
for (u32 i = 0; i < numSeps; ++i)
{
float separation = pitch * float(i + 1);
x0_jointDescriptions.push_back(CJointCollisionDescription::
SphereSubdivideCollision(modDesc.GetPivotId(), modDesc.GetNextId(), modDesc.GetRadius(),
separation, CJointCollisionDescription::EOrientationType::One,
modDesc.GetName(), 0.001f));
TUniqueId newId2 = mgr.AllocateUniqueId();
CCollisionActor* newAct2 =
new CCollisionActor(newId2, area, x10_ownerId,
active, modDesc.GetRadius(), modDesc.GetMass());
if (modDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero)
{
newAct2->SetTransform(
zeus::CTransform::Translate(locXf.origin + separation * locXf.basis[1]));
}
else
{
zeus::CVector3f delta = (locXf2.origin - locXf.origin).normalized();
zeus::CVector3f upVector = locXf.basis[2];
if (zeus::close_enough(
std::fabs(delta.dot(upVector)), 1.f))
upVector = locXf.basis[1];
zeus::CTransform lookAt = zeus::lookAt(zeus::CVector3f::skZero, delta, upVector);
newAct2->SetTransform(
zeus::CTransform::Translate(lookAt.basis[1] * separation + locXf.origin));
}
mgr.AddObject(newAct2);
x0_jointDescriptions.back().SetCollisionActorId(newId2);
}
}
}
}
else
{
TUniqueId newId = mgr.AllocateUniqueId();
CCollisionActor* newAct;
if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::Sphere)
newAct = new CCollisionActor(newId, area, x10_ownerId, active,
modDesc.GetRadius(), modDesc.GetMass());
else if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB)
newAct = new CCollisionActor(newId, area, x10_ownerId, modDesc.GetBounds(),
modDesc.GetPivotPoint(), active, modDesc.GetMass());
else
newAct = new CCollisionActor(newId, area, x10_ownerId, modDesc.GetBounds(),
active, modDesc.GetMass());
newAct->SetTransform(locXf);
mgr.AddObject(newAct);
x0_jointDescriptions.push_back(desc);
x0_jointDescriptions.back().SetCollisionActorId(newId);
}
}
}
}
void CCollisionActorManager::Destroy(CStateManager& mgr) const
@ -20,23 +129,21 @@ void CCollisionActorManager::Destroy(CStateManager& mgr) const
for (const CJointCollisionDescription& desc : x0_jointDescriptions)
mgr.FreeScriptObject(desc.GetCollisionActorId());
const_cast<CCollisionActorManager&>(*this).x13_ = true;
const_cast<CCollisionActorManager&>(*this).x13_destroyed = true;
}
void CCollisionActorManager::SetActive(CStateManager& mgr, bool active)
{
for (const CJointCollisionDescription& jDesc : x0_jointDescriptions)
{
TCastToPtr<CActor> act(mgr.ObjectById(jDesc.GetCollisionActorId()));
if (act)
if (TCastToPtr<CActor> act = mgr.ObjectById(jDesc.GetCollisionActorId()))
{
bool curActive = act->GetActive();
if (curActive != active)
act->SetActive(active);
if (!curActive)
Update(0.f, mgr, EUpdateOptions::One);
Update(0.f, mgr, EUpdateOptions::WorldSpace);
}
}
}
@ -44,26 +151,89 @@ void CCollisionActorManager::SetActive(CStateManager& mgr, bool active)
void CCollisionActorManager::AddMaterial(CStateManager& mgr, const CMaterialList& list)
{
for (const CJointCollisionDescription& jDesc : x0_jointDescriptions)
{
TCastToPtr<CActor> act(mgr.ObjectById(jDesc.GetCollisionActorId()));
if (act)
if (TCastToPtr<CActor> act = mgr.ObjectById(jDesc.GetCollisionActorId()))
act->AddMaterial(list);
}
}
u32 CCollisionActorManager::GetNumCollisionActors() const
void CCollisionActorManager::SetMovable(CStateManager& mgr, bool movable)
{
return x0_jointDescriptions.size();
}
CJointCollisionDescription CCollisionActorManager::GetCollisionDescFromIndex(u32 idx) const
if (x14_movable == movable)
return;
x14_movable = movable;
for (const CJointCollisionDescription& jDesc : x0_jointDescriptions)
{
return x0_jointDescriptions[idx];
}
void CCollisionActorManager::Update(float, CStateManager&, CCollisionActorManager::EUpdateOptions) const
if (TCastToPtr<CCollisionActor> act = mgr.ObjectById(jDesc.GetCollisionActorId()))
{
act->SetMovable(x14_movable);
act->SetUseInSortedLists(x14_movable);
}
}
}
void CCollisionActorManager::Update(float dt, CStateManager& mgr, EUpdateOptions opts)
{
if (!x14_movable)
SetMovable(mgr, true);
if (x12_active)
{
if (TCastToPtr<CActor> act = mgr.ObjectById(x10_ownerId))
{
const CAnimData& animData = *act->GetModelData()->GetAnimationData();
zeus::CTransform actXf = act->GetTransform();
zeus::CTransform scaleXf = zeus::CTransform::Scale(act->GetModelData()->GetScale());
for (const CJointCollisionDescription& jDesc : x0_jointDescriptions)
{
if (TCastToPtr<CCollisionActor> cAct = mgr.ObjectById(jDesc.GetCollisionActorId()))
{
zeus::CTransform pivotXf = GetWRLocatorTransform(animData, jDesc.GetPivotId(), actXf, scaleXf);
zeus::CVector3f origin = pivotXf.origin;
if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBB ||
jDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize)
{
if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero)
{
cAct->SetTransform(zeus::CQuaternion(pivotXf.basis).toTransform(cAct->GetTranslation()));
}
else
{
zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf);
cAct->SetTransform(
zeus::CQuaternion(zeus::lookAt(pivotXf.origin, nextXf.origin, pivotXf.basis[2]).basis).
toTransform(cAct->GetTranslation()));
}
}
else if (jDesc.GetType() == CJointCollisionDescription::ECollisionType::SphereSubdivide)
{
if (jDesc.GetOrientationType() == CJointCollisionDescription::EOrientationType::Zero)
{
origin += jDesc.GetMaxSeparation() * pivotXf.basis[1];
}
else
{
zeus::CTransform nextXf = GetWRLocatorTransform(animData, jDesc.GetNextId(), actXf, scaleXf);
origin += zeus::lookAt(origin, nextXf.origin, pivotXf.basis[2]).basis[1] *
jDesc.GetMaxSeparation();
}
}
if (opts == EUpdateOptions::ObjectSpace)
cAct->MoveToOR(cAct->GetTransform().transposeRotate(origin - cAct->GetTranslation()), dt);
else
cAct->SetTranslation(origin);
}
}
}
}
}
zeus::CTransform CCollisionActorManager::GetWRLocatorTransform(const CAnimData& animData, CSegId id,
const zeus::CTransform& worldXf,
const zeus::CTransform& localXf)
{
zeus::CTransform locXf = animData.GetLocatorTransform(id, nullptr);
zeus::CVector3f origin = worldXf * (localXf * locXf.origin);
locXf = worldXf.multiplyIgnoreTranslation(locXf);
locXf.origin = origin;
return locXf;
}
}

View File

@ -15,26 +15,30 @@ class CCollisionActorManager
public:
enum class EUpdateOptions
{
Zero,
One
ObjectSpace,
WorldSpace
};
private:
std::vector<CJointCollisionDescription> x0_jointDescriptions;
TUniqueId x10_ownerId;
bool x12_;
bool x13_ = false;
bool x14_ = true;
bool x12_active;
bool x13_destroyed = false;
bool x14_movable = true;
public:
CCollisionActorManager(CStateManager&, TUniqueId, TAreaId, const std::vector<CJointCollisionDescription>&, bool);
CCollisionActorManager(CStateManager& mgr, TUniqueId owner, TAreaId area,
const std::vector<CJointCollisionDescription>& descs, bool active);
void Update(float, CStateManager&, EUpdateOptions) const;
void Destroy(CStateManager&) const;
void SetActive(CStateManager&, bool);
void AddMaterial(CStateManager&, const CMaterialList&);
void Update(float dt, CStateManager& mgr, CCollisionActorManager::EUpdateOptions opts);
void Destroy(CStateManager& mgr) const;
void SetActive(CStateManager& mgr, bool active);
void AddMaterial(CStateManager& mgr, const CMaterialList& list);
void SetMovable(CStateManager& mgr, bool movable);
u32 GetNumCollisionActors() const;
CJointCollisionDescription GetCollisionDescFromIndex(u32) const;
zeus::CTransform GetWRLocatorTransform(const CAnimData&, CSegId, const zeus::CTransform&, const zeus::CTransform&);
u32 GetNumCollisionActors() const { return x0_jointDescriptions.size(); }
const CJointCollisionDescription& GetCollisionDescFromIndex(u32 i) const { return x0_jointDescriptions[i]; }
static zeus::CTransform GetWRLocatorTransform(const CAnimData& animData, CSegId id,
const zeus::CTransform& worldXf,
const zeus::CTransform& localXf);
};
}

View File

@ -3,57 +3,68 @@
namespace urde
{
CJointCollisionDescription::CJointCollisionDescription(ECollisionType colType, CSegId seg1, CSegId seg2,
const zeus::CVector3f& v1, const zeus::CVector3f& v2, float f1,
float f2, EOrientationType orientType, std::string_view name,
float f3)
CJointCollisionDescription::CJointCollisionDescription(ECollisionType colType, CSegId pivotId, CSegId nextId,
const zeus::CVector3f& bounds, const zeus::CVector3f& pivotPoint,
float radius, float maxSeparation, EOrientationType orientType,
std::string_view name, float mass)
: x0_colType(colType)
, x4_orientType(orientType)
, x8_(seg1)
, x9_(seg2)
, xc_(v1)
, x18_(v2)
, x24_(f1)
, x28_(f2)
, x8_pivotId(pivotId)
, x9_nextId(nextId)
, xc_bounds(bounds)
, x18_pivotPoint(pivotPoint)
, x24_radius(radius)
, x28_maxSeparation(maxSeparation)
, x2c_name(name)
, x40_(f3)
, x40_mass(mass)
{
}
CJointCollisionDescription CJointCollisionDescription::SphereSubdivideCollision(CSegId seg1, CSegId seg2, float f1,
float f2, EOrientationType orientType,
std::string_view name, float f3)
CJointCollisionDescription
CJointCollisionDescription::SphereSubdivideCollision(CSegId pivotId, CSegId nextId, float radius,
float maxSeparation, EOrientationType orientType,
std::string_view name, float mass)
{
return CJointCollisionDescription(ECollisionType::SphereSubdivide, seg1, seg2, zeus::CVector3f::skZero,
zeus::CVector3f::skZero, f1, f2, orientType, name, f3);
return CJointCollisionDescription(ECollisionType::SphereSubdivide, pivotId, nextId, zeus::CVector3f::skZero,
zeus::CVector3f::skZero, radius, maxSeparation, orientType, name, mass);
}
CJointCollisionDescription CJointCollisionDescription::SphereCollision(CSegId segId, float f1, std::string_view name, float f2)
CJointCollisionDescription
CJointCollisionDescription::SphereCollision(CSegId pivotId, float radius, std::string_view name, float mass)
{
return CJointCollisionDescription(ECollisionType::Sphere, segId, -1, zeus::CVector3f::skZero,
zeus::CVector3f::skZero, f1, 0.f, EOrientationType::Zero, name, f2);
return CJointCollisionDescription(ECollisionType::Sphere, pivotId, {}, zeus::CVector3f::skZero,
zeus::CVector3f::skZero, radius, 0.f, EOrientationType::Zero, name, mass);
}
CJointCollisionDescription CJointCollisionDescription::AABoxCollision(CSegId segId, const zeus::CVector3f& v1,
std::string_view name, float f1)
CJointCollisionDescription
CJointCollisionDescription::AABoxCollision(CSegId pivotId, const zeus::CVector3f& bounds,
std::string_view name, float mass)
{
return CJointCollisionDescription(ECollisionType::AABox, segId, -1, v1, zeus::CVector3f::skZero, 0.f, 0.f,
EOrientationType::Zero, name, f1);
return CJointCollisionDescription(ECollisionType::AABox, pivotId, {}, bounds, zeus::CVector3f::skZero,
0.f, 0.f, EOrientationType::Zero, name, mass);
}
CJointCollisionDescription CJointCollisionDescription::OBBCollision(CSegId segId, const zeus::CVector3f& v1,
const zeus::CVector3f& v2, std::string_view name,
float f1)
CJointCollisionDescription
CJointCollisionDescription::OBBAutoSizeCollision(CSegId pivotId, CSegId nextId, const zeus::CVector3f& bounds,
EOrientationType orientType, std::string_view name, float mass)
{
return CJointCollisionDescription(ECollisionType::OBB, segId, -1, v1, v2, 0.f, 0.f, EOrientationType::Zero, name,
f1);
return CJointCollisionDescription(ECollisionType::OBBAutoSize, pivotId, nextId, bounds, zeus::CVector3f::skZero,
0.f, 0.f, orientType, name, mass);
}
CJointCollisionDescription
CJointCollisionDescription::OBBCollision(CSegId pivotId, const zeus::CVector3f& bounds,
const zeus::CVector3f& pivotPoint, std::string_view name, float mass)
{
return CJointCollisionDescription(ECollisionType::OBB, pivotId, {}, bounds, pivotPoint, 0.f, 0.f,
EOrientationType::Zero, name, mass);
}
void CJointCollisionDescription::ScaleAllBounds(const zeus::CVector3f& scale)
{
xc_ *= scale;
x24_ *= scale.x;
x28_ *= scale.x;
x18_ *= scale;
xc_bounds *= scale;
x24_radius *= scale.x;
x28_maxSeparation *= scale.x;
x18_pivotPoint *= scale;
}
}

View File

@ -26,40 +26,42 @@ public:
private:
ECollisionType x0_colType;
EOrientationType x4_orientType;
CSegId x8_;
CSegId x9_;
zeus::CVector3f xc_;
zeus::CVector3f x18_;
float x24_;
float x28_;
CSegId x8_pivotId;
CSegId x9_nextId;
zeus::CVector3f xc_bounds;
zeus::CVector3f x18_pivotPoint;
float x24_radius;
float x28_maxSeparation;
std::string x2c_name;
TUniqueId x3c_actorId = kInvalidUniqueId;
float x40_;
float x40_mass;
public:
CJointCollisionDescription(ECollisionType, CSegId, CSegId, const zeus::CVector3f&, const zeus::CVector3f&, float,
float, EOrientationType, std::string_view, float);
static CJointCollisionDescription SphereSubdivideCollision(CSegId pivotId, CSegId nextId, float radius,
float maxSeparation, EOrientationType orientType,
std::string_view name, float mass);
static CJointCollisionDescription SphereCollision(CSegId pivotId, float radius, std::string_view name, float mass);
static CJointCollisionDescription AABoxCollision(CSegId pivotId, const zeus::CVector3f& bounds,
std::string_view name, float mass);
static CJointCollisionDescription OBBAutoSizeCollision(CSegId pivotId, CSegId nextId, const zeus::CVector3f& bounds,
EOrientationType orientType, std::string_view, float mass);
static CJointCollisionDescription OBBCollision(CSegId pivotId, const zeus::CVector3f& bounds,
const zeus::CVector3f& pivotPoint, std::string_view name, float mass);
std::string_view GetName() const { return x2c_name; }
TUniqueId GetCollisionActorId() const { return x3c_actorId; }
static CJointCollisionDescription SphereSubdivideCollision(CSegId, CSegId, float, float,
EOrientationType, std::string_view, float);
static CJointCollisionDescription SphereCollision(CSegId, float, std::string_view, float);
static CJointCollisionDescription AABoxCollision(CSegId, zeus::CVector3f const&, std::string_view, float);
static CJointCollisionDescription OBBAutoSizeCollision(CSegId, CSegId, const zeus::CVector3f&, EOrientationType,
std::string_view, float);
static CJointCollisionDescription OBBCollision(CSegId, const zeus::CVector3f&, const zeus::CVector3f&,
std::string_view, float);
zeus::CVector3f GetPivotPoint() const;
float GetRadius() const;
void SetCollisionActorId(TUniqueId);
void SetCollisionActorId(TUniqueId id) { x3c_actorId = id; }
const zeus::CVector3f& GetBounds() const { return xc_bounds; }
float GetRadius() const { return x24_radius; }
float GetMaxSeparation() const { return x28_maxSeparation; }
EOrientationType GetOrientationType() const { return x4_orientType; }
float GetMass() const;
zeus::CAABox GetBounds() const;
void GetType() const;
void GetNextId() const;
void GetPivotId() const;
void ScaleAllBounds(const zeus::CVector3f&);
void GetTween() const;
float GetMass() const { return x40_mass; }
const zeus::CVector3f& GetPivotPoint() const { return x18_pivotPoint; }
ECollisionType GetType() const { return x0_colType; }
CSegId GetNextId() const { return x9_nextId; }
CSegId GetPivotId() const { return x8_pivotId; }
void ScaleAllBounds(const zeus::CVector3f& scale);
};
}

View File

@ -126,6 +126,9 @@ public:
void AddLeaf(const CAreaOctTree::Node& node);
u32 GetNumLeaves() const { return x4_nodeCache.size(); }
bool HasCacheOverflowed() const { return x908_24_overflow; }
const CAreaOctTree& GetOctTree() const { return x0_octTree; }
rstl::reserved_vector<CAreaOctTree::Node, 64>::iterator begin() { return x4_nodeCache.begin(); }
rstl::reserved_vector<CAreaOctTree::Node, 64>::iterator end() { return x4_nodeCache.end(); }
};
static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb,
CMetroidAreaCollider::COctreeLeafCache& cache);

View File

@ -6,12 +6,14 @@
#include "World/CGameArea.hpp"
#include "World/CPlayer.hpp"
#include "World/CScriptWaypoint.hpp"
#include "World/CScriptDoor.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "Graphics/CSkinnedModel.hpp"
#include "Collision/CGameCollision.hpp"
#include "Collision/CCollisionActor.hpp"
namespace urde::MP1
{
@ -24,33 +26,39 @@ const float CParasite::skRetreatVelocity = 3.f / 2.f * std::sqrt(2.5f / 24.52500
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, EWalkerType wType, const CDamageVulnerability& dVuln,const CDamageInfo& parInfo, u16 sfxId1,
u16 sfxId2, u16 sfxId3, CAssetId modelRes, CAssetId skinRes, float f19, const CActorParameters &aParams)
float maxTelegraphReactDist, float advanceWpRadius, float f3, float alignAngVel, float f5,
float stuckTimeThreshold, float collisionCloseMargin, float parasiteSearchRadius,
float parasiteSeparationDist, float parasiteSeparationWeight, float parasiteAlignmentWeight,
float parasiteCohesionWeight, float destinationSeekWeight, float forwardMoveWeight,
float playerSeparationDist, float playerSeparationWeight, float playerObstructionMinDist,
float haltDelay, bool disableMove, EWalkerType wType, const CDamageVulnerability& dVuln,
const CDamageInfo& parInfo, u16 haltSfx, u16 getUpSfx, u16 crouchSfx, CAssetId modelRes,
CAssetId skinRes, float iceZoomerJointHP,
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, wType, f17, b1)
, x64c_(dVuln)
, x6b4_(parInfo)
, x6d0_(f1)
EColliderType::Zero, bodyType, aParams, collisionCloseMargin, alignAngVel, EKnockBackVariant::Small,
advanceWpRadius, wType, playerObstructionMinDist, disableMove)
, x64c_oculusHaltDVuln(dVuln)
, x6b4_oculusHaltDInfo(parInfo)
, x6d0_maxTelegraphReactDist(maxTelegraphReactDist)
, 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_haltSfx(CSfxManager::TranslateSFXID(sfxId1))
, x73e_getUpSfx(CSfxManager::TranslateSFXID(sfxId2))
, x740_crouchSfx(CSfxManager::TranslateSFXID(sfxId3))
, x6e0_stuckTimeThreshold(stuckTimeThreshold)
, x6e4_parasiteSearchRadius(parasiteSearchRadius)
, x6e8_parasiteSeparationDist(parasiteSeparationDist)
, x6ec_parasiteSeparationWeight(parasiteSeparationWeight)
, x6f0_parasiteAlignmentWeight(parasiteAlignmentWeight)
, x6f4_parasiteCohesionWeight(parasiteCohesionWeight)
, x6f8_destinationSeekWeight(destinationSeekWeight)
, x6fc_forwardMoveWeight(forwardMoveWeight)
, x700_playerSeparationDist(playerSeparationDist)
, x704_playerSeparationWeight(playerSeparationWeight)
, x708_unmorphedRadius(pInfo.GetHeight() * 0.5f)
, x710_haltDelay(haltDelay)
, x714_iceZoomerJointHP(iceZoomerJointHP)
, x73c_haltSfx(CSfxManager::TranslateSFXID(haltSfx))
, x73e_getUpSfx(CSfxManager::TranslateSFXID(getUpSfx))
, x740_crouchSfx(CSfxManager::TranslateSFXID(crouchSfx))
{
x742_28_onGround = true;
x742_30_attackOver = true;
@ -85,33 +93,114 @@ CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, c
void CParasite::Accept(IVisitor &visitor) { visitor.Visit(this); }
void CParasite::SetupIceZoomerCollision(CStateManager& mgr)
{
std::vector<CJointCollisionDescription> descs;
descs.reserve(2);
descs.push_back(CJointCollisionDescription::SphereCollision(
x64_modelData->GetAnimationData()->GetLocatorSegId("Ice_LCTR"sv), 0.4f, "Ice_LCTR"sv, 0.001f));
RemoveMaterial(EMaterialTypes::Solid, mgr);
AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr);
x620_collisionActorManager =
std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(),
descs, GetActive());
}
void CParasite::SetupIceZoomerVulnerability(CStateManager& mgr, const CDamageVulnerability& dVuln,
const CHealthInfo& hInfo)
{
for (u32 i = 0; i < x620_collisionActorManager->GetNumCollisionActors(); ++i)
{
const CJointCollisionDescription& cDesc = x620_collisionActorManager->GetCollisionDescFromIndex(i);
if (TCastToPtr<CCollisionActor> act = mgr.ObjectById(cDesc.GetCollisionActorId()))
{
act->SetDamageVulnerability(dVuln);
*act->HealthInfo(mgr) = hInfo;
}
}
}
void CParasite::AddDoorRepulsors(CStateManager& mgr)
{
u32 doorCount = 0;
for (CEntity* ent : mgr.GetPhysicsActorObjectList())
if (TCastToPtr<CScriptDoor> door = ent)
if (door->GetAreaIdAlways() == GetAreaIdAlways())
++doorCount;
x5d8_doorRepulsors.reserve(doorCount);
for (CEntity* ent : mgr.GetPhysicsActorObjectList())
if (TCastToPtr<CScriptDoor> door = ent)
if (door->GetAreaIdAlways() == GetAreaIdAlways())
{
if (auto tb = door->GetTouchBounds())
{
float diagMag = (tb->min - tb->max).magnitude() * 0.75f;
x5d8_doorRepulsors.emplace_back(tb->center(), diagMag);
}
}
}
static TUniqueId lastParasite = kInvalidUniqueId;
void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CPatterned::AcceptScriptMsg(msg, uid, mgr);
if (msg == EScriptObjectMessage::Registered)
switch (msg)
{
case EScriptObjectMessage::Registered:
x450_bodyController->Activate(mgr);
/* TODO: Finish 8015A0E8*/
}
else if (msg == EScriptObjectMessage::Deleted)
mgr.GetActiveParasites().push_back(GetUniqueId());
CActor::CreateShadow(false);
x604_activeSpeed = x3b4_speed;
CPhysicsActor::SetBoundingBox(
zeus::CAABox(zeus::CVector3f(-x590_colSphere.GetSphere().radius),
zeus::CVector3f(x590_colSphere.GetSphere().radius)));
lastParasite = GetUniqueId();
AddDoorRepulsors(mgr);
if (x5d0_walkerType == EWalkerType::IceZoomer)
{
//mgr.xf54_.sub80125d88(GetUniqueId());
if (x5d0_walkerType != EWalkerType::IceZoomer)
DestroyActorManager(mgr);
SetupIceZoomerCollision(mgr);
SetupIceZoomerVulnerability(mgr, x64c_oculusHaltDVuln,
CHealthInfo(x714_iceZoomerJointHP, HealthInfo(mgr)->GetKnockbackResistance()));
}
else if (msg == EScriptObjectMessage::Jumped && x742_25_jumpVelDirty)
break;
case EScriptObjectMessage::Deleted:
mgr.GetActiveParasites().remove(GetUniqueId());
if (x5d0_walkerType == EWalkerType::IceZoomer)
DestroyActorManager(mgr);
break;
case EScriptObjectMessage::Jumped:
if (x742_25_jumpVelDirty)
{
UpdateJumpVelocity();
x742_25_jumpVelDirty = false;
}
else if (msg == EScriptObjectMessage::Activate)
{
x5d6_27_ = false;
if (x5d0_walkerType != EWalkerType::Parasite)
break;
case EScriptObjectMessage::Activate:
x5d6_27_disableMove = false;
if (x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
}
else if (msg == EScriptObjectMessage::SuspendedMove)
break;
case EScriptObjectMessage::InvulnDamage:
if (x5d0_walkerType == EWalkerType::Oculus)
{
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(uid))
{
float distSq = (act->GetTranslation() - GetTranslation()).magSquared();
auto tb = GetTouchBounds();
float maxComp = std::max(std::max(tb->max.y - tb->min.y, tb->max.z - tb->min.z), tb->max.x - tb->min.x);
float maxCompSq = maxComp * maxComp + 1.f;
if (distSq < maxCompSq * maxCompSq)
x743_26_oculusShotAt = true;
}
}
break;
case EScriptObjectMessage::SuspendedMove:
if (x620_collisionActorManager)
x620_collisionActorManager->SetMovable(mgr, false);
break;
default:
break;
}
}
@ -121,60 +210,83 @@ void CParasite::PreThink(float dt, CStateManager& mgr)
x743_26_oculusShotAt = false;
}
void CParasite::UpdateCollisionActors(float dt, CStateManager& mgr)
{
x620_collisionActorManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
if (!x743_25_vulnerable)
{
float totalHP = 0.f;
for (u32 i = 0; i < x620_collisionActorManager->GetNumCollisionActors(); ++i)
{
const CJointCollisionDescription& cDesc = x620_collisionActorManager->GetCollisionDescFromIndex(i);
if (TCastToPtr<CCollisionActor> cact = mgr.ObjectById(cDesc.GetCollisionActorId()))
totalHP += cact->HealthInfo(mgr)->GetHP();
}
if (totalHP <= 0.f)
{
x743_25_vulnerable = true;
AddMaterial(EMaterialTypes::Solid, mgr);
RemoveMaterial(EMaterialTypes::ProjectilePassthrough, mgr);
DestroyActorManager(mgr);
x64_modelData->AnimationData()->SubstituteModelData(x624_extraModel);
}
}
}
void CParasite::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
++x5d4_;
++x5d4_thinkCounter;
if (x5d0_walkerType == EWalkerType::IceZoomer)
UpdateCollisionActors(mgr);
UpdateCollisionActors(dt, mgr);
x5d6_26_ = false;
x5d6_26_playerObstructed = 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;
x5d6_26_playerObstructed = true;
if (!x5d6_26_)
if (!x5d6_26_playerObstructed)
{
zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation();
float distance = (GetTranslation() - plVec).magnitude() ;
if (distance > x5c4_)
if (distance > x5c4_playerObstructionMinDist)
{
CRayCastResult res = mgr.RayStaticIntersection(plVec, (GetTranslation() - plVec).normalized(), distance,
CMaterialFilter::skPassEverything);
if (res.IsValid())
x5d6_26_ = true;
x5d6_26_playerObstructed = true;
}
}
if (x5d6_26_)
if (x5d6_26_playerObstructed)
{
xf8_24_movable = x5d6_26_;
xf8_24_movable = x5d6_26_playerObstructed;
return;
}
xf8_24_movable = !xf8_24_movable;
if (!x5d6_27_)
if (!x5d6_27_disableMove)
{
if (x450_bodyController->IsFrozen())
{
if ((GetTranslation() - x614_).magSquared() < 0.3f /* <- Used to be a static variable */ * dt)
x60c_ += dt;
if ((GetTranslation() - x614_lastStuckPos).magSquared() < 0.3f /* <- Used to be a static variable */ * dt)
x60c_stuckTime += dt;
else
x60c_ = 0.f;
x60c_stuckTime = 0.f;
x614_ = GetTranslation();
if (x608_ > 0.f)
x608_ -= dt;
x614_lastStuckPos = GetTranslation();
if (x608_telegraphRemTime > 0.f)
x608_telegraphRemTime -= dt;
else
x608_ = 0.f;
x608_telegraphRemTime = 0.f;
}
}
@ -185,7 +297,7 @@ void CParasite::Think(float dt, CStateManager& mgr)
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_attackOver)
radius = x590_colSphere.GetSphere().radius;
else
radius = x708_;
radius = x708_unmorphedRadius;
zeus::CAABox aabox{GetTranslation() - radius, GetTranslation() + radius};
auto plBox = pl->GetTouchBounds();
@ -209,14 +321,14 @@ void CParasite::Think(float dt, CStateManager& mgr)
CWallWalker::Think(dt, mgr);
if (x5d6_27_)
if (x5d6_27_disableMove)
return;
if (x450_bodyController->IsFrozen())
return;
x3b4_speed = x604_;
if (x5d6_24_)
x3b4_speed = x604_activeSpeed;
if (x5d6_24_alignToFloor)
AlignToFloor(mgr, x590_colSphere.GetSphere().radius, GetTranslation() + 2.f * dt * x138_velocity, dt);
x742_27_landed = false;
@ -232,11 +344,11 @@ const CDamageVulnerability* CParasite::GetDamageVulnerability() const
switch (x5d0_walkerType)
{
case EWalkerType::Oculus:
if (x743_24_)
return &x64c_;
if (x743_24_halted)
return &x64c_oculusHaltDVuln;
break;
case EWalkerType::IceZoomer:
if (!x743_25_)
if (!x743_25_vulnerable)
return &CDamageVulnerability::ImmuneVulnerabilty();
break;
default:
@ -245,6 +357,13 @@ const CDamageVulnerability* CParasite::GetDamageVulnerability() const
return CAi::GetDamageVulnerability();
}
CDamageInfo CParasite::GetContactDamage() const
{
if (x5d0_walkerType == EWalkerType::Oculus && x743_24_halted)
return x6b4_oculusHaltDInfo;
return CPatterned::GetContactDamage();
}
void CParasite::Touch(CActor& actor, CStateManager& mgr)
{
CPatterned::Touch(actor, mgr);
@ -262,7 +381,7 @@ void CParasite::CollidedWith(TUniqueId uid, const CCollisionInfoList& list, CSta
{
for (const auto& info : list)
{
if (!x5d6_24_ && info.GetMaterialLeft().Intersection(testList) == 0)
if (!x5d6_24_alignToFloor && info.GetMaterialLeft().Intersection(testList) == 0)
{
OrientToSurfaceNormal(info.GetNormalLeft(), 360.f);
CPhysicsActor::Stop();
@ -288,30 +407,30 @@ void CParasite::Patrol(CStateManager& mgr, EStateMsg msg, float dt)
{
case EStateMsg::Activate:
x742_26_ = true;
x5d6_24_ = true;
if (!x5d6_27_ && x5d0_walkerType == EWalkerType::Parasite)
x5d6_24_alignToFloor = true;
if (!x5d6_27_disableMove && x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
SetMomentumWR(zeus::CVector3f::skZero);
x5d6_25_ = false;
x5d6_25_hasAlignSurface = false;
xf8_24_movable = false;
break;
case EStateMsg::Update:
if (x5bc_ > 0.f)
if (x5bc_patrolPauseRemTime > 0.f)
{
x5bc_ -= dt;
if (x5bc_ <= 0.f)
x5bc_patrolPauseRemTime -= dt;
if (x5bc_patrolPauseRemTime <= 0.f)
{
if (x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
x5bc_ = 0.f;
x5bc_patrolPauseRemTime = 0.f;
}
}
GotoNextWaypoint(mgr);
if (x5bc_ <= 0.f && !x5d6_27_)
if (x5bc_patrolPauseRemTime <= 0.f && !x5d6_27_disableMove)
DoFlockingBehavior(mgr);
break;
case EStateMsg::Deactivate:
x5d6_24_ = false;
x5d6_24_alignToFloor = false;
xf8_24_movable = true;
break;
default:
@ -328,13 +447,14 @@ 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)
zeus::CAABox aabb(GetTranslation() - x6e4_parasiteSearchRadius,
GetTranslation() + x6e4_parasiteSearchRadius);
if ((x5d4_thinkCounter % 6) == 0)
{
rstl::reserved_vector<TUniqueId, 1024> nearList;
static CMaterialFilter filter = CMaterialFilter::MakeInclude(EMaterialTypes::Character);
CParasite* closestParasite = nullptr;
float minDistSq = 2.f + x6e8_ * x6e8_;
float minDistSq = 2.f + x6e8_parasiteSeparationDist * x6e8_parasiteSeparationDist;
mgr.BuildNearList(nearList, aabb, filter, nullptr);
for (TUniqueId id : nearList)
{
@ -352,25 +472,28 @@ void CParasite::DoFlockingBehavior(CStateManager& mgr)
}
}
}
if (closestParasite && x6ec_ > 0.f && x6e8_ > 0.f)
x628_ = x45c_steeringBehaviors.Separation(*this, closestParasite->GetTranslation(), x6e8_) * x604_;
if (closestParasite && x6ec_parasiteSeparationWeight > 0.f && x6e8_parasiteSeparationDist > 0.f)
x628_parasiteSeparationMove = x45c_steeringBehaviors.Separation(*this, closestParasite->GetTranslation(),
x6e8_parasiteSeparationDist) * x604_activeSpeed;
else
x628_ = zeus::CVector3f::skZero;
x634_ = x45c_steeringBehaviors.Cohesion(*this, _834, 0.6f, mgr) * x604_;
x640_ = x45c_steeringBehaviors.Alignment(*this, _834, mgr) * x604_;
x628_parasiteSeparationMove = zeus::CVector3f::skZero;
x634_parasiteCohesionMove = x45c_steeringBehaviors.Cohesion(*this, _834, 0.6f, mgr) * x604_activeSpeed;
x640_parasiteAlignmentMove = x45c_steeringBehaviors.Alignment(*this, _834, mgr) * x604_activeSpeed;
}
if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x700_ * x700_)
if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() <
x700_playerSeparationDist * x700_playerSeparationDist)
{
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
x45c_steeringBehaviors.Separation(*this, mgr.GetPlayer().GetTranslation(), x700_), upVec) * x604_,
zeus::CVector3f::skZero, x704_));
x45c_steeringBehaviors.Separation(*this, mgr.GetPlayer().GetTranslation(),
x700_playerSeparationDist), upVec) * x604_activeSpeed,
zeus::CVector3f::skZero, x704_playerSeparationWeight));
}
if (x628_ != zeus::CVector3f::skZero)
if (x628_parasiteSeparationMove != zeus::CVector3f::skZero)
{
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
x628_, upVec), zeus::CVector3f::skZero, x6ec_));
x628_parasiteSeparationMove, upVec), zeus::CVector3f::skZero, x6ec_parasiteSeparationWeight));
}
for (const auto& r : x5d8_doorRepulsors)
@ -378,23 +501,23 @@ void CParasite::DoFlockingBehavior(CStateManager& mgr)
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),
x45c_steeringBehaviors.Separation(*this, r.GetVector(), r.GetFloat()) * x604_activeSpeed, upVec),
zeus::CVector3f::skZero, 1.f));
}
}
if (x608_ <= 0.f)
if (x608_telegraphRemTime <= 0.f)
{
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
x634_, upVec), zeus::CVector3f::skZero, x6f4_));
x634_parasiteCohesionMove, upVec), zeus::CVector3f::skZero, x6f4_parasiteCohesionWeight));
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(ProjectVectorToPlane(
x640_, upVec), zeus::CVector3f::skZero, x6f0_));
x640_parasiteAlignmentMove, upVec), zeus::CVector3f::skZero, x6f0_parasiteAlignmentWeight));
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(
ProjectVectorToPlane(ProjectVectorToPlane(
x45c_steeringBehaviors.Seek(*this, x2e0_destPos), upVec) * x604_, upVec),
zeus::CVector3f::skZero, x6f8_));
x45c_steeringBehaviors.Seek(*this, x2e0_destPos), upVec) * x604_activeSpeed, upVec),
zeus::CVector3f::skZero, x6f8_destinationSeekWeight));
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(
x34_transform.basis[1] * x604_, zeus::CVector3f::skZero, x6fc_));
x34_transform.basis[1] * x604_activeSpeed, zeus::CVector3f::skZero, x6fc_forwardMoveWeight));
}
}
@ -404,7 +527,7 @@ void CParasite::PathFind(CStateManager& mgr, EStateMsg msg, float dt)
{
case EStateMsg::Activate:
x742_26_ = true;
x5d6_24_ = true;
x5d6_24_alignToFloor = true;
if (x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
SetMomentumWR(zeus::CVector3f::skZero);
@ -416,7 +539,7 @@ void CParasite::PathFind(CStateManager& mgr, EStateMsg msg, float dt)
break;
case EStateMsg::Deactivate:
xf8_24_movable = true;
x5d6_24_ = false;
x5d6_24_alignToFloor = false;
x742_26_ = false;
break;
default:
@ -429,11 +552,11 @@ 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);
x5f8_targetPos = 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]),
ProjectVectorToPlane(x5f8_targetPos - GetTranslation(), x34_transform.basis[2]),
x34_transform.basis[1], 2.f);
break;
default:
@ -513,10 +636,10 @@ void CParasite::Halt(CStateManager& mgr, EStateMsg msg, float)
switch (msg)
{
case EStateMsg::Activate:
x330_stateMachineState.SetDelay(x710_);
x330_stateMachineState.SetDelay(x710_haltDelay);
x32c_animState = EAnimState::One;
x743_24_ = true;
x5d6_24_ = true;
x743_24_halted = true;
x5d6_24_alignToFloor = true;
if (x5d0_walkerType == EWalkerType::Geemer)
CSfxManager::AddEmitter(x73c_haltSfx, GetTranslation(), zeus::CVector3f::skZero,
true, false, 0x7f, kInvalidAreaId);
@ -528,8 +651,8 @@ void CParasite::Halt(CStateManager& mgr, EStateMsg msg, float)
case EStateMsg::Deactivate:
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
x32c_animState = EAnimState::Zero;
x743_24_ = false;
x5d6_24_ = false;
x743_24_halted = false;
x5d6_24_alignToFloor = false;
break;
default:
break;
@ -546,20 +669,20 @@ void CParasite::Generate(CStateManager&, EStateMsg msg, float)
switch (msg)
{
case EStateMsg::Activate:
x5e8_ = 0;
x5e8_stateProgress = 0;
break;
case EStateMsg::Update:
switch (x5e8_)
switch (x5e8_stateProgress)
{
case 0:
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
x5e8_ = 1;
x5e8_stateProgress = 1;
else
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero));
break;
case 1:
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
x5e8_ = 2;
x5e8_stateProgress = 2;
break;
default:
break;
@ -575,15 +698,15 @@ void CParasite::Deactivate(CStateManager& mgr, EStateMsg msg, float)
switch (msg)
{
case EStateMsg::Activate:
x5e8_ = 0;
SendScriptMsgs(EScriptObjectState::UNKS2, mgr, EScriptObjectMessage::None);
x5e8_stateProgress = 0;
SendScriptMsgs(EScriptObjectState::DeactivateState, mgr, EScriptObjectMessage::None);
mgr.FreeScriptObject(GetUniqueId());
break;
case EStateMsg::Update:
if (x5e8_ == 0)
if (x5e8_stateProgress == 0)
{
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Generate)
x5e8_ = 1;
x5e8_stateProgress = 1;
else
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::One));
}
@ -598,41 +721,41 @@ void CParasite::Attack(CStateManager& mgr, EStateMsg msg, float)
switch (msg)
{
case EStateMsg::Activate:
x608_ = 0.f;
x608_telegraphRemTime = 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();
x5f8_targetPos = (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())
x5f8_targetPos = (zeus::CVector3f(rx, ry, rz) + mgr.GetPlayer().GetTranslation() - GetTranslation())
.normalized() * 15.f + GetTranslation();
}
FaceTarget(x5f8_);
x5e8_ = 0;
FaceTarget(x5f8_targetPos);
x5e8_stateProgress = 0;
x742_30_attackOver = false;
x742_24_ = false;
x742_24_receivedTelegraph = false;
x742_28_onGround = false;
break;
case EStateMsg::Update:
switch (x5e8_)
switch (x5e8_stateProgress)
{
case 0:
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Jump)
{
x5e8_ = 1;
x5e8_stateProgress = 1;
}
else
{
x742_25_jumpVelDirty = true;
FaceTarget(x5f8_);
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_, pas::EJumpType::Normal));
FaceTarget(x5f8_targetPos);
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_targetPos, pas::EJumpType::Normal));
}
break;
default:
@ -675,20 +798,21 @@ void CParasite::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float)
switch (msg)
{
case EStateMsg::Activate:
for (auto it = mgr.GetParasiteTelegraphs().begin(); it != mgr.GetParasiteTelegraphs().end();)
for (auto it = mgr.GetActiveParasites().begin(); it != mgr.GetActiveParasites().end();)
{
CParasite* other = CPatterned::CastTo<CParasite>(mgr.ObjectById(*it));
if (!other)
{
it = mgr.GetParasiteTelegraphs().erase(it);
it = mgr.GetActiveParasites().erase(it);
continue;
}
if (other != this && other->IsAlive() &&
(other->GetTranslation() - GetTranslation()).magSquared() < x6d0_ * x6d0_)
(other->GetTranslation() - GetTranslation()).magSquared() <
x6d0_maxTelegraphReactDist * x6d0_maxTelegraphReactDist)
{
other->x742_24_ = true;
other->x608_ = mgr.GetActiveRandom()->Float() * 0.5f + 0.5f;
other->x5f8_ = GetTranslation();
other->x742_24_receivedTelegraph = true;
other->x608_telegraphRemTime = mgr.GetActiveRandom()->Float() * 0.5f + 0.5f;
other->x5f8_targetPos = GetTranslation();
}
++it;
}
@ -707,7 +831,7 @@ void CParasite::Jump(CStateManager& mgr, EStateMsg msg, float)
AddMaterial(EMaterialTypes::GroundCollider, mgr);
SetMomentumWR({0.f, 0.f, -GetWeight()});
x742_28_onGround = false;
x5d6_24_ = false;
x5d6_24_alignToFloor = false;
x742_27_landed = false;
x743_27_inJump = true;
break;
@ -744,13 +868,13 @@ void CParasite::Retreat(CStateManager& mgr, EStateMsg msg, float)
dir.normalize();
else
dir = mgr.GetPlayer().GetTransform().basis[1];
x5f8_ = GetTranslation() - dir * 3.f;
FaceTarget(x5f8_);
x5e8_ = 0;
x5f8_targetPos = GetTranslation() - dir * 3.f;
FaceTarget(x5f8_targetPos);
x5e8_stateProgress = 0;
x742_27_landed = false;
x742_28_onGround = false;
x742_25_jumpVelDirty = true;
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_, pas::EJumpType::One));
x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_targetPos, pas::EJumpType::One));
break;
}
case EStateMsg::Update:
@ -764,13 +888,13 @@ void CParasite::Retreat(CStateManager& mgr, EStateMsg msg, float)
bool CParasite::AnimOver(CStateManager&, float)
{
return x5e8_ == 2;
return x5e8_stateProgress == 2;
}
bool CParasite::ShouldAttack(CStateManager& mgr, float arg)
{
bool shouldAttack = false;
if (x742_24_ && x608_ > 0.1f)
if (x742_24_receivedTelegraph && x608_telegraphRemTime > 0.1f)
shouldAttack = true;
if (!TooClose(mgr, arg) && InMaxRange(mgr, arg))
return shouldAttack || InDetectionRange(mgr, 0.f);
@ -790,14 +914,14 @@ bool CParasite::CloseToWall(CStateManager& mgr)
bool CParasite::HitSomething(CStateManager& mgr, float)
{
if (x5d4_ & 0x1)
if (x5d4_thinkCounter & 0x1)
return true;
return x5b8_ < 270.f && CloseToWall(mgr);
return x5b8_tumbleAngle < 270.f && CloseToWall(mgr);
}
bool CParasite::Stuck(CStateManager&, float)
{
return x60c_ > x6e0_;
return x60c_stuckTime > x6e0_stuckTimeThreshold;
}
bool CParasite::Landed(CStateManager&, float)
@ -845,7 +969,7 @@ void CParasite::UpdateWalkerAnimation(CStateManager& mgr, float dt)
void CParasite::DestroyActorManager(CStateManager& mgr)
{
//x620_->Destroy(mgr);
x620_collisionActorManager->Destroy(mgr);
}
void CParasite::UpdateJumpVelocity()
@ -865,8 +989,8 @@ void CParasite::UpdateJumpVelocity()
}
float f30 = x150_momentum.z / xe8_mass;
float f31 = x5f8_.z - GetTranslation().z;
zeus::CVector3f vec2 = x5f8_ - GetTranslation();
float f31 = x5f8_targetPos.z - GetTranslation().z;
zeus::CVector3f vec2 = x5f8_targetPos - GetTranslation();
vec2.z = 0.f;
float f29 = vec2.magnitude();
@ -895,8 +1019,4 @@ void CParasite::UpdateJumpVelocity()
SetVelocityWR(vec);
}
void CParasite::AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float)
{
}
} // namespace urde::MP1

View File

@ -26,38 +26,36 @@ class CParasite : public CWallWalker
static const float flt_805A8FB8;
static const float skRetreatVelocity;
std::vector<CRepulsor> x5d8_doorRepulsors;
s32 x5e8_ = -1;
float x5ec_ = 0.f;
float x5f0_ = 0.f;
float x5f4_ = 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;
s32 x5e8_stateProgress = -1;
zeus::CVector3f x5ec_;
zeus::CVector3f x5f8_targetPos;
float x604_activeSpeed = 1.f;
float x608_telegraphRemTime = 0.f;
float x60c_stuckTime = 0.f;
zeus::CVector3f x614_lastStuckPos;
std::unique_ptr<CCollisionActorManager> x620_collisionActorManager;
TLockedToken<CSkinnedModel> x624_extraModel;
zeus::CVector3f x628_;
zeus::CVector3f x634_;
zeus::CVector3f x640_;
CDamageVulnerability x64c_;
CDamageInfo x6b4_;
float x6d0_;
zeus::CVector3f x628_parasiteSeparationMove;
zeus::CVector3f x634_parasiteCohesionMove;
zeus::CVector3f x640_parasiteAlignmentMove;
CDamageVulnerability x64c_oculusHaltDVuln;
CDamageInfo x6b4_oculusHaltDInfo;
float x6d0_maxTelegraphReactDist;
float x6d4_;
float x6dc_;
float x6e0_;
float x6e4_;
float x6e8_;
float x6ec_;
float x6f0_;
float x6f4_;
float x6f8_;
float x6fc_;
float x700_;
float x704_;
float x708_;
float x710_;
float x714_;
float x6e0_stuckTimeThreshold;
float x6e4_parasiteSearchRadius;
float x6e8_parasiteSeparationDist;
float x6ec_parasiteSeparationWeight;
float x6f0_parasiteAlignmentWeight;
float x6f4_parasiteCohesionWeight;
float x6f8_destinationSeekWeight;
float x6fc_forwardMoveWeight;
float x700_playerSeparationDist;
float x704_playerSeparationWeight;
float x708_unmorphedRadius;
float x710_haltDelay;
float x714_iceZoomerJointHP;
float x718_ = 0.f;
float x71c_ = 0.f;
float x720_ = 0.f;
@ -74,7 +72,7 @@ class CParasite : public CWallWalker
{
struct
{
bool x742_24_ : 1;
bool x742_24_receivedTelegraph : 1;
bool x742_25_jumpVelDirty : 1;
bool x742_26_ : 1;
bool x742_27_landed : 1;
@ -82,8 +80,8 @@ class CParasite : public CWallWalker
bool x742_29_ : 1;
bool x742_30_attackOver : 1;
bool x742_31_ : 1;
bool x743_24_ : 1;
bool x743_25_ : 1;
bool x743_24_halted : 1;
bool x743_25_vulnerable : 1;
bool x743_26_oculusShotAt : 1;
bool x743_27_inJump : 1;
};
@ -95,13 +93,26 @@ class CParasite : public CWallWalker
TUniqueId GetClosestWaypointForState(EScriptObjectState state, CStateManager& mgr);
void UpdatePFDestination(CStateManager& mgr);
void DoFlockingBehavior(CStateManager& mgr);
void SetupIceZoomerCollision(CStateManager& mgr);
void SetupIceZoomerVulnerability(CStateManager& mgr, const CDamageVulnerability& dVuln,
const CHealthInfo& hInfo);
void AddDoorRepulsors(CStateManager& mgr);
void UpdateCollisionActors(float dt, CStateManager& mgr);
void DestroyActorManager(CStateManager& mgr);
void UpdateJumpVelocity();
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, EWalkerType wType, const CDamageVulnerability&, const CDamageInfo&, u16, u16, u16, CAssetId, CAssetId, float,
const CActorParameters&);
const zeus::CTransform &xf, CModelData &&mData, const CPatternedInfo &pInfo, EBodyType bodyType,
float maxTelegraphReactDist, float advanceWpRadius, float f3, float alignAngVel, float f5,
float stuckTimeThreshold, float collisionCloseMargin, float parasiteSearchRadius,
float parasiteSeparationDist, float parasiteSeparationWeight, float parasiteAlignmentWeight,
float parasiteCohesionWeight, float destinationSeekWeight, float forwardMoveWeight,
float playerSeparationDist, float playerSeparationWeight, float playerObstructionMinDist,
float haltDelay, bool disableMove, EWalkerType wType, const CDamageVulnerability& dVuln,
const CDamageInfo& parInfo, u16 haltSfx, u16 getUpSfx, u16 crouchSfx, CAssetId modelRes,
CAssetId skinRes, float iceZoomerJointHP,
const CActorParameters& aParams);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
@ -109,6 +120,7 @@ public:
void Think(float dt, CStateManager& mgr);
void Render(const CStateManager&) const;
const CDamageVulnerability* GetDamageVulnerability() const;
CDamageInfo GetContactDamage() const;
void Touch(CActor& actor, CStateManager&);
zeus::CVector3f GetAimPosition(const CStateManager&, float) const;
void CollidedWith(TUniqueId uid, const CCollisionInfoList&, CStateManager&);
@ -139,16 +151,5 @@ public:
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_walkerType == EWalkerType::Oculus && x743_24_)
return x6b4_;
return CPatterned::GetContactDamage();
}
void AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float);
};
}

View File

@ -485,7 +485,7 @@ void CScriptGunTurret::UpdateGunCollisionManager(float dt, CStateManager& mgr)
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(x4a0_))
colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed);
x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::Zero);
x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
}
void CScriptGunTurret::GetUnFreezeSoundId(float dt, CStateManager& mgr)

View File

@ -3,6 +3,8 @@
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "CScriptWaypoint.hpp"
#include "Collision/CMetroidAreaCollider.hpp"
#include "Collision/CGameCollision.hpp"
namespace urde
{
@ -10,19 +12,20 @@ CWallWalker::CWallWalker(ECharacter chr, TUniqueId uid, std::string_view name, E
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 kbVariant, float f3, EWalkerType wType, float f4, bool b1)
float collisionCloseMargin, float alignAngVel, EKnockBackVariant kbVariant,
float advanceWpRadius, EWalkerType wType, float playerObstructionMinDist, bool disableMove)
: 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_collisionCloseMargin(f1)
, x5b4_(f2)
, x5c0_advanceWpRadius(f3)
, x5c4_(f4)
, x5b0_collisionCloseMargin(collisionCloseMargin)
, x5b4_alignAngVel(alignAngVel)
, x5c0_advanceWpRadius(advanceWpRadius)
, x5c4_playerObstructionMinDist(playerObstructionMinDist)
, x5cc_bendingHackAnim(GetModelData()->GetAnimationData()->GetCharacterInfo().GetAnimationIndex("BendingAnimationHack"sv))
, x5d0_walkerType(wType)
, x5d6_24_(false)
, x5d6_25_(false)
, x5d6_26_(false)
, x5d6_27_(b1)
, x5d6_24_alignToFloor(false)
, x5d6_25_hasAlignSurface(false)
, x5d6_26_playerObstructed(false)
, x5d6_27_disableMove(disableMove)
, x5d6_28_addBendingWeight(true)
, x5d6_29_applyBendingHack(false)
{
@ -39,6 +42,74 @@ void CWallWalker::OrientToSurfaceNormal(const zeus::CVector3f& normal, float cla
SetTransform((zeus::CQuaternion(x34_transform.basis) * q).normalized().toTransform(GetTranslation()));
}
bool CWallWalker::PointOnSurface(const CCollisionSurface& surf, const zeus::CVector3f& point)
{
zeus::CVector3f normal = surf.GetNormal();
zeus::CVector3f projPt = ProjectPointToPlane(point, surf.GetVert(0), normal);
for (int i = 0; i < 3; ++i)
{
zeus::CVector3f projDelta = projPt - surf.GetVert(i);
zeus::CVector3f edge = surf.GetVert((i + 2) % 3) - surf.GetVert(i);
if (projDelta.cross(edge).dot(normal) < 0.f)
return false;
}
return true;
}
void CWallWalker::AlignToFloor(CStateManager& mgr, float radius, const zeus::CVector3f& newPos, float dt)
{
bool hasSurface = false;
float margin = radius + x5b0_collisionCloseMargin;
zeus::CAABox aabb(newPos - margin, newPos + margin);
CAreaCollisionCache ccache(aabb);
CGameCollision::BuildAreaCollisionCache(mgr, ccache);
if (x5d6_25_hasAlignSurface)
x5d6_25_hasAlignSurface = PointOnSurface(x568_alignNormal, newPos);
if (!x5d6_25_hasAlignSurface || !(x5d4_thinkCounter & 0x3))
{
for (auto& leaf : ccache)
{
for (auto& node : leaf)
{
CAreaOctTree::TriListReference triArr = node.GetTriangleArray();
for (u16 i = 0; i < triArr.GetSize(); ++i)
{
u16 triIdx = triArr.GetAt(i);
CCollisionSurface surf = leaf.GetOctTree().GetMasterListTriangle(triIdx);
if (std::fabs(surf.GetPlane().pointToPlaneDist(newPos)) < margin &&
PointOnSurface(surf, newPos))
{
x568_alignNormal = surf;
hasSurface = true;
}
}
}
}
x5d6_25_hasAlignSurface = hasSurface;
}
if (x5d6_25_hasAlignSurface)
{
OrientToSurfaceNormal(x568_alignNormal.GetNormal(), x5b4_alignAngVel * dt);
x5b8_tumbleAngle = 0.f;
x5d6_28_addBendingWeight = false;
}
else
{
float angDelta = zeus::radToDeg(x138_velocity.magnitude()) / x590_colSphere.GetSphere().radius * dt;
OrientToSurfaceNormal(x34_transform.basis[1], angDelta);
if (x450_bodyController->HasBodyState(pas::EAnimationState::Step))
{
x450_bodyController->GetCommandMgr().DeliverCmd(
CBCStepCmd(pas::EStepDirection::Down, pas::EStepType::Normal));
}
else
{
x5d6_28_addBendingWeight = true;
}
x5b8_tumbleAngle += angDelta;
}
}
void CWallWalker::GotoNextWaypoint(CStateManager& mgr)
{
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x2dc_destObj))
@ -49,7 +120,7 @@ void CWallWalker::GotoNextWaypoint(CStateManager& mgr)
x2dc_destObj = wp->NextWaypoint(mgr);
if (!zeus::close_enough(wp->GetPause(), 0.f))
{
x5bc_ = wp->GetPause();
x5bc_patrolPauseRemTime = wp->GetPause();
if (x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
}
@ -62,16 +133,17 @@ void CWallWalker::GotoNextWaypoint(CStateManager& mgr)
void CWallWalker::PreThink(float dt, CStateManager& mgr)
{
CPatterned::PreThink(dt, mgr);
if (!GetActive() || x5d6_26_ || x5bc_ > 0.f || x5d6_27_ || x450_bodyController->IsFrozen() || !x5d6_24_)
if (!GetActive() || x5d6_26_playerObstructed || x5bc_patrolPauseRemTime > 0.f || x5d6_27_disableMove ||
x450_bodyController->IsFrozen() || !x5d6_24_alignToFloor)
return;
zeus::CQuaternion quat(GetTransform().buildMatrix3f());
AddMotionState(PredictMotion(dt));
zeus::CQuaternion quat2(GetTransform().buildMatrix3f());
ClearForcesAndTorques();
if (x5d6_25_)
if (x5d6_25_hasAlignSurface)
{
zeus::CPlane plane = x568_.GetPlane();
zeus::CPlane plane = x568_alignNormal.GetPlane();
const float futureDt = (10.f * dt);
SetTranslation(GetTranslation() * (1.f - futureDt) +
(((GetTranslation() - ((plane.vec.dot(GetTranslation())) - plane.d) -
@ -136,7 +208,7 @@ void CWallWalker::UpdateWPDestination(CStateManager& mgr)
x2dc_destObj = wp->NextWaypoint(mgr);
if (std::fabs(wp->GetPause()) > 0.00001f)
{
x5bc_ = wp->GetPause();
x5bc_patrolPauseRemTime = wp->GetPause();
if (x5d0_walkerType == EWalkerType::Parasite)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
@ -146,4 +218,5 @@ void CWallWalker::UpdateWPDestination(CStateManager& mgr)
SetDestPos(wpPos);
}
}
}

View File

@ -18,36 +18,46 @@ public:
Seedling = 4
};
protected:
CCollisionSurface x568_ = CCollisionSurface(zeus::CVector3f(),
CCollisionSurface x568_alignNormal = CCollisionSurface(zeus::CVector3f(),
zeus::CVector3f::skForward,
zeus::CVector3f::skRight, -1);
CCollidableSphere x590_colSphere;
float x5b0_collisionCloseMargin;
float x5b4_;
float x5b8_ = 0.f;
float x5bc_ = 0.f;
float x5b4_alignAngVel;
float x5b8_tumbleAngle = 0.f;
float x5bc_patrolPauseRemTime = 0.f;
float x5c0_advanceWpRadius;
float x5c4_;
float x5c4_playerObstructionMinDist;
float x5c8_bendingHackWeight = 0.f;
s32 x5cc_bendingHackAnim;
EWalkerType x5d0_walkerType;
s16 x5d4_ = 0;
bool x5d6_24_ : 1;
bool x5d6_25_ : 1;
bool x5d6_26_ : 1;
bool x5d6_27_ : 1;
s16 x5d4_thinkCounter = 0;
bool x5d6_24_alignToFloor : 1;
bool x5d6_25_hasAlignSurface : 1;
bool x5d6_26_playerObstructed : 1;
bool x5d6_27_disableMove : 1;
bool x5d6_28_addBendingWeight : 1;
bool x5d6_29_applyBendingHack : 1;
static zeus::CVector3f ProjectVectorToPlane(const zeus::CVector3f& v0, const zeus::CVector3f& v1)
static zeus::CVector3f ProjectVectorToPlane(const zeus::CVector3f& pt, const zeus::CVector3f& plane)
{
return v0 - v1 * v0.dot(v1);
return pt - plane * pt.dot(plane);
}
static zeus::CVector3f ProjectPointToPlane(const zeus::CVector3f& p0, const zeus::CVector3f& p1,
const zeus::CVector3f& plane)
{
return p0 - (p0 - p1).dot(plane) * plane;
}
void OrientToSurfaceNormal(const zeus::CVector3f& normal, float clampAngle);
static bool PointOnSurface(const CCollisionSurface& surf, const zeus::CVector3f& point);
void AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float);
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, EWalkerType wType, float, bool);
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 collisionCloseMargin, float alignAngVel, EKnockBackVariant kbVariant,
float advanceWpRadius, EWalkerType wType, float playerObstructionMinDist, bool disableMove);
void PreThink(float, CStateManager&);
void Think(float, CStateManager&);

View File

@ -1898,24 +1898,24 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr
CPatternedInfo pInfo(in, pcount.second);
CActorParameters aParms = LoadActorParameters(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float maxTelegraphReactDist = in.readFloatBig();
float advanceWpRadius = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
float alignAngVel = in.readFloatBig();
float f5 = in.readFloatBig();
float f6 = in.readFloatBig();
float f7 = in.readFloatBig();
float f8 = in.readFloatBig();
float f9 = in.readFloatBig();
float f10 = in.readFloatBig();
float f11 = in.readFloatBig();
float f12 = in.readFloatBig();
float f13 = in.readFloatBig();
float f14 = in.readFloatBig();
float f15 = in.readFloatBig();
float f16 = in.readFloatBig();
float f17 = in.readFloatBig();
bool b1 = in.readBool();
float stuckTimeThreshold = in.readFloatBig();
float collisionCloseMargin = in.readFloatBig();
float parasiteSearchRadius = in.readFloatBig();
float parasiteSeparationDist = in.readFloatBig();
float parasiteSeparationWeight = in.readFloatBig();
float parasiteAlignmentWeight = in.readFloatBig();
float parasiteCohesionWeight = in.readFloatBig();
float destinationSeekWeight = in.readFloatBig();
float forwardMoveWeight = in.readFloatBig();
float playerSeparationDist = in.readFloatBig();
float playerSeparationWeight = in.readFloatBig();
float playerObstructionMinDist = in.readFloatBig();
bool disableMove = in.readBool();
if (g_ResFactory->GetResourceTypeById(pInfo.GetAnimationParameters().GetACSFile()) != SBIG('ANCS'))
return nullptr;
@ -1923,8 +1923,11 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr
CModelData mData(
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, CWallWalker::EWalkerType::Parasite,
EBodyType::WallWalker, maxTelegraphReactDist, advanceWpRadius, f3, alignAngVel, f5,
stuckTimeThreshold, collisionCloseMargin, parasiteSearchRadius, parasiteSeparationDist,
parasiteSeparationWeight, parasiteAlignmentWeight, parasiteCohesionWeight,
destinationSeekWeight, forwardMoveWeight, playerSeparationDist, playerSeparationWeight,
playerObstructionMinDist, 0.f, disableMove, CWallWalker::EWalkerType::Parasite,
CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(),
-1, -1, -1, {}, {}, 0.f, aParms);
}

View File

@ -161,7 +161,7 @@ std::string_view ScriptObjectStateToStr(EScriptObjectState state)
case EScriptObjectState::Dead: return "Dead"sv;
case EScriptObjectState::CameraPath: return "CameraPath"sv;
case EScriptObjectState::CameraTarget: return "CameraTarget"sv;
case EScriptObjectState::UNKS2: return "UNKS2"sv;
case EScriptObjectState::DeactivateState: return "DeactivateState"sv;
case EScriptObjectState::Play: return "Play"sv;
case EScriptObjectState::MassiveDeath: return "DeathExplosion"sv;
case EScriptObjectState::DeathRattle: return "DeathRattle"sv;

View File

@ -157,7 +157,7 @@ enum class EScriptObjectState
Dead = 14,
CameraPath = 15,
CameraTarget = 16,
UNKS2 = 17,
DeactivateState = 17,
Play = 18,
MassiveDeath = 19,
DeathRattle = 20,

@ -1 +1 @@
Subproject commit de445734f8909b6eba9680a1c66f9807f48a931a
Subproject commit 90665dd3d12e659f88ee46b2c7bd2873fefa4c90