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.

277 lines
8.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF Mirv 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_mirv.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_MIRV_TIMER 3.0f // seconds
  21. #define GRENADE_MIRV_LEADIN 2.0f
  22. //=============================================================================
  23. //
  24. // TF Demoman Mirv Grenade tables.
  25. //
  26. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeMirv_Demoman, DT_TFGrenadeMirv_Demoman )
  27. BEGIN_NETWORK_TABLE( CTFGrenadeMirv_Demoman, DT_TFGrenadeMirv_Demoman )
  28. END_NETWORK_TABLE()
  29. BEGIN_PREDICTION_DATA( CTFGrenadeMirv_Demoman )
  30. END_PREDICTION_DATA()
  31. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_mirv_demoman, CTFGrenadeMirv_Demoman );
  32. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_mirv_demoman );
  33. //=============================================================================
  34. //
  35. // TF Mirv Grenade tables.
  36. //
  37. IMPLEMENT_NETWORKCLASS_ALIASED( TFGrenadeMirv, DT_TFGrenadeMirv )
  38. BEGIN_NETWORK_TABLE( CTFGrenadeMirv, DT_TFGrenadeMirv )
  39. END_NETWORK_TABLE()
  40. BEGIN_PREDICTION_DATA( CTFGrenadeMirv )
  41. END_PREDICTION_DATA()
  42. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_mirv, CTFGrenadeMirv );
  43. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_mirv );
  44. //=============================================================================
  45. //
  46. // TF Mirv Grenade functions.
  47. //
  48. // Server specific.
  49. #ifdef GAME_DLL
  50. BEGIN_DATADESC( CTFGrenadeMirv )
  51. END_DATADESC()
  52. //-----------------------------------------------------------------------------
  53. // Purpose:
  54. //-----------------------------------------------------------------------------
  55. CTFWeaponBaseGrenadeProj *CTFGrenadeMirv::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel,
  56. AngularImpulse angImpulse, CBasePlayer *pPlayer, float flTime, int iflags )
  57. {
  58. return CTFGrenadeMirvProjectile::Create( vecSrc, vecAngles, vecVel, angImpulse,
  59. pPlayer, GetTFWpnData(), flTime );
  60. }
  61. #endif
  62. //=============================================================================
  63. //
  64. // TF Mirv Grenade Projectile functions (Server specific).
  65. //
  66. #ifdef GAME_DLL
  67. BEGIN_DATADESC( CTFGrenadeMirvProjectile )
  68. DEFINE_THINKFUNC( DetonateThink ),
  69. END_DATADESC()
  70. #define GRENADE_MODEL "models/weapons/w_models/w_grenade_mirv.mdl"
  71. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_mirv_projectile, CTFGrenadeMirvProjectile );
  72. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_mirv_projectile );
  73. //-----------------------------------------------------------------------------
  74. // Purpose:
  75. //-----------------------------------------------------------------------------
  76. CTFGrenadeMirvProjectile* CTFGrenadeMirvProjectile::Create( const Vector &position, const QAngle &angles,
  77. const Vector &velocity, const AngularImpulse &angVelocity,
  78. CBaseCombatCharacter *pOwner, const CTFWeaponInfo &weaponInfo, float timer, int iFlags )
  79. {
  80. CTFGrenadeMirvProjectile *pGrenade = static_cast<CTFGrenadeMirvProjectile*>( CTFWeaponBaseGrenadeProj::Create( "tf_weapon_grenade_mirv_projectile", position, angles, velocity, angVelocity, pOwner, weaponInfo, timer, iFlags ) );
  81. return pGrenade;
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose:
  85. //-----------------------------------------------------------------------------
  86. void CTFGrenadeMirvProjectile::Spawn()
  87. {
  88. SetModel( GRENADE_MODEL );
  89. BaseClass::Spawn();
  90. m_bPlayedLeadIn = false;
  91. SetThink( &CTFGrenadeMirvProjectile::DetonateThink );
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Purpose:
  95. //-----------------------------------------------------------------------------
  96. void CTFGrenadeMirvProjectile::Precache()
  97. {
  98. PrecacheModel( GRENADE_MODEL );
  99. PrecacheScriptSound( "Weapon_Grenade_Mirv.LeadIn" );
  100. BaseClass::Precache();
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose:
  104. //-----------------------------------------------------------------------------
  105. void CTFGrenadeMirvProjectile::BounceSound( void )
  106. {
  107. EmitSound( "Weapon_Grenade_Mirv.Bounce" );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose:
  111. //-----------------------------------------------------------------------------
  112. void CTFGrenadeMirvProjectile::Detonate()
  113. {
  114. if ( ShouldNotDetonate() )
  115. {
  116. RemoveGrenade();
  117. return;
  118. }
  119. BaseClass::Detonate();
  120. }
  121. //-----------------------------------------------------------------------------
  122. // Purpose:
  123. //-----------------------------------------------------------------------------
  124. void CTFGrenadeMirvProjectile::DetonateThink( void )
  125. {
  126. if ( !m_bPlayedLeadIn && gpGlobals->curtime > GetDetonateTime() - GRENADE_MIRV_LEADIN )
  127. {
  128. Vector soundPosition = GetAbsOrigin() + Vector( 0, 0, 5 );
  129. CPASAttenuationFilter filter( soundPosition );
  130. EmitSound( filter, entindex(), "Weapon_Grenade_Mirv.LeadIn" );
  131. m_bPlayedLeadIn = true;
  132. }
  133. BaseClass::DetonateThink();
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose:
  137. //-----------------------------------------------------------------------------
  138. void CTFGrenadeMirvProjectile::Explode( trace_t *pTrace, int bitsDamageType )
  139. {
  140. // Pass through.
  141. BaseClass::Explode( pTrace, bitsDamageType );
  142. m_bPlayedLeadIn = false;
  143. // Server specific.
  144. #ifdef GAME_DLL
  145. // Create the bomblets.
  146. for ( int iBomb = 0; iBomb < TF_WEAPON_GRENADE_MIRV_BOMB_COUNT; ++iBomb )
  147. {
  148. Vector vecSrc = pTrace->endpos + Vector( 0, 0, 1.0f );
  149. Vector vecVelocity( random->RandomFloat( -75.0f, 75.0f ) * 3.0f,
  150. random->RandomFloat( -75.0f, 75.0f ) * 3.0f,
  151. random->RandomFloat( 30.0f, 70.0f ) * 5.0f );
  152. Vector vecZero( 0,0,0 );
  153. CTFPlayer *pPlayer = ToTFPlayer( GetThrower() );
  154. float flTime = 2.0f + random->RandomFloat( 0.0f, 1.0f );
  155. CTFGrenadeMirvBomb::Create( vecSrc, GetAbsAngles(), vecVelocity, vecZero, pPlayer, flTime );
  156. }
  157. #endif
  158. }
  159. //=============================================================================
  160. //
  161. // TF Mirv Bomb functions (Server specific).
  162. //
  163. #define GRENADE_MODEL_BOMBLET "models/weapons/w_models/w_grenade_bomblet.mdl"
  164. #define TF_WEAPON_GRENADE_MIRV_BOMB_GRAVITY 0.5f
  165. #define TF_WEAPON_GRENADE_MIRV_BOMB_FRICTION 0.8f
  166. #define TF_WEAPON_GRENADE_MIRV_BOMB_ELASTICITY 0.45f
  167. LINK_ENTITY_TO_CLASS( tf_weapon_grenade_mirv_bomb, CTFGrenadeMirvBomb );
  168. PRECACHE_WEAPON_REGISTER( tf_weapon_grenade_mirv_bomb );
  169. //-----------------------------------------------------------------------------
  170. // Purpose:
  171. //-----------------------------------------------------------------------------
  172. CTFGrenadeMirvBomb *CTFGrenadeMirvBomb::Create( const Vector &position, const QAngle &angles, const Vector &velocity,
  173. const AngularImpulse &angVelocity, CBaseCombatCharacter *pOwner, float timer )
  174. {
  175. CTFGrenadeMirvBomb *pBomb = static_cast<CTFGrenadeMirvBomb*>( CBaseEntity::Create( "tf_weapon_grenade_mirv_bomb", position, angles, pOwner ) );
  176. if ( pBomb )
  177. {
  178. pBomb->SetDetonateTimerLength( timer );
  179. pBomb->SetupInitialTransmittedGrenadeVelocity( velocity );
  180. pBomb->SetThrower( pOwner );
  181. pBomb->SetOwnerEntity( NULL );
  182. pBomb->SetGravity( TF_WEAPON_GRENADE_MIRV_BOMB_GRAVITY );
  183. pBomb->SetFriction( TF_WEAPON_GRENADE_MIRV_BOMB_GRAVITY );
  184. pBomb->SetElasticity( TF_WEAPON_GRENADE_MIRV_BOMB_ELASTICITY );
  185. pBomb->m_flDamage = 180.0f;
  186. pBomb->m_DmgRadius = 198.0f;
  187. pBomb->ChangeTeam( pOwner->GetTeamNumber() );
  188. pBomb->SetCollisionGroup( TF_COLLISIONGROUP_GRENADES );
  189. IPhysicsObject *pPhysicsObject = pBomb->VPhysicsGetObject();
  190. if ( pPhysicsObject )
  191. {
  192. pPhysicsObject->AddVelocity( &velocity, &angVelocity );
  193. }
  194. }
  195. return pBomb;
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Purpose:
  199. //-----------------------------------------------------------------------------
  200. void CTFGrenadeMirvBomb::Spawn()
  201. {
  202. SetModel( GRENADE_MODEL_BOMBLET );
  203. BaseClass::Spawn();
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Purpose:
  207. //-----------------------------------------------------------------------------
  208. void CTFGrenadeMirvBomb::Precache()
  209. {
  210. PrecacheModel( GRENADE_MODEL_BOMBLET );
  211. BaseClass::Precache();
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. void CTFGrenadeMirvBomb::BounceSound( void )
  217. {
  218. EmitSound( "Weapon_Grenade_MirvBomb.Bounce" );
  219. }
  220. #endif