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.

244 lines
6.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Flaming bottle thrown from the hand
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #include "cbase.h"
  10. #include "player.h"
  11. #include "ammodef.h"
  12. #include "gamerules.h"
  13. #include "grenade_molotov.h"
  14. #include "weapon_brickbat.h"
  15. #include "soundent.h"
  16. #include "decals.h"
  17. #include "fire.h"
  18. #include "shake.h"
  19. #include "ndebugoverlay.h"
  20. #include "vstdlib/random.h"
  21. #include "engine/IEngineSound.h"
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. extern short g_sModelIndexFireball;
  25. extern ConVar sk_plr_dmg_molotov;
  26. extern ConVar sk_npc_dmg_molotov;
  27. ConVar sk_molotov_radius ( "sk_molotov_radius","0");
  28. #define MOLOTOV_EXPLOSION_VOLUME 1024
  29. BEGIN_DATADESC( CGrenade_Molotov )
  30. DEFINE_FIELD( m_pFireTrail, FIELD_CLASSPTR ),
  31. // Function Pointers
  32. DEFINE_FUNCTION( MolotovTouch ),
  33. DEFINE_FUNCTION( MolotovThink ),
  34. END_DATADESC()
  35. LINK_ENTITY_TO_CLASS( grenade_molotov, CGrenade_Molotov );
  36. void CGrenade_Molotov::Spawn( void )
  37. {
  38. SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
  39. SetSolid( SOLID_BBOX );
  40. SetCollisionGroup( COLLISION_GROUP_PROJECTILE );
  41. SetModel( "models/weapons/w_molotov.mdl");
  42. UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
  43. SetTouch( MolotovTouch );
  44. SetThink( MolotovThink );
  45. SetNextThink( gpGlobals->curtime + 0.1f );
  46. m_flDamage = sk_plr_dmg_molotov.GetFloat();
  47. m_DmgRadius = sk_molotov_radius.GetFloat();
  48. m_takedamage = DAMAGE_YES;
  49. m_iHealth = 1;
  50. SetGravity( 1.0 );
  51. SetFriction( 0.8 ); // Give a little bounce so can flatten
  52. SetSequence( 1 );
  53. m_pFireTrail = SmokeTrail::CreateSmokeTrail();
  54. if( m_pFireTrail )
  55. {
  56. m_pFireTrail->m_SpawnRate = 48;
  57. m_pFireTrail->m_ParticleLifetime = 1.0f;
  58. m_pFireTrail->m_StartColor.Init( 0.2f, 0.2f, 0.2f );
  59. m_pFireTrail->m_EndColor.Init( 0.0, 0.0, 0.0 );
  60. m_pFireTrail->m_StartSize = 8;
  61. m_pFireTrail->m_EndSize = 32;
  62. m_pFireTrail->m_SpawnRadius = 4;
  63. m_pFireTrail->m_MinSpeed = 8;
  64. m_pFireTrail->m_MaxSpeed = 16;
  65. m_pFireTrail->m_Opacity = 0.25f;
  66. m_pFireTrail->SetLifetime( 20.0f );
  67. m_pFireTrail->FollowEntity( this, "0" );
  68. }
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Purpose:
  72. // Input :
  73. // Output :
  74. //-----------------------------------------------------------------------------
  75. void CGrenade_Molotov::MolotovTouch( CBaseEntity *pOther )
  76. {
  77. Detonate();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. //
  82. //
  83. //-----------------------------------------------------------------------------
  84. void CGrenade_Molotov::Detonate( void )
  85. {
  86. SetModelName( NULL_STRING ); //invisible
  87. AddSolidFlags( FSOLID_NOT_SOLID ); // intangible
  88. m_takedamage = DAMAGE_NO;
  89. trace_t trace;
  90. UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + Vector ( 0, 0, -128 ), MASK_SOLID_BRUSHONLY,
  91. this, COLLISION_GROUP_NONE, &trace);
  92. // Pull out of the wall a bit
  93. if ( trace.fraction != 1.0 )
  94. {
  95. SetLocalOrigin( trace.endpos + (trace.plane.normal * (m_flDamage - 24) * 0.6) );
  96. }
  97. int contents = UTIL_PointContents ( GetAbsOrigin() );
  98. if ( (contents & MASK_WATER) )
  99. {
  100. UTIL_Remove( this );
  101. return;
  102. }
  103. EmitSound( "Grenade_Molotov.Detonate");
  104. // Start some fires
  105. int i;
  106. QAngle vecTraceAngles;
  107. Vector vecTraceDir;
  108. trace_t firetrace;
  109. for( i = 0 ; i < 16 ; i++ )
  110. {
  111. // build a little ray
  112. vecTraceAngles[PITCH] = random->RandomFloat(45, 135);
  113. vecTraceAngles[YAW] = random->RandomFloat(0, 360);
  114. vecTraceAngles[ROLL] = 0.0f;
  115. AngleVectors( vecTraceAngles, &vecTraceDir );
  116. Vector vecStart, vecEnd;
  117. vecStart = GetAbsOrigin() + ( trace.plane.normal * 128 );
  118. vecEnd = vecStart + vecTraceDir * 512;
  119. UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &firetrace );
  120. Vector ofsDir = ( firetrace.endpos - GetAbsOrigin() );
  121. float offset = VectorNormalize( ofsDir );
  122. if ( offset > 128 )
  123. offset = 128;
  124. //Get our scale based on distance
  125. float scale = 0.1f + ( 0.75f * ( 1.0f - ( offset / 128.0f ) ) );
  126. float growth = 0.1f + ( 0.75f * ( offset / 128.0f ) );
  127. if( firetrace.fraction != 1.0 )
  128. {
  129. FireSystem_StartFire( firetrace.endpos, scale, growth, 30.0f, (SF_FIRE_START_ON|SF_FIRE_SMOKELESS|SF_FIRE_NO_GLOW), (CBaseEntity*) this, FIRE_NATURAL );
  130. }
  131. }
  132. // End Start some fires
  133. CPASFilter filter2( trace.endpos );
  134. te->Explosion( filter2, 0.0,
  135. &trace.endpos,
  136. g_sModelIndexFireball,
  137. 2.0,
  138. 15,
  139. TE_EXPLFLAG_NOPARTICLES,
  140. m_DmgRadius,
  141. m_flDamage );
  142. CBaseEntity *pOwner;
  143. pOwner = GetOwnerEntity();
  144. SetOwnerEntity( NULL ); // can't traceline attack owner if this is set
  145. UTIL_DecalTrace( &trace, "Scorch" );
  146. UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
  147. CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), BASEGRENADE_EXPLOSION_VOLUME, 3.0 );
  148. RadiusDamage( CTakeDamageInfo( this, pOwner, m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL );
  149. AddEffects( EF_NODRAW );
  150. SetAbsVelocity( vec3_origin );
  151. SetNextThink( gpGlobals->curtime + 0.2 );
  152. if ( m_pFireTrail )
  153. {
  154. UTIL_Remove( m_pFireTrail );
  155. }
  156. UTIL_Remove(this);
  157. }
  158. //------------------------------------------------------------------------------
  159. // Purpose :
  160. // Input :
  161. // Output :
  162. //------------------------------------------------------------------------------
  163. void CGrenade_Molotov::MolotovThink( void )
  164. {
  165. // See if I can lose my owner (has dropper moved out of way?)
  166. // Want do this so owner can throw the brickbat
  167. if (GetOwnerEntity())
  168. {
  169. trace_t tr;
  170. Vector vUpABit = GetAbsOrigin();
  171. vUpABit.z += 5.0;
  172. CBaseEntity* saveOwner = GetOwnerEntity();
  173. SetOwnerEntity( NULL );
  174. UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
  175. if ( tr.startsolid || tr.fraction != 1.0 )
  176. {
  177. SetOwnerEntity( saveOwner );
  178. }
  179. }
  180. SetNextThink( gpGlobals->curtime + 0.1f );
  181. }
  182. void CGrenade_Molotov::Precache( void )
  183. {
  184. BaseClass::Precache();
  185. PrecacheModel("models/weapons/w_bb_bottle.mdl");
  186. UTIL_PrecacheOther("_firesmoke");
  187. PrecacheScriptSound( "Grenade_Molotov.Detonate" );
  188. }