Implement CWallCrawlerSwarm

This commit is contained in:
Jack Andersen 2019-03-23 22:06:59 -10:00
parent 99b1a8ef49
commit a63a61fef8
19 changed files with 1443 additions and 170 deletions

View File

@ -56,7 +56,7 @@ enum class ESpecialFunctionType : atUint32 {
PlayerFollowLocator,
SpinnerController,
ObjectFollowLocator,
Function4,
ChaffTarget,
InventoryActivator,
MapStation,
SaveStation,
@ -74,7 +74,7 @@ enum class ESpecialFunctionType : atUint32 {
ObjectFollowObject,
HintSystem,
DropBomb,
Function22,
ScaleActor,
MissileStation,
Billboard,
PlayerInAreaRelay,
@ -85,7 +85,7 @@ enum class ESpecialFunctionType : atUint32 {
Ending,
FusionRelay,
WeaponSwitch // PAL Only
} SPECTER_ENUM("Special Function", "", EPickupType);
} SPECTER_ENUM("Special Function", "", ESpecialFunctionType);
struct AnimationParameters : BigDNA {
AT_DECL_DNA_YAML

View File

@ -14,60 +14,70 @@ struct WallCrawlerSwarm : IScriptObject {
Value<atVec3f> volume;
Value<bool> active;
ActorParameters actorParameters;
Value<atUint32> unknown1;
Value<atUint32> flavor;
AnimationParameters animationParameters;
Value<atUint32> unknown2;
Value<atUint32> unknown3;
UniqueID32 particle1;
UniqueID32 particle2;
Value<atUint32> unknown4; // always FF
Value<atUint32> unknown5; // always FF
DamageInfo damageInfo1;
Value<float> unknown6;
DamageInfo damageInfo2;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
Value<atUint32> unknown11;
Value<atUint32> unknown12;
Value<float> unknown13;
Value<float> unknown14;
Value<float> unknown15;
Value<float> unknown16;
Value<float> unknown17;
Value<float> unknown18;
Value<float> unknown19;
Value<float> unknown20;
Value<atUint32> unknown21;
Value<float> unkown22;
Value<float> unkown23;
Value<float> unkown24;
Value<atUint32> launchAnim;
Value<atUint32> attractAnim;
UniqueID32 part1;
UniqueID32 part2;
UniqueID32 part3;
UniqueID32 part4;
DamageInfo crabDamage;
Value<float> crabDamageCooldown;
DamageInfo scarabExplodeDamage;
Value<float> boidRadius;
Value<float> touchRadius;
Value<float> playerTouchRadius;
Value<float> animPlaybackSpeed;
Value<atUint32> numBoids;
Value<atUint32> maxCreatedBoids;
Value<float> separationRadius;
Value<float> cohesionMagnitude;
Value<float> alignmentWeight;
Value<float> separationMagnitude;
Value<float> moveToWaypointWeight;
Value<float> attractionMagnitude;
Value<float> attractionRadius;
Value<float> boidGenRate;
Value<atUint32> maxLaunches;
Value<float> scarabBoxMargin;
Value<float> scarabScatterXYVelocity;
Value<float> scarabTimeToExplode;
HealthInfo healthInfo;
DamageVulnerability damageVulnerabilty;
Value<atUint32> soundID1; // verification needed
Value<atUint32> soundID2; // verification needed
Value<atUint32> launchSfx;
Value<atUint32> scatterSfx;
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters);
}
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const {
if (particle1) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
if (part1) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part1);
ent->name = name + "_part1";
}
if (particle2) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
if (part2) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part2);
ent->name = name + "_part2";
}
if (part3) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part3);
ent->name = name + "_part3";
}
if (part4) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part4);
ent->name = name + "_part4";
}
animationParameters.nameANCS(pakRouter, name + "_animp");
actorParameters.nameIDs(pakRouter, name + "_actp");
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, std::vector<hecl::ProjectPath>& lazyOut) const {
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(part1, pathsOut);
g_curSpec->flattenDependencies(part2, pathsOut);
g_curSpec->flattenDependencies(part3, pathsOut);
g_curSpec->flattenDependencies(part4, pathsOut);
animationParameters.depANCS(pathsOut);
actorParameters.depIDs(pathsOut, lazyOut);
}

View File

