diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/c_movie_explosion.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/c_movie_explosion.cpp')
| -rw-r--r-- | game/client/c_movie_explosion.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/game/client/c_movie_explosion.cpp b/game/client/c_movie_explosion.cpp new file mode 100644 index 0000000..b548839 --- /dev/null +++ b/game/client/c_movie_explosion.cpp @@ -0,0 +1,218 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "particle_prototype.h" +#include "particle_util.h" +#include "baseparticleentity.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// ------------------------------------------------------------------------- // +// Definitions +// ------------------------------------------------------------------------- // +#define NUM_MOVIEEXPLOSION_EMITTERS 50 +#define EXPLOSION_EMITTER_LIFETIME 3 +#define EMITTED_PARTICLE_LIFETIME 1 + + +// ------------------------------------------------------------------------- // +// Classes +// ------------------------------------------------------------------------- // +class MovieExplosionEmitter +{ +public: + Vector m_Pos; + Vector m_Velocity; + float m_Lifetime; + TimedEvent m_ParticleSpawn; +}; + + +class C_MovieExplosion : public C_BaseParticleEntity, public IPrototypeAppEffect +{ +public: + DECLARE_CLASS( C_MovieExplosion, C_BaseParticleEntity ); + DECLARE_CLIENTCLASS(); + + C_MovieExplosion(); + ~C_MovieExplosion(); + +// C_BaseEntity. +public: + virtual void OnDataChanged(DataUpdateType_t updateType); + +// IPrototypeAppEffect. +public: + virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs); + +// IParticleEffect. +public: + virtual void Update(float fTimeDelta); + virtual void RenderParticles( CParticleRenderIterator *pIterator ); + virtual void SimulateParticles( CParticleSimulateIterator *pIterator ); + + +public: + MovieExplosionEmitter m_Emitters[NUM_MOVIEEXPLOSION_EMITTERS]; + float m_EmitterLifetime; + + CParticleMgr *m_pParticleMgr; + PMaterialHandle m_iFireballMaterial; + + // Setup for temporary usage in SimulateAndRender. + float m_EmitterAlpha; + +private: + C_MovieExplosion( const C_MovieExplosion & ); + +}; + +// Expose to the particle app. +EXPOSE_PROTOTYPE_EFFECT(MovieExplosion, C_MovieExplosion); + +IMPLEMENT_CLIENTCLASS_DT(C_MovieExplosion, DT_MovieExplosion, MovieExplosion) +END_RECV_TABLE() + + + +// ------------------------------------------------------------------------- // +// C_MovieExplosion +// ------------------------------------------------------------------------- // +C_MovieExplosion::C_MovieExplosion() +{ + m_pParticleMgr = NULL; +} + + +C_MovieExplosion::~C_MovieExplosion() +{ + if(m_pParticleMgr) + m_pParticleMgr->RemoveEffect( &m_ParticleEffect ); +} + + +void C_MovieExplosion::OnDataChanged(DataUpdateType_t updateType) +{ + C_BaseEntity::OnDataChanged(updateType); + + if(updateType == DATA_UPDATE_CREATED) + { + Start( ParticleMgr(), NULL ); + } +} + + +void C_MovieExplosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs) +{ + if(!pParticleMgr->AddEffect(&m_ParticleEffect, this)) + return; + + // Setup our emitters. + for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++) + { + MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter]; + pEmitter->m_Velocity = RandomVector(-1, 1) * 200; + + pEmitter->m_Pos = GetAbsOrigin(); + + pEmitter->m_Lifetime = 0; + pEmitter->m_ParticleSpawn.Init(15); + } + m_EmitterLifetime = 0; + + // Get our materials. + m_iFireballMaterial = m_ParticleEffect.FindOrAddMaterial("particle/particle_sphere"); + + m_pParticleMgr = pParticleMgr; +} + + +void C_MovieExplosion::Update(float fTimeDelta) +{ + if(!m_pParticleMgr) + return; + + m_EmitterLifetime += fTimeDelta; + if(m_EmitterLifetime > EXPLOSION_EMITTER_LIFETIME) + return; + + m_EmitterAlpha = (float)sin(m_EmitterLifetime * 3.14159f / EXPLOSION_EMITTER_LIFETIME); + + // Simulate the emitters and have them spit out particles. + for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++) + { + MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter]; + + pEmitter->m_Pos = pEmitter->m_Pos + pEmitter->m_Velocity * fTimeDelta; + pEmitter->m_Velocity = pEmitter->m_Velocity * 0.9; + + float tempDelta = fTimeDelta; + while(pEmitter->m_ParticleSpawn.NextEvent(tempDelta)) + { + StandardParticle_t *pParticle = + (StandardParticle_t*)m_ParticleEffect.AddParticle( sizeof(StandardParticle_t), m_iFireballMaterial); + + if(pParticle) + { + pParticle->m_Pos = pEmitter->m_Pos; + pParticle->m_Velocity = pEmitter->m_Velocity * 0.2f + RandomVector(-20, 20); + } + } + } +} + + +void C_MovieExplosion::RenderParticles( CParticleRenderIterator *pIterator ) +{ + const StandardParticle_t *pParticle = (const StandardParticle_t*)pIterator->GetFirst(); + while ( pParticle ) + { + // Draw. + Vector tPos; + TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos); + float sortKey = tPos.z; + + float lifetimePercent = pParticle->m_Lifetime / EMITTED_PARTICLE_LIFETIME; + Vector color; + color.x = sin(lifetimePercent * 3.14159); + color.y = color.x * 0.5f; + color.z = 0; + RenderParticle_ColorSize( + pIterator->GetParticleDraw(), + tPos, + color, + m_EmitterAlpha * sin(3.14159 * lifetimePercent), + 10); + + pParticle = (const StandardParticle_t*)pIterator->GetNext( sortKey ); + } +} + +void C_MovieExplosion::SimulateParticles( CParticleSimulateIterator *pIterator ) +{ + StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst(); + while ( pParticle ) + { + // Update its lifetime. + pParticle->m_Lifetime += pIterator->GetTimeDelta(); + if(pParticle->m_Lifetime > 1) + { + pIterator->RemoveParticle( pParticle ); + } + else + { + // Move it (this comes after rendering to make it clear that moving the particle here won't change + // its rendering for this frame since m_TransformedPos has already been set). + pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * pIterator->GetTimeDelta(); + } + + pParticle = (StandardParticle_t*)pIterator->GetNext(); + } +} + |