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.

213 lines
6.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF Concussion 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_concussion.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. #endif
  20. #define GRENADE_CONCUSSION_TIMER 3.0f // seconds
  21. //=============================================================================
  22. //
  23. // TF Concussion Grenade tables.
  24. //
  25. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeConcussion, DT_TFGrenadeConcussion )
  26. BEGIN_NETWORK_TABLE( CTFGrenadeConcussion, DT_TFGrenadeConcussion )
  27. END_NETWORK_TABLE()
  28. BEGIN_PREDICTION_DATA( CTFGrenadeConcussion )
  29. END_PREDICTION_DATA()
  30. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_concussion, CTFGrenadeConcussion );
  31. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_concussion );
  32. //=============================================================================
  33. //
  34. // TF Concussion Grenade functions.
  35. //
  36. // Server specific.
  37. #ifdef GAME_DLL
  38. BEGIN_DATADESC( CTFGrenadeConcussion )
  39. END_DATADESC()
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. //-----------------------------------------------------------------------------
  43. CTFWeaponBaseGrenadeProj *CTFGrenadeConcussion::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel,
  44. AngularImpulse angImpulse, CBasePlayer *pPlayer, float flTime, int iflags )
  45. {
  46. return CTFGrenadeConcussionProjectile::Create( vecSrc, vecAngles, vecVel, angImpulse,
  47. pPlayer, GetTFWpnData(), flTime );
  48. }
  49. #endif
  50. //=============================================================================
  51. //
  52. // TF Concussion Grenade Projectile functions (Server specific).
  53. //
  54. #ifdef GAME_DLL
  55. #define GRENADE_MODEL "models/weapons/w_models/w_grenade_conc.mdl"
  56. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_concussion_projectile, CTFGrenadeConcussionProjectile );
  57. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_concussion_projectile );
  58. //-----------------------------------------------------------------------------
  59. // Purpose:
  60. //-----------------------------------------------------------------------------
  61. CTFGrenadeConcussionProjectile* CTFGrenadeConcussionProjectile::Create( const Vector &position, const QAngle &angles,
  62. const Vector &velocity, const AngularImpulse &angVelocity,
  63. CBaseCombatCharacter *pOwner, const CTFWeaponInfo &weaponInfo, float timer, int iFlags )
  64. {
  65. CTFGrenadeConcussionProjectile *pGrenade = static_cast<CTFGrenadeConcussionProjectile*>( CTFWeaponBaseGrenadeProj::Create( "tf_weapon_grenade_concussion_projectile", position, angles, velocity, angVelocity, pOwner, weaponInfo, timer, iFlags ) );
  66. if ( pGrenade )
  67. {
  68. pGrenade->ApplyLocalAngularVelocityImpulse( angVelocity );
  69. }
  70. return pGrenade;
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. //-----------------------------------------------------------------------------
  75. void CTFGrenadeConcussionProjectile::Spawn()
  76. {
  77. SetModel( GRENADE_MODEL );
  78. BaseClass::Spawn();
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. void CTFGrenadeConcussionProjectile::Precache()
  84. {
  85. PrecacheModel( GRENADE_MODEL );
  86. BaseClass::Precache();
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose:
  90. //-----------------------------------------------------------------------------
  91. void CTFGrenadeConcussionProjectile::BounceSound( void )
  92. {
  93. EmitSound( "Weapon_Grenade_Concussion.Bounce" );
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Purpose:
  97. //-----------------------------------------------------------------------------
  98. void CTFGrenadeConcussionProjectile::Detonate()
  99. {
  100. if ( ShouldNotDetonate() )
  101. {
  102. RemoveGrenade();
  103. return;
  104. }
  105. // The trace start/end.
  106. Vector vecStart = GetAbsOrigin() + Vector( 0.0f, 0.0f, 8.0f );
  107. Vector vecEnd = vecStart + Vector( 0.0f, 0.0f, -32.0f );
  108. trace_t trace;
  109. UTIL_TraceLine ( vecStart, vecEnd, MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &trace );
  110. // Explode (concuss).
  111. Explode( &trace, DMG_BLAST );
  112. // Screen shake.
  113. if ( GetShakeAmplitude() )
  114. {
  115. UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START );
  116. }
  117. }
  118. extern ConVar tf_grenade_show_radius;
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. //-----------------------------------------------------------------------------
  122. void CTFGrenadeConcussionProjectile::Explode( trace_t *pTrace, int bitsDamageType )
  123. {
  124. // Server specific.
  125. #ifdef GAME_DLL
  126. // Invisible.
  127. SetModelName( NULL_STRING );
  128. AddSolidFlags( FSOLID_NOT_SOLID );
  129. m_takedamage = DAMAGE_NO;
  130. // Move the impact point away from the surface a little bit.
  131. if ( pTrace->fraction != 1.0 )
  132. {
  133. SetLocalOrigin( pTrace->endpos + ( pTrace->plane.normal * 0.6 ) );
  134. }
  135. // Explosion effect on client
  136. SendDispatchEffect();
  137. // Explosion sound.
  138. CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 );
  139. // Explosion damage, using the thrower's position as the report position.
  140. CTFPlayer *pPlayer = ToTFPlayer( GetThrower() );
  141. Vector vecReported = pPlayer ? pPlayer->GetAbsOrigin() : vec3_origin;
  142. CTakeDamageInfo info( this, pPlayer, GetBlastForce(), GetAbsOrigin(), m_flDamage, bitsDamageType, 0, &vecReported );
  143. RadiusDamage( info, GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL );
  144. // Concussion.
  145. CBaseEntity *pEntityList[64];
  146. int nEntityCount = UTIL_EntitiesInSphere( pEntityList, 64, GetAbsOrigin(), m_DmgRadius, FL_CLIENT );
  147. for ( int iEntity = 0; iEntity < nEntityCount; ++iEntity )
  148. {
  149. CBaseEntity *pEntity = pEntityList[iEntity];
  150. CTFPlayer *pTestPlayer = ToTFPlayer( pEntity );
  151. // You can concuss yourself.
  152. bool bIsThrower = ( pPlayer == pTestPlayer );
  153. if ( bIsThrower || ( pTestPlayer && !InSameTeam( pTestPlayer) ) )
  154. {
  155. pTestPlayer->m_Shared.Concussion( this, m_DmgRadius );
  156. }
  157. }
  158. if ( tf_grenade_show_radius.GetBool() )
  159. {
  160. DrawRadius( m_DmgRadius );
  161. }
  162. // Explosion decal.
  163. UTIL_DecalTrace( pTrace, "Scorch" );
  164. // Reset.
  165. SetThink( &CBaseGrenade::SUB_Remove );
  166. SetTouch( NULL );
  167. AddEffects( EF_NODRAW );
  168. SetAbsVelocity( vec3_origin );
  169. SetNextThink( gpGlobals->curtime );
  170. #endif
  171. }
  172. #endif