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.

231 lines
6.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF Emp Grenade.
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "tf_weaponbase.h"
  8. #include "tf_gamerules.h"
  9. #include "npcevent.h"
  10. #include "engine/IEngineSound.h"
  11. #include "tf_weapon_grenade_emp.h"
  12. // Server specific.
  13. #ifdef GAME_DLL
  14. #include "tf_player.h"
  15. #include "items.h"
  16. #include "tf_weaponbase_grenadeproj.h"
  17. #include "soundent.h"
  18. #include "KeyValues.h"
  19. #include "particle_parse.h"
  20. #include "beam_shared.h"
  21. #endif
  22. #define GRENADE_EMP_TIMER 3.0f //Seconds
  23. #define GRENADE_EMP_LEADIN 2.0f
  24. //=============================================================================
  25. //
  26. // TF Emp Grenade tables.
  27. //
  28. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeEmp, DT_TFGrenadeEmp )
  29. BEGIN_NETWORK_TABLE( CTFGrenadeEmp, DT_TFGrenadeEmp )
  30. END_NETWORK_TABLE()
  31. BEGIN_PREDICTION_DATA( CTFGrenadeEmp )
  32. END_PREDICTION_DATA()
  33. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_emp, CTFGrenadeEmp );
  34. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_emp );
  35. //=============================================================================
  36. //
  37. // TF Emp Grenade functions.
  38. //
  39. // Server specific.
  40. #ifdef GAME_DLL
  41. BEGIN_DATADESC( CTFGrenadeEmp )
  42. END_DATADESC()
  43. //-----------------------------------------------------------------------------
  44. // Purpose:
  45. //-----------------------------------------------------------------------------
  46. CTFWeaponBaseGrenadeProj *CTFGrenadeEmp::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel,
  47. AngularImpulse angImpulse, CBasePlayer *pPlayer, float flTime, int iflags )
  48. {
  49. return CTFGrenadeEmpProjectile::Create( vecSrc, vecAngles, vecVel, angImpulse,
  50. pPlayer, GetTFWpnData(), flTime );
  51. }
  52. #endif
  53. //=============================================================================
  54. //
  55. // TF Emp Grenade Projectile functions (Server specific).
  56. //
  57. #ifdef GAME_DLL
  58. #define GRENADE_MODEL "models/weapons/w_models/w_grenade_emp.mdl"
  59. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_emp_projectile, CTFGrenadeEmpProjectile );
  60. PRECACHE_REGISTER( tf_weapon_grenade_emp_projectile );
  61. BEGIN_DATADESC( CTFGrenadeEmpProjectile )
  62. DEFINE_THINKFUNC( DetonateThink ),
  63. END_DATADESC()
  64. //-----------------------------------------------------------------------------
  65. // Purpose:
  66. //-----------------------------------------------------------------------------
  67. CTFGrenadeEmpProjectile* CTFGrenadeEmpProjectile::Create( const Vector &position, const QAngle &angles,
  68. const Vector &velocity, const AngularImpulse &angVelocity,
  69. CBaseCombatCharacter *pOwner, const CTFWeaponInfo &weaponInfo, float timer, int iFlags )
  70. {
  71. CTFGrenadeEmpProjectile *pGrenade = static_cast<CTFGrenadeEmpProjectile*>( CTFWeaponBaseGrenadeProj::Create( "tf_weapon_grenade_emp_projectile", position, angles, velocity, angVelocity, pOwner, weaponInfo, timer, iFlags ) );
  72. if ( pGrenade )
  73. {
  74. pGrenade->ApplyLocalAngularVelocityImpulse( angVelocity );
  75. }
  76. return pGrenade;
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Purpose:
  80. //-----------------------------------------------------------------------------
  81. void CTFGrenadeEmpProjectile::Spawn()
  82. {
  83. Precache();
  84. SetModel( GRENADE_MODEL );
  85. BaseClass::Spawn();
  86. m_bPlayedLeadIn = false;
  87. SetThink( &CTFGrenadeEmpProjectile::DetonateThink );
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose:
  91. //-----------------------------------------------------------------------------
  92. void CTFGrenadeEmpProjectile::Precache()
  93. {
  94. PrecacheModel( GRENADE_MODEL );
  95. PrecacheScriptSound( "Weapon_Grenade_Emp.LeadIn" );
  96. PrecacheModel( "sprites/physcannon_bluelight1b.vmt" );
  97. PrecacheParticleSystem( "emp_shockwave" );
  98. BaseClass::Precache();
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. //-----------------------------------------------------------------------------
  103. void CTFGrenadeEmpProjectile::BounceSound( void )
  104. {
  105. EmitSound( "Weapon_Grenade_Emp.Bounce" );
  106. }
  107. extern ConVar tf_grenade_show_radius;
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. //-----------------------------------------------------------------------------
  111. void CTFGrenadeEmpProjectile::Detonate()
  112. {
  113. if ( ShouldNotDetonate() )
  114. {
  115. RemoveGrenade();
  116. return;
  117. }
  118. // Explosion effect on client
  119. SendDispatchEffect();
  120. float flRadius = 180;
  121. float flDamage = 1;
  122. if ( tf_grenade_show_radius.GetBool() )
  123. {
  124. DrawRadius( flRadius );
  125. }
  126. // Apply some amount of EMP damage to every entity in the radius. They will calculate
  127. // their own damage based on how much ammo they have or some other wacky calculation.
  128. CTakeDamageInfo info( this, GetThrower(), vec3_origin, GetAbsOrigin(), flDamage, DMG_EMP | DMG_PREVENT_PHYSICS_FORCE );
  129. CBaseEntity *pEntityList[100];
  130. int nEntityCount = UTIL_EntitiesInSphere( pEntityList, 100, GetAbsOrigin(), flRadius, 0 );
  131. int iEntity;
  132. for ( iEntity = 0; iEntity < nEntityCount; ++iEntity )
  133. {
  134. CBaseEntity *pEntity = pEntityList[iEntity];
  135. if ( pEntity == this )
  136. continue;
  137. if ( pEntity && pEntity->IsPlayer() )
  138. continue;
  139. if ( pEntity && ( pEntity->m_takedamage == DAMAGE_YES || pEntity->m_takedamage == DAMAGE_EVENTS_ONLY ) )
  140. {
  141. pEntity->TakeDamage( info );
  142. //if ( pEntity->IsPlayer() /* || is ammo box || is enemy object */ )
  143. {
  144. CBeam *pBeam = CBeam::BeamCreate( "sprites/physcannon_bluelight1b.vmt", 3.0 );
  145. if ( !pBeam )
  146. return;
  147. pBeam->PointsInit( GetAbsOrigin(), pEntity->WorldSpaceCenter() );
  148. pBeam->SetColor( 255, 255, 255 );
  149. pBeam->SetBrightness( 128 );
  150. pBeam->SetNoise( 12.0f );
  151. pBeam->SetEndWidth( 3.0f );
  152. pBeam->SetWidth( 3.0f );
  153. pBeam->LiveForTime( 0.5f ); // Fail-safe
  154. pBeam->SetFrameRate( 25.0f );
  155. pBeam->SetFrame( random->RandomInt( 0, 2 ) );
  156. }
  157. }
  158. }
  159. DispatchParticleEffect( "emp_shockwave", GetAbsOrigin(), vec3_angle );
  160. UTIL_Remove( this );
  161. #if 0
  162. // Tell the bots an HE grenade has exploded
  163. CTFPlayer *pPlayer = ToTFPlayer( GetThrower() );
  164. if ( pPlayer )
  165. {
  166. KeyValues *pEvent = new KeyValues( "tf_weapon_grenade_detonate" );
  167. pEvent->SetInt( "userid", pPlayer->GetUserID() );
  168. gameeventmanager->FireEventServerOnly( pEvent );
  169. }
  170. #endif
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Purpose:
  174. //-----------------------------------------------------------------------------
  175. void CTFGrenadeEmpProjectile::DetonateThink( void )
  176. {
  177. if ( !m_bPlayedLeadIn && gpGlobals->curtime > GetDetonateTime() - GRENADE_EMP_LEADIN )
  178. {
  179. Vector soundPosition = GetAbsOrigin() + Vector( 0, 0, 5 );
  180. CPASAttenuationFilter filter( soundPosition );
  181. EmitSound( filter, entindex(), "Weapon_Grenade_Emp.LeadIn" );
  182. m_bPlayedLeadIn = true;
  183. }
  184. BaseClass::DetonateThink();
  185. }
  186. #endif