Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.6 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "particle_prototype.h"
  9. #include "particle_util.h"
  10. #include "baseparticleentity.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. // ------------------------------------------------------------------------- //
  14. // Definitions
  15. // ------------------------------------------------------------------------- //
  16. #define NUM_MOVIEEXPLOSION_EMITTERS 50
  17. #define EXPLOSION_EMITTER_LIFETIME 3
  18. #define EMITTED_PARTICLE_LIFETIME 1
  19. // ------------------------------------------------------------------------- //
  20. // Classes
  21. // ------------------------------------------------------------------------- //
  22. class MovieExplosionEmitter
  23. {
  24. public:
  25. Vector m_Pos;
  26. Vector m_Velocity;
  27. float m_Lifetime;
  28. TimedEvent m_ParticleSpawn;
  29. };
  30. class C_MovieExplosion : public C_BaseParticleEntity, public IPrototypeAppEffect
  31. {
  32. public:
  33. DECLARE_CLASS( C_MovieExplosion, C_BaseParticleEntity );
  34. DECLARE_CLIENTCLASS();
  35. C_MovieExplosion();
  36. ~C_MovieExplosion();
  37. // C_BaseEntity.
  38. public:
  39. virtual void OnDataChanged(DataUpdateType_t updateType);
  40. // IPrototypeAppEffect.
  41. public:
  42. virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
  43. // IParticleEffect.
  44. public:
  45. virtual void Update(float fTimeDelta);
  46. virtual void RenderParticles( CParticleRenderIterator *pIterator );
  47. virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
  48. public:
  49. MovieExplosionEmitter m_Emitters[NUM_MOVIEEXPLOSION_EMITTERS];
  50. float m_EmitterLifetime;
  51. CParticleMgr *m_pParticleMgr;
  52. PMaterialHandle m_iFireballMaterial;
  53. // Setup for temporary usage in SimulateAndRender.
  54. float m_EmitterAlpha;
  55. private:
  56. C_MovieExplosion( const C_MovieExplosion & );
  57. };
  58. // Expose to the particle app.
  59. EXPOSE_PROTOTYPE_EFFECT(MovieExplosion, C_MovieExplosion);
  60. IMPLEMENT_CLIENTCLASS_DT(C_MovieExplosion, DT_MovieExplosion, MovieExplosion)
  61. END_RECV_TABLE()
  62. // ------------------------------------------------------------------------- //
  63. // C_MovieExplosion
  64. // ------------------------------------------------------------------------- //
  65. C_MovieExplosion::C_MovieExplosion()
  66. {
  67. m_pParticleMgr = NULL;
  68. }
  69. C_MovieExplosion::~C_MovieExplosion()
  70. {
  71. if(m_pParticleMgr)
  72. m_pParticleMgr->RemoveEffect( &m_ParticleEffect );
  73. }
  74. void C_MovieExplosion::OnDataChanged(DataUpdateType_t updateType)
  75. {
  76. C_BaseEntity::OnDataChanged(updateType);
  77. if(updateType == DATA_UPDATE_CREATED)
  78. {
  79. Start( ParticleMgr(), NULL );
  80. }
  81. }
  82. void C_MovieExplosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
  83. {
  84. if(!pParticleMgr->AddEffect(&m_ParticleEffect, this))
  85. return;
  86. // Setup our emitters.
  87. for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++)
  88. {
  89. MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter];
  90. pEmitter->m_Velocity = RandomVector(-1, 1) * 200;
  91. pEmitter->m_Pos = GetAbsOrigin();
  92. pEmitter->m_Lifetime = 0;
  93. pEmitter->m_ParticleSpawn.Init(15);
  94. }
  95. m_EmitterLifetime = 0;
  96. // Get our materials.
  97. m_iFireballMaterial = m_ParticleEffect.FindOrAddMaterial("particle/particle_sphere");
  98. m_pParticleMgr = pParticleMgr;
  99. }
  100. void C_MovieExplosion::Update(float fTimeDelta)
  101. {
  102. if(!m_pParticleMgr)
  103. return;
  104. m_EmitterLifetime += fTimeDelta;
  105. if(m_EmitterLifetime > EXPLOSION_EMITTER_LIFETIME)
  106. return;
  107. m_EmitterAlpha = (float)sin(m_EmitterLifetime * 3.14159f / EXPLOSION_EMITTER_LIFETIME);
  108. // Simulate the emitters and have them spit out particles.
  109. for(int iEmitter=0; iEmitter < NUM_MOVIEEXPLOSION_EMITTERS; iEmitter++)
  110. {
  111. MovieExplosionEmitter *pEmitter = &m_Emitters[iEmitter];
  112. pEmitter->m_Pos = pEmitter->m_Pos + pEmitter->m_Velocity * fTimeDelta;
  113. pEmitter->m_Velocity = pEmitter->m_Velocity * 0.9;
  114. float tempDelta = fTimeDelta;
  115. while(pEmitter->m_ParticleSpawn.NextEvent(tempDelta))
  116. {
  117. StandardParticle_t *pParticle =
  118. (StandardParticle_t*)m_ParticleEffect.AddParticle( sizeof(StandardParticle_t), m_iFireballMaterial);
  119. if(pParticle)
  120. {
  121. pParticle->m_Pos = pEmitter->m_Pos;
  122. pParticle->m_Velocity = pEmitter->m_Velocity * 0.2f + RandomVector(-20, 20);
  123. }
  124. }
  125. }
  126. }
  127. void C_MovieExplosion::RenderParticles( CParticleRenderIterator *pIterator )
  128. {
  129. const StandardParticle_t *pParticle = (const StandardParticle_t*)pIterator->GetFirst();
  130. while ( pParticle )
  131. {
  132. // Draw.
  133. Vector tPos;
  134. TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
  135. float sortKey = tPos.z;
  136. float lifetimePercent = pParticle->m_Lifetime / EMITTED_PARTICLE_LIFETIME;
  137. Vector color;
  138. color.x = sin(lifetimePercent * 3.14159);
  139. color.y = color.x * 0.5f;
  140. color.z = 0;
  141. RenderParticle_ColorSize(
  142. pIterator->GetParticleDraw(),
  143. tPos,
  144. color,
  145. m_EmitterAlpha * sin(3.14159 * lifetimePercent),
  146. 10);
  147. pParticle = (const StandardParticle_t*)pIterator->GetNext( sortKey );
  148. }
  149. }
  150. void C_MovieExplosion::SimulateParticles( CParticleSimulateIterator *pIterator )
  151. {
  152. StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst();
  153. while ( pParticle )
  154. {
  155. // Update its lifetime.
  156. pParticle->m_Lifetime += pIterator->GetTimeDelta();
  157. if(pParticle->m_Lifetime > 1)
  158. {
  159. pIterator->RemoveParticle( pParticle );
  160. }
  161. else
  162. {
  163. // Move it (this comes after rendering to make it clear that moving the particle here won't change
  164. // its rendering for this frame since m_TransformedPos has already been set).
  165. pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * pIterator->GetTimeDelta();
  166. }
  167. pParticle = (StandardParticle_t*)pIterator->GetNext();
  168. }
  169. }