#include "CActorModelParticles.hpp" #include "CStateManager.hpp" #include "GameGlobalObjects.hpp" #include "CSimplePool.hpp" #include "CDependencyGroup.hpp" #include "Particle/CElementGen.hpp" #include "Particle/CParticleElectric.hpp" #include "Particle/CParticleSwoosh.hpp" #include "Particle/CGenDescription.hpp" #include "World/CWorld.hpp" #include "Graphics/CBooRenderer.hpp" #include "Graphics/CSkinnedModel.hpp" namespace urde { CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& parent) : x0_id(ent.GetUniqueId()), x4_areaId(ent.GetAreaIdAlways()), xdc_ashy(parent.x48_ashy), x128_parent(parent) { x8_.resize(8); } void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1) { } static const char* ParticleDGRPs[] = { "Effect_OnFire_DGRP", "Effect_Ash_DGRP", "Effect_IceBreak_DGRP", "Effect_FirePop_DGRP", "Effect_IcePop_DGRP", "Effect_Electric_DGRP", }; std::pair, bool> CActorModelParticles::GetParticleDGRPTokens(const char* name) { std::pair, bool> ret = {}; TToken dgrp = g_SimplePool->GetObj(name); const auto& vector = dgrp->GetObjectTagVector(); ret.first.reserve(vector.size()); for (const SObjectTag& tag : vector) ret.first.push_back(g_SimplePool->GetObj(tag)); return ret; } void CActorModelParticles::LoadParticleDGRPs() { for (int i=0 ; i<6 ; ++i) x50_dgrps.push_back(GetParticleDGRPTokens(ParticleDGRPs[i])); } std::unique_ptr CActorModelParticles::MakeOnFireGen() const { return std::make_unique(x18_onFire, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One); } std::unique_ptr CActorModelParticles::MakeAshGen() const { return std::make_unique(x20_ash, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One); } std::unique_ptr CActorModelParticles::MakeIceGen() const { return std::make_unique(x28_iceBreak, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One); } std::unique_ptr CActorModelParticles::MakeFirePopGen() const { return std::make_unique(x30_firePop, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One); } std::unique_ptr CActorModelParticles::MakeIcePopGen() const { return std::make_unique(x38_icePop, CElementGen::EModelOrientationType::Normal, CElementGen::EOptionalSystemFlags::One); } std::unique_ptr CActorModelParticles::MakeElectricGen() const { return std::make_unique(x40_electric); } CActorModelParticles::CActorModelParticles() { x18_onFire = g_SimplePool->GetObj("Effect_OnFire"); x20_ash = g_SimplePool->GetObj("Effect_Ash"); x28_iceBreak = g_SimplePool->GetObj("Effect_IceBreak"); x30_firePop = g_SimplePool->GetObj("Effect_FirePop"); x38_icePop = g_SimplePool->GetObj("Effect_IcePop"); x40_electric = g_SimplePool->GetObj("Effect_Electric"); x48_ashy = g_SimplePool->GetObj("TXTR_Ashy"); LoadParticleDGRPs(); } void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr) { bool isNotOne = mgr.GetParticleFlags() != 1; bool isNotZero = mgr.GetParticleFlags() != 0; for (CItem& item : x0_items) { if (item.x4_areaId != kInvalidAreaId) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(item.x4_areaId); if (!area->IsPostConstructed()) continue; CGameArea::EOcclusionState occState = area->GetPostConstructed()->x10dc_occlusionState; if (occState == CGameArea::EOcclusionState::Occluded) continue; } if (mgr.GetObjectById(item.x0_id) && ((isNotOne && item.x12c_24_) || (isNotZero && item.x12c_25_))) { item.x12c_24_ = false; item.x12c_25_ = false; continue; } if (isNotOne) { for (int i=0 ; i<8 ; ++i) { std::unique_ptr& gen = item.x8_[i].first; if (gen) g_Renderer->AddParticleGen(*gen); } if (mgr.GetParticleFlags() && item.x78_) g_Renderer->AddParticleGen(*item.x78_); if (item.xb8_) g_Renderer->AddParticleGen(*item.xb8_); if (item.xc0_) g_Renderer->AddParticleGen(*item.xc0_); } if (isNotZero) { for (std::unique_ptr& gen : item.x8c_) g_Renderer->AddParticleGen(*gen); if (item.xe4_) g_Renderer->AddParticleGen(*item.xe4_); } if (isNotOne) { item.x12c_24_ = false; item.x12c_25_ = false; } } } void CActorModelParticles::Update(float dt, CStateManager& mgr) { } void CActorModelParticles::PointGenerator(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1) { reinterpret_cast(item)->GeneratePoints(v1, v2, w1); } void CActorModelParticles::SetupHook(TUniqueId uid) { auto search = FindSystem(uid); if (search != x0_items.cend()) CSkinnedModel::SetPointGeneratorFunc((void*)&*search, PointGenerator); } std::list::const_iterator CActorModelParticles::FindSystem(TUniqueId uid) const { for (auto it = x0_items.cbegin() ; it != x0_items.cend() ; ++it) if (it->x0_id == uid) return it; return x0_items.cend(); } }