mirror of https://github.com/AxioDL/metaforce.git
Initial CSpacePirate and rag doll imps
This commit is contained in:
parent
976fe8d283
commit
9c88971df6
|
@ -8,12 +8,17 @@ CScannableObjectInfo::CScannableObjectInfo(CInputStream& in, CAssetId resId) : x
|
|||
u32 version = in.readUint32Big();
|
||||
Load(in, version);
|
||||
|
||||
for (u32 i = 0 ; i < x14_buckets.size(); ++i)
|
||||
{
|
||||
x14_buckets[i].x4_appearanceRange *= x8_totalDownloadTime;
|
||||
}
|
||||
|
||||
float appearanceOffset = g_tweakGui->GetScanAppearanceDuration();
|
||||
for (u32 i = 0 ; i < x14_buckets.size(); ++i)
|
||||
{
|
||||
if (x14_buckets[i].x8_imagePos != -1)
|
||||
{
|
||||
x14_buckets[i].x4_appearanceRange += appearanceOffset;
|
||||
x8_totalDownloadTime += appearanceOffset;
|
||||
for (u32 j = i; j < x14_buckets.size(); j++)
|
||||
x14_buckets[j].x4_appearanceRange += appearanceOffset;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ CActorLights::CActorLights(u32 areaUpdateFramePeriod, const zeus::CVector3f& act
|
|||
x298_25_castShadows = true;
|
||||
|
||||
x298_28_inArea = (!disableWorldLights && maxAreaLights > 0) ? true : false;
|
||||
x298_29_ambientChannelOverflow = ambientChannelOverflow;
|
||||
x298_29_ambienceGenerated = ambientChannelOverflow;
|
||||
x298_30_layer2 = layer2;
|
||||
x298_31_disableWorldLights = disableWorldLights;
|
||||
x299_24_inBrightLight = true;
|
||||
|
@ -152,7 +152,7 @@ void CActorLights::AddOverflowToLights(const CLight& light, const zeus::CColor&
|
|||
|
||||
void CActorLights::MoveAmbienceToLights(const zeus::CColor& color)
|
||||
{
|
||||
if (x298_29_ambientChannelOverflow)
|
||||
if (x298_29_ambienceGenerated)
|
||||
{
|
||||
x288_ambientColor += color * 0.333333f;
|
||||
x288_ambientColor.a = 1.f;
|
||||
|
@ -342,7 +342,7 @@ bool CActorLights::BuildAreaLightList(const CStateManager& mgr, const CGameArea&
|
|||
float overflowMag = 0.f;
|
||||
|
||||
/* Max significant lights */
|
||||
int maxAreaLights = !x298_29_ambientChannelOverflow ? x2b8_maxAreaLights - 1 : x2b8_maxAreaLights;
|
||||
int maxAreaLights = !x298_29_ambienceGenerated ? x2b8_maxAreaLights - 1 : x2b8_maxAreaLights;
|
||||
x0_areaLights.clear();
|
||||
|
||||
/* Filter for performing final light visibility test */
|
||||
|
@ -415,7 +415,7 @@ bool CActorLights::BuildAreaLightList(const CStateManager& mgr, const CGameArea&
|
|||
else
|
||||
{
|
||||
/* Overflow light */
|
||||
if (!x298_29_ambientChannelOverflow && value.x10_colorMag > 0.001f)
|
||||
if (!x298_29_ambienceGenerated && value.x10_colorMag > 0.001f)
|
||||
{
|
||||
/* Average parameters into final light */
|
||||
MergeOverflowLight(overflowLight, overflowLightColor, light, value.x10_colorMag);
|
||||
|
@ -430,7 +430,7 @@ bool CActorLights::BuildAreaLightList(const CStateManager& mgr, const CGameArea&
|
|||
}
|
||||
|
||||
/* Finalize overflow lights */
|
||||
if (!x298_29_ambientChannelOverflow)
|
||||
if (!x298_29_ambienceGenerated)
|
||||
AddOverflowToLights(overflowLight, overflowLightColor, overflowMag);
|
||||
else
|
||||
MoveAmbienceToLights(overflowAmbColor);
|
||||
|
|
|
@ -29,7 +29,7 @@ class CActorLights
|
|||
bool x298_26_hasAreaLights : 1;
|
||||
bool x298_27_findShadowLight : 1;
|
||||
bool x298_28_inArea : 1;
|
||||
bool x298_29_ambientChannelOverflow : 1;
|
||||
bool x298_29_ambienceGenerated : 1;
|
||||
bool x298_30_layer2 : 1;
|
||||
bool x298_31_disableWorldLights : 1;
|
||||
bool x299_24_inBrightLight : 1;
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
void SetCastShadows(bool v) { x298_25_castShadows = v; }
|
||||
void SetFindShadowLight(bool v) { x298_27_findShadowLight = v; }
|
||||
void SetShadowDynamicRangeThreshold(float t) { x2d0_shadowDynamicRangeThreshold = t; }
|
||||
void SetAmbientChannelOverflow(bool v) { x298_29_ambientChannelOverflow = v; }
|
||||
void SetAmbienceGenerated(bool v) { x298_29_ambienceGenerated = v; }
|
||||
void DisableAreaLights();
|
||||
void SetMaxDynamicLights(int l) { x2bc_maxDynamicLights = l; }
|
||||
void SetFindNearestDynamicLights(bool v) { x29a_findNearestDynamicLights = v; }
|
||||
|
|
|
@ -214,6 +214,7 @@ public:
|
|||
static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags);
|
||||
void PreRender();
|
||||
void BuildPose();
|
||||
const CPoseAsTransforms& GetPose() const { return x224_pose; }
|
||||
static void PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet,
|
||||
std::vector<CToken>& tokensOut, bool preLock);
|
||||
void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const;
|
||||
|
@ -242,7 +243,7 @@ public:
|
|||
void SubstituteModelData(const TCachedToken<CSkinnedModel>& model);
|
||||
static void FreeCache();
|
||||
static void InitializeCache();
|
||||
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
|
||||
CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; }
|
||||
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
|
||||
CParticleDatabase& GetParticleDB() { return x120_particleDB; }
|
||||
void SetParticleCEXTValue(std::string_view name, int idx, float value);
|
||||
|
@ -257,6 +258,8 @@ public:
|
|||
TLockedToken<CMorphableSkinnedModel>& IceModel() { return xe4_iceModelData; }
|
||||
const TLockedToken<CMorphableSkinnedModel>& GetIceModel() const { return xe4_iceModelData; }
|
||||
void SetParticleLightIdx(s32 idx) { x21c_particleLightIdx = idx; }
|
||||
|
||||
void MarkPoseDirty() { x220_30_poseBuilt = false; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ CSegId CCharLayoutInfo::GetSegIdFromString(std::string_view name) const
|
|||
if (it == x18_segIdMap.end())
|
||||
return {};
|
||||
|
||||
return (*it).second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void CCharLayoutNode::Bone::read(CInputStream& in)
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
void BuildNoScale(CPoseAsTransforms& pose);
|
||||
void Insert(const CSegId& boneId, const zeus::CQuaternion& quat);
|
||||
void Insert(const CSegId& boneId, const zeus::CQuaternion& quat, const zeus::CVector3f& offset);
|
||||
TSegIdMap<CTreeNode>& GetTreeMap() { return x38_treeMap; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@ class CIkChain
|
|||
CSegId x0_;
|
||||
CSegId x1_;
|
||||
CSegId x2_;
|
||||
zeus::CVector3f x4_;
|
||||
zeus::CVector3f x10_;
|
||||
float x1c_;
|
||||
float x20_;
|
||||
zeus::CVector3f x4_ = zeus::CVector3f::skForward;
|
||||
zeus::CVector3f x10_ = zeus::CVector3f::skForward;
|
||||
float x1c_ = 1.f;
|
||||
float x20_ = 1.f;
|
||||
zeus::CQuaternion x24_;
|
||||
zeus::CVector3f x34_;
|
||||
float x40_time = 0.f;
|
||||
|
@ -29,7 +29,7 @@ class CIkChain
|
|||
{
|
||||
bool x44_24_activated : 1;
|
||||
};
|
||||
u8 x44_dummy = 0;
|
||||
u32 x44_dummy = 0;
|
||||
};
|
||||
public:
|
||||
CIkChain() = default;
|
||||
|
|
|
@ -91,6 +91,7 @@ set(CHARACTER_SOURCES
|
|||
CGroundMovement.hpp CGroundMovement.cpp
|
||||
CSteeringBehaviors.hpp CSteeringBehaviors.cpp
|
||||
CBodyStateInfo.hpp CBodyStateInfo.cpp
|
||||
CBoneTracking.hpp CBoneTracking.cpp)
|
||||
CBoneTracking.hpp CBoneTracking.cpp
|
||||
CRagDoll.hpp CRagDoll.cpp)
|
||||
|
||||
runtime_add_list(Character CHARACTER_SOURCES)
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
#include "CRagDoll.hpp"
|
||||
#include "Collision/CMetroidAreaCollider.hpp"
|
||||
#include "Collision/CGameCollision.hpp"
|
||||
#include "Collision/CMaterialFilter.hpp"
|
||||
#include "Collision/CCollidableSphere.hpp"
|
||||
#include "Collision/CCollisionInfo.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CRagDoll::CRagDollLengthConstraint::Update()
|
||||
{
|
||||
zeus::CVector3f delta = x4_p2->x4_curPos - x0_p1->x4_curPos;
|
||||
float magSq = delta.magSquared();
|
||||
float lenSq = x8_length * x8_length;
|
||||
bool doSolve = true;
|
||||
switch (xc_ineqType)
|
||||
{
|
||||
case 1: // Min
|
||||
doSolve = magSq < lenSq;
|
||||
break;
|
||||
case 2: // Max
|
||||
doSolve = magSq > lenSq;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!doSolve)
|
||||
return;
|
||||
zeus::CVector3f solveVec = delta * (lenSq / (magSq + lenSq) - 0.5f);
|
||||
x0_p1->x4_curPos -= solveVec;
|
||||
x4_p2->x4_curPos += solveVec;
|
||||
}
|
||||
|
||||
void CRagDoll::CRagDollJointConstraint::Update()
|
||||
{
|
||||
// L_hip, R_shoulder, L_shoulder, L_hip, L_knee, L_ankle
|
||||
zeus::CVector3f P4ToP5 = x10_p5->x4_curPos - xc_p4->x4_curPos; // L_hip->L_knee
|
||||
zeus::CVector3f cross = P4ToP5.cross(
|
||||
(x8_p3->x4_curPos - x0_p1->x4_curPos).cross(x4_p2->x4_curPos - x0_p1->x4_curPos));
|
||||
// L_hip->L_knee X (L_hip->L_shoulder X L_hip->R_shoulder)
|
||||
if (cross.canBeNormalized())
|
||||
{
|
||||
zeus::CVector3f hipUp = cross.cross(P4ToP5).normalized();
|
||||
float dot = (x14_p6->x4_curPos - x10_p5->x4_curPos).dot(hipUp);
|
||||
if (dot > 0.f)
|
||||
{
|
||||
zeus::CVector3f solveVec = 0.5f * dot * hipUp;
|
||||
x14_p6->x4_curPos -= solveVec;
|
||||
x10_p5->x4_curPos += solveVec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRagDoll::CRagDollPlaneConstraint::Update()
|
||||
{
|
||||
zeus::CVector3f P1ToP2 = (x4_p2->x4_curPos - x0_p1->x4_curPos).normalized();
|
||||
float dot = P1ToP2.dot(xc_p4->x4_curPos - x8_p3->x4_curPos);
|
||||
if (dot < 0.f)
|
||||
{
|
||||
zeus::CVector3f solveVec = 0.5f * dot * P1ToP2;
|
||||
xc_p4->x4_curPos -= solveVec;
|
||||
x10_p5->x4_curPos += solveVec;
|
||||
}
|
||||
}
|
||||
|
||||
CRagDoll::CRagDoll(float f1, float f2, float f3, u32 flags)
|
||||
: x44_f1(f1), x48_f2(f2), x50_f3(f3)
|
||||
{
|
||||
x68_27_ = bool(flags & 0x1);
|
||||
x68_28_ = bool(flags & 0x2);
|
||||
x68_29_ = bool(flags & 0x4);
|
||||
}
|
||||
|
||||
void CRagDoll::AccumulateForces(float dt, float f2)
|
||||
{
|
||||
float fps = 1.f / dt;
|
||||
x64_angTimer += dt;
|
||||
if (x64_angTimer > 4.f)
|
||||
x64_angTimer -= 4.f;
|
||||
float f25 = std::sin(zeus::degToRad(90.f) * x64_angTimer) * 0.1f + (f2 - 0.2f);
|
||||
zeus::CVector3f f29;
|
||||
float f24 = 0.f;
|
||||
for (auto& particle : x4_particles)
|
||||
{
|
||||
float cubed = particle.x10_radius * particle.x10_radius * particle.x10_radius;
|
||||
f24 += cubed;
|
||||
f29 += particle.x4_curPos * cubed;
|
||||
float f7 = particle.x4_curPos.z - f25;
|
||||
float f8 = x48_f2;
|
||||
float f23 = 0.f;
|
||||
if (std::fabs(f7) < 0.5f)
|
||||
{
|
||||
f23 = 0.5f * f7 / 0.5f + 0.5f;
|
||||
f8 = x48_f2 * -f7 / 0.5f;
|
||||
}
|
||||
else if (f7 > 0.f)
|
||||
{
|
||||
f8 = x44_f1;
|
||||
f23 = 1.f;
|
||||
}
|
||||
particle.x20_acceleration.z += f8;
|
||||
zeus::CVector3f vel = (particle.x4_curPos - particle.x14_prevPos) * fps;
|
||||
float velMag = vel.magnitude();
|
||||
if (velMag > FLT_EPSILON)
|
||||
{
|
||||
particle.x20_acceleration -= vel * (1.f / velMag) *
|
||||
((velMag * velMag * 0.75f * (1.2f * f23 + 1000.f * (1.f - f23))) / (8000.f * particle.x10_radius));
|
||||
}
|
||||
}
|
||||
zeus::CVector3f _c8;
|
||||
f29 = f29 / f24;
|
||||
for (const auto& particle : x4_particles)
|
||||
{
|
||||
float cubed = particle.x10_radius * particle.x10_radius * particle.x10_radius;
|
||||
_c8 += (particle.x4_curPos - f29).cross(particle.x4_curPos) * cubed;
|
||||
}
|
||||
_c8 = _c8 * (fps / f24);
|
||||
if (_c8.canBeNormalized())
|
||||
for (auto& particle : x4_particles)
|
||||
particle.x20_acceleration -= _c8.cross(particle.x4_curPos - f29) * 25.f;
|
||||
}
|
||||
|
||||
void CRagDoll::AddParticle(CSegId id, const zeus::CVector3f& prevPos, const zeus::CVector3f& curPos, float f1)
|
||||
{
|
||||
x4_particles.emplace_back(id, curPos, f1, prevPos);
|
||||
}
|
||||
|
||||
void CRagDoll::AddLengthConstraint(int i1, int i2)
|
||||
{
|
||||
x14_lengthConstraints.emplace_back(&x4_particles[i1], &x4_particles[i2],
|
||||
(x4_particles[i1].x4_curPos - x4_particles[i2].x4_curPos).magnitude(), 0);
|
||||
}
|
||||
|
||||
void CRagDoll::AddMaxLengthConstraint(int i1, int i2, float length)
|
||||
{
|
||||
x14_lengthConstraints.emplace_back(&x4_particles[i1], &x4_particles[i2], length, 2);
|
||||
}
|
||||
|
||||
void CRagDoll::AddMinLengthConstraint(int i1, int i2, float length)
|
||||
{
|
||||
x14_lengthConstraints.emplace_back(&x4_particles[i1], &x4_particles[i2], length, 1);
|
||||
}
|
||||
|
||||
void CRagDoll::AddJointConstraint(int i1, int i2, int i3, int i4, int i5, int i6)
|
||||
{
|
||||
x24_jointConstraints.emplace_back(&x4_particles[i1], &x4_particles[i2], &x4_particles[i3],
|
||||
&x4_particles[i4], &x4_particles[i5], &x4_particles[i6]);
|
||||
}
|
||||
|
||||
zeus::CQuaternion CRagDoll::BoneAlign(CHierarchyPoseBuilder& pb, const CCharLayoutInfo& charInfo,
|
||||
int i1, int i2, const zeus::CQuaternion& q)
|
||||
{
|
||||
zeus::CVector3f fromParent = charInfo.GetFromParentUnrotated(x4_particles[i2].x0_id);
|
||||
zeus::CVector3f delta = x4_particles[i2].x4_curPos - x4_particles[i1].x4_curPos;
|
||||
delta = q.inverse().transform(delta);
|
||||
zeus::CQuaternion ret = zeus::CQuaternion::shortestRotationArc(fromParent, delta);
|
||||
pb.GetTreeMap()[x4_particles[i1].x0_id].x4_rotation = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
zeus::CAABox CRagDoll::CalculateRenderBounds() const
|
||||
{
|
||||
zeus::CAABox aabb;
|
||||
for (const auto& particle : x4_particles)
|
||||
{
|
||||
aabb.accumulateBounds(zeus::CAABox(particle.x4_curPos - particle.x10_radius,
|
||||
particle.x4_curPos + particle.x10_radius));
|
||||
}
|
||||
return aabb;
|
||||
}
|
||||
|
||||
void CRagDoll::CheckStatic(float dt)
|
||||
{
|
||||
x4c_ = 0;
|
||||
x54_ = 0.f;
|
||||
float f1 = 0.5f * dt;
|
||||
float f31 = f1 * f1;
|
||||
x58_ = zeus::CVector3f::skZero;
|
||||
bool r31 = true;
|
||||
for (auto& particle : x4_particles)
|
||||
{
|
||||
zeus::CVector3f delta = particle.x4_curPos - particle.x14_prevPos;
|
||||
x58_ += delta;
|
||||
if (delta.magSquared() > f31)
|
||||
r31 = false;
|
||||
if (particle.x3c_24_nextDampVel)
|
||||
{
|
||||
x4c_ += 1;
|
||||
x54_ = std::max(particle.x38_, x54_);
|
||||
}
|
||||
}
|
||||
if (!x4_particles.empty())
|
||||
x58_ = x58_ * (1.f / (dt * x4_particles.size()));
|
||||
x54_ /= dt;
|
||||
if (!x68_28_)
|
||||
{
|
||||
x50_f3 -= dt;
|
||||
if (x50_f3 <= 0.f)
|
||||
x68_25_ = true;
|
||||
}
|
||||
if (r31 && x68_24_)
|
||||
x68_25_ = true;
|
||||
x68_24_ = r31;
|
||||
}
|
||||
|
||||
void CRagDoll::ClearForces()
|
||||
{
|
||||
for (auto& particle : x4_particles)
|
||||
particle.x20_acceleration = zeus::CVector3f::skZero;
|
||||
}
|
||||
|
||||
void CRagDoll::SatisfyConstraints(CStateManager& mgr)
|
||||
{
|
||||
for (auto& length : x14_lengthConstraints)
|
||||
length.Update();
|
||||
for (auto& joint : x24_jointConstraints)
|
||||
joint.Update();
|
||||
for (auto& plane : x34_planeConstraints)
|
||||
plane.Update();
|
||||
if (SatisfyWorldConstraints(mgr, 1))
|
||||
SatisfyWorldConstraints(mgr, 2);
|
||||
}
|
||||
|
||||
bool CRagDoll::SatisfyWorldConstraints(CStateManager& mgr, int i1)
|
||||
{
|
||||
zeus::CAABox aabb;
|
||||
for (const auto& particle : x4_particles)
|
||||
{
|
||||
if (i1 == 1 || particle.x3c_24_nextDampVel)
|
||||
{
|
||||
aabb.accumulateBounds(particle.x14_prevPos - particle.x10_radius);
|
||||
aabb.accumulateBounds(particle.x14_prevPos + particle.x10_radius);
|
||||
aabb.accumulateBounds(particle.x4_curPos - particle.x10_radius);
|
||||
aabb.accumulateBounds(particle.x4_curPos + particle.x10_radius);
|
||||
}
|
||||
}
|
||||
|
||||
CAreaCollisionCache ccache(aabb);
|
||||
CGameCollision::BuildAreaCollisionCache(mgr, ccache);
|
||||
bool ret = false;
|
||||
|
||||
TUniqueId bestId = kInvalidUniqueId;
|
||||
CMaterialList include;
|
||||
if (x68_29_)
|
||||
include = CMaterialList(EMaterialTypes::Solid);
|
||||
else
|
||||
include = CMaterialList(EMaterialTypes::Solid, EMaterialTypes::AIBlock);
|
||||
|
||||
CMaterialList exclude;
|
||||
if (x68_29_)
|
||||
exclude = CMaterialList(EMaterialTypes::Character, EMaterialTypes::Player,
|
||||
EMaterialTypes::AIBlock, EMaterialTypes::Occluder);
|
||||
else
|
||||
exclude = CMaterialList(EMaterialTypes::Character, EMaterialTypes::Player);
|
||||
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
CMaterialFilter filter = CMaterialFilter::MakeIncludeExclude(include, exclude);
|
||||
mgr.BuildNearList(nearList, aabb, filter, nullptr);
|
||||
|
||||
for (auto& particle : x4_particles)
|
||||
{
|
||||
if (i1 == 1 || particle.x3c_24_nextDampVel)
|
||||
{
|
||||
zeus::CVector3f delta = particle.x4_curPos - particle.x14_prevPos;
|
||||
float deltaMag = delta.magnitude();
|
||||
if (deltaMag > 0.0001f)
|
||||
{
|
||||
delta = delta * (1.f / deltaMag);
|
||||
double d = deltaMag;
|
||||
CCollidableSphere sphere(zeus::CSphere(particle.x14_prevPos, particle.x10_radius), include);
|
||||
CCollisionInfo info;
|
||||
CGameCollision::DetectCollision_Cached_Moving(mgr, ccache, sphere, {}, filter,
|
||||
nearList, delta, bestId, info, d);
|
||||
if (info.IsValid())
|
||||
{
|
||||
ret = true;
|
||||
switch (i1)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
particle.x3c_24_nextDampVel = true;
|
||||
float dot = delta.dot(info.GetNormalLeft());
|
||||
particle.x2c_nextPosDelta = -0.125f * dot * deltaMag * info.GetNormalLeft();
|
||||
particle.x38_ = -dot * deltaMag;
|
||||
particle.x4_curPos += float(0.0001f - (deltaMag - d) * dot) * info.GetNormalLeft();
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
particle.x4_curPos = float(d - 0.0001) * delta + particle.x14_prevPos;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!x68_27_)
|
||||
{
|
||||
particle.x4_curPos = particle.x14_prevPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CRagDoll::SatisfyWorldConstraintsOnConstruction(CStateManager& mgr)
|
||||
{
|
||||
for (auto& particle : x4_particles)
|
||||
particle.x3c_24_nextDampVel = true;
|
||||
SatisfyWorldConstraints(mgr, 2);
|
||||
for (auto& particle : x4_particles)
|
||||
particle.x14_prevPos = particle.x4_curPos;
|
||||
}
|
||||
|
||||
void CRagDoll::Verlet(float dt)
|
||||
{
|
||||
for (auto& particle : x4_particles)
|
||||
{
|
||||
zeus::CVector3f oldPos = particle.x4_curPos;
|
||||
particle.x4_curPos += (particle.x4_curPos - particle.x14_prevPos) *
|
||||
(particle.x3c_24_nextDampVel ? 0.9f : 1.f);
|
||||
particle.x4_curPos += particle.x20_acceleration * (dt * dt);
|
||||
particle.x4_curPos += particle.x2c_nextPosDelta;
|
||||
particle.x14_prevPos = oldPos;
|
||||
zeus::CVector3f deltaPos = particle.x4_curPos - particle.x14_prevPos;
|
||||
if (deltaPos.magSquared() > 4.f)
|
||||
particle.x4_curPos = deltaPos.normalized() * 2.f + particle.x14_prevPos;
|
||||
particle.x3c_24_nextDampVel = false;
|
||||
particle.x2c_nextPosDelta = zeus::CVector3f::skZero;
|
||||
}
|
||||
}
|
||||
|
||||
void CRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void CRagDoll::Update(CStateManager& mgr, float dt, float f2)
|
||||
{
|
||||
if (!x68_25_ || x68_27_)
|
||||
{
|
||||
AccumulateForces(dt, f2);
|
||||
Verlet(dt);
|
||||
SatisfyConstraints(mgr);
|
||||
ClearForces();
|
||||
CheckStatic(dt);
|
||||
}
|
||||
}
|
||||
|
||||
void CRagDoll::Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData)
|
||||
{
|
||||
zeus::CVector3f scale = mData.GetScale();
|
||||
CAnimData* aData = mData.AnimationData();
|
||||
aData->BuildPose();
|
||||
for (auto& particle : x4_particles)
|
||||
if (particle.x0_id != 0xff)
|
||||
particle.x4_curPos = xf * aData->GetPose().GetOffset(particle.x0_id) * scale;
|
||||
SatisfyWorldConstraints(mgr, 2);
|
||||
for (auto& particle : x4_particles)
|
||||
particle.x3c_24_nextDampVel = false;
|
||||
x68_26_primed = true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
#pragma once
|
||||
#include "RetroTypes.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CQuaternion.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "CSegId.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CHierarchyPoseBuilder;
|
||||
class CCharLayoutInfo;
|
||||
class CModelData;
|
||||
class CStateManager;
|
||||
|
||||
class CRagDoll
|
||||
{
|
||||
protected:
|
||||
class CRagDollParticle
|
||||
{
|
||||
friend class CRagDoll;
|
||||
CSegId x0_id;
|
||||
zeus::CVector3f x4_curPos;
|
||||
float x10_radius;
|
||||
zeus::CVector3f x14_prevPos;
|
||||
zeus::CVector3f x20_acceleration;
|
||||
zeus::CVector3f x2c_nextPosDelta;
|
||||
float x38_ = 0.f;
|
||||
bool x3c_24_nextDampVel : 1;
|
||||
bool x3c_25_ : 1;
|
||||
public:
|
||||
CRagDollParticle(CSegId id, const zeus::CVector3f& curPos, float f1, const zeus::CVector3f& prevPos)
|
||||
: x0_id(id), x4_curPos(curPos), x10_radius(f1), x14_prevPos(prevPos)
|
||||
{
|
||||
x3c_24_nextDampVel = false;
|
||||
x3c_25_ = false;
|
||||
}
|
||||
CSegId GetBone() const { return x0_id; }
|
||||
const zeus::CVector3f& GetPosition() const { return x4_curPos; }
|
||||
zeus::CVector3f& Position() { return x4_curPos; }
|
||||
const zeus::CVector3f& GetAcceleration() const { return x20_acceleration; }
|
||||
zeus::CVector3f& Acceleration() { return x20_acceleration; }
|
||||
float GetRadius() const { return x10_radius; }
|
||||
};
|
||||
class CRagDollLengthConstraint
|
||||
{
|
||||
friend class CRagDoll;
|
||||
CRagDollParticle* x0_p1;
|
||||
CRagDollParticle* x4_p2;
|
||||
float x8_length;
|
||||
int xc_ineqType;
|
||||
public:
|
||||
CRagDollLengthConstraint(CRagDollParticle* p1, CRagDollParticle* p2, float f1, int i1)
|
||||
: x0_p1(p1), x4_p2(p2), x8_length(f1), xc_ineqType(i1) {}
|
||||
void Update();
|
||||
float GetLength() const { return x8_length; }
|
||||
};
|
||||
class CRagDollJointConstraint
|
||||
{
|
||||
friend class CRagDoll;
|
||||
CRagDollParticle* x0_p1; // Shoulder plane 0
|
||||
CRagDollParticle* x4_p2; // Shoulder plane 1
|
||||
CRagDollParticle* x8_p3; // Shoulder plane 2
|
||||
CRagDollParticle* xc_p4; // Shoulder
|
||||
CRagDollParticle* x10_p5; // Elbow
|
||||
CRagDollParticle* x14_p6; // Wrist
|
||||
public:
|
||||
CRagDollJointConstraint(CRagDollParticle* p1, CRagDollParticle* p2, CRagDollParticle* p3,
|
||||
CRagDollParticle* p4, CRagDollParticle* p5, CRagDollParticle* p6)
|
||||
: x0_p1(p1), x4_p2(p2), x8_p3(p3), xc_p4(p4), x10_p5(p5), x14_p6(p6) {}
|
||||
void Update();
|
||||
};
|
||||
class CRagDollPlaneConstraint
|
||||
{
|
||||
friend class CRagDoll;
|
||||
CRagDollParticle* x0_p1;
|
||||
CRagDollParticle* x4_p2;
|
||||
CRagDollParticle* x8_p3;
|
||||
CRagDollParticle* xc_p4;
|
||||
CRagDollParticle* x10_p5;
|
||||
public:
|
||||
CRagDollPlaneConstraint(CRagDollParticle* p1, CRagDollParticle* p2, CRagDollParticle* p3,
|
||||
CRagDollParticle* p4, CRagDollParticle* p5)
|
||||
: x0_p1(p1), x4_p2(p2), x8_p3(p3), xc_p4(p4), x10_p5(p5) {}
|
||||
void Update();
|
||||
};
|
||||
std::vector<CRagDollParticle> x4_particles;
|
||||
std::vector<CRagDollLengthConstraint> x14_lengthConstraints;
|
||||
std::vector<CRagDollJointConstraint> x24_jointConstraints;
|
||||
std::vector<CRagDollPlaneConstraint> x34_planeConstraints;
|
||||
float x44_f1;
|
||||
float x48_f2;
|
||||
u32 x4c_ = 0;
|
||||
float x50_f3;
|
||||
float x54_ = 0.f;
|
||||
zeus::CVector3f x58_;
|
||||
float x64_angTimer = 0.f;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x68_24_ : 1;
|
||||
bool x68_25_ : 1;
|
||||
bool x68_26_primed : 1;
|
||||
bool x68_27_ : 1;
|
||||
bool x68_28_ : 1;
|
||||
bool x68_29_ : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
void AccumulateForces(float dt, float f2);
|
||||
void SetNumParticles(int num) { x4_particles.reserve(num); }
|
||||
void AddParticle(CSegId id, const zeus::CVector3f& prevPos, const zeus::CVector3f& curPos, float f1);
|
||||
void SetNumLengthConstraints(int num) { x14_lengthConstraints.reserve(num); }
|
||||
void AddLengthConstraint(int i1, int i2);
|
||||
void AddMaxLengthConstraint(int i1, int i2, float length);
|
||||
void AddMinLengthConstraint(int i1, int i2, float length);
|
||||
void SetNumJointConstraints(int num) { x24_jointConstraints.reserve(num); }
|
||||
void AddJointConstraint(int i1, int i2, int i3, int i4, int i5, int i6);
|
||||
zeus::CQuaternion BoneAlign(CHierarchyPoseBuilder& pb, const CCharLayoutInfo& charInfo,
|
||||
int i1, int i2, const zeus::CQuaternion& q);
|
||||
zeus::CAABox CalculateRenderBounds() const;
|
||||
void CheckStatic(float dt);
|
||||
void ClearForces();
|
||||
void SatisfyConstraints(CStateManager& mgr);
|
||||
bool SatisfyWorldConstraints(CStateManager& mgr, int i1);
|
||||
void SatisfyWorldConstraintsOnConstruction(CStateManager& mgr);
|
||||
void Verlet(float dt);
|
||||
public:
|
||||
virtual ~CRagDoll() = default;
|
||||
CRagDoll(float f1, float f2, float f3, u32 flags);
|
||||
|
||||
virtual void PreRender(const zeus::CVector3f& v, CModelData& mData);
|
||||
virtual void Update(CStateManager& mgr, float dt, float f2);
|
||||
virtual void Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData);
|
||||
};
|
||||
|
||||
}
|
|
@ -30,6 +30,7 @@ zeus::CVector3f CGuiCamera::ConvertToScreenSpace(const zeus::CVector3f& vec) con
|
|||
zeus::CMatrix4f mat = CGraphics::CalculatePerspectiveMatrix(m_proj.xbc_fov, m_proj.xc0_aspect,
|
||||
m_proj.xc4_znear, m_proj.xc8_zfar,
|
||||
false);
|
||||
local = zeus::CVector3f(local.x, local.z, -local.y);
|
||||
return mat.multiplyOneOverW(local);
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,29 @@ void CGuiTextSupport::SetTypeWriteEffectOptions(bool enable, float chFadeTime, f
|
|||
x50_typeEnable = enable;
|
||||
x54_chFadeTime = std::max(chFadeTime, 0.0001f);
|
||||
x58_chRate = std::max(chRate, 1.f);
|
||||
if (enable)
|
||||
{
|
||||
if (CTextRenderBuffer* buf = GetCurrentPageRenderBuffer())
|
||||
{
|
||||
float chStartTime = 0.f;
|
||||
for (s32 i=0 ; i<buf->GetPrimitiveCount() ; ++i)
|
||||
{
|
||||
for (const std::pair<float, int>& p : x40_primStartTimes)
|
||||
{
|
||||
if (p.second < i)
|
||||
continue;
|
||||
if (p.second != i)
|
||||
break;
|
||||
chStartTime = p.first;
|
||||
break;
|
||||
}
|
||||
|
||||
buf->SetPrimitiveOpacity(i,
|
||||
std::min(std::max(0.f, (x3c_curTime - chStartTime) / x54_chFadeTime), 1.f));
|
||||
chStartTime += 1.f / x58_chRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGuiTextSupport::Update(float dt)
|
||||
|
|
|
@ -21,8 +21,10 @@ void CScanDisplay::CDataDot::Update(float dt)
|
|||
if (x20_remTime > 0.f)
|
||||
{
|
||||
x20_remTime = std::max(0.f, x20_remTime - dt);
|
||||
float d = x20_remTime / x1c_transDur;
|
||||
xc_curPos = (x14_targetPos * (x4_startPos * d)) + (1.f - x1c_transDur > 0.f ? d : 0.f);
|
||||
float d = 0.f;
|
||||
if (x1c_transDur > 0.f)
|
||||
d = x20_remTime / x1c_transDur;
|
||||
xc_curPos = zeus::CVector2f::lerp(x14_targetPos, x4_startPos, d);
|
||||
}
|
||||
|
||||
if (x24_alpha > x28_desiredAlpha)
|
||||
|
@ -32,7 +34,7 @@ void CScanDisplay::CDataDot::Update(float dt)
|
|||
}
|
||||
else if (x24_alpha < x28_desiredAlpha)
|
||||
{
|
||||
float tmp = 2.0 * dt + x24_alpha;
|
||||
float tmp = 2.f * dt + x24_alpha;
|
||||
x24_alpha = std::min(tmp, x28_desiredAlpha);
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +245,8 @@ void CScanDisplay::StartScan(TUniqueId id, const CScannableObjectInfo& scanInfo,
|
|||
}
|
||||
state.second->SetTextureID0(bucket.x0_texture, g_SimplePool);
|
||||
state.second->SetFlashFactor(0.f);
|
||||
if (scanTime >= GetDownloadStartTime(i))
|
||||
float startTime = GetDownloadStartTime(i);
|
||||
if (scanTime >= startTime)
|
||||
x170_paneStates[i].first = 0.f;
|
||||
else
|
||||
x170_paneStates[i].first = -1.f;
|
||||
|
@ -400,6 +403,7 @@ void CScanDisplay::Update(float dt, float scanningTime)
|
|||
if (tmp == 0.f)
|
||||
{
|
||||
dot.SetDotState(CDataDot::EDotState::Done);
|
||||
dot.SetDesiredAlpha(0.f);
|
||||
CSfxManager::SfxStart(SFXui_scan_pane_reveal, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
x170_paneStates[i].first = g_tweakGui->GetScanPaneFadeOutTime() + g_tweakGui->GetScanPaneFadeInTime();
|
||||
}
|
||||
|
@ -423,12 +427,14 @@ void CScanDisplay::Update(float dt, float scanningTime)
|
|||
float tmp = dot.GetTransitionFactor();
|
||||
if (tmp == 0.f)
|
||||
{
|
||||
float posRand = g_tweakGui->GetScanDataDotPosRandMagnitude();
|
||||
float vpRatio = g_Viewport.xc_height / 480.f;
|
||||
float posRand = g_tweakGui->GetScanDataDotPosRandMagnitude() * vpRatio;
|
||||
float durMin = dot.GetDotState() == CDataDot::EDotState::Hold ? g_tweakGui->GetScanDataDotHoldDurationMin() : g_tweakGui->GetScanDataDotSeekDurationMin();
|
||||
float durMax = dot.GetDotState() == CDataDot::EDotState::Hold ? g_tweakGui->GetScanDataDotHoldDurationMax() : g_tweakGui->GetScanDataDotSeekDurationMax();
|
||||
zeus::CVector2f vec(dot.GetDotState() == CDataDot::EDotState::Hold ? dot.GetCurrPosition().x : (posRand * (rand() / float(RAND_MAX)) - 0.5f * posRand),
|
||||
dot.GetDotState() == CDataDot::EDotState::Hold ? dot.GetCurrPosition().y : (posRand * (rand() / float(RAND_MAX)) - 0.5f * posRand));
|
||||
dot.StartTransitionTo(vec, (durMax - durMin) * (rand() / float(RAND_MAX)) + durMin);
|
||||
float dur = (durMax - durMin) * (rand() / float(RAND_MAX)) + durMin;
|
||||
dot.StartTransitionTo(vec, dur);
|
||||
dot.SetDotState(dot.GetDotState() == CDataDot::EDotState::Hold ? CDataDot::EDotState::Seek : CDataDot::EDotState::Hold);
|
||||
}
|
||||
break;
|
||||
|
@ -436,7 +442,8 @@ void CScanDisplay::Update(float dt, float scanningTime)
|
|||
case CDataDot::EDotState::RevealPane:
|
||||
case CDataDot::EDotState::Done:
|
||||
{
|
||||
zeus::CVector3f screenPos = xa0_selHud.GetFrameCamera()->ConvertToScreenSpace(x170_paneStates[i].second->GetWorldPosition());
|
||||
const zeus::CVector3f& panePos = x170_paneStates[i].second->GetWorldPosition();
|
||||
zeus::CVector3f screenPos = xa0_selHud.GetFrameCamera()->ConvertToScreenSpace(panePos);
|
||||
zeus::CVector2f viewportCoords(screenPos.x * g_Viewport.x8_width * 0.5f,
|
||||
screenPos.y * g_Viewport.xc_height * 0.5f);
|
||||
dot.SetDestPosition(viewportCoords);
|
||||
|
@ -485,7 +492,8 @@ void CScanDisplay::Draw() const
|
|||
g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f);
|
||||
// Additive alpha
|
||||
|
||||
float vpRatio = g_Viewport.xc_height / 480.f;
|
||||
for (const CDataDot& dot : xbc_dataDots)
|
||||
dot.Draw(g_tweakGuiColors->GetScanDataDotColor(), g_tweakGui->GetScanDataDotRadius());
|
||||
dot.Draw(g_tweakGuiColors->GetScanDataDotColor(), g_tweakGui->GetScanDataDotRadius() * vpRatio);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ CFireFlea::CFireFlea(TUniqueId uid, std::string_view name, const CEntityInfo& in
|
|||
: CPatterned(ECharacter::FireFlea, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Flyer, EColliderType::One, EBodyType::NewFlyer, actParms, EKnockBackVariant::Small)
|
||||
, x56c_(f1)
|
||||
, xd8c_pathFind(nullptr, 2, pInfo.GetParticle1Frames(), 1.f, 1.f)
|
||||
, xd8c_pathFind(nullptr, 2, pInfo.GetPathfindingIndex(), 1.f, 1.f)
|
||||
{
|
||||
CMaterialFilter filter = GetMaterialFilter();
|
||||
filter.ExcludeList().Add(EMaterialTypes::Character);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "CSpacePirate.hpp"
|
||||
#include "Character/CCharLayoutInfo.hpp"
|
||||
#include "Character/CPASAnimParmData.hpp"
|
||||
#include "World/CScriptWaypoint.hpp"
|
||||
#include "World/CPatternedInfo.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
|
||||
namespace urde::MP1
|
||||
|
@ -10,21 +13,455 @@ CSpacePirate::CSpacePirateData::CSpacePirateData(urde::CInputStream& in, u32 pro
|
|||
, x48_(CSfxManager::TranslateSFXID(in.readUint32Big())), x4c_(in), x68_(in.readFloatBig()), x6c_(in)
|
||||
, x94_(in.readFloatBig()), x98_(CSfxManager::TranslateSFXID(in.readUint32Big())), x9c_(in.readFloatBig())
|
||||
, xa0_(in.readFloatBig()), xa4_(CSfxManager::TranslateSFXID(in.readUint32Big())), xa8_(in.readFloatBig())
|
||||
, xac_(in.readUint32Big()), xb0_(in.readFloatBig()), xb4_(in.readFloatBig()), xb8_(in.readFloatBig())
|
||||
, xac_firstBurstCount(in.readUint32Big()), xb0_(in.readFloatBig()), xb4_(in.readFloatBig()), xb8_(in.readFloatBig())
|
||||
, xbc_(in.readFloatBig()), xc0_(CSfxManager::TranslateSFXID(in.readUint32Big()))
|
||||
, xc2_(CSfxManager::TranslateSFXID(in.readUint32Big())), xc4_(propCount > 35 ? in.readFloatBig() : 0.2f)
|
||||
, xc8_(propCount > 36 ? in.readFloatBig() : 8.f)
|
||||
{
|
||||
{}
|
||||
|
||||
static const std::string_view skParts[] =
|
||||
{
|
||||
"Collar"sv,
|
||||
"Neck_1"sv,
|
||||
"R_shoulder"sv,
|
||||
"R_elbow"sv,
|
||||
"R_wrist"sv,
|
||||
"L_shoulder"sv,
|
||||
"L_elbow"sv,
|
||||
"L_wrist"sv,
|
||||
"R_hip"sv,
|
||||
"R_knee"sv,
|
||||
"R_ankle"sv,
|
||||
"L_hip"sv,
|
||||
"L_knee"sv,
|
||||
"L_ankle"sv
|
||||
};
|
||||
|
||||
static const float skRadii[] =
|
||||
{
|
||||
0.45f,
|
||||
0.52f,
|
||||
0.35f,
|
||||
0.1f,
|
||||
0.15f,
|
||||
0.35f,
|
||||
0.1f,
|
||||
0.15f,
|
||||
0.15f,
|
||||
0.15f,
|
||||
0.15f,
|
||||
0.15f,
|
||||
0.15f,
|
||||
0.15f
|
||||
};
|
||||
|
||||
CPirateRagDoll::CPirateRagDoll(CStateManager& mgr, CSpacePirate* sp, u16 s1, u32 flags)
|
||||
: CRagDoll(-sp->GetGravityConstant(), -3.f, 8.f, flags), x6c_spacePirate(sp), x70_s1(s1)
|
||||
{
|
||||
xb0_24_ = true;
|
||||
x6c_spacePirate->RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::AIBlock,
|
||||
EMaterialTypes::GroundCollider, mgr);
|
||||
x6c_spacePirate->HealthInfo(mgr)->SetHP(-1.f);
|
||||
SetNumParticles(14);
|
||||
SetNumLengthConstraints(47);
|
||||
SetNumJointConstraints(4);
|
||||
zeus::CVector3f scale = x6c_spacePirate->GetModelData()->GetScale();
|
||||
CAnimData* aData = x6c_spacePirate->ModelData()->AnimationData();
|
||||
aData->BuildPose();
|
||||
zeus::CVector3f center = x6c_spacePirate->GetBoundingBox().center();
|
||||
for (int i = 0; i < 14; ++i)
|
||||
{
|
||||
CSegId id = aData->GetLocatorSegId(skParts[i]);
|
||||
AddParticle(id, center, x6c_spacePirate->GetTransform() * (aData->GetPose().GetOffset(id) * scale),
|
||||
skRadii[i] * scale.z);
|
||||
}
|
||||
SatisfyWorldConstraintsOnConstruction(mgr);
|
||||
AddLengthConstraint(0, 1);
|
||||
AddLengthConstraint(0, 2);
|
||||
AddLengthConstraint(0, 8);
|
||||
AddLengthConstraint(0, 11);
|
||||
AddLengthConstraint(0, 5);
|
||||
AddLengthConstraint(2, 3);
|
||||
AddLengthConstraint(3, 4);
|
||||
AddLengthConstraint(5, 6);
|
||||
AddLengthConstraint(6, 7);
|
||||
AddLengthConstraint(2, 5);
|
||||
AddLengthConstraint(2, 8);
|
||||
AddLengthConstraint(2, 11);
|
||||
AddLengthConstraint(5, 8);
|
||||
AddLengthConstraint(5, 11);
|
||||
AddLengthConstraint(8, 11);
|
||||
AddLengthConstraint(8, 9);
|
||||
AddLengthConstraint(9, 10);
|
||||
AddLengthConstraint(11, 12);
|
||||
AddLengthConstraint(12, 13);
|
||||
AddMinLengthConstraint(1, 8, x14_lengthConstraints[2].GetLength());
|
||||
AddMinLengthConstraint(1, 11, x14_lengthConstraints[3].GetLength());
|
||||
AddMinLengthConstraint(1, 2, x14_lengthConstraints[1].GetLength() * 0.9f);
|
||||
AddMinLengthConstraint(1, 5, x14_lengthConstraints[4].GetLength() * 0.9f);
|
||||
AddMinLengthConstraint(1, 4, x14_lengthConstraints[0].GetLength() * 2.5f);
|
||||
AddMinLengthConstraint(1, 7, x14_lengthConstraints[0].GetLength() * 2.5f);
|
||||
AddMinLengthConstraint(4, 2, x14_lengthConstraints[5].GetLength());
|
||||
AddMinLengthConstraint(7, 5, x14_lengthConstraints[7].GetLength());
|
||||
AddMinLengthConstraint(3, 5, x14_lengthConstraints[5].GetLength() * 0.5f + x14_lengthConstraints[9].GetLength());
|
||||
AddMinLengthConstraint(6, 2, x14_lengthConstraints[7].GetLength() * 0.5f + x14_lengthConstraints[9].GetLength());
|
||||
AddMinLengthConstraint(4, 5, x14_lengthConstraints[5].GetLength() * 0.5f + x14_lengthConstraints[9].GetLength());
|
||||
AddMinLengthConstraint(7, 2, x14_lengthConstraints[7].GetLength() * 0.5f + x14_lengthConstraints[9].GetLength());
|
||||
AddMinLengthConstraint(4, 7, x14_lengthConstraints[9].GetLength());
|
||||
AddMinLengthConstraint(4, 8, x14_lengthConstraints[14].GetLength());
|
||||
AddMinLengthConstraint(7, 11, x14_lengthConstraints[14].GetLength());
|
||||
AddMinLengthConstraint(10, 8, x14_lengthConstraints[15].GetLength());
|
||||
AddMinLengthConstraint(13, 11, x14_lengthConstraints[17].GetLength());
|
||||
AddMinLengthConstraint(9, 2, x14_lengthConstraints[15].GetLength() * 0.707f + x14_lengthConstraints[10].GetLength());
|
||||
AddMinLengthConstraint(12, 5, x14_lengthConstraints[17].GetLength() * 0.707f + x14_lengthConstraints[13].GetLength());
|
||||
AddMinLengthConstraint(9, 11, x14_lengthConstraints[15].GetLength());
|
||||
AddMinLengthConstraint(12, 8, x14_lengthConstraints[17].GetLength());
|
||||
AddMinLengthConstraint(10, 0, x14_lengthConstraints[2].GetLength() + x14_lengthConstraints[15].GetLength());
|
||||
AddMinLengthConstraint(13, 0, x14_lengthConstraints[3].GetLength() + x14_lengthConstraints[17].GetLength());
|
||||
AddMinLengthConstraint(10, 13, x14_lengthConstraints[14].GetLength());
|
||||
AddMinLengthConstraint(9, 12, x14_lengthConstraints[14].GetLength());
|
||||
AddMinLengthConstraint(10, 12, x14_lengthConstraints[14].GetLength());
|
||||
AddMinLengthConstraint(13, 9, x14_lengthConstraints[14].GetLength());
|
||||
AddMaxLengthConstraint(10, 13, x14_lengthConstraints[14].GetLength() * 5.f);
|
||||
AddJointConstraint(8, 2, 5, 8, 9, 10); // R_hip, R_shoulder, L_shoulder, R_hip, R_knee, R_ankle
|
||||
AddJointConstraint(11, 2, 5, 11, 12, 13); // L_hip, R_shoulder, L_shoulder, L_hip, L_knee, L_ankle
|
||||
AddJointConstraint(2, 11, 5, 2, 3, 4); // R_shoulder, L_hip, L_shoulder, R_shoulder, R_elbow, R_wrist
|
||||
AddJointConstraint(5, 2, 8, 5, 6, 7); // L_shoulder, R_shoulder, R_hip, L_shoulder, L_elbow, R_wrist
|
||||
for (const auto& conn : x6c_spacePirate->GetConnectionList())
|
||||
{
|
||||
if (conn.x0_state == EScriptObjectState::Modify && conn.x4_msg == EScriptObjectMessage::Follow)
|
||||
{
|
||||
TUniqueId wpId = mgr.GetIdForScript(conn.x8_objId);
|
||||
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(wpId))
|
||||
{
|
||||
x90_waypoints.push_back(wpId);
|
||||
x9c_wpParticleIdxs.push_back(wp->GetAnimation());
|
||||
if (x90_waypoints.size() == 4)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPirateRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData)
|
||||
{
|
||||
if (!x68_25_ || x68_27_)
|
||||
{
|
||||
CAnimData* aData = mData.AnimationData();
|
||||
for (CSegId id : aData->GetCharLayoutInfo().GetSegIdList().GetList())
|
||||
if (aData->GetCharLayoutInfo().GetRootNode()->GetBoneMap()[id].x10_children.size() > 1)
|
||||
aData->PoseBuilder().GetTreeMap()[id].x4_rotation = zeus::CQuaternion::skNoRotation;
|
||||
CSegId rootId = aData->GetLocatorSegId("Skeleton_Root"sv);
|
||||
aData->PoseBuilder().GetTreeMap()[rootId].x14_offset =
|
||||
(0.5f * (x4_particles[8].GetPosition() + x4_particles[11].GetPosition()) - v) / mData.GetScale();
|
||||
zeus::CVector3f _7c = x4_particles[2].GetPosition() - x4_particles[5].GetPosition();
|
||||
zeus::CVector3f _88 =
|
||||
(x4_particles[0].GetPosition() -
|
||||
(x4_particles[8].GetPosition() + x4_particles[11].GetPosition()) * 0.5f).normalized();
|
||||
zeus::CVector3f _x94 = _88.cross(_7c).normalized();
|
||||
zeus::CQuaternion _a4(zeus::CMatrix3f(_x94.cross(_88), _x94, _88).transposed());
|
||||
aData->PoseBuilder().GetTreeMap()[rootId].x4_rotation = _a4;
|
||||
if (x6c_spacePirate->x7b4_ == kInvalidUniqueId)
|
||||
{
|
||||
zeus::CVector3f _b0 = aData->GetCharLayoutInfo().GetFromParentUnrotated(x4_particles[1].GetBone());
|
||||
aData->PoseBuilder().GetTreeMap()[x4_particles[1].GetBone()] = zeus::CQuaternion::shortestRotationArc(_b0,
|
||||
_a4.inverse().transform(x4_particles[1].GetPosition() - x4_particles[0].GetPosition()));
|
||||
}
|
||||
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 3, 4,
|
||||
_a4 * BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 2, 3, _a4));
|
||||
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 6, 7,
|
||||
_a4 * BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 5, 6, _a4));
|
||||
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 9, 10,
|
||||
_a4 * BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 8, 9, _a4));
|
||||
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 12, 13,
|
||||
_a4 * BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 11, 12, _a4));
|
||||
zeus::CQuaternion q;
|
||||
q.rotateX(zeus::degToRad(-70.f));
|
||||
aData->PoseBuilder().GetTreeMap()[x4_particles[10].GetBone()].x4_rotation = q;
|
||||
aData->PoseBuilder().GetTreeMap()[x4_particles[13].GetBone()].x4_rotation = q;
|
||||
aData->MarkPoseDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void CPirateRagDoll::Update(CStateManager& mgr, float dt, float f2in)
|
||||
{
|
||||
if (!x68_25_ || x68_27_)
|
||||
{
|
||||
if (x6c_spacePirate->x7b4_ != kInvalidUniqueId)
|
||||
{
|
||||
float f2 = x4_particles[2].GetPosition().z - x4_particles[5].GetPosition().z;
|
||||
if (f2 * f2 > 0.0625f)
|
||||
{
|
||||
zeus::CVector3f vec(0.f, 0.f, ((f2 > 0.f) ? f2 - 0.25f : f2 + 0.25f) * 0.1f);
|
||||
x4_particles[2].Position() -= vec;
|
||||
x4_particles[5].Position() += vec;
|
||||
}
|
||||
f2 = x4_particles[0].GetPosition().z -
|
||||
(x4_particles[8].GetPosition().z + x4_particles[11].GetPosition().z) * 0.5f;
|
||||
if (f2 * f2 > 0.0625f)
|
||||
{
|
||||
zeus::CVector3f vec(0.f, 0.f, ((f2 > 0.f) ? f2 - 0.25f : f2 + 0.25f) * 0.1f);
|
||||
x4_particles[0].Position() -= vec;
|
||||
x4_particles[8].Position() += vec;
|
||||
x4_particles[11].Position() += vec;
|
||||
}
|
||||
}
|
||||
zeus::CVector3f _54 =
|
||||
x4_particles[8].GetPosition() * 0.25f +
|
||||
x4_particles[11].GetPosition() * 0.25f + x4_particles[0].GetPosition() * 0.5f;
|
||||
_54.z =
|
||||
std::min(x4_particles[0].GetPosition().z - x4_particles[0].GetRadius(),
|
||||
std::min(x4_particles[8].GetPosition().z - x4_particles[8].GetRadius(),
|
||||
x4_particles[11].GetPosition().z - x4_particles[11].GetRadius()));
|
||||
if (_54.z < 0.5f + f2in)
|
||||
x84_ = x84_ * 1000.f;
|
||||
zeus::CVector3f vec = x84_ * 0.333f * (1.f / x6c_spacePirate->GetMass());
|
||||
x4_particles[11].Acceleration() += vec;
|
||||
x4_particles[8].Acceleration() += vec;
|
||||
x4_particles[0].Acceleration() += vec;
|
||||
x84_ = zeus::CVector3f::skZero;
|
||||
CRagDoll::Update(mgr, dt, f2in);
|
||||
auto particleIdxIt = x9c_wpParticleIdxs.begin();
|
||||
for (TUniqueId id : x90_waypoints)
|
||||
{
|
||||
if (const CScriptWaypoint* wp = static_cast<const CScriptWaypoint*>(mgr.GetObjectById(id)))
|
||||
if (wp->GetActive())
|
||||
x4_particles[*particleIdxIt].Position() = wp->GetTranslation();
|
||||
++particleIdxIt;
|
||||
}
|
||||
zeus::CVector3f _60 =
|
||||
x4_particles[8].GetPosition() * 0.25f +
|
||||
x4_particles[11].GetPosition() * 0.25f + x4_particles[0].GetPosition() * 0.5f;
|
||||
_60.z =
|
||||
std::min(x4_particles[0].GetPosition().z - x4_particles[0].GetRadius(),
|
||||
std::min(x4_particles[8].GetPosition().z - x4_particles[8].GetRadius(),
|
||||
x4_particles[11].GetPosition().z - x4_particles[11].GetRadius()));
|
||||
x6c_spacePirate->SetTransform({});
|
||||
x6c_spacePirate->SetTranslation(_60);
|
||||
x6c_spacePirate->SetVelocityWR((_60 - _54) * (1.f / dt));
|
||||
x74_ -= dt;
|
||||
if (x54_ > 2.5f && x74_ < 0.f &&
|
||||
(xb0_24_ || (x6c_spacePirate->GetTranslation() - x78_).magSquared() > 0.1f))
|
||||
{
|
||||
CSfxManager::AddEmitter(x70_s1, x6c_spacePirate->GetTranslation(), zeus::CVector3f::skZero,
|
||||
std::min(25.f * x54_, 127.f) / 127.f, true, false, 0x7f, kInvalidAreaId);
|
||||
x74_ = mgr.GetActiveRandom()->Float() * 0.222f + 0.222f;
|
||||
xb0_24_ = false;
|
||||
x78_ = x6c_spacePirate->GetTranslation();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x6c_spacePirate->SetMomentumWR(zeus::CVector3f::skZero);
|
||||
x6c_spacePirate->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void CPirateRagDoll::Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData)
|
||||
{
|
||||
const auto& aabb = x6c_spacePirate->GetBaseBoundingBox();
|
||||
zeus::CVector3f newMax = aabb.max;
|
||||
newMax.z = (aabb.max.z - aabb.min.z) * 0.5f + aabb.min.z;
|
||||
x6c_spacePirate->SetBoundingBox({aabb.min, newMax});
|
||||
CRagDoll::Prime(mgr, xf, mData);
|
||||
}
|
||||
|
||||
const SBurst CSpacePirate::skBurstsQuick[] =
|
||||
{
|
||||
{20, {3, 4, 5, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {2, 3, 4, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {6, 5, 4, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {1, 2, 3, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {7, 6, 5, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsStandard[] =
|
||||
{
|
||||
{15, {5, 3, 2, 1, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {1, 2, 3, 4, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {7, 6, 5, 4, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {3, 4, 5, 6, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {6, 5, 4, 3, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {2, 3, 4, 5, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsFrenzied[] =
|
||||
{
|
||||
{40, {1, 2, 3, 4, 5, 6, -1, 0}, 0.100000, 0.050000},
|
||||
{40, {7, 6, 5, 4, 3, 2, -1, 0}, 0.100000, 0.050000},
|
||||
{10, {2, 3, 4, 5, 4, 3, -1, 0}, 0.100000, 0.050000},
|
||||
{10, {6, 5, 4, 3, 4, 5, -1, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsJumping[] =
|
||||
{
|
||||
{20, {16, 4, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{40, {5, 7, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{40, {1, 10, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsInjured[] =
|
||||
{
|
||||
{15, {16, 1, 3, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {3, 4, 6, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{25, {7, 5, 4, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{25, {2, 6, 4, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {7, 5, 3, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsSeated[] =
|
||||
{
|
||||
{35, {7, 13, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{35, {9, 1, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{30, {16, 12, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsQuickOOV[] =
|
||||
{
|
||||
{10, {16, 15, 13, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {13, 12, 10, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{30, {9, 11, 12, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{30, {14, 10, 12, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{10, {9, 11, 13, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsStandardOOV[] =
|
||||
{
|
||||
{26, {16, 8, 11, 14, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{26, {16, 13, 11, 12, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{16, {9, 11, 13, 10, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{16, {14, 13, 12, 11, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{8, {10, 11, 12, 13, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{8, {6, 8, 11, 13, -1, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsFrenziedOOV[] =
|
||||
{
|
||||
{40, {1, 16, 14, 12, 10, 11, -1, 0}, 0.100000, 0.050000},
|
||||
{40, {9, 11, 12, 13, 11, 7, -1, 0}, 0.100000, 0.050000},
|
||||
{10, {8, 10, 11, 12, 13, 12, -1, 0}, 0.100000, 0.050000},
|
||||
{10, {15, 13, 12, 10, 12, 9, -1, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsJumpingOOV[] =
|
||||
{
|
||||
{40, {7, 13, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{40, {9, 1, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{20, {16, 12, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsInjuredOOV[] =
|
||||
{
|
||||
{30, {9, 11, 13, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{10, {13, 12, 10, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {9, 11, 12, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{15, {14, 10, 12, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{30, {16, 15, 13, -1, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
const SBurst CSpacePirate::skBurstsSeatedOOV[] =
|
||||
{
|
||||
{35, {7, 13, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{35, {9, 1, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{30, {16, 12, -1, 0, 0, 0, 0, 0}, 0.100000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
const SBurst* CSpacePirate::skBursts[] =
|
||||
{
|
||||
skBurstsQuick,
|
||||
skBurstsStandard,
|
||||
skBurstsFrenzied,
|
||||
skBurstsJumping,
|
||||
skBurstsInjured,
|
||||
skBurstsSeated,
|
||||
skBurstsQuickOOV,
|
||||
skBurstsStandardOOV,
|
||||
skBurstsFrenziedOOV,
|
||||
skBurstsJumpingOOV,
|
||||
skBurstsInjuredOOV,
|
||||
skBurstsSeatedOOV,
|
||||
nullptr
|
||||
};
|
||||
|
||||
CSpacePirate::CSpacePirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
CModelData&& mData, const CActorParameters& aParams, const CPatternedInfo& pInfo,
|
||||
CInputStream& in, u32 propCount)
|
||||
: CPatterned(ECharacter::SpacePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground,
|
||||
EColliderType::One, EBodyType::BiPedal, aParams, EKnockBackVariant::Medium)
|
||||
, x568_(in, propCount)
|
||||
: CPatterned(ECharacter::SpacePirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||
EMovementType::Ground, EColliderType::One, EBodyType::BiPedal, aParams, EKnockBackVariant::Medium)
|
||||
, x568_pirateData(in, propCount), x660_(nullptr, 0x1, pInfo.GetPathfindingIndex(), 1.f, 1.f),
|
||||
x750_(pInfo.GetHealthInfo().GetHP()),
|
||||
x764_(*x64_modelData->AnimationData(), "Head_1"sv, 1.22173f, 3.14159f, false),
|
||||
x7c4_(skBursts, x568_pirateData.xac_firstBurstCount),
|
||||
x8b8_(x568_pirateData.xb0_), x8bc_(x568_pirateData.xb4_),
|
||||
x8c0_(x568_pirateData.xb8_), x8c4_(x568_pirateData.xa8_)
|
||||
{
|
||||
x634_24_ = bool(x568_pirateData.x18_ & 0x1);
|
||||
x634_25_ = bool(x568_pirateData.x18_ & 0x2);
|
||||
x634_26_ = bool(x568_pirateData.x18_ & 0x4);
|
||||
x634_27_ = bool(x568_pirateData.x18_ & 0x8);
|
||||
x634_28_ = bool(x568_pirateData.x18_ & 0x10);
|
||||
x634_29_ = bool(x568_pirateData.x18_ & 0x20);
|
||||
x634_30_ = bool(x568_pirateData.x18_ & 0x40);
|
||||
x634_31_ = bool(x568_pirateData.x18_ & 0x80);
|
||||
x635_24_ = bool(x568_pirateData.x18_ & 0x200);
|
||||
x635_25_ = bool(x568_pirateData.x18_ & 0x400);
|
||||
x635_26_ = bool(x568_pirateData.x18_ & 0x1000);
|
||||
x635_27_ = bool(x568_pirateData.x18_ & 0x2000);
|
||||
x635_28_ = bool(x568_pirateData.x18_ & 0x4000);
|
||||
x635_29_ = bool(x568_pirateData.x18_ & 0x8000);
|
||||
x635_30_ = bool(x568_pirateData.x18_ & 0x10000);
|
||||
x635_31_ = bool(x568_pirateData.x18_ & 0x20000);
|
||||
x636_24_trooper = bool(x568_pirateData.x18_ & 0x40000);
|
||||
|
||||
x758_headSeg = x64_modelData->GetAnimationData()->GetLocatorSegId("Head_1"sv);
|
||||
x7b6_gunSeg = x64_modelData->GetAnimationData()->GetLocatorSegId("R_gun_LCTR"sv);
|
||||
x7b7_elbowSeg = x64_modelData->GetAnimationData()->GetLocatorSegId("R_elbow"sv);
|
||||
x7b8_wristSeg = x64_modelData->GetAnimationData()->GetLocatorSegId("R_wrist"sv);
|
||||
x7b9_swooshSeg = x64_modelData->GetAnimationData()->GetLocatorSegId("Swoosh_LCTR"sv);
|
||||
|
||||
if (!x634_29_)
|
||||
{
|
||||
x7a4_intoJumpDist = GetAnimationDistance(CPASAnimParmData(13,
|
||||
CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(0)));
|
||||
x848_dodgeDist = GetAnimationDistance(CPASAnimParmData(3,
|
||||
CPASAnimParm::FromEnum(3), CPASAnimParm::FromEnum(1)));
|
||||
x84c_breakDodgeDist = GetAnimationDistance(CPASAnimParmData(3,
|
||||
CPASAnimParm::FromEnum(3), CPASAnimParm::FromEnum(2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
x450_bodyController->BodyStateInfo().SetLocoAnimChangeAtEndOfAnimOnly(true);
|
||||
}
|
||||
|
||||
const auto& baseAABB = GetBaseBoundingBox();
|
||||
x7a8_ = (baseAABB.max.z - baseAABB.min.z) * 0.6f;
|
||||
|
||||
if (x90_actorLights)
|
||||
x90_actorLights->SetAmbienceGenerated(false);
|
||||
|
||||
x460_knockBackController.sub80233d40(3, 3.f, FLT_MAX);
|
||||
x460_knockBackController.SetLocomotionDuringElectrocution(true);
|
||||
|
||||
if (x634_29_)
|
||||
x460_knockBackController.SetKnockBackVariant(EKnockBackVariant::Small);
|
||||
else if (x636_24_trooper && GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Plasma), false))
|
||||
x460_knockBackController.SetKnockBackVariant(EKnockBackVariant::Large);
|
||||
|
||||
if (!x450_bodyController->HasBodyState(pas::EAnimationState::AdditiveAim))
|
||||
x634_27_ = true;
|
||||
|
||||
if (x636_24_trooper)
|
||||
{
|
||||
if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Plasma), false))
|
||||
x8cc_trooperColor = zeus::CColor(0.996f, 0.f, 0.157f, 1.f);
|
||||
else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Ice), false))
|
||||
x8cc_trooperColor = zeus::CColor::skWhite;
|
||||
else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Power), false))
|
||||
x8cc_trooperColor = zeus::CColor(0.992f, 0.937f, 0.337f, 1.f);
|
||||
else if (GetDamageVulnerability()->WeaponHurts(CWeaponMode(EWeaponType::Wave), false))
|
||||
x8cc_trooperColor = zeus::CColor(0.776f, 0.054f, 1.f, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
void CSpacePirate::Accept(IVisitor &visitor)
|
||||
|
@ -39,6 +476,72 @@ void CSpacePirate::Think(float dt, CStateManager& mgr)
|
|||
|
||||
if (!x450_bodyController->GetActive())
|
||||
x450_bodyController->Activate(mgr);
|
||||
|
||||
#if 0
|
||||
bool inCineCam = mgr.GetCameraManager()->IsInCinematicCamera();
|
||||
if (inCineCam && !x637_31_prevInCineCam)
|
||||
sub_801283a8(mgr);
|
||||
else if (!inCineCam && x637_31_prevInCineCam && !x635_31_)
|
||||
CreateCollisionActor(mgr);
|
||||
x637_31_prevInCineCam = inCineCam;
|
||||
|
||||
float steeringSpeed = x748_ == 0.f ? x644_ : 0.f;
|
||||
x450_bodyController->GetCommandMgr().SetSteeringSpeedRange(steeringSpeed, steeringSpeed);
|
||||
|
||||
x744_ = std::max(x744_ - dt, 0.f);
|
||||
|
||||
if (x400_25_alive)
|
||||
{
|
||||
x850_ += dt;
|
||||
x854_ += dt;
|
||||
if (x637_27_)
|
||||
{
|
||||
x854_ = 0.f;
|
||||
x637_27_ = false;
|
||||
}
|
||||
if (x400_24_hitByPlayerProjectile)
|
||||
{
|
||||
x850_ = 0.f;
|
||||
x400_24_hitByPlayerProjectile = false;
|
||||
}
|
||||
}
|
||||
|
||||
sub_8012169c(dt, mgr);
|
||||
|
||||
if (!x450_bodyController->IsFrozen())
|
||||
{
|
||||
if (x400_25_alive)
|
||||
{
|
||||
x748_ = std::max(x748_ - dt, 0.f);
|
||||
if (x637_28_)
|
||||
x7ac_ += dt;
|
||||
else
|
||||
x7ac_ = 0.f;
|
||||
x838_ = std::max(x838_ - dt, 0.f);
|
||||
x8c0_ = std::max(x8c0_ - dt, 0.f);
|
||||
CheckForProjectiles(mgr);
|
||||
}
|
||||
sub_80121214(dt, mgr);
|
||||
sub_8012102c(dt, mgr);
|
||||
x860_ikChain.Update(dt);
|
||||
}
|
||||
|
||||
if (x634_24_)
|
||||
{
|
||||
x634_24_ = false;
|
||||
if (x634_25_)
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Internal6);
|
||||
else
|
||||
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
|
||||
x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Ambushing"sv);
|
||||
}
|
||||
|
||||
bool r29 = x85c_ragDoll == 0;
|
||||
if (r29 || )
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
CPatterned::Think(dt, mgr);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,43 @@
|
|||
|
||||
#include "World/CPatterned.hpp"
|
||||
#include "Weapon/CProjectileInfo.hpp"
|
||||
#include "Character/CBoneTracking.hpp"
|
||||
#include "Character/CIkChain.hpp"
|
||||
#include "Character/CRagDoll.hpp"
|
||||
#include "World/CPathFindSearch.hpp"
|
||||
#include "Weapon/CBurstFire.hpp"
|
||||
|
||||
namespace urde::MP1
|
||||
{
|
||||
class CSpacePirate;
|
||||
|
||||
class CPirateRagDoll : public CRagDoll
|
||||
{
|
||||
CSpacePirate* x6c_spacePirate;
|
||||
u16 x70_s1;
|
||||
float x74_ = 0.f;
|
||||
zeus::CVector3f x78_;
|
||||
zeus::CVector3f x84_;
|
||||
rstl::reserved_vector<TUniqueId, 4> x90_waypoints;
|
||||
rstl::reserved_vector<u32, 4> x9c_wpParticleIdxs;
|
||||
bool xb0_24_ : 1;
|
||||
public:
|
||||
CPirateRagDoll(CStateManager& mgr, CSpacePirate* sp, u16 s1, u32 flags);
|
||||
|
||||
void PreRender(const zeus::CVector3f& v, CModelData& mData);
|
||||
void Update(CStateManager& mgr, float dt, float f2);
|
||||
void Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData);
|
||||
};
|
||||
|
||||
class CSpacePirate : public CPatterned
|
||||
{
|
||||
friend class CPirateRagDoll;
|
||||
public:
|
||||
DEFINE_PATTERNED(SpacePirate)
|
||||
|
||||
private:
|
||||
class CSpacePirateData
|
||||
{
|
||||
friend class CSpacePirate;
|
||||
float x0_;
|
||||
float x4_;
|
||||
float x8_;
|
||||
|
@ -33,7 +58,7 @@ private:
|
|||
float xa0_;
|
||||
u16 xa4_;
|
||||
float xa8_;
|
||||
u32 xac_;
|
||||
u32 xac_firstBurstCount;
|
||||
float xb0_;
|
||||
float xb4_;
|
||||
float xb8_;
|
||||
|
@ -46,7 +71,7 @@ private:
|
|||
CSpacePirateData(CInputStream&, u32);
|
||||
};
|
||||
|
||||
CSpacePirateData x568_;
|
||||
CSpacePirateData x568_pirateData;
|
||||
union
|
||||
{
|
||||
struct
|
||||
|
@ -67,11 +92,115 @@ private:
|
|||
bool x635_29_ : 1;
|
||||
bool x635_30_ : 1;
|
||||
bool x635_31_ : 1;
|
||||
bool x636_24_trooper : 1;
|
||||
bool x636_25_ : 1;
|
||||
bool x636_26_ : 1;
|
||||
bool x636_27_ : 1;
|
||||
bool x636_28_ : 1;
|
||||
bool x636_29_ : 1;
|
||||
bool x636_30_ : 1;
|
||||
bool x636_31_ : 1;
|
||||
bool x637_24_ : 1;
|
||||
bool x637_25_ : 1;
|
||||
bool x637_26_ : 1;
|
||||
bool x637_27_ : 1;
|
||||
bool x637_28_ : 1;
|
||||
bool x637_29_ : 1;
|
||||
bool x637_30_ : 1;
|
||||
bool x637_31_prevInCineCam : 1;
|
||||
bool x638_24_ : 1;
|
||||
bool x638_25_ : 1;
|
||||
bool x638_26_ : 1;
|
||||
bool x638_27_ : 1;
|
||||
bool x638_28_ : 1;
|
||||
bool x638_29_ : 1;
|
||||
bool x638_30_ : 1;
|
||||
bool x638_31_ : 1;
|
||||
bool x639_24_ : 1;
|
||||
bool x639_25_ : 1;
|
||||
bool x639_26_ : 1;
|
||||
bool x639_27_ : 1;
|
||||
bool x639_28_ : 1;
|
||||
bool x639_29_ : 1;
|
||||
bool x639_30_ : 1;
|
||||
bool x639_31_ : 1;
|
||||
bool x63a_24_ : 1;
|
||||
};
|
||||
|
||||
u32 _dummy = 0;
|
||||
u64 _dummy = 0;
|
||||
};
|
||||
|
||||
u32 x63c_ = 0;
|
||||
TUniqueId x640_ = kInvalidUniqueId;
|
||||
TUniqueId x642_ = kInvalidUniqueId;
|
||||
float x644_ = 1.f;
|
||||
zeus::CVector3f x648_ = zeus::CVector3f::skForward;
|
||||
zeus::CVector3f x654_;
|
||||
CPathFindSearch x660_;
|
||||
float x744_ = 0.f;
|
||||
float x748_ = 0.f;
|
||||
u32 x74c_ = 0;
|
||||
float x750_;
|
||||
float x754_ = 0.f;
|
||||
CSegId x758_headSeg;
|
||||
u32 x75c_ = 0;
|
||||
s32 x760_ = -1;
|
||||
CBoneTracking x764_;
|
||||
s32 x79c_ = -1;
|
||||
float x7a4_intoJumpDist = 1.f;
|
||||
float x7a8_ = 2.f;
|
||||
float x7ac_ = 0.f;
|
||||
u32 x7b0_ = 0;
|
||||
TUniqueId x7b4_ = kInvalidUniqueId;
|
||||
CSegId x7b6_gunSeg;
|
||||
CSegId x7b7_elbowSeg;
|
||||
CSegId x7b8_wristSeg;
|
||||
CSegId x7b9_swooshSeg;
|
||||
float x7bc_ = 1.f;
|
||||
TUniqueId x7c0_ = kInvalidUniqueId;
|
||||
CBurstFire x7c4_;
|
||||
float x824_ = 3.f;
|
||||
zeus::CVector3f x828_;
|
||||
s32 x834_ = -1;
|
||||
float x838_ = 0.f;
|
||||
s32 x83c_ = -1;
|
||||
TUniqueId x840_ = kInvalidUniqueId;
|
||||
s32 x844_ = -1;
|
||||
float x848_dodgeDist = 3.f;
|
||||
float x84c_breakDodgeDist = 3.f;
|
||||
float x850_ = FLT_MAX;
|
||||
float x854_ = FLT_MAX;
|
||||
float x858_ = 0.f;
|
||||
std::unique_ptr<CPirateRagDoll> x85c_ragDoll;
|
||||
CIkChain x860_ikChain;
|
||||
float x8a8_ = 0.f;
|
||||
float x8ac_ = 0.f;
|
||||
float x8b0_ = 0.f;
|
||||
float x8b4_ = 0.5f;
|
||||
float x8b8_;
|
||||
float x8bc_;
|
||||
float x8c0_;
|
||||
float x8c4_;
|
||||
TUniqueId x8c8_ = kInvalidUniqueId;
|
||||
zeus::CColor x8cc_trooperColor = zeus::CColor::skWhite;
|
||||
zeus::CVector2f x8d0_;
|
||||
float x8d8_ = 0.f;
|
||||
float x8dc_ = 0.f;
|
||||
|
||||
static const SBurst skBurstsSeatedOOV[];
|
||||
static const SBurst skBurstsInjuredOOV[];
|
||||
static const SBurst skBurstsJumpingOOV[];
|
||||
static const SBurst skBurstsFrenziedOOV[];
|
||||
static const SBurst skBurstsStandardOOV[];
|
||||
static const SBurst skBurstsQuickOOV[];
|
||||
static const SBurst skBurstsSeated[];
|
||||
static const SBurst skBurstsInjured[];
|
||||
static const SBurst skBurstsJumping[];
|
||||
static const SBurst skBurstsFrenzied[];
|
||||
static const SBurst skBurstsStandard[];
|
||||
static const SBurst skBurstsQuick[];
|
||||
static const SBurst* skBursts[];
|
||||
|
||||
public:
|
||||
CSpacePirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||
const CActorParameters&, const CPatternedInfo&, CInputStream&, u32);
|
||||
|
|
|
@ -124,34 +124,28 @@ bool CMVEBounce::GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPo
|
|||
if (!x14_planePrecomputed)
|
||||
{
|
||||
/* Compute Hesse normal form of plane (for penetration testing) */
|
||||
x8_planeNormal->GetValue(frame, ((zeus::CVector3f&)x18_planeValidatedNormal));
|
||||
((zeus::CVector3f&)x18_planeValidatedNormal).normalize();
|
||||
x8_planeNormal->GetValue(frame, const_cast<zeus::CVector3f&>(x18_planeValidatedNormal));
|
||||
const_cast<zeus::CVector3f&>(x18_planeValidatedNormal).normalize();
|
||||
|
||||
zeus::CVector3f a;
|
||||
x4_planePoint->GetValue(frame, a);
|
||||
|
||||
(float&)(x24_planeD) = x18_planeValidatedNormal.dot(a);
|
||||
const_cast<float&>(x24_planeD) = x18_planeValidatedNormal.dot(a);
|
||||
}
|
||||
|
||||
float dot = x18_planeValidatedNormal.dot(pPos);
|
||||
if ((dot - x24_planeD) <= 0.0f)
|
||||
{
|
||||
if (x15_dieOnPenetrate)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (dot - x24_planeD > 0.0f)
|
||||
return false;
|
||||
else if (x15_dieOnPenetrate)
|
||||
return true;
|
||||
|
||||
/* Deflection event */
|
||||
|
||||
if (pVel.magSquared() > 0.0f)
|
||||
if (pVel.dot(x18_planeValidatedNormal) >= 0.0f)
|
||||
return false;
|
||||
|
||||
zeus::CVector3f delta = pPos - pVel;
|
||||
pPos += zeus::CVector3f{(-((((delta.z * ((delta.x * (delta.y * x18_planeValidatedNormal.y))
|
||||
+ ((pVel.x * (x18_planeValidatedNormal.y * pVel.y)) + x18_planeValidatedNormal.x))) + x18_planeValidatedNormal.z) - x24_planeD)) /
|
||||
((pVel.z * ((pVel.x * (x18_planeValidatedNormal.y * pVel.y)) + x18_planeValidatedNormal.x)) + x18_planeValidatedNormal.z)) - (
|
||||
(x18_planeValidatedNormal.z * ((x18_planeValidatedNormal.x * (x18_planeValidatedNormal.y * pVel.y)) + pVel.x)) + pVel.z)} * pVel;
|
||||
pPos += (-(delta.dot(x18_planeValidatedNormal) - x24_planeD) / pVel.dot(x18_planeValidatedNormal) - 1.f) * pVel;
|
||||
|
||||
float d = 0.0f;
|
||||
x10_restitution->GetValue(frame, d);
|
||||
|
@ -159,7 +153,7 @@ bool CMVEBounce::GetValue(int frame, zeus::CVector3f& pVel, zeus::CVector3f& pPo
|
|||
|
||||
float c = 0.0f;
|
||||
xc_friction->GetValue(frame, c);
|
||||
pVel -= zeus::CVector3f{(1.0f + c) * ((x18_planeValidatedNormal.z * (x18_planeValidatedNormal.x * (x18_planeValidatedNormal.y * pVel.y)) + pVel.x) + pVel.x)} * x18_planeValidatedNormal;
|
||||
pVel -= (1.f + c) * x18_planeValidatedNormal.dot(pVel) * x18_planeValidatedNormal;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,78 +1,108 @@
|
|||
#include "CBurstFire.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
CBurstFire::CBurstFire(SBurst** bursts, s32 firstIndex)
|
||||
: x10_(firstIndex)
|
||||
CBurstFire::CBurstFire(const SBurst** burstDefs, s32 firstBurstCount)
|
||||
: x10_firstBurstCounter(firstBurstCount)
|
||||
{
|
||||
SBurst** burst = bursts;
|
||||
while (1)
|
||||
while (*burstDefs)
|
||||
{
|
||||
if (!*burst)
|
||||
break;
|
||||
|
||||
x18_bursts.push_back(*burst);
|
||||
++burst;
|
||||
x1c_burstDefs.push_back(*burstDefs);
|
||||
++burstDefs;
|
||||
}
|
||||
}
|
||||
|
||||
void CBurstFire::Update(CStateManager&, float)
|
||||
void CBurstFire::Update(CStateManager& mgr, float dt)
|
||||
{
|
||||
|
||||
x14_24_shouldFire = false;
|
||||
if (x18_curBursts)
|
||||
{
|
||||
x8_timeToNextShot -= dt;
|
||||
if (x8_timeToNextShot < 0.f)
|
||||
{
|
||||
x4_angleIdx += 1;
|
||||
if (x18_curBursts->x4_shotAngles[x4_angleIdx] > 0)
|
||||
{
|
||||
x14_24_shouldFire = true;
|
||||
x8_timeToNextShot = x18_curBursts->x24_timeToNextShot;
|
||||
x8_timeToNextShot += (mgr.GetActiveRandom()->Float() - 0.5f) *
|
||||
x18_curBursts->x28_timeToNextShotVariance;
|
||||
}
|
||||
else
|
||||
{
|
||||
x18_curBursts = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CVector3f CBurstFire::GetDistanceCompensatedError(float, float) const
|
||||
zeus::CVector3f CBurstFire::GetDistanceCompensatedError(float dist, float maxErrDist) const
|
||||
{
|
||||
return {};
|
||||
float xErr = GetMaxXError();
|
||||
float zErr = GetMaxZError();
|
||||
xErr = std::min(xErr, dist / maxErrDist * xErr);
|
||||
zErr = std::min(zErr, dist / maxErrDist * zErr);
|
||||
return GetError(xErr, zErr);
|
||||
}
|
||||
|
||||
void CBurstFire::SetFirstBurst(bool)
|
||||
void CBurstFire::Start(CStateManager& mgr)
|
||||
{
|
||||
|
||||
s32 burstIdx = -1;
|
||||
const SBurst* bursts = x1c_burstDefs[x0_burstType];
|
||||
if (x10_firstBurstCounter-- > 0)
|
||||
{
|
||||
burstIdx = xc_firstBurstIdx < 0 ? 0 : xc_firstBurstIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
int random = mgr.GetActiveRandom()->Range(0, 100);
|
||||
int advanceAccum = 0;
|
||||
do
|
||||
{
|
||||
burstIdx += 1;
|
||||
s32 advanceWeight = bursts[burstIdx].x0_randomSelectionWeight;
|
||||
if (advanceWeight == 0)
|
||||
{
|
||||
advanceAccum = 100;
|
||||
burstIdx -= 1;
|
||||
}
|
||||
advanceAccum += advanceWeight;
|
||||
} while (random > advanceAccum);
|
||||
}
|
||||
x18_curBursts = &bursts[burstIdx];
|
||||
x4_angleIdx = -1;
|
||||
x8_timeToNextShot = 0.f;
|
||||
x14_24_shouldFire = false;
|
||||
}
|
||||
|
||||
bool CBurstFire::IsBurstSet() const
|
||||
zeus::CVector3f CBurstFire::GetError(float xMag, float zMag) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBurstFire::SetTimeToNextShot(float)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CBurstFire::ShouldFire() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBurstFire::Start(CStateManager&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CBurstFire::GetError(float, float) const
|
||||
{
|
||||
|
||||
zeus::CVector3f ret;
|
||||
if (x14_24_shouldFire && x18_curBursts)
|
||||
{
|
||||
s32 r0 = x18_curBursts->x4_shotAngles[x4_angleIdx];
|
||||
if (x14_25_avoidAccuracy && (r0 == 4 || r0 == 12))
|
||||
r0 = x4_angleIdx > 0 ? x18_curBursts->x4_shotAngles[x4_angleIdx - 1] :
|
||||
x18_curBursts->x4_shotAngles[x4_angleIdx + 1];
|
||||
if (r0 > 0)
|
||||
{
|
||||
float angle = r0 * zeus::degToRad(-22.5f);
|
||||
ret.x = std::cos(angle) * xMag;
|
||||
ret.z = std::sin(angle) * zMag;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float CBurstFire::GetMaxXError() const
|
||||
{
|
||||
return 0;
|
||||
return g_tweakPlayer->GetPlayerXYHalfExtent() * 3.625f + 0.2f;
|
||||
}
|
||||
|
||||
float CBurstFire::GetMaxZError() const
|
||||
{
|
||||
return 0;
|
||||
return g_tweakPlayer->GetEyeOffset();
|
||||
}
|
||||
|
||||
void CBurstFire::GetError() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CBurstFire::SetFirstBurstIndex(s32)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,53 +6,42 @@ namespace urde
|
|||
{
|
||||
struct SBurst
|
||||
{
|
||||
u32 x0_;
|
||||
u32 x4_;
|
||||
u32 x8_;
|
||||
s32 xc_;
|
||||
s32 x10_;
|
||||
u32 x14_;
|
||||
u32 x18_;
|
||||
u32 x1c_;
|
||||
u32 x20_;
|
||||
float x24_;
|
||||
float x28_;
|
||||
s32 x0_randomSelectionWeight;
|
||||
s32 x4_shotAngles[8];
|
||||
float x24_timeToNextShot;
|
||||
float x28_timeToNextShotVariance;
|
||||
};
|
||||
|
||||
class CBurstFire
|
||||
{
|
||||
friend class CScriptGunTurret;
|
||||
s32 x0_ = -1;
|
||||
s32 x4_ = -1;
|
||||
float x8_ = 0.f;
|
||||
u32 xc_ = 0;
|
||||
s32 x10_;
|
||||
s32 x0_burstType = -1;
|
||||
s32 x4_angleIdx = -1;
|
||||
float x8_timeToNextShot = 0.f;
|
||||
s32 xc_firstBurstIdx = 0;
|
||||
s32 x10_firstBurstCounter;
|
||||
union
|
||||
{
|
||||
struct { bool x14_24_ : 1; bool x14_25_ : 1; };
|
||||
struct { bool x14_24_shouldFire : 1; bool x14_25_avoidAccuracy : 1; };
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
|
||||
rstl::reserved_vector<SBurst*, 16> x18_bursts;
|
||||
const SBurst* x18_curBursts = nullptr;
|
||||
rstl::reserved_vector<const SBurst*, 16> x1c_burstDefs;
|
||||
public:
|
||||
CBurstFire(SBurst**, s32);
|
||||
CBurstFire(const SBurst** burstDefs, s32 firstBurstCount);
|
||||
|
||||
void SetFirstBurst(bool);
|
||||
void SetBurstType(s32 type) { x0_ = type; }
|
||||
bool IsBurstSet() const;
|
||||
void SetTimeToNextShot(float);
|
||||
bool ShouldFire() const;
|
||||
s32 GetBurstType() const { return x0_; }
|
||||
void Start(CStateManager&);
|
||||
void Update(CStateManager&, float);
|
||||
void Update();
|
||||
void GetError(float, float) const;
|
||||
zeus::CVector3f GetDistanceCompensatedError(float, float) const;
|
||||
void SetAvoidAccuracy(bool b) { x14_25_avoidAccuracy = b; }
|
||||
void SetBurstType(s32 type) { x0_burstType = type; }
|
||||
void SetTimeToNextShot(float t) { x8_timeToNextShot = t; }
|
||||
s32 GetBurstType() const { return x0_burstType; }
|
||||
void Start(CStateManager& mgr);
|
||||
void Update(CStateManager& mgr, float dt);
|
||||
zeus::CVector3f GetError(float xMag, float zMag) const;
|
||||
zeus::CVector3f GetDistanceCompensatedError(float dist, float maxErrDist) const;
|
||||
float GetMaxXError() const;
|
||||
float GetMaxZError() const;
|
||||
void GetError() const;
|
||||
void SetFirstBurstIndex(s32);
|
||||
|
||||
bool GetX14_24() const { return x14_24_; }
|
||||
void SetFirstBurstIndex(s32 idx) { xc_firstBurstIdx = idx; }
|
||||
bool ShouldFire() const { return x14_24_shouldFire; }
|
||||
bool IsBurstSet() const { return x18_curBursts != nullptr; }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ set(WEAPON_SOURCES
|
|||
CGunController.hpp CGunController.cpp
|
||||
CGunMotion.hpp CGunMotion.cpp
|
||||
CGrappleArm.hpp CGrappleArm.cpp
|
||||
CWeaponMode.hpp CWeaponMode.cpp
|
||||
CWeaponMode.hpp
|
||||
CPlayerGun.hpp CPlayerGun.cpp
|
||||
CGunWeapon.hpp CGunWeapon.cpp
|
||||
CAuxWeapon.hpp CAuxWeapon.cpp
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#include "CWeaponMode.hpp"
|
||||
#include "DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
CWeaponMode::CWeaponMode(EWeaponType type, bool charged, bool comboed, bool instaKill)
|
||||
: x0_weaponType(type), x4_24_charged(charged), x4_25_comboed(comboed), x4_26_instantKill(instaKill)
|
||||
{
|
||||
}
|
||||
|
||||
CWeaponMode CWeaponMode::Invalid() { return CWeaponMode(EWeaponType::None); }
|
||||
|
||||
CWeaponMode CWeaponMode::Phazon() { return CWeaponMode(EWeaponType::Phazon); }
|
||||
|
||||
CWeaponMode CWeaponMode::Plasma() { return CWeaponMode(EWeaponType::Plasma); }
|
||||
|
||||
CWeaponMode CWeaponMode::Wave() { return CWeaponMode(EWeaponType::Wave); }
|
||||
|
||||
CWeaponMode CWeaponMode::BoostBall() { return CWeaponMode(EWeaponType::BoostBall); }
|
||||
|
||||
CWeaponMode CWeaponMode::Ice() { return CWeaponMode(EWeaponType::Ice); }
|
||||
|
||||
CWeaponMode CWeaponMode::Power() { return CWeaponMode(EWeaponType::Power); }
|
||||
|
||||
CWeaponMode CWeaponMode::Bomb() { return CWeaponMode(EWeaponType::Bomb); }
|
||||
|
||||
CWeaponMode CWeaponMode::PowerBomb() { return CWeaponMode(EWeaponType::PowerBomb); }
|
||||
}
|
|
@ -13,21 +13,22 @@ class CWeaponMode
|
|||
|
||||
public:
|
||||
CWeaponMode() { x4_24_charged = false; x4_25_comboed = false; x4_26_instantKill = false; }
|
||||
CWeaponMode(EWeaponType, bool charged = false, bool comboed = false, bool instaKill = false);
|
||||
CWeaponMode(EWeaponType type, bool charged = false, bool comboed = false, bool instaKill = false)
|
||||
: x0_weaponType(type), x4_24_charged(charged), x4_25_comboed(comboed), x4_26_instantKill(instaKill) {}
|
||||
EWeaponType GetType() const { return x0_weaponType; }
|
||||
|
||||
bool IsCharged() const { return x4_24_charged; }
|
||||
bool IsComboed() const { return x4_25_comboed; }
|
||||
bool IsInstantKill() const { return x4_26_instantKill; }
|
||||
|
||||
static CWeaponMode Invalid();
|
||||
static CWeaponMode Phazon();
|
||||
static CWeaponMode Plasma();
|
||||
static CWeaponMode Wave();
|
||||
static CWeaponMode BoostBall();
|
||||
static CWeaponMode Ice();
|
||||
static CWeaponMode Power();
|
||||
static CWeaponMode Bomb();
|
||||
static CWeaponMode PowerBomb();
|
||||
static CWeaponMode Invalid() { return CWeaponMode(EWeaponType::None); }
|
||||
static CWeaponMode Phazon() { return CWeaponMode(EWeaponType::Phazon); }
|
||||
static CWeaponMode Plasma() { return CWeaponMode(EWeaponType::Plasma); }
|
||||
static CWeaponMode Wave() { return CWeaponMode(EWeaponType::Wave); }
|
||||
static CWeaponMode BoostBall() { return CWeaponMode(EWeaponType::BoostBall); }
|
||||
static CWeaponMode Ice() { return CWeaponMode(EWeaponType::Ice); }
|
||||
static CWeaponMode Power() { return CWeaponMode(EWeaponType::Power); }
|
||||
static CWeaponMode Bomb() { return CWeaponMode(EWeaponType::Bomb); }
|
||||
static CWeaponMode PowerBomb() { return CWeaponMode(EWeaponType::PowerBomb); }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -605,7 +605,7 @@ void CKnockBackController::Update(float dt, CStateManager& mgr, CPatterned& pare
|
|||
x64_flinchRemTime -= dt;
|
||||
if (TickDeferredTimer(dt))
|
||||
DoDeferredKnockBack(mgr, parent);
|
||||
if (x82_26_ && parent.BodyController()->IsElectrocuting())
|
||||
if (x82_26_locomotionDuringElectrocution && parent.BodyController()->IsElectrocuting())
|
||||
parent.BodyController()->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::Locomotion));
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ private:
|
|||
bool x81_31_ : 1; // t
|
||||
bool x82_24_ : 1; // t
|
||||
bool x82_25_inDeferredKnockBack : 1;
|
||||
bool x82_26_ : 1;
|
||||
bool x82_26_locomotionDuringElectrocution : 1;
|
||||
};
|
||||
u32 dummy = 0;
|
||||
};
|
||||
|
@ -155,6 +155,7 @@ public:
|
|||
void SetEnableExplodeDeath(bool b) { x81_29_enableExplodeDeath = b; }
|
||||
void SetEnableLaggedBurnDeath(bool b) { x81_30_enableLaggedBurnDeath = b; }
|
||||
void SetX82_24(bool b) { x82_24_ = b; }
|
||||
void SetLocomotionDuringElectrocution(bool b) { x82_26_locomotionDuringElectrocution = b; }
|
||||
const KnockBackParms& GetActiveParms() const { return x4_activeParms; }
|
||||
EKnockBackVariant GetVariant() const { return x0_variant; }
|
||||
float GetFlinchRemTime() const { return x64_flinchRemTime; }
|
||||
|
|
|
@ -1597,6 +1597,19 @@ EScriptObjectState CPatterned::GetDesiredAttackState(CStateManager& mgr) const
|
|||
return EScriptObjectState::Attack;
|
||||
}
|
||||
|
||||
float CPatterned::GetAnimationDistance(const CPASAnimParmData& data) const
|
||||
{
|
||||
auto bestAnim =
|
||||
x64_modelData->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(data, -1);
|
||||
float dist = 1.f;
|
||||
if (bestAnim.first > FLT_EPSILON)
|
||||
{
|
||||
dist = x64_modelData->GetAnimationData()->GetAnimationDuration(bestAnim.second) *
|
||||
x64_modelData->GetAnimationData()->GetAverageVelocity(bestAnim.second);
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
|
||||
{
|
||||
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
|
||||
|
|
|
@ -308,6 +308,7 @@ protected:
|
|||
void UpdatePatternDestPos(CStateManager& mgr);
|
||||
void SetupPattern(CStateManager& mgr);
|
||||
EScriptObjectState GetDesiredAttackState(CStateManager& mgr) const;
|
||||
float GetAnimationDistance(const CPASAnimParmData& data) const;
|
||||
public:
|
||||
CPatterned(ECharacter character, TUniqueId uid, std::string_view name, EFlavorType flavor,
|
||||
const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData,
|
||||
|
|
|
@ -36,7 +36,7 @@ CPatternedInfo::CPatternedInfo(CInputStream& in, u32 pcount)
|
|||
, x100_intoFreezeDur(in.readFloatBig())
|
||||
, x104_outofFreezeDur(in.readFloatBig())
|
||||
, x108_(in.readFloatBig())
|
||||
, x10c_particle1Frames(in.readUint32Big())
|
||||
, x10c_pathfindingIndex(in.readUint32Big())
|
||||
, x110_particle1Scale(zeus::CVector3f::ReadBig(in))
|
||||
, x11c_particle1(in)
|
||||
, x120_electric(in)
|
||||
|
|
|
@ -45,7 +45,7 @@ class CPatternedInfo
|
|||
float x104_outofFreezeDur;
|
||||
float x108_;
|
||||
|
||||
u32 x10c_particle1Frames;
|
||||
u32 x10c_pathfindingIndex;
|
||||
zeus::CVector3f x110_particle1Scale;
|
||||
CAssetId x11c_particle1;
|
||||
|
||||
|
@ -64,7 +64,8 @@ public:
|
|||
|
||||
float GetHalfExtent() const { return xc4_halfExtent; }
|
||||
float GetHeight() const { return xc8_height; }
|
||||
u32 GetParticle1Frames() const { return x10c_particle1Frames; }
|
||||
u32 GetPathfindingIndex() const { return x10c_pathfindingIndex; }
|
||||
const CHealthInfo& GetHealthInfo() const { return x54_healthInfo; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1138,7 +1138,7 @@ void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr,
|
|||
if (scanTime >= 1.f)
|
||||
{
|
||||
x9c6_30_newScanScanning = false;
|
||||
scanTime = 0.f;
|
||||
scanTime = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntity
|
|||
x150_momentum = zeus::CVector3f(0.f, 0.f, -24.525f * xe8_mass);
|
||||
|
||||
if (x90_actorLights)
|
||||
x90_actorLights->SetAmbientChannelOverflow(true);
|
||||
x90_actorLights->SetAmbienceGenerated(true);
|
||||
}
|
||||
|
||||
CScriptDebris::CScriptDebris(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||
|
|
|
@ -59,71 +59,77 @@ CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount)
|
|||
{
|
||||
}
|
||||
|
||||
SBurst CScriptGunTurret::skOOVBurst4InfoTemplate[5] =
|
||||
const SBurst CScriptGunTurret::skBurst2InfoTemplate[] =
|
||||
{
|
||||
{3, 1, 2, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{3, 7, 6, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{4, 3, 5, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{60, 16, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, 4, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{3, {1, 2, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{3, {7, 6, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{4, {3, 5, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{60, {16, 4, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{30, {4, 4, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst CScriptGunTurret::skOOVBurst3InfoTemplate[5] =
|
||||
const SBurst CScriptGunTurret::skBurst3InfoTemplate[] =
|
||||
{
|
||||
{30, 4, 5, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, 2, 3, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, 3, 4, 5, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{5, 16, 1, 2, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{5, 8, 7, 6, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, {4, 5, 4, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{30, {2, 3, 4, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{30, {3, 4, 5, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{5, {16, 1, 2, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{5, {8, 7, 6, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst CScriptGunTurret::skOOVBurst2InfoTemplate[7] =
|
||||
const SBurst CScriptGunTurret::skBurst4InfoTemplate[] =
|
||||
{
|
||||
{5, 16, 1, 2, 3, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{5, 9, 8, 7, 6, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{15, 2, 3, 4, 5, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{15, 5, 4, 3, 2, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{15, 10, 11, 4, 13, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{15, 14, 13, 4, 11, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, 2, 4, 4, 6, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{5, {16, 1, 2, 3, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{5, {9, 8, 7, 6, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{15, {2, 3, 4, 5, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{15, {5, 4, 3, 2, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{15, {10, 11, 4, 13, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{15, {14, 13, 4, 11, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{30, {2, 4, 4, 6, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst CScriptGunTurret::skBurst4InfoTemplate[5] =
|
||||
const SBurst CScriptGunTurret::skOOVBurst2InfoTemplate[] =
|
||||
{
|
||||
{20, 16, 15, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 8, 9, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 13, 11, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 2, 6, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 3, 4, -1, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, {16, 15, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {8, 9, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {13, 11, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {2, 6, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {3, 4, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst CScriptGunTurret::skBurst3InfoTemplate[5] =
|
||||
const SBurst CScriptGunTurret::skOOVBurst3InfoTemplate[] =
|
||||
{
|
||||
{10, 14, 4, 10, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{10, 15, 13, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{10, 9, 11, 4, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{35, 15, 13, 11, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{35, 9, 11, 13, -1, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{10, {14, 4, 10, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{10, {15, 13, 4, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{10, {9, 11, 4, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{35, {15, 13, 11, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{35, {9, 11, 13, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst CScriptGunTurret::skBurst2InfoTemplate[6] =
|
||||
const SBurst CScriptGunTurret::skOOVBurst4InfoTemplate[] =
|
||||
{
|
||||
{10, 14, 13, 4, 11, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{30, 1, 15, 13, 11, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 16, 15, 14, 13, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{10, 8, 9, 11, 4, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{10, 1, 15, 13, 4, 0, 0, 0, 0, 0.15f, 0.05f},
|
||||
{20, 8, 9, 10, 11, 0, 0, 0, 0, 0.15f, 0.05f}
|
||||
{10, {14, 13, 4, 11, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{30, {1, 15, 13, 11, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {16, 15, 14, 13, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{10, {8, 9, 11, 4, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{10, {1, 15, 13, 4, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{20, {8, 9, 10, 11, 0, 0, 0, 0}, 0.150000, 0.050000},
|
||||
{0, {0, 0, 0, 0, 0, 0, 0, 0}, 0.000000, 0.000000},
|
||||
};
|
||||
|
||||
SBurst* CScriptGunTurret::skBursts[] =
|
||||
const SBurst* CScriptGunTurret::skBursts[] =
|
||||
{
|
||||
skOOVBurst4InfoTemplate,
|
||||
skOOVBurst3InfoTemplate,
|
||||
skOOVBurst2InfoTemplate,
|
||||
skBurst4InfoTemplate,
|
||||
skBurst3InfoTemplate,
|
||||
skBurst2InfoTemplate,
|
||||
skBurst3InfoTemplate,
|
||||
skBurst4InfoTemplate,
|
||||
skOOVBurst2InfoTemplate,
|
||||
skOOVBurst3InfoTemplate,
|
||||
skOOVBurst4InfoTemplate,
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -324,7 +330,7 @@ void CScriptGunTurret::Think(float dt, CStateManager& mgr)
|
|||
}
|
||||
else if (x258_type == ETurretComponent::Gun)
|
||||
{
|
||||
UpdatGunParticles(dt, mgr);
|
||||
UpdateGunParticles(dt, mgr);
|
||||
SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
|
||||
MoveToOR(deltas.x0_posDelta, dt);
|
||||
RotateToOR(deltas.xc_rotDelta, dt);
|
||||
|
@ -512,7 +518,7 @@ void CScriptGunTurret::GetUnFreezeSoundId(float dt, CStateManager& mgr)
|
|||
x53c_ = 0.f;
|
||||
}
|
||||
|
||||
void CScriptGunTurret::UpdatGunParticles(float dt, CStateManager& mgr)
|
||||
void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr)
|
||||
{
|
||||
CGameLight* light = nullptr;
|
||||
if (x498_lightId != kInvalidUniqueId)
|
||||
|
@ -1104,7 +1110,7 @@ void CScriptGunTurret::sub80216594(CStateManager& mgr)
|
|||
{
|
||||
u32 r3 = x2d4_data.x90_ - 2;
|
||||
x3a4_burstFire.SetBurstType(r3);
|
||||
x3a4_burstFire.xc_ = x2d4_data.x94_;
|
||||
x3a4_burstFire.SetFirstBurstIndex(x2d4_data.x94_);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1115,7 +1121,7 @@ void CScriptGunTurret::sub80216594(CStateManager& mgr)
|
|||
|
||||
bool CScriptGunTurret::sub80217950(CStateManager& mgr)
|
||||
{
|
||||
if (x520_ == 9 && x534_ <= 0.f && x3a4_burstFire.GetX14_24())
|
||||
if (x520_ == 9 && x534_ <= 0.f && x3a4_burstFire.ShouldFire())
|
||||
return sub80217ad8(mgr);
|
||||
|
||||
return false;
|
||||
|
|
|
@ -70,13 +70,13 @@ public:
|
|||
|
||||
class CScriptGunTurret : public CPhysicsActor
|
||||
{
|
||||
static SBurst skOOVBurst4InfoTemplate[5];
|
||||
static SBurst skOOVBurst3InfoTemplate[5];
|
||||
static SBurst skOOVBurst2InfoTemplate[7];
|
||||
static SBurst skBurst4InfoTemplate[5];
|
||||
static SBurst skBurst3InfoTemplate[5];
|
||||
static SBurst skBurst2InfoTemplate[6];
|
||||
static SBurst* skBursts[];
|
||||
static const SBurst skOOVBurst4InfoTemplate[];
|
||||
static const SBurst skOOVBurst3InfoTemplate[];
|
||||
static const SBurst skOOVBurst2InfoTemplate[];
|
||||
static const SBurst skBurst4InfoTemplate[];
|
||||
static const SBurst skBurst3InfoTemplate[];
|
||||
static const SBurst skBurst2InfoTemplate[];
|
||||
static const SBurst* skBursts[];
|
||||
public:
|
||||
enum class ETurretComponent
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ public:
|
|||
void sub802189c8();
|
||||
void UpdateGunCollisionManager(float, CStateManager&);
|
||||
void GetUnFreezeSoundId(float, CStateManager&);
|
||||
void UpdatGunParticles(float, CStateManager&);
|
||||
void UpdateGunParticles(float, CStateManager&);
|
||||
void sub80219938(s32, CStateManager&);
|
||||
void sub802196c4(s32, CStateManager&, float);
|
||||
void sub802195bc(s32, CStateManager&, float);
|
||||
|
|
|
@ -96,7 +96,7 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, std::string_view n
|
|||
x90_actorLights->DisableAreaLights();
|
||||
x90_actorLights->SetMaxDynamicLights(4);
|
||||
x90_actorLights->SetCastShadows(false);
|
||||
x90_actorLights->SetAmbientChannelOverflow(false);
|
||||
x90_actorLights->SetAmbienceGenerated(false);
|
||||
x90_actorLights->SetFindNearestDynamicLights(true);
|
||||
x148_24_detectCamera = true;
|
||||
CalculateRenderBounds();
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 5fece8ddb1a58e23e0957232964bc91a007cf123
|
||||
Subproject commit 14b54ca6c20a5b20eb4ccd23f1194fb3f6c2f984
|
Loading…
Reference in New Issue