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.

260 lines
7.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF Gas 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_gas.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_GAS_TIMER 3.0f //Seconds
  21. //=============================================================================
  22. //
  23. // TF Gas Grenade tables.
  24. //
  25. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeGas, DT_TFGrenadeGas )
  26. BEGIN_NETWORK_TABLE( CTFGrenadeGas, DT_TFGrenadeGas )
  27. END_NETWORK_TABLE()
  28. BEGIN_PREDICTION_DATA( CTFGrenadeGas )
  29. END_PREDICTION_DATA()
  30. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_gas, CTFGrenadeGas );
  31. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_gas );
  32. //=============================================================================
  33. //
  34. // TF Gas Grenade functions.
  35. //
  36. // Server specific.
  37. #ifdef GAME_DLL
  38. BEGIN_DATADESC( CTFGrenadeGas )
  39. END_DATADESC()
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. //-----------------------------------------------------------------------------
  43. CTFWeaponBaseGrenadeProj *CTFGrenadeGas::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel,
  44. AngularImpulse angImpulse, CBasePlayer *pPlayer, float flTime, int iflags )
  45. {
  46. return CTFGrenadeGasProjectile::Create( vecSrc, vecAngles, vecVel, angImpulse,
  47. pPlayer, GetTFWpnData(), flTime );
  48. }
  49. #endif
  50. //=============================================================================
  51. //
  52. // TF Gas Grenade Projectile functions (Server specific).
  53. //
  54. #ifdef GAME_DLL
  55. #define GRENADE_MODEL "models/weapons/w_models/w_grenade_gas.mdl"
  56. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_gas_projectile, CTFGrenadeGasProjectile );
  57. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_gas_projectile );
  58. BEGIN_DATADESC( CTFGrenadeGasProjectile )
  59. DEFINE_THINKFUNC( Think_Emit ),
  60. DEFINE_THINKFUNC( Think_Fade ),
  61. END_DATADESC()
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. CTFGrenadeGasProjectile* CTFGrenadeGasProjectile::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. CTFGrenadeGasProjectile *pGrenade = static_cast<CTFGrenadeGasProjectile*>( CTFWeaponBaseGrenadeProj::Create( "tf_weapon_grenade_gas_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 CTFGrenadeGasProjectile::Spawn()
  80. {
  81. SetModel( GRENADE_MODEL );
  82. BaseClass::Spawn();
  83. m_hGasEffect = NULL;
  84. }
  85. CTFGrenadeGasProjectile::~CTFGrenadeGasProjectile()
  86. {
  87. if ( m_hGasEffect.Get() )
  88. {
  89. UTIL_Remove( m_hGasEffect );
  90. }
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose:
  94. //-----------------------------------------------------------------------------
  95. void CTFGrenadeGasProjectile::Precache()
  96. {
  97. PrecacheModel( GRENADE_MODEL );
  98. PrecacheParticleSystem( "spy_gasgrenade" );
  99. BaseClass::Precache();
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose:
  103. //-----------------------------------------------------------------------------
  104. void CTFGrenadeGasProjectile::BounceSound( void )
  105. {
  106. EmitSound( "Weapon_Grenade_Gas.Bounce" );
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. //-----------------------------------------------------------------------------
  111. void CTFGrenadeGasProjectile::DetonateThink( void )
  112. {
  113. // if we're past the detonate time but still moving, delay the detonate
  114. if ( gpGlobals->curtime > GetDetonateTime() && VPhysicsGetObject() )
  115. {
  116. Vector vel;
  117. VPhysicsGetObject()->GetVelocity( &vel, NULL );
  118. if ( vel.Length() > 35.0 )
  119. {
  120. SetTimer( gpGlobals->curtime + 0.5 );
  121. }
  122. }
  123. BaseClass::DetonateThink();
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose:
  127. //-----------------------------------------------------------------------------
  128. void CTFGrenadeGasProjectile::Detonate()
  129. {
  130. if ( ShouldNotDetonate() )
  131. {
  132. RemoveGrenade();
  133. return;
  134. }
  135. // start emitting gas
  136. VPhysicsGetObject()->EnableMotion( false );
  137. m_hGasEffect = ( CTFGasGrenadeEffect * )CreateEntityByName("tf_gas_grenade_effect");
  138. CBaseEntity *pGasEffect = m_hGasEffect.Get();
  139. if ( pGasEffect )
  140. {
  141. DispatchSpawn( pGasEffect );
  142. pGasEffect->SetAbsOrigin( GetAbsOrigin() );
  143. }
  144. EmitSound( "BaseSmokeEffect.Sound" );
  145. // damage / hallucination effect in waves
  146. m_nPulses = 20;
  147. SetThink( &CTFGrenadeGasProjectile::Think_Emit );
  148. SetNextThink( gpGlobals->curtime + 0.1f );
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose: Emit gas pulses
  152. //-----------------------------------------------------------------------------
  153. void CTFGrenadeGasProjectile::Think_Emit( void )
  154. {
  155. Vector vecOrigin = GetAbsOrigin();
  156. float flDamage = 10;
  157. CTakeDamageInfo info( this, GetThrower(), vec3_origin, vecOrigin, flDamage, DMG_NERVEGAS | DMG_PREVENT_PHYSICS_FORCE );
  158. CBaseEntity* pEntity = NULL;
  159. while ( ( pEntity = gEntList.FindEntityInSphere( pEntity, vecOrigin, TF_HALLUCINATION_RADIUS ) ) != NULL )
  160. {
  161. // check for valid player
  162. if ( !pEntity->IsPlayer() )
  163. continue;
  164. pEntity->TakeDamage( info );
  165. }
  166. m_nPulses--;
  167. if ( m_nPulses <= 0 )
  168. {
  169. // Fade out
  170. SetThink( &CTFGrenadeGasProjectile::Think_Fade );
  171. }
  172. SetNextThink( gpGlobals->curtime + 0.75 );
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Fade the projectile out over time before making it disappear
  176. //-----------------------------------------------------------------------------
  177. void CTFGrenadeGasProjectile::Think_Fade()
  178. {
  179. color32 c = GetRenderColor();
  180. c.a -= 1;
  181. SetRenderColor( c.r, c.b, c.g, c.a );
  182. if ( !c.a )
  183. {
  184. UTIL_Remove( this );
  185. }
  186. SetNextThink( gpGlobals->curtime );
  187. }
  188. #endif
  189. IMPLEMENT_NETWORKCLASS_ALIASED( TFGasGrenadeEffect, DT_TFGasGrenadeEffect )
  190. BEGIN_NETWORK_TABLE(CTFGasGrenadeEffect, DT_TFGasGrenadeEffect )
  191. END_NETWORK_TABLE()
  192. #ifndef CLIENT_DLL
  193. LINK_ENTITY_TO_CLASS( tf_gas_grenade_effect, CTFGasGrenadeEffect );
  194. #endif
  195. #ifndef CLIENT_DLL
  196. int CTFGasGrenadeEffect::UpdateTransmitState( void )
  197. {
  198. return SetTransmitState( FL_EDICT_PVSCHECK );
  199. }
  200. #else
  201. void CTFGasGrenadeEffect::OnDataChanged( DataUpdateType_t updateType )
  202. {
  203. if ( updateType == DATA_UPDATE_CREATED && m_pGasEffect == NULL )
  204. {
  205. m_pGasEffect = ParticleProp()->Create( "spy_gasgrenade", PATTACH_ABSORIGIN );
  206. }
  207. }
  208. #endif // CLIENT_DLL