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.

218 lines
5.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "c_plantedc4.h"
  10. #include "c_te_legacytempents.h"
  11. #include "tempent.h"
  12. #include "engine/IEngineSound.h"
  13. #include "dlight.h"
  14. #include "iefx.h"
  15. #include "SoundEmitterSystem/isoundemittersystembase.h"
  16. #include <bitbuf.h>
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. #define PLANTEDC4_MSG_JUSTBLEW 1
  20. ConVar cl_c4dynamiclight( "cl_c4dynamiclight", "0", 0, "Draw dynamic light when planted c4 flashes" );
  21. IMPLEMENT_CLIENTCLASS_DT(C_PlantedC4, DT_PlantedC4, CPlantedC4)
  22. RecvPropBool( RECVINFO(m_bBombTicking) ),
  23. RecvPropFloat( RECVINFO(m_flC4Blow) ),
  24. RecvPropFloat( RECVINFO(m_flTimerLength) ),
  25. RecvPropFloat( RECVINFO(m_flDefuseLength) ),
  26. RecvPropFloat( RECVINFO(m_flDefuseCountDown) ),
  27. END_RECV_TABLE()
  28. CUtlVector< C_PlantedC4* > g_PlantedC4s;
  29. C_PlantedC4::C_PlantedC4()
  30. {
  31. g_PlantedC4s.AddToTail( this );
  32. m_flNextRadarFlashTime = gpGlobals->curtime;
  33. m_bRadarFlash = true;
  34. m_pC4Explosion = NULL;
  35. // Don't beep right away, leave time for the planting sound
  36. m_flNextGlow = gpGlobals->curtime + 1.0;
  37. m_flNextBeep = gpGlobals->curtime + 1.0;
  38. }
  39. C_PlantedC4::~C_PlantedC4()
  40. {
  41. g_PlantedC4s.FindAndRemove( this );
  42. //=============================================================================
  43. // HPE_BEGIN:
  44. // [menglish] Upon the new round remove the remaining bomb explosion particle effect
  45. //=============================================================================
  46. if (m_pC4Explosion)
  47. {
  48. m_pC4Explosion->SetRemoveFlag();
  49. }
  50. //=============================================================================
  51. // HPE_END
  52. //=============================================================================
  53. }
  54. void C_PlantedC4::SetDormant( bool bDormant )
  55. {
  56. BaseClass::SetDormant( bDormant );
  57. // Remove us from the list of planted C4s.
  58. if ( bDormant )
  59. {
  60. g_PlantedC4s.FindAndRemove( this );
  61. }
  62. else
  63. {
  64. if ( g_PlantedC4s.Find( this ) == -1 )
  65. g_PlantedC4s.AddToTail( this );
  66. }
  67. }
  68. void C_PlantedC4::Spawn( void )
  69. {
  70. BaseClass::Spawn();
  71. SetNextClientThink( CLIENT_THINK_ALWAYS );
  72. }
  73. void C_PlantedC4::ClientThink( void )
  74. {
  75. BaseClass::ClientThink();
  76. // If it's dormant, don't beep or anything..
  77. if ( IsDormant() )
  78. return;
  79. if ( !m_bBombTicking )
  80. {
  81. // disable C4 thinking if not armed
  82. SetNextClientThink( CLIENT_THINK_NEVER );
  83. return;
  84. }
  85. if( gpGlobals->curtime > m_flNextBeep )
  86. {
  87. // as it gets closer to going off, increase the radius
  88. CLocalPlayerFilter filter;
  89. float attenuation;
  90. float freq;
  91. //the percent complete of the bomb timer
  92. float fComplete = ( ( m_flC4Blow - gpGlobals->curtime ) / m_flTimerLength );
  93. fComplete = clamp( fComplete, 0.0f, 1.0f );
  94. attenuation = MIN( 0.3 + 0.6 * fComplete, 1.0 );
  95. CSoundParameters params;
  96. if ( GetParametersForSound( "C4.PlantSound", params, NULL ) )
  97. {
  98. EmitSound_t ep( params );
  99. ep.m_SoundLevel = ATTN_TO_SNDLVL( attenuation );
  100. ep.m_pOrigin = &GetAbsOrigin();
  101. EmitSound( filter, SOUND_FROM_WORLD, ep );
  102. }
  103. freq = MAX( 0.1 + 0.9 * fComplete, 0.15 );
  104. m_flNextBeep = gpGlobals->curtime + freq;
  105. }
  106. if( gpGlobals->curtime > m_flNextGlow )
  107. {
  108. int modelindex = modelinfo->GetModelIndex( "sprites/ledglow.vmt" );
  109. float scale = 0.8f;
  110. Vector vPos = GetAbsOrigin();
  111. const Vector offset( 0, 0, 4 );
  112. // See if the c4 ended up underwater - we need to pull the flash up, or it won't get seen
  113. if ( enginetrace->GetPointContents( vPos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
  114. {
  115. C_CSPlayer *player = GetLocalOrInEyeCSPlayer();
  116. if ( player )
  117. {
  118. const Vector& eyes = player->EyePosition();
  119. if ( ( enginetrace->GetPointContents( eyes ) & (CONTENTS_WATER|CONTENTS_SLIME) ) == 0 )
  120. {
  121. // trace from the player to the water
  122. trace_t waterTrace;
  123. UTIL_TraceLine( eyes, vPos, (CONTENTS_WATER|CONTENTS_SLIME), player, COLLISION_GROUP_NONE, &waterTrace );
  124. if( waterTrace.allsolid != 1 )
  125. {
  126. // now trace from the C4 to the edge of the water (in case there was something solid in the water)
  127. trace_t solidTrace;
  128. UTIL_TraceLine( vPos, waterTrace.endpos, MASK_SOLID, this, COLLISION_GROUP_NONE, &solidTrace );
  129. if( solidTrace.allsolid != 1 )
  130. {
  131. float waterDist = (solidTrace.endpos - vPos).Length();
  132. float remainingDist = (solidTrace.endpos - eyes).Length();
  133. scale = scale * remainingDist / ( remainingDist + waterDist );
  134. vPos = solidTrace.endpos;
  135. }
  136. }
  137. }
  138. }
  139. }
  140. vPos += offset;
  141. tempents->TempSprite( vPos, vec3_origin, scale, modelindex, kRenderTransAdd, 0, 1.0, 0.05, FTENT_SPRANIMATE | FTENT_SPRANIMATELOOP );
  142. if( cl_c4dynamiclight.GetBool() )
  143. {
  144. dlight_t *dl;
  145. dl = effects->CL_AllocDlight( entindex() );
  146. if( dl )
  147. {
  148. dl->origin = GetAbsOrigin() + offset; // can't use vPos because it might have been moved
  149. dl->color.r = 255;
  150. dl->color.g = 0;
  151. dl->color.b = 0;
  152. dl->radius = 64;
  153. dl->die = gpGlobals->curtime + 0.01;
  154. }
  155. }
  156. float freq = 0.1 + 0.9 * ( ( m_flC4Blow - gpGlobals->curtime ) / m_flTimerLength );
  157. if( freq < 0.15 ) freq = 0.15;
  158. m_flNextGlow = gpGlobals->curtime + freq;
  159. }
  160. }
  161. //=============================================================================
  162. // HPE_BEGIN:
  163. // [menglish] Create the client side explosion particle effect for when the bomb explodes and hide the bomb
  164. //=============================================================================
  165. void C_PlantedC4::Explode( void )
  166. {
  167. m_pC4Explosion = ParticleProp()->Create( "bomb_explosion_huge", PATTACH_ABSORIGIN );
  168. AddEffects( EF_NODRAW );
  169. SetDormant( true );
  170. }
  171. //=============================================================================
  172. // HPE_END
  173. //=============================================================================