@ -83,6 +83,7 @@ class CAnimData {
friend class CActor;
friend class CPlayerGun;
friend class CGrappleArm;
friend class CWallCrawlerSwarm;
public:
enum class EAnimDir { Forward, Backward };

View File

@ -117,7 +117,7 @@ void CBodyController::FaceDirection3D(const zeus::CVector3f& v0, const zeus::CVe
zeus::CUnitVector3f uv0 = v0;
zeus::CUnitVector3f uv1 = v1;
float dot = uv0.dot(uv1);
if (std::fabs(dot - 1.f) >= 0.00001f) {
if (!zeus::close_enough(dot, 1.f)) {
if (dot < -0.9999f) {
zeus::CQuaternion rot =
zeus::CQuaternion::fromAxisAngle(act->GetTransform().basis[2], zeus::degToRad(dt * x2fc_turnSpeed));

View File

@ -273,10 +273,8 @@ void CModelData::Touch(const CStateManager& stateMgr, int shaderIdx) const {
Touch(const_cast<CModelData&>(*this).GetRenderingModel(stateMgr), shaderIdx);
}
void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor,
void CModelData::RenderThermal(const zeus::CColor& mulColor, const zeus::CColor& addColor,
const CModelFlags& flags) const {
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale));
CGraphics::DisableAllLights();
CModelFlags drawFlags = flags;
drawFlags.x4_color *= mulColor;
drawFlags.addColor = addColor;
@ -292,6 +290,13 @@ void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& m
}
}
void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor,
const CModelFlags& flags) const {
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale));
CGraphics::DisableAllLights();
RenderThermal(mulColor, addColor, flags);
}
void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights,
const CModelFlags& drawFlags) const {
if ((x14_25_sortThermal && which == EWhichModel::ThermalHot) || x10_animData || !x1c_normalModel ||

View File

@ -48,7 +48,9 @@ public:
void SetCharacterNodeId(s32 id) { x4_charIdx = id; }
const zeus::CVector3f& GetScale() const { return x8_scale; }
bool CanLoop() const { return x14_canLoop; }
void SetCanLoop(bool l) { x14_canLoop = l; }
s32 GetDefaultAnim() const { return x18_defaultAnim; }
void SetDefaultAnim(s32 anim) { x18_defaultAnim = anim; }
};
class CModelData {
@ -116,6 +118,8 @@ public:
void RenderParticles(const zeus::CFrustum& frustum) const;
void Touch(EWhichModel, int shaderIdx) const;
void Touch(const CStateManager& stateMgr, int shaderIdx) const;
void RenderThermal(const zeus::CColor& mulColor, const zeus::CColor& addColor,
const CModelFlags& flags) const;
void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor,
const CModelFlags& flags) const;
void RenderUnsortedParts(EWhichModel, const zeus::CTransform& xf, const CActorLights* lights,

View File

@ -447,13 +447,13 @@ bool CGameCollision::DetectStaticCollisionBoolean_Cached(const CStateManager& mg
return DetectStaticCollisionBoolean(mgr, prim, xf, filter);
if (prim.GetPrimType() == FOURCC('AABX')) {
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
if (CMetroidAreaCollider::AABoxCollisionCheckBoolean_Cached(leafCache, aabb, filter))
return true;
} else if (prim.GetPrimType() == FOURCC('SPHR')) {
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
zeus::CSphere xfSphere = sphere.Transform(xf);
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
if (CMetroidAreaCollider::SphereCollisionCheckBoolean_Cached(leafCache, aabb, xfSphere, filter))
return true;
} else if (prim.GetPrimType() == FOURCC('ABSH')) {
@ -566,13 +566,13 @@ bool CGameCollision::DetectStaticCollision_Cached(const CStateManager& mgr, CAre
return DetectStaticCollision(mgr, prim, xf, filter, list);
if (prim.GetPrimType() == FOURCC('AABX')) {
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
if (CMetroidAreaCollider::AABoxCollisionCheck_Cached(leafCache, calcAABB, filter, prim.GetMaterial(), list))
ret = true;
} else if (prim.GetPrimType() == FOURCC('SPHR')) {
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
zeus::CSphere xfSphere = sphere.Transform(xf);
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
if (CMetroidAreaCollider::SphereCollisionCheck_Cached(leafCache, calcAABB, xfSphere, prim.GetMaterial(), filter,
list))
ret = true;
@ -604,7 +604,7 @@ bool CGameCollision::DetectStaticCollision_Cached_Moving(const CStateManager& mg
}
if (prim.GetPrimType() == FOURCC('AABX')) {
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache) {
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache) {
CCollisionInfo info;
double d = dOut;
if (CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(
@ -617,7 +617,7 @@ bool CGameCollision::DetectStaticCollision_Cached_Moving(const CStateManager& mg
} else if (prim.GetPrimType() == FOURCC('SPHR')) {
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
zeus::CSphere xfSphere = sphere.Transform(xf);
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache) {
for (const CMetroidAreaCollider::COctreeLeafCache& leafCache : cache) {
CCollisionInfo info;
double d = dOut;
if (CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(

View File

@ -121,8 +121,8 @@ public:
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(); }
rstl::reserved_vector<CAreaOctTree::Node, 64>::const_iterator begin() const { return x4_nodeCache.begin(); }
rstl::reserved_vector<CAreaOctTree::Node, 64>::const_iterator end() const { return x4_nodeCache.end(); }
};
static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb,
CMetroidAreaCollider::COctreeLeafCache& cache);
@ -182,8 +182,10 @@ public:
u32 GetNumCaches() const { return x18_leafCaches.size(); }
const CMetroidAreaCollider::COctreeLeafCache& GetOctreeLeafCache(int idx) { return x18_leafCaches[idx]; }
bool HasCacheOverflowed() const { return x1b40_24_leafOverflow; }
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::iterator begin() { return x18_leafCaches.begin(); }
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::iterator end() { return x18_leafCaches.end(); }
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::const_iterator begin() const
{ return x18_leafCaches.begin(); }
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::const_iterator end() const
{ return x18_leafCaches.end(); }
};
} // namespace urde

View File

@ -200,6 +200,7 @@ public:
bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; }
void ActivateLights(const std::vector<CLight>& lights);
void SetAmbientColor(const zeus::CColor& color) { m_lightingData.ambient = color; }
void DisableAllLights();
void RemapMaterialData(SShader& shader);
void RemapMaterialData(SShader& shader, const std::unordered_map<int, CModelShaders::ShaderPipelines>& pipelines);

View File

@ -898,6 +898,9 @@ void GeometryUniformLayout::Update(const CModelFlags& flags, const CSkinRules* c
boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr,
const CPoseAsTransforms* pose,
int sharedLayoutBuf) const {
if (!TryLockTextures())
return {};
/* Invalidate instances if new shadow being drawn */
if (flags.m_extendedShader == EExtendedShader::WorldShadow && m_lastDrawnShadowMap != g_shadowMap) {
const_cast<CBooModel*>(this)->m_lastDrawnShadowMap = g_shadowMap;
@ -916,7 +919,7 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
do {
inst = const_cast<CBooModel*>(this)->PushNewModelInstance(m_instances.size());
if (!inst)
return nullptr;
return {};
} while (m_instances.size() <= sharedLayoutBuf);
} else
inst = &m_instances[sharedLayoutBuf];
@ -925,7 +928,7 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
if (m_instances.size() <= m_uniUpdateCount) {
inst = const_cast<CBooModel*>(this)->PushNewModelInstance(sharedLayoutBuf);
if (!inst)
return nullptr;
return {};
} else
inst = &m_instances[m_uniUpdateCount];
++const_cast<CBooModel*>(this)->m_uniUpdateCount;

View File

@ -27,6 +27,9 @@ public:
TLockedToken<CCharLayoutInfo> layoutInfo, int shaderIdx, int drawInsts);
CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo, int shaderIdx,
int drawInsts);
std::unique_ptr<CSkinnedModel> Clone(int shaderIdx = 0, int drawInsts = 1) const {
return std::make_unique<CSkinnedModel>(x4_model, x10_skinRules, x1c_layoutInfo, shaderIdx, drawInsts);
}
const TLockedToken<CModel>& GetModel() const { return x4_model; }
const std::unique_ptr<CBooModel>& GetModelInst() const { return m_modelInst; }

View File

@ -89,8 +89,7 @@ sourcef = open('TCastTo.cpp', 'w')
headerf.write('''#pragma once
namespace urde
{
namespace urde {
class CEntity;
''')
@ -98,58 +97,56 @@ for tp in CENTITY_TYPES:
if type(tp) == tuple:
headerf.write('class %s;\n' % tp[0])
elif isinstance(tp, Namespace):
headerf.write('namespace %s\n{\n' % tp.name)
headerf.write('namespace %s {\n' % tp.name)
elif isinstance(tp, EndNamespace):
headerf.write('}\n')
headerf.write('\nclass IVisitor\n{\npublic:\n')
headerf.write('\nclass IVisitor {\npublic:\n')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
headerf.write(' virtual void Visit(%s* p)=0;\n' % getqualified(tp))
headerf.write(' virtual void Visit(%s* p)=0;\n' % getqualified(tp))
headerf.write('''};
template <class T>
class TCastToPtr : public IVisitor
{
class TCastToPtr : public IVisitor {
protected:
T* ptr = nullptr;
T* ptr = nullptr;
public:
TCastToPtr() = default;
TCastToPtr(CEntity* p);
TCastToPtr(CEntity& p);
TCastToPtr<T>& operator=(CEntity& p);
TCastToPtr<T>& operator=(CEntity* p);
TCastToPtr() = default;
TCastToPtr(CEntity* p);
TCastToPtr(CEntity& p);
TCastToPtr<T>& operator=(CEntity& p);
TCastToPtr<T>& operator=(CEntity* p);
''')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
headerf.write(' void Visit(%s* p);\n' % getqualified(tp))
headerf.write(' void Visit(%s* p);\n' % getqualified(tp))
headerf.write('''
T* GetPtr() const { return ptr; }
operator T*() const { return GetPtr(); }
T& operator*() const { return *GetPtr(); }
T* operator->() const { return GetPtr(); }
operator bool() const { return ptr != nullptr; }
T* GetPtr() const { return ptr; }
operator T*() const { return GetPtr(); }
T& operator*() const { return *GetPtr(); }
T* operator->() const { return GetPtr(); }
operator bool() const { return ptr != nullptr; }
};
template <class T>
class TCastToConstPtr : TCastToPtr<T>
{
class TCastToConstPtr : TCastToPtr<T> {
public:
TCastToConstPtr() = default;
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
TCastToConstPtr<T>& operator=(const CEntity& p) { TCastToPtr<T>::operator=(const_cast<CEntity&>(p)); return *this; }
TCastToConstPtr<T>& operator=(const CEntity* p) { TCastToPtr<T>::operator=(const_cast<CEntity*>(p)); return *this; }
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
operator const T*() const { return GetPtr(); }
const T& operator*() const { return *GetPtr(); }
const T* operator->() const { return GetPtr(); }
operator bool() const { return TCastToPtr<T>::ptr != nullptr; }
TCastToConstPtr() = default;
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
TCastToConstPtr<T>& operator=(const CEntity& p) { TCastToPtr<T>::operator=(const_cast<CEntity&>(p)); return *this; }
TCastToConstPtr<T>& operator=(const CEntity* p) { TCastToPtr<T>::operator=(const_cast<CEntity*>(p)); return *this; }
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
operator const T*() const { return GetPtr(); }
const T& operator*() const { return *GetPtr(); }
const T* operator->() const { return GetPtr(); }
operator bool() const { return TCastToPtr<T>::ptr != nullptr; }
};
}
@ -164,8 +161,7 @@ for tp in CENTITY_TYPES:
sourcef.write('#include "%s"\n' % tp[1])
sourcef.write('''
namespace urde
{
namespace urde {
template <class T>
TCastToPtr<T>::TCastToPtr(CEntity* p) { if (p) p->Accept(*this); else ptr = nullptr; }
@ -185,10 +181,9 @@ for tp in CENTITY_TYPES:
if type(tp) == tuple:
qual = getqualified(tp)
sourcef.write('''template <class T>
void TCastToPtr<T>::Visit(%s* p)
{
static_assert(sizeof(T) > 0 && !std::is_void<T>::value, "TCastToPtr can not cast to incomplete type");
ptr = reinterpret_cast<T*>(std::is_convertible<%s*, T*>::value ? p : nullptr);
void TCastToPtr<T>::Visit(%s* p) {
static_assert(sizeof(T) > 0 && !std::is_void<T>::value, "TCastToPtr can not cast to incomplete type");
ptr = reinterpret_cast<T*>(std::is_convertible<%s*, T*>::value ? p : nullptr);
}
''' % (qual, qual))

View File

@ -67,5 +67,7 @@ public:
const CLightParameters& GetLightParameters() const { return x0_lightParms; }
bool HasThermalHeat() const { return x58_25_thermalHeat; }
float GetThermalMag() const { return x64_thermalMag; }
const std::pair<CAssetId, CAssetId>& GetXRayAssets() const { return x44_xrayAssets; }
const std::pair<CAssetId, CAssetId>& GetThermalAssets() const { return x4c_thermalAssets; }
};
} // namespace urde

File diff suppressed because it is too large Load Diff

View File

@ -2,65 +2,200 @@
#include "World/CActor.hpp"
#include "Collision/CCollisionSurface.hpp"
#include "World/CDamageInfo.hpp"
#include "World/CDamageVulnerability.hpp"
#include "Particle/CElementGen.hpp"
namespace urde {
class CAreaCollisionCache;
class CWallCrawlerSwarm : public CActor {
public:
enum class EFlavor {
Parasite,
Scarab,
Crab
};
class CBoid {
zeus::CTransform x0_;
float x30_ = 0.f;
float x34_ = 0.f;
float x38_ = 0.f;
TUniqueId x3c_ = kInvalidUniqueId;
zeus::CColor x40_ = zeus::CColor(0.3f, 0.3f, 0.3f, 1.f);
u32 x44_ = 0;
float x48_ = 0.f;
float x4c_ = 0.f;
CCollisionSurface x50_ = CCollisionSurface(zeus::CVector3f(0.f, 0.f, 1.f), zeus::CVector3f(0.f, 1.f, 0.f),
zeus::CVector3f(1.f, 0.f, 0.f), -1);
union {
struct {
u32 x7c_unk1 : 8;
u32 x7c_unk2 : 10;
};
u32 x7c_;
};
friend class CWallCrawlerSwarm;
zeus::CTransform x0_xf;
zeus::CVector3f x30_velocity;
TUniqueId x3c_targetWaypoint = kInvalidUniqueId;
zeus::CColor x40_ambientLighting = zeus::CColor(0.3f, 0.3f, 0.3f, 1.f);
CBoid* x44_next = nullptr;
float x48_timeToDie = 0.f;
float x4c_timeToExplode = 0.f;
CCollisionSurface x50_surface =
CCollisionSurface(zeus::CVector3f(0.f, 0.f, 1.f), zeus::CVector3f(0.f, 1.f, 0.f),
zeus::CVector3f(1.f, 0.f, 0.f), 0xffffffff);
float x78_health;
int x7c_framesNotOnSurface : 8;
int x7c_idx : 10;
int x7c_remainingLaunchNotOnSurfaceFrames : 8;
union {
struct {
bool x80_24_active : 1;
bool x80_25_ : 1;
bool x80_26_ : 1;
bool x80_27_ : 1;
bool x80_28_ : 1;
bool x80_25_inFrustum : 1;
bool x80_26_launched : 1;
bool x80_27_scarabExplodeTimerEnabled : 1;
bool x80_28_nearPlayer : 1;
};
u32 x80_;
u32 x80_ = 0;
};
public:
const zeus::CTransform& GetTransform() const { return x0_; }
const zeus::CVector3f& GetTranslation() const { return x0_.origin; }
CBoid(const zeus::CTransform& xf, int idx) : x0_xf(xf) {
x7c_framesNotOnSurface = 0;
x7c_idx = idx;
}
zeus::CTransform& Transform() { return x0_xf; }
zeus::CVector3f& Translation() { return x0_xf.origin; }
const zeus::CTransform& GetTransform() const { return x0_xf; }
const zeus::CVector3f& GetTranslation() const { return x0_xf.origin; }
bool GetActive() const { return x80_24_active; }
};
class CRepulsor {
friend class CWallCrawlerSwarm;
zeus::CVector3f x0_center;
float xc_mag;
public:
CRepulsor(const zeus::CVector3f& center, float mag) : x0_center(center), xc_mag(mag) {}
};
private:
zeus::CAABox xe8_aabox = zeus::skNullBox;
s32 x100_thinkCounter = 0;
float x104_occludedTimer = 5.f;
std::vector<CBoid> x108_boids;
zeus::CVector3f x118_boundingBoxExtent;
mutable zeus::CVector3f x124_lastOrbitPosition;
zeus::CVector3f x130_lastKilledOffset;
int x42c_lockOnId = -1;
float x13c_separationRadius;
float x140_cohesionMagnitude;
float x144_alignmentWeight;
float x148_separationMagnitude;
float x14c_moveToWaypointWeight;
float x150_attractionMagnitude;
float x154_attractionRadius;
float x158_scarabScatterXYVelocity;
float x15c_scarabTimeToExplode;
float x160_animPlaybackSpeed;
float x164_waypointGoalRadius = 3.f;
rstl::reserved_vector<CBoid*, 125> x168_partitionedBoidLists;
CBoid* x360_outlierBoidList = nullptr;
float x364_boidGenRate;
float x368_boidGenCooldownTimer = 0.f;
float x36c_crabDamageCooldownTimer = 0.f;
float x370_crabDamageCooldown;
float x374_boidRadius;
float x378_touchRadius;
float x37c_scarabBoxMargin;
float x380_playerTouchRadius;
CDamageInfo x384_crabDamage;
CDamageInfo x3a0_scarabExplodeDamage;
CHealthInfo x3bc_hInfo;
CDamageVulnerability x3c4_dVuln;
s32 x42c_lockOnIdx = -1;
/* Used to be position and normal array pointers */
//rstl::reserved_vector<std::unique_ptr<float[]>, 10> x430_;
//rstl::reserved_vector<std::unique_ptr<float[]>, 10> x484_;
rstl::reserved_vector<std::shared_ptr<CModelData>, 10> x4b0_modelDatas;
CModelData::EWhichModel x4dc_whichModel = CModelData::EWhichModel::Normal;
std::vector<CRepulsor> x4e0_doorRepulsors;
rstl::reserved_vector<TLockedToken<CGenDescription>, 4> x4f0_particleDescs;
rstl::reserved_vector<std::unique_ptr<CElementGen>, 4> x524_particleGens;
s32 x548_numBoids;
s32 x54c_maxCreatedBoids;
u32 x550_createdBoids = 0;
s32 x554_maxLaunches;
EFlavor x558_flavor;
u16 x55c_launchSfx;
u16 x55e_scatterSfx;
bool x560_24_enableLighting : 1;
bool x560_25_useSoftwareLight : 1;
bool x560_26_modelAssetDirty : 1;
void AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which);
void AddDoorRepulsors(CStateManager& mgr);
void UpdateParticles(float dt);
int SelectLockOnIdx(CStateManager& mgr) const;
zeus::CAABox GetBoundingBox() const;
TUniqueId GetWaypointForState(EScriptObjectState state, CStateManager& mgr) const;
static zeus::CVector3f ProjectVectorToPlane(const zeus::CVector3f& pt, const zeus::CVector3f& plane) {
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;
}
bool PointOnSurface(const CCollisionSurface& surf, const zeus::CVector3f& pos, const zeus::CPlane& plane) const;
bool FindBestSurface(const CAreaCollisionCache& ccache, const zeus::CVector3f& pos, float radius,
CCollisionSurface& out) const;
CCollisionSurface FindBestCollisionInBox(CStateManager& mgr, const zeus::CVector3f& wpPos) const;
void CreateBoid(CStateManager& mgr, int idx);
void ExplodeBoid(CBoid& boid, CStateManager& mgr);
void SetExplodeTimers(const zeus::CVector3f& pos, float radius, float minTime, float maxTime);
CBoid* GetListAt(const zeus::CVector3f& pos);
void BuildBoidNearList(const CBoid& boid, float radius, rstl::reserved_vector<CBoid*, 50>& nearList);
void ApplySeparation(const CBoid& boid, const rstl::reserved_vector<CBoid*, 50>& nearList,
zeus::CVector3f& aheadVec) const;
void ApplySeparation(const CBoid& boid, const zeus::CVector3f& separateFrom, float separationRadius, float separationMagnitude,
zeus::CVector3f& aheadVec) const;
void ScatterScarabBoid(CBoid& boid, CStateManager& mgr) const;
void MoveToWayPoint(CBoid& boid, CStateManager& mgr, zeus::CVector3f& aheadVec) const;
void ApplyCohesion(const CBoid& boid, const rstl::reserved_vector<CBoid*, 50>& nearList,
zeus::CVector3f& aheadVec) const;
void ApplyCohesion(const CBoid& boid, const zeus::CVector3f& cohesionFrom, float cohesionRadius, float cohesionMagnitude,
zeus::CVector3f& aheadVec) const;
void ApplyAlignment(const CBoid& boid, const rstl::reserved_vector<CBoid*, 50>& nearList,
zeus::CVector3f& aheadVec) const;
void ApplyAttraction(const CBoid& boid, const zeus::CVector3f& attractTo, float attractionRadius, float attractionMagnitude,
zeus::CVector3f& aheadVec) const;
void UpdateBoid(const CAreaCollisionCache& ccache, CStateManager& mgr, float dt, CBoid& boid);
void LaunchBoid(CBoid& boid, const zeus::CVector3f& dir);
void AddParticle(const zeus::CTransform& xf);
void KillBoid(CBoid& boid, CStateManager& mgr, float deathRattleChance, float deadChance);
void UpdatePartition();
zeus::CVector3f FindClosestCell(const zeus::CVector3f& pos) const;
void UpdateEffects(CStateManager& mgr, CAnimData& aData, int vol);
zeus::CAABox BoxForPosition(int x, int y, int z, float f) const;
void RenderParticles() const;
zeus::CColor SoftwareLight(const CStateManager& mgr, const zeus::CAABox& aabb) const;
void HardwareLight(const CStateManager& mgr, const zeus::CAABox& aabb) const;
void RenderBoid(const CBoid* boid, u32& drawMask, bool thermalHot, const CModelFlags& flags) const;
public:
CWallCrawlerSwarm(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CVector3f&,
const zeus::CTransform&, u32, const CAnimRes&, u32, u32, u32, u32, u32, u32, const CDamageInfo&,
const CDamageInfo&, float, float, float, float, u32, u32, float, float, float, float, float, float,
float, float, float, u32, float, float, float, const CHealthInfo&, const CDamageVulnerability&, u32,
u32, const CActorParameters&);
CWallCrawlerSwarm(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f& boundingBoxExtent, const zeus::CTransform& xf,
EFlavor flavor, const CAnimRes& animRes, s32 launchAnim, s32 attractAnim,
CAssetId part1, CAssetId part2, CAssetId part3, CAssetId part4,
const CDamageInfo& crabDamage, const CDamageInfo& scarabExplodeDamage,
float crabDamageCooldown, float boidRadius, float touchRadius,
float playerTouchRadius, u32 numBoids, u32 maxCreatedBoids,
float animPlaybackSpeed, float separationRadius, float cohesionMagnitude,
float alignmentWeight, float separationMagnitude, float moveToWaypointWeight,
float attractionMagnitude, float attractionRadius, float boidGenRate,
u32 maxLaunches, float scarabBoxMargin, float scarabScatterXYVelocity,
float scarabTimeToExplode, const CHealthInfo& hInfo,
const CDamageVulnerability& dVuln, s32 launchSfx,
s32 scatterSfx, const CActorParameters& aParams);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
void PreRender(CStateManager&, const zeus::CFrustum&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void Render(const CStateManager&) const;
bool CanRenderUnsorted(const CStateManager&) const;
void CalculateRenderBounds();
rstl::optional<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor& other, CStateManager&);
zeus::CVector3f GetOrbitPosition(const CStateManager&) const;
zeus::CVector3f GetAimPosition(const CStateManager&, float) const;
const zeus::CVector3f& GetLastKilledOffset() const { return x130_lastKilledOffset; }
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr) {}
const std::vector<CBoid>& GetBoids() const { return x108_boids; }
int GetCurrentLockOnId() const { return x42c_lockOnId; }
int GetCurrentLockOnId() const { return x42c_lockOnIdx; }
bool GetLockOnLocationValid(int id) const { return id >= 0 && id < x108_boids.size() && x108_boids[id].GetActive(); }
const zeus::CVector3f& GetLockOnLocation(int id) const { return x108_boids[id].GetTranslation(); }
};

View File

@ -2466,46 +2466,51 @@ CEntity* ScriptLoader::LoadWallCrawlerSwarm(CStateManager& mgr, CInputStream& in
SScaledActorHead aHead = LoadScaledActorHead(in, mgr);
bool active = in.readBool();
CActorParameters aParams = LoadActorParameters(in);
u32 w1 = in.readUint32Big();
u32 w2 = in.readUint32Big();
u32 w3 = in.readUint32Big();
u32 w4 = in.readUint32Big();
u32 w5 = in.readUint32Big();
u32 w6 = in.readUint32Big();
u32 w7 = in.readUint32Big();
u32 w8 = in.readUint32Big();
u32 w9 = in.readUint32Big();
u32 w10 = in.readUint32Big();
CDamageInfo dInfo1(in);
float f1 = in.readFloatBig();
CDamageInfo dInfo2(in);
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
float f5 = in.readFloatBig();
u32 w11 = in.readUint32Big();
u32 w12 = in.readUint32Big();
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();
u32 w13 = in.readUint32Big();
float f14 = in.readFloatBig();
float f15 = in.readFloatBig();
float f16 = in.readFloatBig();
CWallCrawlerSwarm::EFlavor flavor = CWallCrawlerSwarm::EFlavor(in.readUint32Big());
u32 actor = in.readUint32Big();
u32 charIdx = in.readUint32Big();
u32 defaultAnim = in.readUint32Big();
u32 launchAnim = in.readUint32Big();
u32 attractAnim = in.readUint32Big();
u32 part1 = in.readUint32Big();
u32 part2 = in.readUint32Big();
u32 part3 = in.readUint32Big();
u32 part4 = in.readUint32Big();
CDamageInfo crabDamage(in);
float crabDamageCooldown = in.readFloatBig();
CDamageInfo scarabExplodeDamage(in);
float boidRadius = in.readFloatBig();
float touchRadius = in.readFloatBig();
float playerTouchRadius = in.readFloatBig();
float animPlaybackSpeed = in.readFloatBig();
u32 numBoids = in.readUint32Big();
u32 maxCreatedBoids = in.readUint32Big();
float separationRadius = in.readFloatBig();
float cohesionMagnitude = in.readFloatBig();
float alignmentWeight = in.readFloatBig();
float separationMagnitude = in.readFloatBig();
float moveToWaypointWeight = in.readFloatBig();
float attractionMagnitude = in.readFloatBig();
float attractionRadius = in.readFloatBig();
float boidGenRate = in.readFloatBig();
u32 maxLaunches = in.readUint32Big();
float scarabBoxMargin = in.readFloatBig();
float scarabScatterXYVelocity = in.readFloatBig();
float scarabTimeToExplode = in.readFloatBig();
CHealthInfo hInfo(in);
CDamageVulnerability dVulns(in);
u32 w14 = in.readUint32Big();
u32 w15 = in.readUint32Big();
u32 launchSfx = in.readUint32Big();
u32 scatterSfx = in.readUint32Big();
return new CWallCrawlerSwarm(mgr.AllocateUniqueId(), active, aHead.x0_name, info, aHead.x40_scale,
aHead.x10_transform, w1, CAnimRes(w2, w3, zeus::CVector3f(1.5f), w4, true), w5, w6, w7,
w8, w9, w10, dInfo1, dInfo2, f1, f2, f3, f4, w11, w12, f5, f6, f7, f8, f9, f10, f11, f12,
f13, w13, f14, f15, f16, hInfo, dVulns, w14, w15, aParams);
aHead.x10_transform, flavor,
CAnimRes(actor, charIdx, zeus::CVector3f(1.5f), defaultAnim, true),
launchAnim, attractAnim, part1, part2, part3, part4, crabDamage, scarabExplodeDamage,
crabDamageCooldown, boidRadius, touchRadius, playerTouchRadius, numBoids,
maxCreatedBoids, animPlaybackSpeed, separationRadius, cohesionMagnitude, alignmentWeight,
separationMagnitude, moveToWaypointWeight, attractionMagnitude, attractionRadius,
boidGenRate, maxLaunches, scarabBoxMargin, scarabScatterXYVelocity, scarabTimeToExplode,
hInfo, dVulns, launchSfx, scatterSfx, aParams);
}
CEntity* ScriptLoader::LoadAiJumpPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {

2
hecl

@ -1 +1 @@
Subproject commit e57b8113abfb6fb256da97bf0acb082acca07dfc
Subproject commit 957a6c6851ee80c413cd1ba69795f92a8f336363

View File

@ -14,7 +14,7 @@ type summary add --summary-string "(${var.mSimd.__s_.__storage_[0]}, ${var.mSimd
type summary add --summary-string "${var.angle}" zeus::CRelAngle
type summary add --summary-string "(${var.mSimd.__s_.__storage_[0]}, ${var.mSimd.__s_.__storage_[1]}, ${var.mSimd.__s_.__storage_[2]}, ${var.mSimd.__s_.__storage_[3]})" zeus::CQuaternion
type summary add --summary-string "pos=${var.position} radius=${var.radius}" zeus::CSphere
type summary add --summary-string "norm=${var.position} d=${var.d}" zeus::CPlane
type summary add --summary-string "norm=(${var.mSimd.__s_.__storage_[0]}, ${var.mSimd.__s_.__storage_[1]}, ${var.mSimd.__s_.__storage_[2]}) d=${var.mSimd.__s_.__storage_[3]}" zeus::CPlane
type summary add --summary-string "min=${var.min} max=${var.max}" zeus::CAABox
type summary add --summary-string "start=${var.origin} dir=${var.dir}" zeus::CLine
type summary add --summary-string "start=${var.x0_start} dir=${var.xc_dir} end=${var.x18_end}" zeus::CLineSeg

@ -1 +1 @@
Subproject commit a7bd8f8235372b986c8793397398c49173f0c1a3
Subproject commit 6d00c4007a9eb090b6b1e8525766cfd9c6732100