CSnakeWeedSwarm: Renaming & cleanup

This commit is contained in:
Luke Street 2020-03-16 20:07:20 -04:00
parent dc77fb0c41
commit 87eeafe0b0
3 changed files with 160 additions and 148 deletions

View File

@ -15,31 +15,33 @@
namespace urde { namespace urde {
static constexpr CMaterialFilter matFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); static constexpr CMaterialFilter skMaterialFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid});
CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info, CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f& pos, const zeus::CVector3f& scale, const CAnimRes& animRes, const zeus::CVector3f& pos, const zeus::CVector3f& scale, const CAnimRes& animRes,
const CActorParameters& actParms, float f1, float f2, float f3, float f4, float f5, const CActorParameters& actParms, float spacing, float height, float f3,
float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, float weaponDamageRadius, float maxPlayerDistance, float loweredTime,
float f14, const CDamageInfo& dInfo, float /*f15*/, u32 sfxId1, u32 sfxId2, u32 sfxId3, float loweredTimeVariation, float maxZOffset, float speed, float speedVariation,
CAssetId w4, u32 w5, CAssetId w6, float f16) float f11, float scaleMin, float scaleMax, float distanceBelowGround,
const CDamageInfo& dInfo, float /*f15*/, u32 sfxId1, u32 sfxId2, u32 sfxId3,
CAssetId particleGenDesc1, u32 w5, CAssetId particleGenDesc2, float f16)
: CActor(uid, active, name, info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), : CActor(uid, active, name, info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(),
CMaterialList(EMaterialTypes::Trigger, EMaterialTypes::NonSolidDamageable), actParms, kInvalidUniqueId) CMaterialList(EMaterialTypes::Trigger, EMaterialTypes::NonSolidDamageable), actParms, kInvalidUniqueId)
, xe8_scale(scale) , xe8_scale(scale)
, xf4_boidSpacing(f1) , xf4_boidSpacing(spacing)
, xf8_height(f2) , xf8_height(height)
, xfc_(f3) , xfc_(f3)
, x100_weaponDamageRadius(f4) , x100_weaponDamageRadius(weaponDamageRadius)
, x104_(f5) , x104_maxPlayerDistance(maxPlayerDistance)
, x108_(f6) , x108_loweredTime(loweredTime)
, x10c_(f7) , x10c_loweredTimeVariation(loweredTimeVariation)
, x110_(f8) , x110_maxZOffset(maxZOffset)
, x114_(f9) , x114_speed(speed)
, x118_(f10) , x118_speedVariation(speedVariation)
, x11c_(std::cos(zeus::degToRad(f11))) , x11c_(std::cos(zeus::degToRad(f11)))
, x120_(f12) , x120_scaleMin(scaleMin)
, x124_(f13) , x124_scaleMax(scaleMax)
, x128_(f14) , x128_distanceBelowGround(distanceBelowGround)
, x140_24_hasGround(false) , x140_24_hasGround(false)
, x140_25_modelAssetDirty(false) , x140_25_modelAssetDirty(false)
, x140_26_playerTouching(false) , x140_26_playerTouching(false)
@ -57,21 +59,23 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na
x1b0_modelData.emplace_back(std::make_unique<CModelData>(animRes)); x1b0_modelData.emplace_back(std::make_unique<CModelData>(animRes));
x1b0_modelData.emplace_back(std::make_unique<CModelData>(animRes)); x1b0_modelData.emplace_back(std::make_unique<CModelData>(animRes));
if (actParms.GetXRayAssets().first.IsValid()) { if (actParms.GetXRayAssets().first.IsValid()) {
for (int i = 0; i < 4; ++i) for (const auto& modelData : x1b0_modelData) {
x1b0_modelData[i]->SetXRayModel(actParms.GetXRayAssets()); modelData->SetXRayModel(actParms.GetXRayAssets());
}
x140_25_modelAssetDirty = true; x140_25_modelAssetDirty = true;
} }
if (actParms.GetThermalAssets().first.IsValid()) { if (actParms.GetThermalAssets().first.IsValid()) {
for (int i = 0; i < 4; ++i) for (const auto& modelData : x1b0_modelData) {
x1b0_modelData[i]->SetInfraModel(actParms.GetThermalAssets()); modelData->SetInfraModel(actParms.GetThermalAssets());
}
x140_25_modelAssetDirty = true; x140_25_modelAssetDirty = true;
} }
if (w4.IsValid()) { if (particleGenDesc1.IsValid()) {
x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), w4}); x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), particleGenDesc1});
x1ec_particleGen1 = std::make_unique<CElementGen>(x1dc_particleGenDesc); x1ec_particleGen1 = std::make_unique<CElementGen>(x1dc_particleGenDesc);
} }
if (w6.IsValid()) { if (particleGenDesc2.IsValid()) {
x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), w6}); x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), particleGenDesc2});
x1f4_particleGen2 = std::make_unique<CElementGen>(x1dc_particleGenDesc); x1f4_particleGen2 = std::make_unique<CElementGen>(x1dc_particleGenDesc);
} }
} }
@ -79,11 +83,11 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na
void CSnakeWeedSwarm::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } void CSnakeWeedSwarm::Accept(urde::IVisitor& visitor) { visitor.Visit(this); }
void CSnakeWeedSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) { void CSnakeWeedSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < x1b0_modelData.size(); ++i) {
const auto& modelData = x1b0_modelData[i]; auto& modelData = *x1b0_modelData[i];
modelData->EnableLooping(true); modelData.EnableLooping(true);
modelData->AdvanceAnimation(modelData->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.25f), mgr, const float dt = modelData.GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.25f);
x4_areaId, true); modelData.AdvanceAnimation(dt, mgr, x4_areaId, true);
} }
x1c4_which = which; x1c4_which = which;
} }
@ -150,7 +154,7 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM
} }
} else { } else {
CGraphics::DisableAllLights(); CGraphics::DisableAllLights();
g_Renderer->SetAmbientColor(zeus::skWhite); CGraphics::SetAmbientColor(zeus::skWhite);
} }
u32 posesToBuild = -1; u32 posesToBuild = -1;
@ -161,13 +165,14 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM
void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) {
if (TCastToPtr<CGameProjectile> proj = actor) { if (TCastToPtr<CGameProjectile> proj = actor) {
if (proj->GetDamageInfo().GetWeaponMode().GetType() != EWeaponType::AI) if (proj->GetDamageInfo().GetWeaponMode().GetType() != EWeaponType::AI) {
HandleRadiusDamage(x100_weaponDamageRadius, mgr, proj->GetTransform().origin); HandleRadiusDamage(x100_weaponDamageRadius, mgr, proj->GetTransform().origin);
}
} }
if (TCastToPtr<CPlayer> player = actor) { if (TCastToPtr<CPlayer> player = actor) {
for (const auto& boid : x134_boids) { for (const auto& boid : x134_boids) {
float m = (boid.GetPosition() - player->GetTransform().origin).magnitude(); float m = (boid.GetPosition() - player->GetTransform().origin).magnitude();
if (m < x104_ && boid.GetState() == EBoidState::Raised) { if (m < x104_maxPlayerDistance && boid.GetState() == EBoidState::Raised) {
mgr.SendScriptMsg(player, kInvalidUniqueId, EScriptObjectMessage::InSnakeWeed); mgr.SendScriptMsg(player, kInvalidUniqueId, EScriptObjectMessage::InSnakeWeed);
x140_26_playerTouching = true; x140_26_playerTouching = true;
} }
@ -178,11 +183,11 @@ void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) {
void CSnakeWeedSwarm::HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos) { void CSnakeWeedSwarm::HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos) {
float radiusSquared = radius * radius; float radiusSquared = radius * radius;
for (auto& boid : x134_boids) { for (auto& boid : x134_boids) {
const zeus::CVector3f& boidPosition = boid.GetPosition(); const auto& boidPosition = boid.GetPosition();
if ((boidPosition - pos).magSquared() < radiusSquared && if ((boidPosition - pos).magSquared() < radiusSquared &&
(boid.GetState() == EBoidState::Raised || boid.GetState() == EBoidState::Raising)) { (boid.GetState() == EBoidState::Raised || boid.GetState() == EBoidState::Raising)) {
boid.SetState(EBoidState::x3); boid.SetState(EBoidState::Lowering);
boid.Set_x18(x118_ * mgr.GetActiveRandom()->Float() + x114_); boid.SetSpeed(x118_speedVariation * mgr.GetActiveRandom()->Float() + x114_speed);
CSfxManager::AddEmitter(x1d2_sfx2, boidPosition, zeus::skZero3f, true, false, 0x7f, x4_areaId); CSfxManager::AddEmitter(x1d2_sfx2, boidPosition, zeus::skZero3f, true, false, 0x7f, x4_areaId);
EmitParticles1(boidPosition); EmitParticles1(boidPosition);
} }
@ -232,25 +237,25 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) {
EmitParticles2(pos); EmitParticles2(pos);
} }
} else if (state == EBoidState::Raising) { } else if (state == EBoidState::Raising) {
boid.SetYOffset(boid.GetYOffset() - dt * boid.Get_x18()); boid.SetZOffset(boid.GetZOffset() - dt * boid.GetSpeed());
if (boid.GetYOffset() <= 0.f) { if (boid.GetZOffset() <= 0.f) {
boid.SetYOffset(0.f); boid.SetZOffset(0.f);
boid.SetState(EBoidState::Raised); boid.SetState(EBoidState::Raised);
} }
} else if (state == EBoidState::x2) { } else if (state == EBoidState::Lowered) {
boid.Set_x10(boid.Get_x10() - dt); boid.SetLoweredTimer(boid.GetLoweredTimer() - dt);
if (boid.Get_x10() <= 0.f) { if (boid.GetLoweredTimer() <= 0.f) {
boid.SetState(EBoidState::Raising); boid.SetState(EBoidState::Raising);
CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId);
EmitParticles1(pos); EmitParticles1(pos);
} }
} else if (state == EBoidState::x3) { } else if (state == EBoidState::Lowering) {
boid.SetYOffset(dt * boid.Get_x18() + boid.GetYOffset()); boid.SetZOffset(boid.GetZOffset() + dt * boid.GetSpeed());
const float max = x110_ * boid.Get_x20(); const float max = x110_maxZOffset * boid.GetScale();
if (boid.GetYOffset() >= max) { if (boid.GetZOffset() >= max) {
boid.SetYOffset(max); boid.SetZOffset(max);
boid.Set_x10(x10c_ * mgr.GetActiveRandom()->Float() + x108_); boid.SetLoweredTimer(x10c_loweredTimeVariation * mgr.GetActiveRandom()->Float() + x108_loweredTime);
boid.SetState(EBoidState::x2); boid.SetState(EBoidState::Lowered);
} }
} }
} }
@ -265,21 +270,21 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) {
} }
if (x140_26_playerTouching) { if (x140_26_playerTouching) {
mgr.ApplyDamage(x8_uid, mgr.GetPlayer().GetUniqueId(), x8_uid, CDamageInfo(x15c_damageInfo, dt), matFilter, mgr.ApplyDamage(x8_uid, mgr.GetPlayer().GetUniqueId(), x8_uid, {x15c_damageInfo, dt}, skMaterialFilter,
zeus::skZero3f); zeus::skZero3f);
} }
x140_26_playerTouching = false; x140_26_playerTouching = false;
} }
zeus::CAABox CSnakeWeedSwarm::GetBoidBox() { zeus::CAABox CSnakeWeedSwarm::GetBoidBox() {
const zeus::CVector3f& scale = xe8_scale * 0.75f; const auto& scale = xe8_scale * 0.75f;
return zeus::CAABox(GetTransform().origin - scale, GetTransform().origin + scale); return {GetTransform().origin - scale, GetTransform().origin + scale};
} }
void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) { void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) {
const zeus::CAABox& box = GetBoidBox(); const auto& box = GetBoidBox();
const CRayCastResult& result = const auto& result =
mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), matFilter); mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), skMaterialFilter);
if (result.IsValid()) { if (result.IsValid()) {
int ct = GetNumBoidsX() * GetNumBoidsY(); int ct = GetNumBoidsX() * GetNumBoidsY();
x134_boids.reserve(ct); x134_boids.reserve(ct);
@ -291,29 +296,29 @@ void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) {
} }
int CSnakeWeedSwarm::GetNumBoidsY() { int CSnakeWeedSwarm::GetNumBoidsY() {
const zeus::CAABox& box = GetBoidBox(); const auto& box = GetBoidBox();
return (int)((box.max.y() - box.min.y()) / xf4_boidSpacing) + 1; return static_cast<int>((box.max.y() - box.min.y()) / xf4_boidSpacing) + 1;
} }
int CSnakeWeedSwarm::GetNumBoidsX() { int CSnakeWeedSwarm::GetNumBoidsX() {
const zeus::CAABox& box = GetBoidBox(); const auto& box = GetBoidBox();
return (int)((box.max.x() - box.min.x()) / xf4_boidSpacing) + 1; return static_cast<int>((box.max.x() - box.min.x()) / xf4_boidSpacing) + 1;
} }
void CSnakeWeedSwarm::CreateBoids(CStateManager& mgr, int num) { void CSnakeWeedSwarm::CreateBoids(CStateManager& mgr, int num) {
int width = GetNumBoidsX(); auto width = GetNumBoidsX();
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i) {
if (x1c8_boidPositions->empty()) if (x1c8_boidPositions->empty())
break; break;
const zeus::CVector3f pos = x1c8_boidPositions->back(); const auto pos = x1c8_boidPositions->back();
x1c8_boidPositions->pop_back(); x1c8_boidPositions->pop_back();
const zeus::CVector2i& idx = GetBoidIndex(pos); const auto& idx = GetBoidIndex(pos);
if (CreateBoid(pos, mgr)) { if (CreateBoid(pos, mgr)) {
x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Placed; x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Placed;
AddBoidPosition(zeus::CVector3f(pos.x(), pos.y() - xf4_boidSpacing, pos.z())); AddBoidPosition({pos.x(), pos.y() - xf4_boidSpacing, pos.z()});
AddBoidPosition(zeus::CVector3f(pos.x(), xf4_boidSpacing + pos.y(), pos.z())); AddBoidPosition({pos.x(), xf4_boidSpacing + pos.y(), pos.z()});
AddBoidPosition(zeus::CVector3f(pos.x() - xf4_boidSpacing, pos.y(), pos.z())); AddBoidPosition({pos.x() - xf4_boidSpacing, pos.y(), pos.z()});
AddBoidPosition(zeus::CVector3f(xf4_boidSpacing + pos.x(), pos.y(), pos.z())); AddBoidPosition({xf4_boidSpacing + pos.x(), pos.y(), pos.z()});
} else { } else {
x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Invalid; x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Invalid;
} }
@ -326,19 +331,18 @@ void CSnakeWeedSwarm::CreateBoids(CStateManager& mgr, int num) {
} }
zeus::CVector2i CSnakeWeedSwarm::GetBoidIndex(const zeus::CVector3f& pos) { zeus::CVector2i CSnakeWeedSwarm::GetBoidIndex(const zeus::CVector3f& pos) {
const zeus::CAABox& box = GetBoidBox(); const auto& box = GetBoidBox();
int x = (pos.x() - box.min.x()) / xf4_boidSpacing; return {static_cast<int>((pos.x() - box.min.x()) / xf4_boidSpacing),
int y = (pos.y() - box.min.y()) / xf4_boidSpacing; static_cast<int>((pos.y() - box.min.y()) / xf4_boidSpacing)};
return zeus::CVector2i(x, y);
} }
bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) { bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) {
const zeus::CVector3f& pos = vec + zeus::CVector3f(GetBoidOffsetX(vec), GetBoidOffsetY(vec), xf8_height); const auto& pos = vec + zeus::CVector3f(GetBoidOffsetX(vec), GetBoidOffsetY(vec), xf8_height);
const CRayCastResult& result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, matFilter); const auto& result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, skMaterialFilter);
if (result.IsValid() && result.GetPlane().normal().dot(zeus::skUp) > x11c_) { if (result.IsValid() && result.GetPlane().normal().dot(zeus::skUp) > x11c_) {
const zeus::CVector3f& boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_); const auto& boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_distanceBelowGround);
x134_boids.push_back( x134_boids.push_back({boidPosition, x110_maxZOffset, x114_speed + x118_speedVariation,
{boidPosition, x110_, x114_ + x118_, (x124_ - x120_) * mgr.GetActiveRandom()->Float() + x120_}); (x124_scaleMax - x120_scaleMin) * mgr.GetActiveRandom()->Float() + x120_scaleMin});
return true; return true;
} }
return false; return false;
@ -357,11 +361,12 @@ float CSnakeWeedSwarm::GetBoidOffsetX(const zeus::CVector3f& pos) {
void CSnakeWeedSwarm::AddBoidPosition(const zeus::CVector3f& pos) { void CSnakeWeedSwarm::AddBoidPosition(const zeus::CVector3f& pos) {
int x = GetNumBoidsX(); int x = GetNumBoidsX();
int y = GetNumBoidsY(); int y = GetNumBoidsY();
const zeus::CVector2i& v = GetBoidIndex(pos); const auto& v = GetBoidIndex(pos);
if (-1 < v.x && v.x < x && -1 < v.y && v.y < y) { if (-1 < v.x && v.x < x && -1 < v.y && v.y < y) {
int idx = v.x + x * v.y; int idx = v.x + x * v.y;
if (x1cc_boidPlacement->at(idx) == EBoidPlacement::None) { auto& placement = x1cc_boidPlacement->at(idx);
x1cc_boidPlacement->at(idx) = EBoidPlacement::Ready; if (placement == EBoidPlacement::None) {
placement = EBoidPlacement::Ready;
x1c8_boidPositions->push_back(pos); x1c8_boidPositions->push_back(pos);
} }
} }
@ -369,7 +374,7 @@ void CSnakeWeedSwarm::AddBoidPosition(const zeus::CVector3f& pos) {
void CSnakeWeedSwarm::CalculateTouchBounds() { void CSnakeWeedSwarm::CalculateTouchBounds() {
if (x134_boids.empty()) { if (x134_boids.empty()) {
x144_touchBounds = zeus::CAABox(GetTransform().origin, GetTransform().origin); x144_touchBounds = {x34_transform.origin, x34_transform.origin};
} else { } else {
x144_touchBounds = zeus::skInvertedBox; x144_touchBounds = zeus::skInvertedBox;
for (const auto& boid : x134_boids) { for (const auto& boid : x134_boids) {
@ -384,41 +389,43 @@ void CSnakeWeedSwarm::EmitParticles1(const zeus::CVector3f& pos) {
if (!x1ec_particleGen1) if (!x1ec_particleGen1)
return; return;
x1ec_particleGen1->SetParticleEmission(true); auto& particleGen = *x1ec_particleGen1;
x1ec_particleGen1->SetTranslation(pos); particleGen.SetParticleEmission(true);
x1ec_particleGen1->ForceParticleCreation(x1fc_); particleGen.SetTranslation(pos);
x1ec_particleGen1->SetParticleEmission(false); particleGen.ForceParticleCreation(x1fc_);
particleGen.SetParticleEmission(false);
} }
void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) { void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) {
if (!x1f4_particleGen2) if (!x1f4_particleGen2)
return; return;
x1f4_particleGen2->SetParticleEmission(true); auto& particleGen = *x1f4_particleGen2;
x1f4_particleGen2->SetTranslation(pos); particleGen.SetParticleEmission(true);
x1f4_particleGen2->ForceParticleCreation(1); particleGen.SetTranslation(pos);
x1f4_particleGen2->SetParticleEmission(false); particleGen.ForceParticleCreation(1);
particleGen.SetParticleEmission(false);
} }
void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) const { void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) const {
const u32 modelIdx = idx & 3; const u32 modelIdx = idx & 3;
const auto& modelData = x1b0_modelData[modelIdx]; auto& modelData = *x1b0_modelData[modelIdx];
CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_which); auto& model = modelData.PickAnimatedModel(x1c4_which);
auto& animData = *modelData.GetAnimationData();
const CModelFlags useFlags(0, 0, 3, zeus::skWhite); const CModelFlags useFlags(0, 0, 3, zeus::skWhite);
if (posesToBuild & 1 << modelIdx) { if (posesToBuild & 1 << modelIdx) {
posesToBuild &= ~(1 << modelIdx); posesToBuild &= ~(1 << modelIdx);
modelData->GetAnimationData()->BuildPose(); animData.BuildPose();
model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); model.Calculate(animData.GetPose(), useFlags, std::nullopt, nullptr);
} }
const zeus::CTransform& xf = CGraphics::SetModelMatrix(
zeus::CTransform::Translate(boid.GetPosition() - zeus::CVector3f(0.f, 0.f, boid.GetYOffset())) * zeus::CTransform::Translate(boid.GetPosition() - zeus::CVector3f(0.f, 0.f, boid.GetZOffset())) *
zeus::CTransform::Scale(boid.Get_x20()); zeus::CTransform::Scale(boid.GetScale()));
CGraphics::SetModelMatrix(xf); animData.Render(model, useFlags, std::nullopt, nullptr);
modelData->GetAnimationData()->Render(model, useFlags, {}, nullptr);
} }
void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& mgr) { void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& mgr) {
EWeaponType type = info.GetWeaponMode().GetType(); auto type = info.GetWeaponMode().GetType();
if (type == EWeaponType::Bomb || type == EWeaponType::PowerBomb) if (type == EWeaponType::Bomb || type == EWeaponType::PowerBomb)
HandleRadiusDamage(info.GetRadius(), mgr, pos); HandleRadiusDamage(info.GetRadius(), mgr, pos);
} }

View File

@ -13,8 +13,8 @@ public:
enum class EBoidState : u32 { enum class EBoidState : u32 {
Raised = 0, Raised = 0,
Raising = 1, Raising = 1,
x2 = 2, Lowered = 2,
x3 = 3, Lowering = 3,
}; };
enum class EBoidPlacement : u32 { enum class EBoidPlacement : u32 {
@ -27,26 +27,26 @@ public:
class CBoid { class CBoid {
zeus::CVector3f x0_pos; zeus::CVector3f x0_pos;
EBoidState xc_state; EBoidState xc_state;
float x10_ = 0.f; // some timer float x10_loweredTimer = 0.f;
float x14_yOffset; float x14_zOffset;
float x18_; float x18_speed;
float x1c_ = 0.f; // x1c unused
float x20_; float x20_scale;
public: public:
constexpr CBoid(const zeus::CVector3f& pos, float f1, float f2, float f3) constexpr CBoid(const zeus::CVector3f& pos, float zOffset, float speed, float scale)
: x0_pos(pos), xc_state(EBoidState::Raising), x14_yOffset(f1), x18_(f2), x20_(f3) {} : x0_pos(pos), xc_state(EBoidState::Raising), x14_zOffset(zOffset), x18_speed(speed), x20_scale(scale) {}
constexpr const zeus::CVector3f& GetPosition() const { return x0_pos; } constexpr const zeus::CVector3f& GetPosition() const { return x0_pos; }
constexpr EBoidState GetState() const { return xc_state; } constexpr EBoidState GetState() const { return xc_state; }
constexpr float Get_x10() const { return x10_; } constexpr float GetLoweredTimer() const { return x10_loweredTimer; }
constexpr float GetYOffset() const { return x14_yOffset; } constexpr float GetZOffset() const { return x14_zOffset; }
constexpr float Get_x18() const { return x18_; } constexpr float GetSpeed() const { return x18_speed; }
constexpr float Get_x20() const { return x20_; } constexpr float GetScale() const { return x20_scale; }
constexpr void SetState(EBoidState v) { xc_state = v; } constexpr void SetState(EBoidState v) { xc_state = v; }
constexpr void Set_x10(float v) { x10_ = v; } constexpr void SetLoweredTimer(float v) { x10_loweredTimer = v; }
constexpr void SetYOffset(float v) { x14_yOffset = v; } constexpr void SetZOffset(float v) { x14_zOffset = v; }
constexpr void Set_x18(float v) { x18_ = v; } constexpr void SetSpeed(float v) { x18_speed = v; }
}; };
private: private:
@ -55,16 +55,16 @@ private:
float xf8_height; float xf8_height;
float xfc_; float xfc_;
float x100_weaponDamageRadius; float x100_weaponDamageRadius;
float x104_; float x104_maxPlayerDistance;
float x108_; float x108_loweredTime;
float x10c_; float x10c_loweredTimeVariation;
float x110_; float x110_maxZOffset;
float x114_; float x114_speed;
float x118_; float x118_speedVariation;
float x11c_; float x11c_;
float x120_; float x120_scaleMin;
float x124_; float x124_scaleMax;
float x128_; float x128_distanceBelowGround;
// u32 x12c_ = 0; // u32 x12c_ = 0;
std::vector<CBoid> x134_boids; std::vector<CBoid> x134_boids;
bool x140_24_hasGround : 1; bool x140_24_hasGround : 1;
@ -73,7 +73,7 @@ private:
zeus::CAABox x144_touchBounds = zeus::skInvertedBox; zeus::CAABox x144_touchBounds = zeus::skInvertedBox;
CDamageInfo x15c_damageInfo; CDamageInfo x15c_damageInfo;
// x178_ / x19c_: vectors of CSkinnedModel*, not needed // x178_ / x19c_: vectors of CSkinnedModel*, not needed
rstl::reserved_vector<std::shared_ptr<CModelData>, 4> x1b0_modelData; rstl::reserved_vector<std::unique_ptr<CModelData>, 4> x1b0_modelData;
CModelData::EWhichModel x1c4_which; CModelData::EWhichModel x1c4_which;
std::unique_ptr<std::vector<zeus::CVector3f>> x1c8_boidPositions; std::unique_ptr<std::vector<zeus::CVector3f>> x1c8_boidPositions;
std::unique_ptr<std::vector<EBoidPlacement>> x1cc_boidPlacement; std::unique_ptr<std::vector<EBoidPlacement>> x1cc_boidPlacement;
@ -86,14 +86,17 @@ private:
std::unique_ptr<CElementGen> x1ec_particleGen1; std::unique_ptr<CElementGen> x1ec_particleGen1;
std::unique_ptr<CElementGen> x1f4_particleGen2; std::unique_ptr<CElementGen> x1f4_particleGen2;
u32 x1fc_; u32 x1fc_;
float x200_; float x200_; // unused?
float x204_particleTimer = 0.f; float x204_particleTimer = 0.f;
public: public:
CSnakeWeedSwarm(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CVector3f&, const zeus::CVector3f&, CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info,
const CAnimRes&, const CActorParameters&, float, float, float, float, float, float, float, float, const zeus::CVector3f& pos, const zeus::CVector3f& scale, const CAnimRes& animRes,
float, float, float, float, float, float, const CDamageInfo&, float, u32, u32, u32, CAssetId, u32, const CActorParameters& actParms, float spacing, float height, float f3, float weaponDamageRadius,
CAssetId, float); float maxPlayerDistance, float loweredTime, float loweredTimeVariation, float maxZOffset, float speed,
float speedVariation, float f11, float scaleMin, float scaleMax, float distanceBelowGround,
const CDamageInfo& dInfo, float /*f15*/, u32 sfxId1, u32 sfxId2, u32 sfxId3, CAssetId particleGenDesc1, u32 w5,
CAssetId particleGenDesc2, float f16);
void Accept(IVisitor&) override; void Accept(IVisitor&) override;
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr); void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr);

