mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-09 21:47:57 +00:00
Add CExplosion
This commit is contained in:
156
src/MetroidPrime/CExplosion.cpp
Normal file
156
src/MetroidPrime/CExplosion.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "MetroidPrime/CExplosion.hpp"
|
||||
|
||||
#include "MetroidPrime/CGameLight.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
#include "MetroidPrime/Player/CPlayerState.hpp"
|
||||
|
||||
#include "Kyoto/Graphics/CCubeModel.hpp"
|
||||
#include "Kyoto/Graphics/CGraphics.hpp"
|
||||
#include "Kyoto/Math/CFrustumPlanes.hpp"
|
||||
#include "Kyoto/Particles/CElementGen.hpp"
|
||||
#include "Kyoto/Particles/CGenDescription.hpp"
|
||||
#include "Kyoto/Particles/CParticleElectric.hpp"
|
||||
#include "MetaRender/CCubeRenderer.hpp"
|
||||
|
||||
CExplosion::CExplosion(const TLockedToken< CGenDescription >& particle, TUniqueId uid, bool active,
|
||||
const CEntityInfo& info, const rstl::string& name, const CTransform4f& xf,
|
||||
uint flags, const CVector3f& scale, const CColor& color)
|
||||
: CEffect(uid, info, active, name, xf)
|
||||
, xe8_particleGen(new CElementGen(TToken< CGenDescription >(particle), CElementGen::kMOT_Normal,
|
||||
flags & 0x2 ? CElementGen::kOSF_Two : CElementGen::kOSF_One))
|
||||
, xec_explosionLight(kInvalidUniqueId)
|
||||
, xf0_sourceId(CToken(particle).GetTag().id)
|
||||
, xf4_24_renderThermalHot(flags & 0x4)
|
||||
, xf4_25_(true)
|
||||
, xf4_26_renderXray(flags & 0x8)
|
||||
, xf8_time(0.0f) {
|
||||
SetThermalFlags(flags & 0x1 ? kTF_Cold : kTF_Hot);
|
||||
xe8_particleGen->SetGlobalTranslation(xf.GetTranslation());
|
||||
xe8_particleGen->SetOrientation(xf.GetRotation());
|
||||
xe8_particleGen->SetGlobalScale(scale);
|
||||
xe8_particleGen->SetModulationColor(color);
|
||||
}
|
||||
|
||||
CExplosion::CExplosion(const TLockedToken< CElectricDescription >& electric, TUniqueId uid,
|
||||
bool active, const CEntityInfo& info, const rstl::string& name,
|
||||
const CTransform4f& xf, uint flags, const CVector3f& scale,
|
||||
const CColor& color)
|
||||
: CEffect(uid, info, active, name, xf)
|
||||
, xe8_particleGen(new CParticleElectric(electric))
|
||||
, xec_explosionLight(kInvalidUniqueId)
|
||||
, xf0_sourceId(CToken(electric).GetTag().id)
|
||||
, xf4_24_renderThermalHot(flags & 0x4)
|
||||
, xf4_25_(true)
|
||||
, xf4_26_renderXray(flags & 0x8)
|
||||
// , xf8_time(0.0f)
|
||||
{
|
||||
SetThermalFlags(flags & 0x1 ? kTF_Cold : kTF_Hot);
|
||||
xe8_particleGen->SetGlobalTranslation(xf.GetTranslation());
|
||||
xe8_particleGen->SetOrientation(xf.GetRotation());
|
||||
xe8_particleGen->SetGlobalScale(scale);
|
||||
xe8_particleGen->SetModulationColor(color);
|
||||
}
|
||||
|
||||
CExplosion::~CExplosion() {}
|
||||
|
||||
void CExplosion::AddToRenderer(const CFrustumPlanes& frustum, const CStateManager& mgr) const {
|
||||
if (GetPreRenderClipped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((xf4_24_renderThermalHot && mgr.GetThermalDrawFlag() == kTD_Hot) ||
|
||||
(xf4_26_renderXray && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::kPV_XRay)) {
|
||||
EnsureRendered(mgr);
|
||||
} else {
|
||||
gpRender->AddParticleGen(*xe8_particleGen);
|
||||
}
|
||||
}
|
||||
|
||||
void CExplosion::PreRender(CStateManager& mgr, const CFrustumPlanes& frustum) {
|
||||
CActor::PreRender(mgr, frustum);
|
||||
SetPreRenderClipped(!xf4_25_ || !frustum.BoxInFrustumPlanes(GetRenderBoundsCached()));
|
||||
}
|
||||
|
||||
void CExplosion::Think(float dt, CStateManager& mgr) {
|
||||
if (GetTransformDirtySpare()) {
|
||||
xe8_particleGen->SetGlobalTranslation(GetTranslation());
|
||||
xe8_particleGen->SetOrientation(GetTransform().GetRotation());
|
||||
SetTransformDirtySpare(false);
|
||||
}
|
||||
xe8_particleGen->Update(dt);
|
||||
|
||||
if (xec_explosionLight != kInvalidUniqueId) {
|
||||
CGameLight* light = TCastToPtr< CGameLight >(mgr.ObjectById(xec_explosionLight));
|
||||
if (light && GetActive())
|
||||
light->SetLight(xe8_particleGen->GetLight());
|
||||
}
|
||||
|
||||
xf8_time += dt;
|
||||
|
||||
if (xf8_time > 15.f) {
|
||||
mgr.FreeScriptObject(GetUniqueId());
|
||||
} else if (xe8_particleGen->IsSystemDeletable()) {
|
||||
mgr.FreeScriptObject(GetUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
void CExplosion::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|
||||
|
||||
void CExplosion::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) {
|
||||
switch (msg) {
|
||||
case kSM_Registered:
|
||||
if (xe8_particleGen->SystemHasLight()) {
|
||||
xec_explosionLight = mgr.AllocateUniqueId();
|
||||
uint sourceId = xf0_sourceId;
|
||||
mgr.AddObject(new CGameLight(xec_explosionLight, GetCurrentAreaId(), GetActive(),
|
||||
rstl::string_l("ExplodePLight_") + GetDebugName(),
|
||||
GetTransform(), GetUniqueId(), xe8_particleGen->GetLight(),
|
||||
sourceId, 1, 0.f));
|
||||
}
|
||||
break;
|
||||
case kSM_Deleted:
|
||||
if (xec_explosionLight != kInvalidUniqueId) {
|
||||
mgr.FreeScriptObject(xec_explosionLight);
|
||||
xec_explosionLight = kInvalidUniqueId;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CActor::AcceptScriptMsg(msg, sender, mgr);
|
||||
|
||||
if (xec_explosionLight != kInvalidUniqueId)
|
||||
mgr.SendScriptMsgAlways(sender, xec_explosionLight, msg);
|
||||
}
|
||||
|
||||
void CExplosion::CalculateRenderBounds() {
|
||||
rstl::optional_object< CAABox > bounds = xe8_particleGen->GetBounds();
|
||||
if (bounds) {
|
||||
SetRenderBounds(*bounds);
|
||||
xf4_25_ = true;
|
||||
} else {
|
||||
xf4_25_ = false;
|
||||
CVector3f pos = GetTransform().GetTranslation();
|
||||
SetRenderBounds(CAABox(pos, pos));
|
||||
}
|
||||
}
|
||||
|
||||
void CExplosion::Render(const CStateManager& mgr) const {
|
||||
if (mgr.GetThermalDrawFlag() == kTD_Hot && xf4_24_renderThermalHot) {
|
||||
CElementGen::SetSubtractBlend(true);
|
||||
CCubeModel::SetRenderModelBlack(true);
|
||||
xe8_particleGen->Render();
|
||||
CCubeModel::SetRenderModelBlack(false);
|
||||
CElementGen::SetSubtractBlend(false);
|
||||
return;
|
||||
}
|
||||
|
||||
CElementGen::SetSubtractBlend(!xf4_24_renderThermalHot);
|
||||
CGraphics::SetFog(kRFM_PerspLin, 0.f, 75.f, CColor::Black());
|
||||
xe8_particleGen->Render();
|
||||
mgr.SetupFogForArea(GetCurrentAreaId());
|
||||
CElementGen::SetSubtractBlend(false);
|
||||
}
|
||||
|
||||
// bool CExplosion::CanRenderUnsorted(const CStateManager&) const { return false; }
|
||||
@@ -125,6 +125,6 @@ bool CParticleGenInfoGeneric::HasActiveParticles() const {
|
||||
return x84_system->GetParticleCount() > 0;
|
||||
}
|
||||
|
||||
CAABox CParticleGenInfoGeneric::GetBounds() const { return x84_system->GetBounds(); }
|
||||
rstl::optional_object<CAABox> CParticleGenInfoGeneric::GetBounds() const { return x84_system->GetBounds(); }
|
||||
|
||||
bool CParticleGenInfoGeneric::IsSystemDeletable() const { return x84_system->IsSystemDeletable(); }
|
||||
|
||||
@@ -154,10 +154,11 @@ void CScriptPickup::Touch(CActor& act, CStateManager& mgr) {
|
||||
if (x27c_pickupParticleDesc) {
|
||||
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::kPV_Thermal) {
|
||||
mgr.AddObject(new CExplosion(
|
||||
*x27c_pickupParticleDesc, mgr.AllocateUniqueId(), true,
|
||||
TLockedToken< CGenDescription >(*x27c_pickupParticleDesc), mgr.AllocateUniqueId(), true,
|
||||
CEntityInfo(GetCurrentAreaId(), CEntity::NullConnectionList, kInvalidEditorId),
|
||||
rstl::string_l("Explosion - Pickup Effect"), GetTransform(), 0,
|
||||
CVector3f(1.f, 1.f, 1.f), CColor::White()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user