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.

261 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "cbase.h"
  14. #include "clientsideeffects.h"
  15. #include "tier0/vprof.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. bool g_FXCreationAllowed = false;
  19. //-----------------------------------------------------------------------------
  20. // Purpose:
  21. // Input : state -
  22. //-----------------------------------------------------------------------------
  23. void SetFXCreationAllowed( bool state )
  24. {
  25. g_FXCreationAllowed = state;
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Purpose:
  29. // Output : Returns true on success, false on failure.
  30. //-----------------------------------------------------------------------------
  31. bool FXCreationAllowed( void )
  32. {
  33. return g_FXCreationAllowed;
  34. }
  35. // TODO: Sort effects and their children back to front from view positon? At least with buckets or something.
  36. //
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Construct and activate effect
  39. // Input : *name -
  40. //-----------------------------------------------------------------------------
  41. CClientSideEffect::CClientSideEffect( const char *name )
  42. {
  43. m_pszName = name;
  44. Assert( name );
  45. m_bActive = true;
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Purpose: Destroy effect
  49. //-----------------------------------------------------------------------------
  50. CClientSideEffect::~CClientSideEffect( void )
  51. {
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose: Get name of effect
  55. // Output : const char
  56. //-----------------------------------------------------------------------------
  57. const char *CClientSideEffect::GetName( void )
  58. {
  59. return m_pszName;
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Set the name of effect
  63. // Input : const char
  64. //-----------------------------------------------------------------------------
  65. void CClientSideEffect::SetEffectName( const char *pszName )
  66. {
  67. m_pszName = pszName;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Is effect still active?
  71. // Output : Returns true on success, false on failure.
  72. //-----------------------------------------------------------------------------
  73. bool CClientSideEffect::IsActive( void )
  74. {
  75. return m_bActive;
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Purpose: Mark effect for destruction
  79. //-----------------------------------------------------------------------------
  80. void CClientSideEffect::Destroy( void )
  81. {
  82. m_bActive = false;
  83. }
  84. #define MAX_EFFECTS 256
  85. //-----------------------------------------------------------------------------
  86. // Purpose: Implements effects list interface
  87. //-----------------------------------------------------------------------------
  88. class CEffectsList : public IEffectsList
  89. {
  90. public:
  91. CEffectsList( void );
  92. virtual ~CEffectsList( void );
  93. // Add an effect to the effects list
  94. void AddEffect( CClientSideEffect *effect );
  95. // Remove the specified effect
  96. void RemoveEffect( CClientSideEffect *effect );
  97. // Draw/update all effects in the current list
  98. void DrawEffects( double frametime );
  99. // Flush out all effects from the list
  100. void Flush( void );
  101. private:
  102. void RemoveEffect( int effectIndex );
  103. // Current number of effects
  104. int m_nEffects;
  105. // Pointers to current effects
  106. CClientSideEffect *m_rgEffects[ MAX_EFFECTS ];
  107. };
  108. // Implements effects list and exposes interface
  109. static CEffectsList g_EffectsList;
  110. // Public interface
  111. IEffectsList *clienteffects = ( IEffectsList * )&g_EffectsList;
  112. //-----------------------------------------------------------------------------
  113. // Purpose:
  114. //-----------------------------------------------------------------------------
  115. CEffectsList::CEffectsList( void )
  116. {
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose:
  120. //-----------------------------------------------------------------------------
  121. CEffectsList::~CEffectsList( void )
  122. {
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose: Add effect to effects list
  126. // Input : *effect -
  127. //-----------------------------------------------------------------------------
  128. void CEffectsList::AddEffect( CClientSideEffect *effect )
  129. {
  130. #if 0
  131. if ( FXCreationAllowed() == false )
  132. {
  133. //NOTENOTE: If you've hit this, you may not add a client effect where you have attempted to.
  134. // Most often this means that you have added it in an entity's DrawModel function.
  135. // Move this to the ClientThink function instead!
  136. Assert(0);
  137. return;
  138. }
  139. #endif
  140. if ( effect == NULL )
  141. return;
  142. if ( m_nEffects >= MAX_EFFECTS )
  143. {
  144. DevWarning( 1, "No room for effect %s\n", effect->GetName() );
  145. return;
  146. }
  147. m_rgEffects[ m_nEffects++ ] = effect;
  148. }
  149. //-----------------------------------------------------------------------------
  150. void CEffectsList::RemoveEffect( CClientSideEffect *effect )
  151. {
  152. Assert( effect );
  153. CClientSideEffect **end = &m_rgEffects[m_nEffects];
  154. for( CClientSideEffect **p = &m_rgEffects[0]; p < end; ++p)
  155. {
  156. if ( *p == effect )
  157. {
  158. RemoveEffect( p - &m_rgEffects[0] ); // todo remove this crutch
  159. return;
  160. }
  161. }
  162. Assert( false ); // don't know this effect
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Purpose: Remove specified effect by index
  166. // Input : effectIndex -
  167. //-----------------------------------------------------------------------------
  168. void CEffectsList::RemoveEffect( int effectIndex )
  169. {
  170. if ( effectIndex >= m_nEffects || effectIndex < 0 )
  171. return;
  172. CClientSideEffect *pEffect = m_rgEffects[effectIndex];
  173. m_nEffects--;
  174. if ( m_nEffects > 0 && effectIndex != m_nEffects )
  175. {
  176. // move the last one down to fill the empty slot
  177. m_rgEffects[effectIndex] = m_rgEffects[m_nEffects];
  178. }
  179. pEffect->Destroy();
  180. delete pEffect; //FIXME: Yes, no?
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose: Iterate through list and simulate/draw stuff
  184. // Input : frametime -
  185. //-----------------------------------------------------------------------------
  186. void CEffectsList::DrawEffects( double frametime )
  187. {
  188. VPROF_BUDGET( "CEffectsList::DrawEffects", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  189. int i;
  190. CClientSideEffect *effect;
  191. // Go backwards so deleting effects doesn't screw up
  192. for ( i = m_nEffects - 1 ; i >= 0; i-- )
  193. {
  194. effect = m_rgEffects[ i ];
  195. if ( !effect )
  196. continue;
  197. // Simulate
  198. effect->Draw( frametime );
  199. // Remove it if needed
  200. if ( !effect->IsActive() )
  201. {
  202. RemoveEffect( i );
  203. }
  204. }
  205. }
  206. //==================================================
  207. // Purpose:
  208. // Input:
  209. //==================================================
  210. void CEffectsList::Flush( void )
  211. {
  212. int i;
  213. CClientSideEffect *effect;
  214. // Go backwards so deleting effects doesn't screw up
  215. for ( i = m_nEffects - 1 ; i >= 0; i-- )
  216. {
  217. effect = m_rgEffects[ i ];
  218. if ( effect == NULL )
  219. continue;
  220. RemoveEffect( i );
  221. }
  222. }