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.

216 lines
6.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF Heal 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_heal.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. #endif
  21. #define GRENADE_HEAL_TIMER 3.0f //Seconds
  22. #define GRENADE_HEAL_LEADIN 2.0f
  23. //=============================================================================
  24. //
  25. // TF Heal Grenade tables.
  26. //
  27. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeHeal, DT_TFGrenadeHeal )
  28. BEGIN_NETWORK_TABLE( CTFGrenadeHeal, DT_TFGrenadeHeal )
  29. END_NETWORK_TABLE()
  30. BEGIN_PREDICTION_DATA( CTFGrenadeHeal )
  31. END_PREDICTION_DATA()
  32. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_heal, CTFGrenadeHeal );
  33. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_heal );
  34. //=============================================================================
  35. //
  36. // TF Heal Grenade functions.
  37. //
  38. // Server specific.
  39. #ifdef GAME_DLL
  40. BEGIN_DATADESC( CTFGrenadeHeal )
  41. END_DATADESC()
  42. ConVar tf_grenade_heal_amount( "tf_grenade_heal_amount", "100", FCVAR_CHEAT, "Amount healed by the medic heal grenade.\n" );
  43. //-----------------------------------------------------------------------------
  44. // Purpose:
  45. //-----------------------------------------------------------------------------
  46. CTFWeaponBaseGrenadeProj *CTFGrenadeHeal::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel,
  47. AngularImpulse angImpulse, CBasePlayer *pPlayer, float flTime, int iflags )
  48. {
  49. return CTFGrenadeHealProjectile::Create( vecSrc, vecAngles, vecVel, angImpulse,
  50. pPlayer, GetTFWpnData(), flTime );
  51. }
  52. //=============================================================================
  53. //
  54. // TF Heal Grenade Projectile functions (Server specific).
  55. //
  56. #define GRENADE_MODEL "models/weapons/w_models/w_grenade_heal.mdl"
  57. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_heal_projectile, CTFGrenadeHealProjectile );
  58. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_heal_projectile );
  59. BEGIN_DATADESC( CTFGrenadeHealProjectile )
  60. DEFINE_THINKFUNC( DetonateThink ),
  61. END_DATADESC()
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. CTFGrenadeHealProjectile* CTFGrenadeHealProjectile::Create( const Vector &position, const QAngle &angles,
  66. const Vector &velocity, const AngularImpulse &angVelocity,
  67. CBaseCombatCharacter *pOwner, const CTFWeaponInfo &weaponInfo, float timer, int iFlags )
  68. {
  69. CTFGrenadeHealProjectile *pGrenade = static_cast<CTFGrenadeHealProjectile*>( CTFWeaponBaseGrenadeProj::Create( "tf_weapon_grenade_heal_projectile", position, angles, velocity, angVelocity, pOwner, weaponInfo, timer, iFlags ) );
  70. if ( pGrenade )
  71. {
  72. pGrenade->ApplyLocalAngularVelocityImpulse( angVelocity );
  73. }
  74. return pGrenade;
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. //-----------------------------------------------------------------------------
  79. void CTFGrenadeHealProjectile::Spawn()
  80. {
  81. SetModel( GRENADE_MODEL );
  82. BaseClass::Spawn();
  83. m_bPlayedLeadIn = false;
  84. SetThink( &CTFGrenadeHealProjectile::DetonateThink );
  85. // Since this code only runs on the server, make sure it shows the tempents it creates.
  86. CDisablePredictionFiltering disabler;
  87. if ( GetTeamNumber() == TF_TEAM_BLUE )
  88. {
  89. DispatchParticleEffect( "heal_ticker_blue", PATTACH_ABSORIGIN_FOLLOW, this );
  90. }
  91. else
  92. {
  93. DispatchParticleEffect( "heal_ticker_red", PATTACH_ABSORIGIN_FOLLOW, this );
  94. }
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose:
  98. //-----------------------------------------------------------------------------
  99. void CTFGrenadeHealProjectile::Precache()
  100. {
  101. PrecacheModel( GRENADE_MODEL );
  102. PrecacheScriptSound( "Weapon_Grenade_Heal.LeadIn" );
  103. PrecacheScriptSound( "Weapon_Grenade_Heal.Bounce" );
  104. PrecacheScriptSound( "Weapon_Grenade_Heal.Explode" );
  105. PrecacheParticleSystem( "heal_ticker_blue" );
  106. PrecacheParticleSystem( "heal_ticker_red" );
  107. PrecacheParticleSystem( "heal_grenade_blue" );
  108. PrecacheParticleSystem( "heal_grenade_red" );
  109. BaseClass::Precache();
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose:
  113. //-----------------------------------------------------------------------------
  114. void CTFGrenadeHealProjectile::BounceSound( void )
  115. {
  116. EmitSound( "Weapon_Grenade_Heal.Bounce" );
  117. }
  118. extern ConVar tf_grenade_show_radius;
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. //-----------------------------------------------------------------------------
  122. void CTFGrenadeHealProjectile::Detonate()
  123. {
  124. if ( ShouldNotDetonate() )
  125. {
  126. RemoveGrenade();
  127. return;
  128. }
  129. float flRadius = 180;
  130. float flHealAmount = tf_grenade_heal_amount.GetFloat();
  131. if ( tf_grenade_show_radius.GetBool() )
  132. {
  133. DrawRadius( flRadius );
  134. }
  135. // Heal every friendly player in the radius for 100 health
  136. CBaseEntity *pEntityList[100];
  137. int nEntityCount = UTIL_EntitiesInSphere( pEntityList, 100, GetAbsOrigin(), flRadius, FL_CLIENT );
  138. int iEntity;
  139. for ( iEntity = 0; iEntity < nEntityCount; ++iEntity )
  140. {
  141. CTFPlayer *pPlayer = ToTFPlayer( pEntityList[iEntity] );
  142. if ( pPlayer )
  143. {
  144. pPlayer->TakeHealth( flHealAmount, DMG_GENERIC );
  145. }
  146. }
  147. EmitSound( "Weapon_Grenade_Heal.Explode" );
  148. // Since this code only runs on the server, make sure it shows the tempents it creates.
  149. CDisablePredictionFiltering disabler;
  150. if ( GetTeamNumber() == TF_TEAM_BLUE )
  151. {
  152. DispatchParticleEffect( "heal_grenade_blue", GetAbsOrigin(), vec3_angle );
  153. }
  154. else
  155. {
  156. DispatchParticleEffect( "heal_grenade_red", GetAbsOrigin(), vec3_angle );
  157. }
  158. UTIL_Remove( this );
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Purpose:
  162. //-----------------------------------------------------------------------------
  163. void CTFGrenadeHealProjectile::DetonateThink( void )
  164. {
  165. if ( !m_bPlayedLeadIn && gpGlobals->curtime > GetDetonateTime() - GRENADE_HEAL_LEADIN )
  166. {
  167. Vector soundPosition = GetAbsOrigin() + Vector( 0, 0, 5 );
  168. CPASAttenuationFilter filter( soundPosition );
  169. EmitSound( filter, entindex(), "Weapon_Grenade_Heal.LeadIn" );
  170. m_bPlayedLeadIn = true;
  171. }
  172. BaseClass::DetonateThink();
  173. }
  174. #endif