metaforce/Runtime/World/CExplosion.cpp

122 lines
4.7 KiB
C++
Raw Normal View History

#include "Runtime/World/CExplosion.hpp"
#include "Runtime/CStateManager.hpp"
#include "Runtime/GameGlobalObjects.hpp"
#include "Runtime/Graphics/CCubeRenderer.hpp"
#include "Runtime/World/CGameLight.hpp"
#include "TCastTo.hpp" // Generated file, do not modify include path
2017-04-13 19:28:31 +00:00
2021-04-10 08:42:06 +00:00
namespace metaforce {
2017-04-13 19:28:31 +00:00
CExplosion::CExplosion(const TLockedToken<CGenDescription>& particle, TUniqueId uid, bool active,
2018-12-08 05:30:43 +00:00
const CEntityInfo& info, std::string_view name, const zeus::CTransform& xf, u32 flags,
const zeus::CVector3f& scale, const zeus::CColor& color)
: CEffect(uid, info, active, name, xf) {
xe8_particleGen = std::make_unique<CElementGen>(particle, CElementGen::EModelOrientationType::Normal,
flags & 0x2 ? CElementGen::EOptionalSystemFlags::Two
: CElementGen::EOptionalSystemFlags::One);
xf0_particleDesc = particle.GetObj();
xf4_24_renderThermalHot = flags & 0x4;
xf4_26_renderXray = flags & 0x8;
xe6_27_thermalVisorFlags = flags & 0x1 ? 1 : 2;
xe8_particleGen->SetGlobalTranslation(xf.origin);
xe8_particleGen->SetOrientation(xf.getRotation());
xe8_particleGen->SetGlobalScale(scale);
xe8_particleGen->SetModulationColor(color);
2018-11-06 06:16:12 +00:00
}
CExplosion::CExplosion(const TLockedToken<CElectricDescription>& electric, TUniqueId uid, bool active,
2018-12-08 05:30:43 +00:00
const CEntityInfo& info, std::string_view name, const zeus::CTransform& xf, u32 flags,
const zeus::CVector3f& scale, const zeus::CColor& color)
: CEffect(uid, info, active, name, xf) {
xe8_particleGen = std::make_unique<CParticleElectric>(electric);
xf0_electricDesc = electric.GetObj();
xf4_24_renderThermalHot = flags & 0x4;
xf4_26_renderXray = flags & 0x8;
xe6_27_thermalVisorFlags = flags & 0x1 ? 1 : 2;
xe8_particleGen->SetGlobalTranslation(xf.origin);
xe8_particleGen->SetOrientation(xf.getRotation());
xe8_particleGen->SetGlobalScale(scale);
xe8_particleGen->SetModulationColor(color);
2017-04-13 19:28:31 +00:00
}
2018-12-08 05:30:43 +00:00
void CExplosion::Accept(IVisitor& visitor) { visitor.Visit(this); }
2018-12-08 05:30:43 +00:00
void CExplosion::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) {
if (msg == EScriptObjectMessage::Deleted) {
if (xec_explosionLight != kInvalidUniqueId)
mgr.FreeScriptObject(xec_explosionLight);
} else if (msg == EScriptObjectMessage::Registered) {
if (xe8_particleGen->SystemHasLight()) {
xec_explosionLight = mgr.AllocateUniqueId();
2022-03-27 00:23:44 +00:00
mgr.AddObject(new CGameLight(xec_explosionLight, GetAreaIdAlways(), GetActive(), "ExplodePLight_" + x10_name,
x34_transform, GetUniqueId(), xe8_particleGen->GetLight(), 1, 0, 0.f));
}
2018-12-08 05:30:43 +00:00
}
2018-12-08 05:30:43 +00:00
CActor::AcceptScriptMsg(msg, sender, mgr);
2018-12-08 05:30:43 +00:00
if (xec_explosionLight != kInvalidUniqueId)
mgr.SendScriptMsgAlways(sender, xec_explosionLight, msg);
}
2018-12-08 05:30:43 +00:00
void CExplosion::Think(float dt, CStateManager& mgr) {
if (xe4_28_transformDirty) {
xe8_particleGen->SetGlobalTranslation(GetTranslation());
2019-03-13 03:46:20 +00:00
xe8_particleGen->SetOrientation(GetTransform().getRotation());
2018-12-08 05:30:43 +00:00
xe4_28_transformDirty = false;
}
xe8_particleGen->Update(dt);
2018-12-08 05:30:43 +00:00
if (xec_explosionLight != kInvalidUniqueId) {
TCastToPtr<CGameLight> light = mgr.ObjectById(xec_explosionLight);
if (light && x30_24_active)
light->SetLight(xe8_particleGen->GetLight());
}
2018-12-08 05:30:43 +00:00
xf8_time += dt;
2018-12-08 05:30:43 +00:00
if (xf8_time > 15.f || xe8_particleGen->IsSystemDeletable())
mgr.FreeScriptObject(GetUniqueId());
}
2018-12-08 05:30:43 +00:00
void CExplosion::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
CActor::PreRender(mgr, frustum);
xe4_30_outOfFrustum = !xf4_25_ || !frustum.aabbFrustumTest(x9c_renderBounds);
}
void CExplosion::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) {
if (xe4_30_outOfFrustum) {
2018-12-08 05:30:43 +00:00
return;
}
2018-12-08 05:30:43 +00:00
if (!(xf4_24_renderThermalHot && mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot) &&
!(xf4_26_renderXray && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)) {
g_Renderer->AddParticleGen(*xe8_particleGen);
2018-12-08 05:30:43 +00:00
return;
}
2018-12-08 05:30:43 +00:00
EnsureRendered(mgr);
}
void CExplosion::Render(CStateManager& mgr) {
2018-12-08 05:30:43 +00:00
if (mgr.GetThermalDrawFlag() == EThermalDrawFlag::Hot && xf4_24_renderThermalHot) {
CElementGen::SetSubtractBlend(true);
CCubeModel::SetRenderModelBlack(true);
xe8_particleGen->Render();
CCubeModel::SetRenderModelBlack(false);
CElementGen::SetSubtractBlend(false);
2018-12-08 05:30:43 +00:00
return;
}
2022-03-27 00:23:44 +00:00
CElementGen::SetSubtractBlend(!xf4_24_renderThermalHot);
CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack);
2018-12-08 05:30:43 +00:00
xe8_particleGen->Render();
mgr.SetupFogForArea(GetAreaIdAlways());
CElementGen::SetSubtractBlend(false);
}
2018-12-08 05:30:43 +00:00
bool CExplosion::CanRenderUnsorted(const CStateManager&) const { return false; }
2021-04-10 08:42:06 +00:00
} // namespace metaforce