Team Fortress 2 Source Code as on 22/4/2020
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.

301 lines
8.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "c_grenadetrail.h"
  10. #include "fx.h"
  11. //#include "engine/ivdebugoverlay.h"
  12. //#include "engine/IEngineSound.h"
  13. //#include "c_te_effect_dispatch.h"
  14. //#include "glow_overlay.h"
  15. //#include "fx_explosion.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. class CSmokeParticle : public CSimpleEmitter
  19. {
  20. public:
  21. CSmokeParticle( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
  22. //Create
  23. static CSmokeParticle *Create( const char *pDebugName )
  24. {
  25. return new CSmokeParticle( pDebugName );
  26. }
  27. //Alpha
  28. virtual float UpdateAlpha( const SimpleParticle *pParticle )
  29. {
  30. return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
  31. }
  32. //Color
  33. virtual Vector UpdateColor( const SimpleParticle *pParticle )
  34. {
  35. Vector color;
  36. float tLifetime = pParticle->m_flLifetime / pParticle->m_flDieTime;
  37. float ramp = 1.0f - tLifetime;
  38. Vector endcolor(75, 75, 75);
  39. color[0] = ( (float) pParticle->m_uchColor[0] * ramp ) / 255.0f + ( 1-ramp) * endcolor[0];
  40. color[1] = ( (float) pParticle->m_uchColor[1] * ramp ) / 255.0f + ( 1-ramp) * endcolor[1];
  41. color[2] = ( (float) pParticle->m_uchColor[2] * ramp ) / 255.0f + ( 1-ramp) * endcolor[2];
  42. return color;
  43. }
  44. //Roll
  45. virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
  46. {
  47. pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
  48. pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -8.0f );
  49. //Cap the minimum roll
  50. if ( fabs( pParticle->m_flRollDelta ) < 0.5f )
  51. {
  52. pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f;
  53. }
  54. return pParticle->m_flRoll;
  55. }
  56. private:
  57. CSmokeParticle( const CSmokeParticle & );
  58. };
  59. // Datatable.. this can have all the smoketrail parameters when we need it to.
  60. IMPLEMENT_CLIENTCLASS_DT(C_GrenadeTrail, DT_GrenadeTrail, CGrenadeTrail)
  61. RecvPropFloat(RECVINFO(m_SpawnRate)),
  62. RecvPropFloat(RECVINFO(m_ParticleLifetime)),
  63. RecvPropFloat(RECVINFO(m_StopEmitTime)),
  64. RecvPropInt(RECVINFO(m_bEmit)),
  65. RecvPropInt(RECVINFO(m_nAttachment)),
  66. END_RECV_TABLE()
  67. // ------------------------------------------------------------------------- //
  68. // ParticleMovieExplosion
  69. // ------------------------------------------------------------------------- //
  70. C_GrenadeTrail::C_GrenadeTrail()
  71. {
  72. m_MaterialHandle[0] = NULL;
  73. m_MaterialHandle[1] = NULL;
  74. // things that we will change
  75. m_SpawnRate = 10;
  76. m_ParticleLifetime = 5;
  77. m_bEmit = true;
  78. m_nAttachment = -1;
  79. m_StopEmitTime = 0; // No end time
  80. // invariants
  81. m_ParticleSpawn.Init(10);
  82. m_StartColor.Init(0.65, 0.65, 0.65);
  83. m_MinSpeed = 2;
  84. m_MaxSpeed = 6;
  85. m_MinDirectedSpeed = m_MaxDirectedSpeed = 0;
  86. m_StartSize = 2;
  87. m_EndSize = 6;
  88. m_SpawnRadius = 2;
  89. m_VelocityOffset.Init();
  90. m_Opacity = 0.3f;
  91. m_pSmokeEmitter = NULL;
  92. m_pParticleMgr = NULL;
  93. }
  94. C_GrenadeTrail::~C_GrenadeTrail()
  95. {
  96. if ( m_pParticleMgr )
  97. {
  98. m_pParticleMgr->RemoveEffect( &m_ParticleEffect );
  99. }
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose:
  103. //-----------------------------------------------------------------------------
  104. void C_GrenadeTrail::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles )
  105. {
  106. C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity();
  107. if (pEnt && (m_nAttachment > 0))
  108. {
  109. pEnt->GetAttachment( m_nAttachment, *pAbsOrigin, *pAbsAngles );
  110. }
  111. else
  112. {
  113. BaseClass::GetAimEntOrigin( pAttachedTo, pAbsOrigin, pAbsAngles );
  114. }
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. // Input : bEmit -
  119. //-----------------------------------------------------------------------------
  120. void C_GrenadeTrail::SetEmit(bool bEmit)
  121. {
  122. m_bEmit = bEmit;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. // Input : rate -
  127. //-----------------------------------------------------------------------------
  128. void C_GrenadeTrail::SetSpawnRate(float rate)
  129. {
  130. m_SpawnRate = rate;
  131. m_ParticleSpawn.Init(rate);
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose:
  135. // Input : bnewentity -
  136. //-----------------------------------------------------------------------------
  137. void C_GrenadeTrail::OnDataChanged(DataUpdateType_t updateType)
  138. {
  139. C_BaseEntity::OnDataChanged(updateType);
  140. if ( updateType == DATA_UPDATE_CREATED )
  141. {
  142. Start( ParticleMgr(), NULL );
  143. }
  144. }
  145. //-----------------------------------------------------------------------------
  146. // Purpose:
  147. // Input : *pParticleMgr -
  148. // *pArgs -
  149. //-----------------------------------------------------------------------------
  150. void C_GrenadeTrail::Start( CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs )
  151. {
  152. if(!pParticleMgr->AddEffect( &m_ParticleEffect, this ))
  153. return;
  154. m_pParticleMgr = pParticleMgr;
  155. m_pSmokeEmitter = CSmokeParticle::Create("smokeTrail");
  156. if ( !m_pSmokeEmitter )
  157. {
  158. Assert( false );
  159. return;
  160. }
  161. m_pSmokeEmitter->SetSortOrigin( GetAbsOrigin() );
  162. m_pSmokeEmitter->SetNearClip( 64.0f, 128.0f );
  163. m_MaterialHandle[0] = g_Mat_DustPuff[0];
  164. m_MaterialHandle[1] = g_Mat_DustPuff[1];
  165. m_ParticleSpawn.Init( m_SpawnRate );
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose:
  169. // Input : fTimeDelta -
  170. //-----------------------------------------------------------------------------
  171. void C_GrenadeTrail::Update( float fTimeDelta )
  172. {
  173. if ( !m_pSmokeEmitter )
  174. return;
  175. // Grenades thrown out of the PVS should not draw particles at the world origin
  176. if ( IsDormant() )
  177. return;
  178. Vector offsetColor;
  179. // Add new particles
  180. if ( !m_bEmit )
  181. return;
  182. if ( ( m_StopEmitTime != 0 ) && ( m_StopEmitTime <= gpGlobals->curtime ) )
  183. return;
  184. float tempDelta = fTimeDelta;
  185. SimpleParticle *pParticle;
  186. Vector offset;
  187. Vector vecOrigin;
  188. VectorMA( GetAbsOrigin(), -fTimeDelta, GetAbsVelocity(), vecOrigin );
  189. Vector vecForward;
  190. GetVectors( &vecForward, NULL, NULL );
  191. while( m_ParticleSpawn.NextEvent( tempDelta ) )
  192. {
  193. float fldt = fTimeDelta - tempDelta;
  194. offset.Random( -m_SpawnRadius, m_SpawnRadius );
  195. offset += vecOrigin;
  196. VectorMA( offset, fldt, GetAbsVelocity(), offset );
  197. pParticle = (SimpleParticle *) m_pSmokeEmitter->AddParticle( sizeof( SimpleParticle ), m_MaterialHandle[random->RandomInt(0,1)], offset );
  198. if ( pParticle == NULL )
  199. continue;
  200. pParticle->m_flLifetime = 0.0f;
  201. pParticle->m_flDieTime = m_ParticleLifetime;
  202. pParticle->m_iFlags = 0; // no wind!
  203. pParticle->m_vecVelocity.Random( -1.0f, 1.0f );
  204. pParticle->m_vecVelocity *= random->RandomFloat( m_MinSpeed, m_MaxSpeed );
  205. float flDirectedVel = random->RandomFloat( m_MinDirectedSpeed, m_MaxDirectedSpeed );
  206. VectorMA( pParticle->m_vecVelocity, flDirectedVel, vecForward, pParticle->m_vecVelocity );
  207. pParticle->m_vecVelocity[2] += 15;
  208. offsetColor = m_StartColor;
  209. float flMaxVal = MAX( m_StartColor[0], m_StartColor[1] );
  210. if ( flMaxVal < m_StartColor[2] )
  211. {
  212. flMaxVal = m_StartColor[2];
  213. }
  214. offsetColor /= flMaxVal;
  215. offsetColor *= random->RandomFloat( -0.2f, 0.2f );
  216. offsetColor += m_StartColor;
  217. offsetColor[0] = clamp( offsetColor[0], 0.0f, 1.0f );
  218. offsetColor[1] = clamp( offsetColor[1], 0.0f, 1.0f );
  219. offsetColor[2] = clamp( offsetColor[2], 0.0f, 1.0f );
  220. pParticle->m_uchColor[0] = offsetColor[0]*255.0f;
  221. pParticle->m_uchColor[1] = offsetColor[1]*255.0f;
  222. pParticle->m_uchColor[2] = offsetColor[2]*255.0f;
  223. pParticle->m_uchStartSize = m_StartSize;
  224. pParticle->m_uchEndSize = m_EndSize;
  225. float alpha = random->RandomFloat( m_Opacity*0.75f, m_Opacity*1.25f );
  226. alpha = clamp( alpha, 0.0f, 1.0f );
  227. pParticle->m_uchStartAlpha = alpha * 255;
  228. pParticle->m_uchEndAlpha = 0;
  229. pParticle->m_flRoll = random->RandomInt( 0, 360 );
  230. pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
  231. }
  232. }
  233. void C_GrenadeTrail::RenderParticles( CParticleRenderIterator *pIterator )
  234. {
  235. }
  236. void C_GrenadeTrail::SimulateParticles( CParticleSimulateIterator *pIterator )
  237. {
  238. }