From f50f5cedef299ae0bf8981df18ce278717d22a52 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 23 Feb 2020 18:30:46 -0500 Subject: [PATCH 1/6] CSnakeWeedSwarm: Implement remaining methods --- Runtime/World/CSnakeWeedSwarm.cpp | 400 +++++++++++++++++++++++++++++- Runtime/World/CSnakeWeedSwarm.hpp | 89 ++++++- 2 files changed, 466 insertions(+), 23 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index b79327cbb..24f882ba5 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -1,9 +1,16 @@ #include "Runtime/World/CSnakeWeedSwarm.hpp" #include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CSkinnedModel.hpp" +#include "Runtime/Graphics/CVertexMorphEffect.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" #include "Runtime/World/CActorParameters.hpp" #include "Runtime/World/CAnimationParameters.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CWorld.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde { @@ -32,36 +39,409 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na , x124_(f13) , x128_(f14) , x15c_dInfo(dInfo) +, x1c8_(std::make_unique>()) +, x1cc_(std::make_unique>()) , x1d0_sfx1(CSfxManager::TranslateSFXID(sfxId1)) , x1d2_sfx2(CSfxManager::TranslateSFXID(sfxId2)) , x1d4_sfx3(CSfxManager::TranslateSFXID(sfxId3)) , x1fc_(w5) , x200_(f16) { SetActorLights(actParms.GetLightParameters().MakeActorLights()); - x1b4_modelData.emplace_back(std::make_unique(animRes)); - x1b4_modelData.emplace_back(std::make_unique(animRes)); - x1b4_modelData.emplace_back(std::make_unique(animRes)); - x1b4_modelData.emplace_back(std::make_unique(animRes)); + x1b0_modelData.emplace_back(std::make_unique(animRes)); + x1b0_modelData.emplace_back(std::make_unique(animRes)); + x1b0_modelData.emplace_back(std::make_unique(animRes)); + x1b0_modelData.emplace_back(std::make_unique(animRes)); if (actParms.GetXRayAssets().first.IsValid()) { for (int i = 0; i < 4; ++i) - x1b4_modelData[i]->SetXRayModel(actParms.GetXRayAssets()); - x13c_xbf_modelAssetDirty = true; + x1b0_modelData[i]->SetXRayModel(actParms.GetXRayAssets()); + x140_25_modelAssetDirty = true; } if (actParms.GetThermalAssets().first.IsValid()) { for (int i = 0; i < 4; ++i) - x1b4_modelData[i]->SetInfraModel(actParms.GetThermalAssets()); - x13c_xbf_modelAssetDirty = true; + x1b0_modelData[i]->SetInfraModel(actParms.GetThermalAssets()); + x140_25_modelAssetDirty = true; } if (w4.IsValid()) { x1dc_ = g_SimplePool->GetObj({FOURCC('PART'), w4}); - x1ec_ = std::make_unique(x1dc_); + x1ec_particleGen1 = std::make_unique(x1dc_); } if (w6.IsValid()) { x1dc_ = g_SimplePool->GetObj({FOURCC('PART'), w6}); - x1f4_ = std::make_unique(x1dc_); + x1f4_particleGen2 = std::make_unique(x1dc_); } } void CSnakeWeedSwarm::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } +void CSnakeWeedSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) { + // x178_.clear(); + // x19c_.clear(); + for (int i = 0; i < 4; ++i) { + // CSkinnedModel& skinnedModel = x1b0_modelData[i]->PickAnimatedModel(which); + // x178_.push_back(skinnedModel.Clone()); + // x19c_.push_back(ptr); + x1b0_modelData[i]->EnableLooping(true); + x1b0_modelData[i]->AdvanceAnimation( + // TODO calculation may be wrong + x1b0_modelData[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.25f), mgr, x4_areaId, + true); + } + x1c4_ = which; +} + +void CSnakeWeedSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId id, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, id, mgr); + if (msg == EScriptObjectMessage::Deleted) { + if (x1d8_) { + CSfxManager::RemoveEmitter(x1d8_); + x1d8_.reset(); + } + } else if (msg == EScriptObjectMessage::InitializedInArea) { + AllocateSkinnedModels(mgr, CModelData::EWhichModel::Normal); + SetCalculateLighting(true); + x90_actorLights->SetCastShadows(true); + } +} +void CSnakeWeedSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + if (frustum.aabbFrustumTest(x144_)) { + SetCalculateLighting(false); + for (int i = 0; i < 4; ++i) { + x1b0_modelData[i]->GetAnimationData()->PreRender(); + } + bool bVar2 = false; + if (x90_actorLights) { + if (x140_24_) { + if (!xe4_29_actorLightsDirty) { + if (x90_actorLights->GetIsDirty()) { + bVar2 = true; + } + } else { + bVar2 = true; + xe4_29_actorLightsDirty = false; + } + if (xe4_31_calculateLighting && x90_actorLights) { + auto visor = mgr.GetPlayerState()->GetActiveVisor(mgr); + if (visor == CPlayerState::EPlayerVisor::Thermal) { + x90_actorLights->BuildConstantAmbientLighting(zeus::skWhite); + } else { + if (bVar2) { + if (x4_areaId != kInvalidAreaId) { + CGameArea* area = mgr.GetWorld()->GetArea(x4_areaId); + if (area != nullptr) { + x90_actorLights->BuildAreaLightList(mgr, *area, x144_); + } + } + } + x90_actorLights->BuildDynamicLightList(mgr, x144_); + } + } + } + } + } else { + SetCalculateLighting(true); + } +} + +void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + if (!xe4_30_outOfFrustum) { + if (x1ec_particleGen1) { + g_Renderer->AddParticleGen(*x1ec_particleGen1); + } + if (x1f4_particleGen2) { + g_Renderer->AddParticleGen(*x1f4_particleGen2); + } + if (x90_actorLights) { + // x90_actorLights->ActivateLights(); FIXME pass what here? + } else { + CGraphics::DisableAllLights(); + g_Renderer->SetAmbientColor(zeus::skWhite); + } + u32 l18 = -1; + for (u32 i = 0; i < x134_boids.size(); ++i) { + RenderBoid(i, &x134_boids[i], &l18); + } + CGraphics::DisableAllLights(); + } +} + +void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { + if (TCastToPtr proj = actor) { + if (proj->GetDamageInfo().GetWeaponMode().GetType() != EWeaponType::AI) { + sub_8023ca48(x100_, mgr, proj->GetTransform().origin); + } + } + if (TCastToPtr player = actor) { + for (auto boid : x134_boids) { + float m = (boid.GetPosition() - player->GetTransform().origin).magnitude(); + if (m < x104_ && boid.GetState() == EBoidState::x0) { + mgr.SendScriptMsg(player, kInvalidUniqueId, EScriptObjectMessage::InSnakeWeed); + x140_26_ = true; + } + } + } +} + +void CSnakeWeedSwarm::sub_8023ca48(float param_1, CStateManager& mgr, const zeus::CVector3f& pos) { + float dVar8 = param_1 * param_1; + for (auto boid : x134_boids) { + const zeus::CVector3f& boidPosition = boid.GetPosition(); + if ((boidPosition - pos).magSquared() < dVar8 && + (boid.GetState() == EBoidState::x0 || boid.GetState() == EBoidState::x1)) { + boid.SetState(EBoidState::x3); + float random = mgr.GetActiveRandom()->Float(); + boid.Set_x18(x118_ * random + x114_); + CSfxManager::AddEmitter(x1d2_sfx2, boidPosition, zeus::skZero3f, true, false, 0x7f, x4_areaId); + EmitParticles1(boidPosition); + } + } +} + +void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { + CEntity::Think(dt, mgr); + if (x30_24_active) { + if (x1ec_particleGen1) { + x1ec_particleGen1->Update(dt); + } + if (x1f4_particleGen2) { + x1f4_particleGen2->Update(dt); + } + x204_ -= dt; + bool bVar5 = x204_ < 0.f; + if (bVar5) { + x204_ = 0.f; + } + x204_ = std::max(x204_ - dt, 0.f); + if (!x140_24_) { + sub_8023c238(mgr); + } + if (x140_24_ && x1c8_ && !x1c8_->empty()) { + int v = (u64)(dt * x1cc_->size()) >> 0x20; // TODO ? + sub_8023bca8(mgr, v + 1); + } + CModelData::EWhichModel model = CModelData::GetRenderingModel(mgr); + if (x140_26_ && x1c4_ != model) { + AllocateSkinnedModels(mgr, model); + } + for (int i = 0; i < 4; ++i) { + x1b0_modelData[i]->GetAnimationData()->SetPlaybackRate(1.f); + x1b0_modelData[i]->AdvanceAnimation(dt, mgr, x4_areaId, true); + } + int numBoidsInx0 = 0; + for (auto boid : x134_boids) { + const zeus::CVector3f& pos = boid.GetPosition(); + EBoidState state = boid.GetState(); + if (state == EBoidState::x0) { + numBoidsInx0++; + if (x1f4_particleGen2 && bVar5) { + EmitParticles2(pos); + } + } else if (state == EBoidState::x1) { + float x14 = boid.Get_x14() - dt * boid.Get_x18(); + boid.Set_x14(x14); + // printf("setting x14 to %f (dt %f)\n", x14, dt * boid.Get_x18()); + if (x14 <= 0.f) { + boid.Set_x14(0.f); + boid.SetState(EBoidState::x0); + } + } else if (state == EBoidState::x2) { + float x10 = boid.Get_x10() - dt; + boid.Set_x10(x10); + if (x10 <= 0.f) { + boid.SetState(EBoidState::x1); + CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); + EmitParticles1(pos); + } + } else if (state == EBoidState::x3) { + float x14 = dt * boid.Get_x18() + boid.Get_x14(); + boid.Set_x14(x14); + float dVar8 = x110_ * boid.Get_x20(); + if (dVar8 < x14) { + boid.Set_x14(dVar8); + float random = mgr.GetActiveRandom()->Float(); + boid.Set_x10(x10c_ * random + x108_); + boid.SetState(EBoidState::x2); + } + } + } + if (numBoidsInx0 == 0) { + if (x1d8_) { + CSfxManager::RemoveEmitter(x1d8_); + x1d8_.reset(); + } + } else { + if (!x1d8_) { + x1d8_ = CSfxManager::AddEmitter(x1d0_sfx1, GetTransform().origin, zeus::skZero3f, true, true, 0x7f, x4_areaId); + } + } + if (x140_26_) { + mgr.ApplyDamage(x8_uid, mgr.GetPlayer().GetUniqueId(), x8_uid, CDamageInfo(x15c_dInfo, dt), + CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Player, EMaterialTypes::Stone)), + zeus::skZero3f); + } + x140_26_ = false; + } +} + +zeus::CAABox CSnakeWeedSwarm::sub_8023d3f4() { + const zeus::CVector3f& scale = xe8_scale * 0.75f; + const zeus::CVector3f& min = GetTransform().origin - scale; + const zeus::CVector3f& max = GetTransform().origin + scale; + return zeus::CAABox(min, max); +} + +static CMaterialList matList1 = CMaterialList(EMaterialTypes::RadarObject, EMaterialTypes::Stone); +static CMaterialFilter matFilter1 = CMaterialFilter::MakeInclude(matList1); + +void CSnakeWeedSwarm::sub_8023c238(const CStateManager& mgr) { + const zeus::CAABox& box = sub_8023d3f4(); + const CRayCastResult& result = + mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), matFilter1); + if (result.IsValid()) { + int ct = sub_8023c154() * sub_8023c0fc(); + x134_boids.reserve(ct); + x1c8_->reserve(ct); + x1cc_->resize(ct, 0); + x1c8_->push_back(result.GetPoint()); + x140_24_ = true; + } + + // matFilter.IncludeList().Add(CMaterialList(matFilter.IncludeList().GetValue() >> 0x20)); +} + +int CSnakeWeedSwarm::sub_8023c0fc() { + const zeus::CAABox& box = sub_8023d3f4(); + return (int)((box.max.y() - box.min.y()) / xf4_) + 1; +} + +int CSnakeWeedSwarm::sub_8023c154() { + const zeus::CAABox& box = sub_8023d3f4(); + return (int)((box.max.x() - box.min.x()) / xf4_) + 1; +} + +void CSnakeWeedSwarm::sub_8023bca8(CStateManager& mgr, int v) { + int n = sub_8023c154(); + for (int i = 0; i < v; ++i) { + if (x1c8_->empty()) + break; + zeus::CVector3f vec = x1c8_->back(); + x1c8_->pop_back(); + const zeus::CVector2i& v2i = sub_8023c1ac(vec); + if (CreateBoid(vec, mgr)) { + x1cc_->at(v2i.x + n * v2i.y) = 3; + sub_8023bfb8(zeus::CVector3f(vec.x(), vec.y() - xf4_, vec.z())); + sub_8023bfb8(zeus::CVector3f(vec.x(), xf4_ + vec.y(), vec.z())); + sub_8023bfb8(zeus::CVector3f(vec.x() - xf4_, vec.y(), vec.z())); + sub_8023bfb8(zeus::CVector3f(xf4_ + vec.x(), vec.y(), vec.z())); + } else { + x1cc_->at(v2i.x + n * v2i.y) = 2; + } + } + sub_8023d204(); + if (x1c8_->empty()) { + x1c8_ = nullptr; + x1cc_ = nullptr; + } +} + +zeus::CVector2i CSnakeWeedSwarm::sub_8023c1ac(const zeus::CVector3f& vec) { + const zeus::CAABox& box = sub_8023d3f4(); + int x = (vec.x() - box.min.x()) / xf4_; + int y = (vec.y() - box.min.y()) / xf4_; + return zeus::CVector2i(x, y); +} + +// TODO double check these params +static CMaterialList matList2 = CMaterialList(EMaterialTypes::RadarObject, EMaterialTypes::Stone); +static CMaterialFilter matFilter2 = CMaterialFilter::MakeInclude(matList2); + +bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) { + const zeus::CVector3f pos = vec + zeus::CVector3f(sub_8023bc38(vec), sub_8023bbc8(vec), xf8_); + const CRayCastResult result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_, matFilter2); + if (result.IsInvalid() || result.GetPlane().normal().dot(zeus::skUp) <= x11c_) { + return false; + } else { + const zeus::CVector3f boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_); + float random = mgr.GetActiveRandom()->Float(); + const CBoid boid(boidPosition, x110_, x114_ + x118_, (x124_ - x120_) * random + x120_); + x134_boids.push_back(boid); +// printf("created boid @ %f|%f|%f, new size %zu\n", boidPosition.x(), boidPosition.y(), boidPosition.z(), +// x134_boids.size()); + return true; + } +} + +float CSnakeWeedSwarm::sub_8023bbc8(const zeus::CVector3f& vec) { + float f = 2.4729404f * vec.y() + 0.3478602f * vec.x() * vec.x(); + return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); +} + +float CSnakeWeedSwarm::sub_8023bc38(const zeus::CVector3f& vec) { + float f = 8.21395f * vec.x() + 0.112869f * vec.y() * vec.y(); + return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); +} + +void CSnakeWeedSwarm::sub_8023bfb8(const zeus::CVector3f& vec) { + int x = sub_8023c154(); + int y = sub_8023c0fc(); + zeus::CVector2i v = sub_8023c1ac(vec); + if (-1 < v.x && v.x < x && -1 < v.y && v.y < y) { + v.x += x * v.y; + if (x1cc_->at(v.x) == 0) { + x1cc_->at(v.x) = 1; + x1c8_->push_back(vec); + } + } +} + +void CSnakeWeedSwarm::sub_8023d204() { + if (x134_boids.empty()) { + x144_ = zeus::CAABox(GetTransform().origin, GetTransform().origin); + } else { + x144_ = zeus::skInvertedBox; + for (auto boid : x134_boids) { + x144_.accumulateBounds(boid.GetPosition() - x100_); + x144_.accumulateBounds(boid.GetPosition() + x100_); + } + } + xe4_27_notInSortedLists = true; +} + +void CSnakeWeedSwarm::EmitParticles1(const zeus::CVector3f& pos) { + if (x1ec_particleGen1) { + x1ec_particleGen1->SetParticleEmission(true); + x1ec_particleGen1->SetTranslation(pos); + x1ec_particleGen1->ForceParticleCreation(x1fc_); + x1ec_particleGen1->SetParticleEmission(false); + } +} + +void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) { + if (x1f4_particleGen2) { + x1f4_particleGen2->SetParticleEmission(true); + x1f4_particleGen2->SetTranslation(pos); + x1f4_particleGen2->ForceParticleCreation(1); + x1f4_particleGen2->SetParticleEmission(false); + } +} + +void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32* p3) const { + u32 idx = p1 & 3; + u32 var3 = *p3; + auto modelData = x1b0_modelData[idx]; + CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_); + CModelFlags useFlags(0, 0, 3, zeus::skWhite); + if ((var3 & 1 << idx) != 0) { + var3 &= ~(1 << idx); + modelData->GetAnimationData()->BuildPose(); + model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); + } + // printf("rendering boid with x14 %f\n", boid->Get_x14()); + const zeus::CTransform& xf = + zeus::CTransform::Translate(boid->GetPosition() /*- zeus::CVector3f(0.f, 0.f, boid->Get_x14())*/) * + zeus::CTransform::Scale(boid->Get_x20()); + g_Renderer->SetModelMatrix(xf); + model.Draw(useFlags); + *p3 = var3; +} + } // namespace urde diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index c05bc1ac2..484b18ffe 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -9,6 +9,40 @@ namespace urde { class CAnimationParameters; class CSnakeWeedSwarm : public CActor { +public: + enum class EBoidState : u32 { + x0 = 0, + x1 = 1, + x2 = 2, + x3 = 3, + }; + + class CBoid { + zeus::CVector3f x0_pos; + EBoidState xc_state; + float x10_ = 0.f; // some timer + float x14_; // height? + float x18_; + float x1c_ = 0.f; + float x20_; + + public: + constexpr CBoid(const zeus::CVector3f& pos, float f1, float f2, float f3) + : x0_pos(pos), xc_state(EBoidState::x1), x14_(f1), x18_(f2), x20_(f3) {} + + constexpr const zeus::CVector3f& GetPosition() const { return x0_pos; } + constexpr EBoidState GetState() const { return xc_state; } + constexpr float Get_x10() const { return x10_; } + constexpr float Get_x14() const { return x14_; } + constexpr float Get_x18() const { return x18_; } + constexpr float Get_x20() const { return x20_; } + constexpr void SetState(EBoidState v) { xc_state = v; } + constexpr void Set_x10(float v) { x10_ = v; } + constexpr void Set_x14(float v) { x14_ = v; } + constexpr void Set_x18(float v) { x18_ = v; } + }; + +private: zeus::CVector3f xe8_scale; float xf4_; float xf8_; @@ -26,25 +60,26 @@ class CSnakeWeedSwarm : public CActor { float x128_; u32 x12c_ = 0; // x130_ - u32 x134_ = 0; - u32 x138_ = 0; - u32 x13c_ = 0; - bool x13c_xbf_modelAssetDirty : 1; + std::vector x134_boids; + bool x140_24_ : 1; + bool x140_25_modelAssetDirty : 1; + bool x140_26_ : 1; zeus::CAABox x144_ = zeus::skInvertedBox; CDamageInfo x15c_dInfo; - // x178_ = 0 - // x19c_ = 0 - rstl::reserved_vector, 4> x1b4_modelData; - // x1c8_ = ptr to 0x10 sz? - // x1cc_ = ptr to 0x10 sz? +// std::vector> x178_; +// std::vector> x19c_; + rstl::reserved_vector, 4> x1b0_modelData; + CModelData::EWhichModel x1c4_; + std::unique_ptr> x1c8_; + std::unique_ptr> x1cc_; u16 x1d0_sfx1; u16 x1d2_sfx2; u16 x1d4_sfx3; - u32 x1d8_ = 0; + CSfxHandle x1d8_ = 0; TLockedToken x1dc_; // TLockedToken x1e4_; both assign to x1dc_? - std::unique_ptr x1ec_; - std::unique_ptr x1f4_; + std::unique_ptr x1ec_particleGen1; + std::unique_ptr x1f4_particleGen2; u32 x1fc_; float x200_; float x204_ = 0.f; @@ -57,6 +92,34 @@ public: void Accept(IVisitor&) override; void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr) {} - std::optional GetTouchBounds() const override { /* FIXME check flags */ return x144_; } + std::optional GetTouchBounds() const override { + if (x140_24_) { + return {}; + } + return x144_; + } + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; + void PreRender(CStateManager&, const zeus::CFrustum&) override; + void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; + void Touch(CActor&, CStateManager&) override; + void Think(float, CStateManager&) override; + +private: + void AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which); + void sub_8023ca48(float param_1, CStateManager& mgr, const zeus::CVector3f& pos); + void sub_8023c238(const CStateManager& mgr); + zeus::CAABox sub_8023d3f4(); + int sub_8023c0fc(); + int sub_8023c154(); + void sub_8023bca8(CStateManager& mgr, int v); + zeus::CVector2i sub_8023c1ac(const zeus::CVector3f& vec); + bool CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr); + float sub_8023bbc8(const zeus::CVector3f& vec); + float sub_8023bc38(const zeus::CVector3f& vec); + void sub_8023bfb8(const zeus::CVector3f& vec); + void sub_8023d204(); + void EmitParticles1(const zeus::CVector3f& pos); + void EmitParticles2(const zeus::CVector3f& pos); + void RenderBoid(u32 p1, const CBoid* boid, u32 *p3) const; }; } // namespace urde From 34a80aab81119169090b282f6da98d26419a2d0e Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 24 Feb 2020 00:43:20 -0500 Subject: [PATCH 2/6] CSnakeWeedSwarm: Implement ApplyRadiusDamage --- Runtime/World/CSnakeWeedSwarm.cpp | 15 ++++++++++++--- Runtime/World/CSnakeWeedSwarm.hpp | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index 24f882ba5..e9d0e0e6e 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -151,7 +151,9 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM g_Renderer->AddParticleGen(*x1f4_particleGen2); } if (x90_actorLights) { - // x90_actorLights->ActivateLights(); FIXME pass what here? + for (auto modelData : x1b0_modelData) { + x90_actorLights->ActivateLights(*modelData->PickAnimatedModel(x1c4_).GetModelInst()); + } } else { CGraphics::DisableAllLights(); g_Renderer->SetAmbientColor(zeus::skWhite); @@ -181,8 +183,8 @@ void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { } } -void CSnakeWeedSwarm::sub_8023ca48(float param_1, CStateManager& mgr, const zeus::CVector3f& pos) { - float dVar8 = param_1 * param_1; +void CSnakeWeedSwarm::sub_8023ca48(float radius, CStateManager& mgr, const zeus::CVector3f& pos) { + float dVar8 = radius * radius; for (auto boid : x134_boids) { const zeus::CVector3f& boidPosition = boid.GetPosition(); if ((boidPosition - pos).magSquared() < dVar8 && @@ -444,4 +446,11 @@ void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32* p3) const { *p3 = var3; } +void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& mgr) { + EWeaponType type = info.GetWeaponMode().GetType(); + if (type == EWeaponType::Bomb || type == EWeaponType::PowerBomb) { + sub_8023ca48(info.GetRadius(), mgr, pos); + } +} + } // namespace urde diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index 484b18ffe..15019fb3a 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -91,7 +91,7 @@ public: CAssetId, float); 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); std::optional GetTouchBounds() const override { if (x140_24_) { return {}; @@ -106,7 +106,7 @@ public: private: void AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which); - void sub_8023ca48(float param_1, CStateManager& mgr, const zeus::CVector3f& pos); + void sub_8023ca48(float radius, CStateManager& mgr, const zeus::CVector3f& pos); void sub_8023c238(const CStateManager& mgr); zeus::CAABox sub_8023d3f4(); int sub_8023c0fc(); From 046fbe77606a1317f965c082804db4992456269c Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 24 Feb 2020 02:55:19 -0500 Subject: [PATCH 3/6] CSnakeWeedSwarm: Cleanup, renaming & fixes --- Runtime/World/CSnakeWeedSwarm.cpp | 503 +++++++++++++++--------------- Runtime/World/CSnakeWeedSwarm.hpp | 74 ++--- 2 files changed, 280 insertions(+), 297 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index e9d0e0e6e..e65a8902f 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -15,6 +15,9 @@ namespace urde { +static CMaterialFilter matFilter = + CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Character)); + 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 CActorParameters& actParms, float f1, float f2, float f3, float f4, float f5, @@ -24,10 +27,10 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na : CActor(uid, active, name, info, zeus::CTransform::Translate(pos), CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Trigger, EMaterialTypes::NonSolidDamageable), actParms, kInvalidUniqueId) , xe8_scale(scale) -, xf4_(f1) -, xf8_(f2) +, xf4_boidSpacing(f1) +, xf8_height(f2) , xfc_(f3) -, x100_(f4) +, x100_weaponDamageRadius(f4) , x104_(f5) , x108_(f6) , x10c_(f7) @@ -38,9 +41,9 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na , x120_(f12) , x124_(f13) , x128_(f14) -, x15c_dInfo(dInfo) -, x1c8_(std::make_unique>()) -, x1cc_(std::make_unique>()) +, x15c_damageInfo(dInfo) +, x1c8_boidPositions(std::make_unique>()) +, x1cc_boidPlacement(std::make_unique>()) , x1d0_sfx1(CSfxManager::TranslateSFXID(sfxId1)) , x1d2_sfx2(CSfxManager::TranslateSFXID(sfxId2)) , x1d4_sfx3(CSfxManager::TranslateSFXID(sfxId3)) @@ -62,39 +65,33 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na x140_25_modelAssetDirty = true; } if (w4.IsValid()) { - x1dc_ = g_SimplePool->GetObj({FOURCC('PART'), w4}); - x1ec_particleGen1 = std::make_unique(x1dc_); + x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), w4}); + x1ec_particleGen1 = std::make_unique(x1dc_particleGenDesc); } if (w6.IsValid()) { - x1dc_ = g_SimplePool->GetObj({FOURCC('PART'), w6}); - x1f4_particleGen2 = std::make_unique(x1dc_); + x1dc_particleGenDesc = g_SimplePool->GetObj({FOURCC('PART'), w6}); + x1f4_particleGen2 = std::make_unique(x1dc_particleGenDesc); } } void CSnakeWeedSwarm::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } void CSnakeWeedSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) { - // x178_.clear(); - // x19c_.clear(); for (int i = 0; i < 4; ++i) { - // CSkinnedModel& skinnedModel = x1b0_modelData[i]->PickAnimatedModel(which); - // x178_.push_back(skinnedModel.Clone()); - // x19c_.push_back(ptr); x1b0_modelData[i]->EnableLooping(true); - x1b0_modelData[i]->AdvanceAnimation( - // TODO calculation may be wrong - x1b0_modelData[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.25f), mgr, x4_areaId, - true); + x1b0_modelData[i]->AdvanceAnimation(x1b0_modelData[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * + (i * 0.25f), + mgr, x4_areaId, true); } - x1c4_ = which; + x1c4_which = which; } void CSnakeWeedSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId id, CStateManager& mgr) { CActor::AcceptScriptMsg(msg, id, mgr); if (msg == EScriptObjectMessage::Deleted) { - if (x1d8_) { - CSfxManager::RemoveEmitter(x1d8_); - x1d8_.reset(); + if (x1d8_sfxHandle) { + CSfxManager::RemoveEmitter(x1d8_sfxHandle); + x1d8_sfxHandle.reset(); } } else if (msg == EScriptObjectMessage::InitializedInArea) { AllocateSkinnedModels(mgr, CModelData::EWhichModel::Normal); @@ -102,93 +99,86 @@ void CSnakeWeedSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId id, CS x90_actorLights->SetCastShadows(true); } } + void CSnakeWeedSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { - if (frustum.aabbFrustumTest(x144_)) { - SetCalculateLighting(false); - for (int i = 0; i < 4; ++i) { - x1b0_modelData[i]->GetAnimationData()->PreRender(); + if (!frustum.aabbFrustumTest(x144_touchBounds)) { + SetCalculateLighting(true); + return; + } + + SetCalculateLighting(false); + for (int i = 0; i < 4; ++i) { + x1b0_modelData[i]->GetAnimationData()->PreRender(); + } + if (x90_actorLights && x140_24_hasGround) { + bool buildLights = false; + if (xe4_29_actorLightsDirty) { + buildLights = true; + xe4_29_actorLightsDirty = false; + } else if (x90_actorLights->GetIsDirty()) { + buildLights = true; } - bool bVar2 = false; - if (x90_actorLights) { - if (x140_24_) { - if (!xe4_29_actorLightsDirty) { - if (x90_actorLights->GetIsDirty()) { - bVar2 = true; - } - } else { - bVar2 = true; - xe4_29_actorLightsDirty = false; - } - if (xe4_31_calculateLighting && x90_actorLights) { - auto visor = mgr.GetPlayerState()->GetActiveVisor(mgr); - if (visor == CPlayerState::EPlayerVisor::Thermal) { - x90_actorLights->BuildConstantAmbientLighting(zeus::skWhite); - } else { - if (bVar2) { - if (x4_areaId != kInvalidAreaId) { - CGameArea* area = mgr.GetWorld()->GetArea(x4_areaId); - if (area != nullptr) { - x90_actorLights->BuildAreaLightList(mgr, *area, x144_); - } - } - } - x90_actorLights->BuildDynamicLightList(mgr, x144_); - } + if (xe4_31_calculateLighting && x90_actorLights) { + auto visor = mgr.GetPlayerState()->GetActiveVisor(mgr); + if (visor == CPlayerState::EPlayerVisor::Thermal) { + x90_actorLights->BuildConstantAmbientLighting(zeus::skWhite); + } else if (buildLights && x4_areaId != kInvalidAreaId) { + CGameArea* area = mgr.GetWorld()->GetArea(x4_areaId); + if (area != nullptr) { + x90_actorLights->BuildAreaLightList(mgr, *area, x144_touchBounds); } } + x90_actorLights->BuildDynamicLightList(mgr, x144_touchBounds); } - } else { - SetCalculateLighting(true); } } void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - if (!xe4_30_outOfFrustum) { - if (x1ec_particleGen1) { - g_Renderer->AddParticleGen(*x1ec_particleGen1); - } - if (x1f4_particleGen2) { - g_Renderer->AddParticleGen(*x1f4_particleGen2); - } - if (x90_actorLights) { - for (auto modelData : x1b0_modelData) { - x90_actorLights->ActivateLights(*modelData->PickAnimatedModel(x1c4_).GetModelInst()); - } - } else { - CGraphics::DisableAllLights(); - g_Renderer->SetAmbientColor(zeus::skWhite); - } - u32 l18 = -1; - for (u32 i = 0; i < x134_boids.size(); ++i) { - RenderBoid(i, &x134_boids[i], &l18); + if (xe4_30_outOfFrustum) + return; + + if (x1ec_particleGen1) + g_Renderer->AddParticleGen(*x1ec_particleGen1); + if (x1f4_particleGen2) + g_Renderer->AddParticleGen(*x1f4_particleGen2); + + if (x90_actorLights) { + for (auto modelData : x1b0_modelData) { + x90_actorLights->ActivateLights(*modelData->PickAnimatedModel(x1c4_which).GetModelInst()); } + } else { CGraphics::DisableAllLights(); + g_Renderer->SetAmbientColor(zeus::skWhite); } + + u32 posesToBuild = -1; + for (u32 i = 0; i < x134_boids.size(); ++i) + RenderBoid(i, &x134_boids[i], posesToBuild); + CGraphics::DisableAllLights(); } void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { if (TCastToPtr proj = actor) { - if (proj->GetDamageInfo().GetWeaponMode().GetType() != EWeaponType::AI) { - sub_8023ca48(x100_, mgr, proj->GetTransform().origin); - } + if (proj->GetDamageInfo().GetWeaponMode().GetType() != EWeaponType::AI) + HandleRadiusDamage(x100_weaponDamageRadius, mgr, proj->GetTransform().origin); } if (TCastToPtr player = actor) { for (auto boid : x134_boids) { float m = (boid.GetPosition() - player->GetTransform().origin).magnitude(); - if (m < x104_ && boid.GetState() == EBoidState::x0) { + if (m < x104_ && boid.GetState() == EBoidState::Raised) { mgr.SendScriptMsg(player, kInvalidUniqueId, EScriptObjectMessage::InSnakeWeed); - x140_26_ = true; + x140_26_playerTouching = true; } } } } -void CSnakeWeedSwarm::sub_8023ca48(float radius, CStateManager& mgr, const zeus::CVector3f& pos) { - float dVar8 = radius * radius; +void CSnakeWeedSwarm::HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos) { + float radiusSquared = radius * radius; for (auto boid : x134_boids) { const zeus::CVector3f& boidPosition = boid.GetPosition(); - if ((boidPosition - pos).magSquared() < dVar8 && - (boid.GetState() == EBoidState::x0 || boid.GetState() == EBoidState::x1)) { + if ((boidPosition - pos).magSquared() < radiusSquared && + (boid.GetState() == EBoidState::Raised || boid.GetState() == EBoidState::x1)) { boid.SetState(EBoidState::x3); float random = mgr.GetActiveRandom()->Float(); boid.Set_x18(x118_ * random + x114_); @@ -200,240 +190,229 @@ void CSnakeWeedSwarm::sub_8023ca48(float radius, CStateManager& mgr, const zeus: void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { CEntity::Think(dt, mgr); - if (x30_24_active) { - if (x1ec_particleGen1) { - x1ec_particleGen1->Update(dt); - } - if (x1f4_particleGen2) { - x1f4_particleGen2->Update(dt); - } - x204_ -= dt; - bool bVar5 = x204_ < 0.f; - if (bVar5) { - x204_ = 0.f; - } - x204_ = std::max(x204_ - dt, 0.f); - if (!x140_24_) { - sub_8023c238(mgr); - } - if (x140_24_ && x1c8_ && !x1c8_->empty()) { - int v = (u64)(dt * x1cc_->size()) >> 0x20; // TODO ? - sub_8023bca8(mgr, v + 1); - } - CModelData::EWhichModel model = CModelData::GetRenderingModel(mgr); - if (x140_26_ && x1c4_ != model) { - AllocateSkinnedModels(mgr, model); - } - for (int i = 0; i < 4; ++i) { - x1b0_modelData[i]->GetAnimationData()->SetPlaybackRate(1.f); - x1b0_modelData[i]->AdvanceAnimation(dt, mgr, x4_areaId, true); - } - int numBoidsInx0 = 0; - for (auto boid : x134_boids) { - const zeus::CVector3f& pos = boid.GetPosition(); - EBoidState state = boid.GetState(); - if (state == EBoidState::x0) { - numBoidsInx0++; - if (x1f4_particleGen2 && bVar5) { - EmitParticles2(pos); - } - } else if (state == EBoidState::x1) { - float x14 = boid.Get_x14() - dt * boid.Get_x18(); - boid.Set_x14(x14); - // printf("setting x14 to %f (dt %f)\n", x14, dt * boid.Get_x18()); - if (x14 <= 0.f) { - boid.Set_x14(0.f); - boid.SetState(EBoidState::x0); - } - } else if (state == EBoidState::x2) { - float x10 = boid.Get_x10() - dt; - boid.Set_x10(x10); - if (x10 <= 0.f) { - boid.SetState(EBoidState::x1); - CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); - EmitParticles1(pos); - } - } else if (state == EBoidState::x3) { - float x14 = dt * boid.Get_x18() + boid.Get_x14(); - boid.Set_x14(x14); - float dVar8 = x110_ * boid.Get_x20(); - if (dVar8 < x14) { - boid.Set_x14(dVar8); - float random = mgr.GetActiveRandom()->Float(); - boid.Set_x10(x10c_ * random + x108_); - boid.SetState(EBoidState::x2); - } - } - } - if (numBoidsInx0 == 0) { - if (x1d8_) { - CSfxManager::RemoveEmitter(x1d8_); - x1d8_.reset(); - } - } else { - if (!x1d8_) { - x1d8_ = CSfxManager::AddEmitter(x1d0_sfx1, GetTransform().origin, zeus::skZero3f, true, true, 0x7f, x4_areaId); - } - } - if (x140_26_) { - mgr.ApplyDamage(x8_uid, mgr.GetPlayer().GetUniqueId(), x8_uid, CDamageInfo(x15c_dInfo, dt), - CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Player, EMaterialTypes::Stone)), - zeus::skZero3f); - } - x140_26_ = false; + if (!x30_24_active) + return; + + if (x1ec_particleGen1) + x1ec_particleGen1->Update(dt); + if (x1f4_particleGen2) + x1f4_particleGen2->Update(dt); + + x204_particleTimer -= dt; + bool emitParticle = false; + if (x204_particleTimer < 0.f) { + x204_particleTimer = 0.f; + emitParticle = true; } + + if (!x140_24_hasGround) + FindGround(mgr); + if (x140_24_hasGround && x1c8_boidPositions && !x1c8_boidPositions->empty()) { + int n = (u64)(dt * x1cc_boidPlacement->size()) >> 0x20; // TODO ? + CreateBoids(mgr, n + 1); + } + + CModelData::EWhichModel model = CModelData::GetRenderingModel(mgr); + if (x140_25_modelAssetDirty && x1c4_which != model) + AllocateSkinnedModels(mgr, model); + + for (int i = 0; i < 4; ++i) { + x1b0_modelData[i]->GetAnimationData()->SetPlaybackRate(1.f); + x1b0_modelData[i]->AdvanceAnimation(dt, mgr, x4_areaId, true); + } + + int raisedBoids = 0; + for (auto boid : x134_boids) { + const zeus::CVector3f& pos = boid.GetPosition(); + EBoidState state = boid.GetState(); + if (state == EBoidState::Raised) { + raisedBoids++; + if (x1f4_particleGen2 && emitParticle) { + EmitParticles2(pos); + } + } else if (state == EBoidState::x1) { + float x14 = boid.Get_x14() - dt * boid.Get_x18(); + if (x14 <= 0.f) { + boid.Set_x14(0.f); + boid.SetState(EBoidState::Raised); + } else { + boid.Set_x14(x14); + } + } else if (state == EBoidState::x2) { + float x10 = boid.Get_x10() - dt; + boid.Set_x10(x10); + if (x10 <= 0.f) { + boid.SetState(EBoidState::x1); + CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); + EmitParticles1(pos); + } + } else if (state == EBoidState::x3) { + float x14 = dt * boid.Get_x18() + boid.Get_x14(); + float max = x110_ * boid.Get_x20(); + if (x14 >= max) { + boid.Set_x14(max); + float random = mgr.GetActiveRandom()->Float(); + boid.Set_x10(x10c_ * random + x108_); + boid.SetState(EBoidState::x2); + } else { + boid.Set_x14(x14); + } + } + } + if (raisedBoids == 0) { + if (x1d8_sfxHandle) { + CSfxManager::RemoveEmitter(x1d8_sfxHandle); + x1d8_sfxHandle.reset(); + } + } else if (!x1d8_sfxHandle) { + x1d8_sfxHandle = + CSfxManager::AddEmitter(x1d0_sfx1, GetTransform().origin, zeus::skZero3f, true, true, 0x7f, x4_areaId); + } + + if (x140_26_playerTouching) { + mgr.ApplyDamage(x8_uid, mgr.GetPlayer().GetUniqueId(), x8_uid, CDamageInfo(x15c_damageInfo, dt), matFilter, + zeus::skZero3f); + } + x140_26_playerTouching = false; } -zeus::CAABox CSnakeWeedSwarm::sub_8023d3f4() { +zeus::CAABox CSnakeWeedSwarm::GetBoidBox() { const zeus::CVector3f& scale = xe8_scale * 0.75f; - const zeus::CVector3f& min = GetTransform().origin - scale; - const zeus::CVector3f& max = GetTransform().origin + scale; - return zeus::CAABox(min, max); + return zeus::CAABox(GetTransform().origin - scale, GetTransform().origin + scale); } -static CMaterialList matList1 = CMaterialList(EMaterialTypes::RadarObject, EMaterialTypes::Stone); -static CMaterialFilter matFilter1 = CMaterialFilter::MakeInclude(matList1); - -void CSnakeWeedSwarm::sub_8023c238(const CStateManager& mgr) { - const zeus::CAABox& box = sub_8023d3f4(); +void CSnakeWeedSwarm::FindGround(const CStateManager& mgr) { + const zeus::CAABox& box = GetBoidBox(); const CRayCastResult& result = - mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), matFilter1); + mgr.RayStaticIntersection(box.center(), zeus::skDown, box.max.z() - box.min.z(), matFilter); if (result.IsValid()) { - int ct = sub_8023c154() * sub_8023c0fc(); + int ct = GetNumBoidsX() * GetNumBoidsY(); x134_boids.reserve(ct); - x1c8_->reserve(ct); - x1cc_->resize(ct, 0); - x1c8_->push_back(result.GetPoint()); - x140_24_ = true; + x1c8_boidPositions->reserve(ct); + x1c8_boidPositions->push_back(result.GetPoint()); + x1cc_boidPlacement->resize(ct, EBoidPlacement::None); + x140_24_hasGround = true; } - - // matFilter.IncludeList().Add(CMaterialList(matFilter.IncludeList().GetValue() >> 0x20)); } -int CSnakeWeedSwarm::sub_8023c0fc() { - const zeus::CAABox& box = sub_8023d3f4(); - return (int)((box.max.y() - box.min.y()) / xf4_) + 1; +int CSnakeWeedSwarm::GetNumBoidsY() { + const zeus::CAABox& box = GetBoidBox(); + return (int)((box.max.y() - box.min.y()) / xf4_boidSpacing) + 1; } -int CSnakeWeedSwarm::sub_8023c154() { - const zeus::CAABox& box = sub_8023d3f4(); - return (int)((box.max.x() - box.min.x()) / xf4_) + 1; +int CSnakeWeedSwarm::GetNumBoidsX() { + const zeus::CAABox& box = GetBoidBox(); + return (int)((box.max.x() - box.min.x()) / xf4_boidSpacing) + 1; } -void CSnakeWeedSwarm::sub_8023bca8(CStateManager& mgr, int v) { - int n = sub_8023c154(); - for (int i = 0; i < v; ++i) { - if (x1c8_->empty()) +void CSnakeWeedSwarm::CreateBoids(CStateManager& mgr, int num) { + int width = GetNumBoidsX(); + for (int i = 0; i < num; ++i) { + if (x1c8_boidPositions->empty()) break; - zeus::CVector3f vec = x1c8_->back(); - x1c8_->pop_back(); - const zeus::CVector2i& v2i = sub_8023c1ac(vec); - if (CreateBoid(vec, mgr)) { - x1cc_->at(v2i.x + n * v2i.y) = 3; - sub_8023bfb8(zeus::CVector3f(vec.x(), vec.y() - xf4_, vec.z())); - sub_8023bfb8(zeus::CVector3f(vec.x(), xf4_ + vec.y(), vec.z())); - sub_8023bfb8(zeus::CVector3f(vec.x() - xf4_, vec.y(), vec.z())); - sub_8023bfb8(zeus::CVector3f(xf4_ + vec.x(), vec.y(), vec.z())); + const zeus::CVector3f pos = x1c8_boidPositions->back(); + x1c8_boidPositions->pop_back(); + const zeus::CVector2i& idx = GetBoidIndex(pos); + if (CreateBoid(pos, mgr)) { + x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Placed; + AddBoidPosition(zeus::CVector3f(pos.x(), pos.y() - xf4_boidSpacing, pos.z())); + AddBoidPosition(zeus::CVector3f(pos.x(), xf4_boidSpacing + pos.y(), pos.z())); + AddBoidPosition(zeus::CVector3f(pos.x() - xf4_boidSpacing, pos.y(), pos.z())); + AddBoidPosition(zeus::CVector3f(xf4_boidSpacing + pos.x(), pos.y(), pos.z())); } else { - x1cc_->at(v2i.x + n * v2i.y) = 2; + x1cc_boidPlacement->at(idx.x + width * idx.y) = EBoidPlacement::Invalid; } } - sub_8023d204(); - if (x1c8_->empty()) { - x1c8_ = nullptr; - x1cc_ = nullptr; + CalculateTouchBounds(); + if (x1c8_boidPositions->empty()) { + x1c8_boidPositions = nullptr; + x1cc_boidPlacement = nullptr; } } -zeus::CVector2i CSnakeWeedSwarm::sub_8023c1ac(const zeus::CVector3f& vec) { - const zeus::CAABox& box = sub_8023d3f4(); - int x = (vec.x() - box.min.x()) / xf4_; - int y = (vec.y() - box.min.y()) / xf4_; +zeus::CVector2i CSnakeWeedSwarm::GetBoidIndex(const zeus::CVector3f& pos) { + const zeus::CAABox& box = GetBoidBox(); + int x = (pos.x() - box.min.x()) / xf4_boidSpacing; + int y = (pos.y() - box.min.y()) / xf4_boidSpacing; return zeus::CVector2i(x, y); } -// TODO double check these params -static CMaterialList matList2 = CMaterialList(EMaterialTypes::RadarObject, EMaterialTypes::Stone); -static CMaterialFilter matFilter2 = CMaterialFilter::MakeInclude(matList2); - bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) { - const zeus::CVector3f pos = vec + zeus::CVector3f(sub_8023bc38(vec), sub_8023bbc8(vec), xf8_); - const CRayCastResult result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_, matFilter2); - if (result.IsInvalid() || result.GetPlane().normal().dot(zeus::skUp) <= x11c_) { - return false; - } else { - const zeus::CVector3f boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_); + const zeus::CVector3f& pos = vec + zeus::CVector3f(GetBoidOffsetX(vec), GetBoidOffsetY(vec), xf8_height); + const CRayCastResult& result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, matFilter); + if (result.IsValid() && result.GetPlane().normal().dot(zeus::skUp) > x11c_) { + const zeus::CVector3f& boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_); float random = mgr.GetActiveRandom()->Float(); const CBoid boid(boidPosition, x110_, x114_ + x118_, (x124_ - x120_) * random + x120_); x134_boids.push_back(boid); -// printf("created boid @ %f|%f|%f, new size %zu\n", boidPosition.x(), boidPosition.y(), boidPosition.z(), -// x134_boids.size()); return true; } + return false; } -float CSnakeWeedSwarm::sub_8023bbc8(const zeus::CVector3f& vec) { - float f = 2.4729404f * vec.y() + 0.3478602f * vec.x() * vec.x(); +float CSnakeWeedSwarm::GetBoidOffsetY(const zeus::CVector3f& pos) { + float f = 2.4729404f * pos.y() + 0.3478602f * pos.x() * pos.x(); return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); } -float CSnakeWeedSwarm::sub_8023bc38(const zeus::CVector3f& vec) { - float f = 8.21395f * vec.x() + 0.112869f * vec.y() * vec.y(); +float CSnakeWeedSwarm::GetBoidOffsetX(const zeus::CVector3f& pos) { + float f = 8.21395f * pos.x() + 0.112869f * pos.y() * pos.y(); return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); } -void CSnakeWeedSwarm::sub_8023bfb8(const zeus::CVector3f& vec) { - int x = sub_8023c154(); - int y = sub_8023c0fc(); - zeus::CVector2i v = sub_8023c1ac(vec); +void CSnakeWeedSwarm::AddBoidPosition(const zeus::CVector3f& pos) { + int x = GetNumBoidsX(); + int y = GetNumBoidsY(); + const zeus::CVector2i& v = GetBoidIndex(pos); if (-1 < v.x && v.x < x && -1 < v.y && v.y < y) { - v.x += x * v.y; - if (x1cc_->at(v.x) == 0) { - x1cc_->at(v.x) = 1; - x1c8_->push_back(vec); + int idx = v.x + x * v.y; + if (x1cc_boidPlacement->at(idx) == EBoidPlacement::None) { + x1cc_boidPlacement->at(idx) = EBoidPlacement::Ready; + x1c8_boidPositions->push_back(pos); } } } -void CSnakeWeedSwarm::sub_8023d204() { +void CSnakeWeedSwarm::CalculateTouchBounds() { if (x134_boids.empty()) { - x144_ = zeus::CAABox(GetTransform().origin, GetTransform().origin); + x144_touchBounds = zeus::CAABox(GetTransform().origin, GetTransform().origin); } else { - x144_ = zeus::skInvertedBox; + x144_touchBounds = zeus::skInvertedBox; for (auto boid : x134_boids) { - x144_.accumulateBounds(boid.GetPosition() - x100_); - x144_.accumulateBounds(boid.GetPosition() + x100_); + x144_touchBounds.accumulateBounds(boid.GetPosition() - x100_weaponDamageRadius); + x144_touchBounds.accumulateBounds(boid.GetPosition() + x100_weaponDamageRadius); } } xe4_27_notInSortedLists = true; } void CSnakeWeedSwarm::EmitParticles1(const zeus::CVector3f& pos) { - if (x1ec_particleGen1) { - x1ec_particleGen1->SetParticleEmission(true); - x1ec_particleGen1->SetTranslation(pos); - x1ec_particleGen1->ForceParticleCreation(x1fc_); - x1ec_particleGen1->SetParticleEmission(false); - } + if (!x1ec_particleGen1) + return; + + x1ec_particleGen1->SetParticleEmission(true); + x1ec_particleGen1->SetTranslation(pos); + x1ec_particleGen1->ForceParticleCreation(x1fc_); + x1ec_particleGen1->SetParticleEmission(false); } void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) { - if (x1f4_particleGen2) { - x1f4_particleGen2->SetParticleEmission(true); - x1f4_particleGen2->SetTranslation(pos); - x1f4_particleGen2->ForceParticleCreation(1); - x1f4_particleGen2->SetParticleEmission(false); - } + if (!x1f4_particleGen2) + return; + + x1f4_particleGen2->SetParticleEmission(true); + x1f4_particleGen2->SetTranslation(pos); + x1f4_particleGen2->ForceParticleCreation(1); + x1f4_particleGen2->SetParticleEmission(false); } -void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32* p3) const { - u32 idx = p1 & 3; - u32 var3 = *p3; - auto modelData = x1b0_modelData[idx]; - CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_); +void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32& posesToBuild) const { + u32 modelIdx = p1 & 3; + auto modelData = x1b0_modelData[modelIdx]; + CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_which); CModelFlags useFlags(0, 0, 3, zeus::skWhite); - if ((var3 & 1 << idx) != 0) { - var3 &= ~(1 << idx); + if ((posesToBuild & 1 << modelIdx) != 0) { + posesToBuild &= ~(1 << modelIdx); modelData->GetAnimationData()->BuildPose(); model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); } @@ -443,14 +422,18 @@ void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32* p3) const { zeus::CTransform::Scale(boid->Get_x20()); g_Renderer->SetModelMatrix(xf); model.Draw(useFlags); - *p3 = var3; } void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& mgr) { EWeaponType type = info.GetWeaponMode().GetType(); - if (type == EWeaponType::Bomb || type == EWeaponType::PowerBomb) { - sub_8023ca48(info.GetRadius(), mgr, pos); - } + if (type == EWeaponType::Bomb || type == EWeaponType::PowerBomb) + HandleRadiusDamage(info.GetRadius(), mgr, pos); +} + +std::optional CSnakeWeedSwarm::GetTouchBounds() const { + if (x140_24_hasGround) + return x144_touchBounds; + return {}; } } // namespace urde diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index 15019fb3a..ce93991ae 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -11,12 +11,19 @@ class CAnimationParameters; class CSnakeWeedSwarm : public CActor { public: enum class EBoidState : u32 { - x0 = 0, + Raised = 0, x1 = 1, x2 = 2, x3 = 3, }; + enum class EBoidPlacement : u32 { + None = 0, + Ready = 1, + Invalid = 2, + Placed = 3, + }; + class CBoid { zeus::CVector3f x0_pos; EBoidState xc_state; @@ -44,10 +51,10 @@ public: private: zeus::CVector3f xe8_scale; - float xf4_; - float xf8_; + float xf4_boidSpacing; + float xf8_height; float xfc_; - float x100_; + float x100_weaponDamageRadius; float x104_; float x108_; float x10c_; @@ -58,31 +65,29 @@ private: float x120_; float x124_; float x128_; - u32 x12c_ = 0; - // x130_ + // u32 x12c_ = 0; std::vector x134_boids; - bool x140_24_ : 1; + bool x140_24_hasGround : 1; bool x140_25_modelAssetDirty : 1; - bool x140_26_ : 1; - zeus::CAABox x144_ = zeus::skInvertedBox; - CDamageInfo x15c_dInfo; -// std::vector> x178_; -// std::vector> x19c_; + bool x140_26_playerTouching : 1; + zeus::CAABox x144_touchBounds = zeus::skInvertedBox; + CDamageInfo x15c_damageInfo; + // x178_ / x19c_: vectors of CSkinnedModel, not needed rstl::reserved_vector, 4> x1b0_modelData; - CModelData::EWhichModel x1c4_; - std::unique_ptr> x1c8_; - std::unique_ptr> x1cc_; + CModelData::EWhichModel x1c4_which; + std::unique_ptr> x1c8_boidPositions; + std::unique_ptr> x1cc_boidPlacement; u16 x1d0_sfx1; u16 x1d2_sfx2; u16 x1d4_sfx3; - CSfxHandle x1d8_ = 0; - TLockedToken x1dc_; - // TLockedToken x1e4_; both assign to x1dc_? + CSfxHandle x1d8_sfxHandle = 0; + TLockedToken x1dc_particleGenDesc; + // TLockedToken x1e4_; both assign to x1dc_ std::unique_ptr x1ec_particleGen1; std::unique_ptr x1f4_particleGen2; u32 x1fc_; float x200_; - float x204_ = 0.f; + float x204_particleTimer = 0.f; public: CSnakeWeedSwarm(TUniqueId, bool, std::string_view, const CEntityInfo&, const zeus::CVector3f&, const zeus::CVector3f&, @@ -92,12 +97,7 @@ public: void Accept(IVisitor&) override; void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr); - std::optional GetTouchBounds() const override { - if (x140_24_) { - return {}; - } - return x144_; - } + std::optional GetTouchBounds() const override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override; void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; @@ -106,20 +106,20 @@ public: private: void AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which); - void sub_8023ca48(float radius, CStateManager& mgr, const zeus::CVector3f& pos); - void sub_8023c238(const CStateManager& mgr); - zeus::CAABox sub_8023d3f4(); - int sub_8023c0fc(); - int sub_8023c154(); - void sub_8023bca8(CStateManager& mgr, int v); - zeus::CVector2i sub_8023c1ac(const zeus::CVector3f& vec); + void HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos); + void FindGround(const CStateManager& mgr); + zeus::CAABox GetBoidBox(); + int GetNumBoidsY(); + int GetNumBoidsX(); + void CreateBoids(CStateManager& mgr, int num); + zeus::CVector2i GetBoidIndex(const zeus::CVector3f& pos); bool CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr); - float sub_8023bbc8(const zeus::CVector3f& vec); - float sub_8023bc38(const zeus::CVector3f& vec); - void sub_8023bfb8(const zeus::CVector3f& vec); - void sub_8023d204(); + float GetBoidOffsetY(const zeus::CVector3f& pos); + float GetBoidOffsetX(const zeus::CVector3f& pos); + void AddBoidPosition(const zeus::CVector3f& pos); + void CalculateTouchBounds(); void EmitParticles1(const zeus::CVector3f& pos); void EmitParticles2(const zeus::CVector3f& pos); - void RenderBoid(u32 p1, const CBoid* boid, u32 *p3) const; + void RenderBoid(u32 p1, const CBoid* boid, u32& posesToBuild) const; }; } // namespace urde From f064bc2f7b112fc818847d9b33764fdb11e83e43 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 25 Feb 2020 14:09:49 -0500 Subject: [PATCH 4/6] CSnakeWeedSwarm: Initialize bitfields; some more cleanup --- Runtime/World/CSnakeWeedSwarm.cpp | 28 +++++++++++++++------------- Runtime/World/CSnakeWeedSwarm.hpp | 4 ++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index e65a8902f..19aec5093 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -15,8 +15,7 @@ namespace urde { -static CMaterialFilter matFilter = - CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Solid, EMaterialTypes::Character)); +static constexpr CMaterialFilter matFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid}); CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view name, const CEntityInfo& info, const zeus::CVector3f& pos, const zeus::CVector3f& scale, const CAnimRes& animRes, @@ -41,6 +40,9 @@ CSnakeWeedSwarm::CSnakeWeedSwarm(TUniqueId uid, bool active, std::string_view na , x120_(f12) , x124_(f13) , x128_(f14) +, x140_24_hasGround(false) +, x140_25_modelAssetDirty(false) +, x140_26_playerTouching(false) , x15c_damageInfo(dInfo) , x1c8_boidPositions(std::make_unique>()) , x1cc_boidPlacement(std::make_unique>()) @@ -153,7 +155,7 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM u32 posesToBuild = -1; for (u32 i = 0; i < x134_boids.size(); ++i) - RenderBoid(i, &x134_boids[i], posesToBuild); + RenderBoid(i, x134_boids[i], posesToBuild); CGraphics::DisableAllLights(); } @@ -208,7 +210,7 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { if (!x140_24_hasGround) FindGround(mgr); if (x140_24_hasGround && x1c8_boidPositions && !x1c8_boidPositions->empty()) { - int n = (u64)(dt * x1cc_boidPlacement->size()) >> 0x20; // TODO ? + int n = (u64)(dt * x1cc_boidPlacement->size()) >> 0x20; CreateBoids(mgr, n + 1); } @@ -352,12 +354,12 @@ bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) float CSnakeWeedSwarm::GetBoidOffsetY(const zeus::CVector3f& pos) { float f = 2.4729404f * pos.y() + 0.3478602f * pos.x() * pos.x(); - return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); + return xfc_ * (2.f * std::abs(f - std::trunc(f)) - 1.f); } float CSnakeWeedSwarm::GetBoidOffsetX(const zeus::CVector3f& pos) { float f = 8.21395f * pos.x() + 0.112869f * pos.y() * pos.y(); - return xfc_ * (2.f * std::abs(f - (int)f) - 1.f); + return xfc_ * (2.f * std::abs(f - std::trunc(f)) - 1.f); } void CSnakeWeedSwarm::AddBoidPosition(const zeus::CVector3f& pos) { @@ -406,20 +408,20 @@ void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) { x1f4_particleGen2->SetParticleEmission(false); } -void CSnakeWeedSwarm::RenderBoid(u32 p1, const CBoid* boid, u32& posesToBuild) const { - u32 modelIdx = p1 & 3; +void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) const { + const u32 modelIdx = idx & 3; auto modelData = x1b0_modelData[modelIdx]; CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_which); - CModelFlags useFlags(0, 0, 3, zeus::skWhite); - if ((posesToBuild & 1 << modelIdx) != 0) { + const CModelFlags useFlags(0, 0, 3, zeus::skWhite); + if (posesToBuild & 1 << modelIdx) { posesToBuild &= ~(1 << modelIdx); modelData->GetAnimationData()->BuildPose(); model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); } // printf("rendering boid with x14 %f\n", boid->Get_x14()); const zeus::CTransform& xf = - zeus::CTransform::Translate(boid->GetPosition() /*- zeus::CVector3f(0.f, 0.f, boid->Get_x14())*/) * - zeus::CTransform::Scale(boid->Get_x20()); + zeus::CTransform::Translate(boid.GetPosition() /*- zeus::CVector3f(0.f, 0.f, boid.Get_x14())*/) * + zeus::CTransform::Scale(boid.Get_x20()); g_Renderer->SetModelMatrix(xf); model.Draw(useFlags); } @@ -433,7 +435,7 @@ void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamag std::optional CSnakeWeedSwarm::GetTouchBounds() const { if (x140_24_hasGround) return x144_touchBounds; - return {}; + return std::nullopt; } } // namespace urde diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index ce93991ae..55b440306 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -72,7 +72,7 @@ private: bool x140_26_playerTouching : 1; zeus::CAABox x144_touchBounds = zeus::skInvertedBox; CDamageInfo x15c_damageInfo; - // x178_ / x19c_: vectors of CSkinnedModel, not needed + // x178_ / x19c_: vectors of CSkinnedModel*, not needed rstl::reserved_vector, 4> x1b0_modelData; CModelData::EWhichModel x1c4_which; std::unique_ptr> x1c8_boidPositions; @@ -120,6 +120,6 @@ private: void CalculateTouchBounds(); void EmitParticles1(const zeus::CVector3f& pos); void EmitParticles2(const zeus::CVector3f& pos); - void RenderBoid(u32 p1, const CBoid* boid, u32& posesToBuild) const; + void RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) const; }; } // namespace urde From 17b9813b3ec09e4b8ba0d09774ede338c29bf586 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 1 Mar 2020 02:52:17 -0500 Subject: [PATCH 5/6] CSnakeWeedSwarm: Rendering & state fixes --- Runtime/World/CSnakeWeedSwarm.cpp | 68 ++++++++++++++----------------- Runtime/World/CSnakeWeedSwarm.hpp | 6 +-- Runtime/World/ScriptLoader.cpp | 6 +-- 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index 19aec5093..0b9523997 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -80,10 +80,10 @@ void CSnakeWeedSwarm::Accept(urde::IVisitor& visitor) { visitor.Visit(this); } void CSnakeWeedSwarm::AllocateSkinnedModels(CStateManager& mgr, CModelData::EWhichModel which) { for (int i = 0; i < 4; ++i) { - x1b0_modelData[i]->EnableLooping(true); - x1b0_modelData[i]->AdvanceAnimation(x1b0_modelData[i]->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * - (i * 0.25f), - mgr, x4_areaId, true); + const auto& modelData = x1b0_modelData[i]; + modelData->EnableLooping(true); + modelData->AdvanceAnimation(modelData->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) * (i * 0.25f), mgr, + x4_areaId, true); } x1c4_which = which; } @@ -109,8 +109,8 @@ void CSnakeWeedSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustu } SetCalculateLighting(false); - for (int i = 0; i < 4; ++i) { - x1b0_modelData[i]->GetAnimationData()->PreRender(); + for (const auto& modelData : x1b0_modelData) { + modelData->GetAnimationData()->PreRender(); } if (x90_actorLights && x140_24_hasGround) { bool buildLights = false; @@ -145,7 +145,7 @@ void CSnakeWeedSwarm::AddToRenderer(const zeus::CFrustum& frustum, const CStateM g_Renderer->AddParticleGen(*x1f4_particleGen2); if (x90_actorLights) { - for (auto modelData : x1b0_modelData) { + for (const auto& modelData : x1b0_modelData) { x90_actorLights->ActivateLights(*modelData->PickAnimatedModel(x1c4_which).GetModelInst()); } } else { @@ -165,7 +165,7 @@ void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { HandleRadiusDamage(x100_weaponDamageRadius, mgr, proj->GetTransform().origin); } if (TCastToPtr player = actor) { - for (auto boid : x134_boids) { + for (const auto& boid : x134_boids) { float m = (boid.GetPosition() - player->GetTransform().origin).magnitude(); if (m < x104_ && boid.GetState() == EBoidState::Raised) { mgr.SendScriptMsg(player, kInvalidUniqueId, EScriptObjectMessage::InSnakeWeed); @@ -177,13 +177,12 @@ void CSnakeWeedSwarm::Touch(CActor& actor, CStateManager& mgr) { void CSnakeWeedSwarm::HandleRadiusDamage(float radius, CStateManager& mgr, const zeus::CVector3f& pos) { float radiusSquared = radius * radius; - for (auto boid : x134_boids) { + for (auto& boid : x134_boids) { const zeus::CVector3f& boidPosition = boid.GetPosition(); if ((boidPosition - pos).magSquared() < radiusSquared && - (boid.GetState() == EBoidState::Raised || boid.GetState() == EBoidState::x1)) { + (boid.GetState() == EBoidState::Raised || boid.GetState() == EBoidState::Raising)) { boid.SetState(EBoidState::x3); - float random = mgr.GetActiveRandom()->Float(); - boid.Set_x18(x118_ * random + x114_); + boid.Set_x18(x118_ * mgr.GetActiveRandom()->Float() + x114_); CSfxManager::AddEmitter(x1d2_sfx2, boidPosition, zeus::skZero3f, true, false, 0x7f, x4_areaId); EmitParticles1(boidPosition); } @@ -218,13 +217,13 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { if (x140_25_modelAssetDirty && x1c4_which != model) AllocateSkinnedModels(mgr, model); - for (int i = 0; i < 4; ++i) { - x1b0_modelData[i]->GetAnimationData()->SetPlaybackRate(1.f); - x1b0_modelData[i]->AdvanceAnimation(dt, mgr, x4_areaId, true); + for (const auto& modelData : x1b0_modelData) { + modelData->GetAnimationData()->SetPlaybackRate(1.f); + modelData->AdvanceAnimation(dt, mgr, x4_areaId, true); } int raisedBoids = 0; - for (auto boid : x134_boids) { + for (auto& boid : x134_boids) { const zeus::CVector3f& pos = boid.GetPosition(); EBoidState state = boid.GetState(); if (state == EBoidState::Raised) { @@ -232,32 +231,27 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { if (x1f4_particleGen2 && emitParticle) { EmitParticles2(pos); } - } else if (state == EBoidState::x1) { - float x14 = boid.Get_x14() - dt * boid.Get_x18(); - if (x14 <= 0.f) { + } else if (state == EBoidState::Raising) { + boid.Set_x14(boid.Get_x14() - dt * boid.Get_x18()); + if (boid.Get_x14() <= 0.f) { boid.Set_x14(0.f); boid.SetState(EBoidState::Raised); - } else { - boid.Set_x14(x14); } } else if (state == EBoidState::x2) { - float x10 = boid.Get_x10() - dt; - boid.Set_x10(x10); - if (x10 <= 0.f) { - boid.SetState(EBoidState::x1); + boid.Set_x10(boid.Get_x10() - dt); + if (boid.Get_x10() <= 0.f) { + boid.SetState(EBoidState::Raising); CSfxManager::AddEmitter(x1d4_sfx3, pos, zeus::skZero3f, true, false, 0x7f, x4_areaId); EmitParticles1(pos); } } else if (state == EBoidState::x3) { - float x14 = dt * boid.Get_x18() + boid.Get_x14(); + boid.Set_x14(dt * boid.Get_x18() + boid.Get_x14()); float max = x110_ * boid.Get_x20(); - if (x14 >= max) { + if (boid.Get_x14() >= max) { boid.Set_x14(max); float random = mgr.GetActiveRandom()->Float(); boid.Set_x10(x10c_ * random + x108_); boid.SetState(EBoidState::x2); - } else { - boid.Set_x14(x14); } } } @@ -344,9 +338,8 @@ bool CSnakeWeedSwarm::CreateBoid(const zeus::CVector3f& vec, CStateManager& mgr) const CRayCastResult& result = mgr.RayStaticIntersection(pos, zeus::skDown, 2.f * xf8_height, matFilter); if (result.IsValid() && result.GetPlane().normal().dot(zeus::skUp) > x11c_) { const zeus::CVector3f& boidPosition = result.GetPoint() - zeus::CVector3f(0.f, 0.f, x128_); - float random = mgr.GetActiveRandom()->Float(); - const CBoid boid(boidPosition, x110_, x114_ + x118_, (x124_ - x120_) * random + x120_); - x134_boids.push_back(boid); + x134_boids.push_back( + {boidPosition, x110_, x114_ + x118_, (x124_ - x120_) * mgr.GetActiveRandom()->Float() + x120_}); return true; } return false; @@ -380,7 +373,7 @@ void CSnakeWeedSwarm::CalculateTouchBounds() { x144_touchBounds = zeus::CAABox(GetTransform().origin, GetTransform().origin); } else { x144_touchBounds = zeus::skInvertedBox; - for (auto boid : x134_boids) { + for (const auto& boid : x134_boids) { x144_touchBounds.accumulateBounds(boid.GetPosition() - x100_weaponDamageRadius); x144_touchBounds.accumulateBounds(boid.GetPosition() + x100_weaponDamageRadius); } @@ -410,7 +403,7 @@ void CSnakeWeedSwarm::EmitParticles2(const zeus::CVector3f& pos) { void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) const { const u32 modelIdx = idx & 3; - auto modelData = x1b0_modelData[modelIdx]; + const auto& modelData = x1b0_modelData[modelIdx]; CSkinnedModel& model = modelData->PickAnimatedModel(x1c4_which); const CModelFlags useFlags(0, 0, 3, zeus::skWhite); if (posesToBuild & 1 << modelIdx) { @@ -418,12 +411,11 @@ void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) modelData->GetAnimationData()->BuildPose(); model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); } - // printf("rendering boid with x14 %f\n", boid->Get_x14()); const zeus::CTransform& xf = - zeus::CTransform::Translate(boid.GetPosition() /*- zeus::CVector3f(0.f, 0.f, boid.Get_x14())*/) * + zeus::CTransform::Translate(boid.GetPosition() - zeus::CVector3f(0.f, 0.f, boid.Get_x14())) * zeus::CTransform::Scale(boid.Get_x20()); - g_Renderer->SetModelMatrix(xf); - model.Draw(useFlags); + CGraphics::SetModelMatrix(xf); + modelData->GetAnimationData()->Render(model, useFlags, {}, nullptr); } void CSnakeWeedSwarm::ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& mgr) { diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index 55b440306..3b9697e74 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -12,7 +12,7 @@ class CSnakeWeedSwarm : public CActor { public: enum class EBoidState : u32 { Raised = 0, - x1 = 1, + Raising = 1, x2 = 2, x3 = 3, }; @@ -35,7 +35,7 @@ public: public: constexpr CBoid(const zeus::CVector3f& pos, float f1, float f2, float f3) - : x0_pos(pos), xc_state(EBoidState::x1), x14_(f1), x18_(f2), x20_(f3) {} + : x0_pos(pos), xc_state(EBoidState::Raising), x14_(f1), x18_(f2), x20_(f3) {} constexpr const zeus::CVector3f& GetPosition() const { return x0_pos; } constexpr EBoidState GetState() const { return xc_state; } @@ -43,7 +43,7 @@ public: constexpr float Get_x14() const { return x14_; } constexpr float Get_x18() const { return x18_; } constexpr float Get_x20() const { return x20_; } - constexpr void SetState(EBoidState v) { xc_state = v; } + void SetState(EBoidState v) { xc_state = v; fmt::print(fmt("Setting boid state {}"), v); } constexpr void Set_x10(float v) { x10_ = v; } constexpr void Set_x14(float v) { x14_ = v; } constexpr void Set_x18(float v) { x18_ = v; } diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index db62e24af..6f1495681 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -3054,9 +3054,9 @@ CEntity* ScriptLoader::LoadSnakeWeedSwarm(CStateManager& mgr, CInputStream& in, u32 w1 = in.readUint32Big(); u32 w2 = in.readUint32Big(); u32 w3 = in.readUint32Big(); - CAssetId w4 = (propCount < 29 ? -1 : in.readUint32Big()); - u32 w5 = (propCount < 29 ? -1 : in.readUint32Big()); - CAssetId w6 = (propCount < 29 ? -1 : in.readUint32Big()); + CAssetId w4 = (propCount < 29 ? CAssetId() : in.readUint32Big()); + u32 w5 = (propCount < 29 ? 0 : in.readUint32Big()); + CAssetId w6 = (propCount < 29 ? CAssetId() : in.readUint32Big()); float f16 = (propCount < 29 ? 0.f : in.readFloatBig()); CAnimRes animRes(animParms.GetACSFile(), animParms.GetCharacter(), zeus::skOne3f, animParms.GetInitialAnimation(), From 12393d4c4d0702bf0078dde8fbc6f6695e83aaf1 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 1 Mar 2020 03:05:16 -0500 Subject: [PATCH 6/6] CSnakeWeedSwarm: Fix lighting --- Runtime/World/CSnakeWeedSwarm.cpp | 25 ++++++++++++------------- Runtime/World/CSnakeWeedSwarm.hpp | 10 +++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Runtime/World/CSnakeWeedSwarm.cpp b/Runtime/World/CSnakeWeedSwarm.cpp index 0b9523997..4154ca656 100644 --- a/Runtime/World/CSnakeWeedSwarm.cpp +++ b/Runtime/World/CSnakeWeedSwarm.cpp @@ -104,11 +104,11 @@ void CSnakeWeedSwarm::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId id, CS void CSnakeWeedSwarm::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { if (!frustum.aabbFrustumTest(x144_touchBounds)) { - SetCalculateLighting(true); + xe4_30_outOfFrustum = true; return; } - SetCalculateLighting(false); + xe4_30_outOfFrustum = false; for (const auto& modelData : x1b0_modelData) { modelData->GetAnimationData()->PreRender(); } @@ -225,16 +225,16 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { int raisedBoids = 0; for (auto& boid : x134_boids) { const zeus::CVector3f& pos = boid.GetPosition(); - EBoidState state = boid.GetState(); + const EBoidState state = boid.GetState(); if (state == EBoidState::Raised) { raisedBoids++; if (x1f4_particleGen2 && emitParticle) { EmitParticles2(pos); } } else if (state == EBoidState::Raising) { - boid.Set_x14(boid.Get_x14() - dt * boid.Get_x18()); - if (boid.Get_x14() <= 0.f) { - boid.Set_x14(0.f); + boid.SetYOffset(boid.GetYOffset() - dt * boid.Get_x18()); + if (boid.GetYOffset() <= 0.f) { + boid.SetYOffset(0.f); boid.SetState(EBoidState::Raised); } } else if (state == EBoidState::x2) { @@ -245,12 +245,11 @@ void CSnakeWeedSwarm::Think(float dt, CStateManager& mgr) { EmitParticles1(pos); } } else if (state == EBoidState::x3) { - boid.Set_x14(dt * boid.Get_x18() + boid.Get_x14()); - float max = x110_ * boid.Get_x20(); - if (boid.Get_x14() >= max) { - boid.Set_x14(max); - float random = mgr.GetActiveRandom()->Float(); - boid.Set_x10(x10c_ * random + x108_); + boid.SetYOffset(dt * boid.Get_x18() + boid.GetYOffset()); + const float max = x110_ * boid.Get_x20(); + if (boid.GetYOffset() >= max) { + boid.SetYOffset(max); + boid.Set_x10(x10c_ * mgr.GetActiveRandom()->Float() + x108_); boid.SetState(EBoidState::x2); } } @@ -412,7 +411,7 @@ void CSnakeWeedSwarm::RenderBoid(u32 idx, const CBoid& boid, u32& posesToBuild) model.Calculate(modelData->GetAnimationData()->GetPose(), useFlags, {}, nullptr); } const zeus::CTransform& xf = - zeus::CTransform::Translate(boid.GetPosition() - zeus::CVector3f(0.f, 0.f, boid.Get_x14())) * + zeus::CTransform::Translate(boid.GetPosition() - zeus::CVector3f(0.f, 0.f, boid.GetYOffset())) * zeus::CTransform::Scale(boid.Get_x20()); CGraphics::SetModelMatrix(xf); modelData->GetAnimationData()->Render(model, useFlags, {}, nullptr); diff --git a/Runtime/World/CSnakeWeedSwarm.hpp b/Runtime/World/CSnakeWeedSwarm.hpp index 3b9697e74..17b59e227 100644 --- a/Runtime/World/CSnakeWeedSwarm.hpp +++ b/Runtime/World/CSnakeWeedSwarm.hpp @@ -28,24 +28,24 @@ public: zeus::CVector3f x0_pos; EBoidState xc_state; float x10_ = 0.f; // some timer - float x14_; // height? + float x14_yOffset; float x18_; float x1c_ = 0.f; float x20_; public: constexpr CBoid(const zeus::CVector3f& pos, float f1, float f2, float f3) - : x0_pos(pos), xc_state(EBoidState::Raising), x14_(f1), x18_(f2), x20_(f3) {} + : x0_pos(pos), xc_state(EBoidState::Raising), x14_yOffset(f1), x18_(f2), x20_(f3) {} constexpr const zeus::CVector3f& GetPosition() const { return x0_pos; } constexpr EBoidState GetState() const { return xc_state; } constexpr float Get_x10() const { return x10_; } - constexpr float Get_x14() const { return x14_; } + constexpr float GetYOffset() const { return x14_yOffset; } constexpr float Get_x18() const { return x18_; } constexpr float Get_x20() const { return x20_; } - void SetState(EBoidState v) { xc_state = v; fmt::print(fmt("Setting boid state {}"), v); } + constexpr void SetState(EBoidState v) { xc_state = v; } constexpr void Set_x10(float v) { x10_ = v; } - constexpr void Set_x14(float v) { x14_ = v; } + constexpr void SetYOffset(float v) { x14_yOffset = v; } constexpr void Set_x18(float v) { x18_ = v; } };