View File

@ -3033,34 +3033,36 @@ CEntity* ScriptLoader::LoadSnakeWeedSwarm(CStateManager& mgr, CInputStream& in,
bool active = in.readBool(); bool active = in.readBool();
CAnimationParameters animParms = LoadAnimationParameters(in); CAnimationParameters animParms = LoadAnimationParameters(in);
CActorParameters actParms = LoadActorParameters(in); CActorParameters actParms = LoadActorParameters(in);
float f1 = in.readFloatBig(); float spacing = in.readFloatBig();
float f2 = in.readFloatBig(); float height = in.readFloatBig();
float f3 = in.readFloatBig(); float f3 = in.readFloatBig();
float f4 = in.readFloatBig(); float weaponDamageRadius = in.readFloatBig();
float f5 = in.readFloatBig(); float maxPlayerDistance = in.readFloatBig();
float f6 = in.readFloatBig(); float loweredTime = in.readFloatBig();
float f7 = in.readFloatBig(); float loweredTimeVariation = in.readFloatBig();
float f8 = in.readFloatBig(); float maxZOffset = in.readFloatBig();
float f9 = in.readFloatBig(); float speed = in.readFloatBig();
float f10 = in.readFloatBig(); float speedVariation = in.readFloatBig();
float f11 = in.readFloatBig(); float f11 = in.readFloatBig();
float f12 = in.readFloatBig(); float scaleMin = in.readFloatBig();
float f13 = in.readFloatBig(); float scaleMax = in.readFloatBig();
float f14 = in.readFloatBig(); float distanceBelowGround = in.readFloatBig();
CDamageInfo dInfo(in); CDamageInfo dInfo(in);
float f15 = in.readFloatBig(); float unused = in.readFloatBig();
u32 w1 = in.readUint32Big(); u32 sfxId1 = in.readUint32Big();
u32 w2 = in.readUint32Big(); u32 sfxId2 = in.readUint32Big();
u32 w3 = in.readUint32Big(); u32 sfxId3 = in.readUint32Big();
CAssetId w4 = (propCount < 29 ? CAssetId() : in.readUint32Big()); CAssetId particleGenDesc1 = (propCount < 29 ? CAssetId() : CAssetId(in));
u32 w5 = (propCount < 29 ? 0 : in.readUint32Big()); u32 w5 = (propCount < 29 ? 0 : in.readUint32Big());
CAssetId w6 = (propCount < 29 ? CAssetId() : in.readUint32Big()); CAssetId particleGenDesc2 = (propCount < 29 ? CAssetId() : CAssetId(in));
float f16 = (propCount < 29 ? 0.f : in.readFloatBig()); float f16 = (propCount < 29 ? 0.f : in.readFloatBig());
CAnimRes animRes(animParms.GetACSFile(), animParms.GetCharacter(), zeus::skOne3f, animParms.GetInitialAnimation(), CAnimRes animRes(animParms.GetACSFile(), animParms.GetCharacter(), zeus::skOne3f, animParms.GetInitialAnimation(),
true); true);
return new CSnakeWeedSwarm(mgr.AllocateUniqueId(), active, name, info, pos, scale, animRes, actParms, f1, f2, f3, f4, return new CSnakeWeedSwarm(mgr.AllocateUniqueId(), active, name, info, pos, scale, animRes, actParms, spacing, height,
f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, dInfo, f15, w1, w2, w3, w4, w5, w6, f16); f3, weaponDamageRadius, maxPlayerDistance, loweredTime, loweredTimeVariation, maxZOffset,
speed, speedVariation, f11, scaleMin, scaleMax, distanceBelowGround, dInfo, unused, sfxId1,
sfxId2, sfxId3, particleGenDesc1, w5, particleGenDesc2, f16);
} }
CEntity* ScriptLoader::LoadActorContraption(CStateManager& mgr, CInputStream& in, int propCount, CEntity* ScriptLoader::LoadActorContraption(CStateManager& mgr, CInputStream& in, int propCount,