Counter Strike : Global Offensive Source Code
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.

283 lines
7.9 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Dissolve entity to be attached to target entity. Serves two purposes:
  4. //
  5. // 1) An entity that can be placed by a level designer and triggered
  6. // to ignite a target entity.
  7. //
  8. // 2) An entity that can be created at runtime to ignite a target entity.
  9. //
  10. //===========================================================================//
  11. #include "cbase.h"
  12. #include "RagdollBoogie.h"
  13. #include "physics_prop_ragdoll.h"
  14. #include "effect_dispatch_data.h"
  15. #include "te_effect_dispatch.h"
  16. #include "IEffects.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. //-----------------------------------------------------------------------------
  20. // Make electriciy every so often
  21. //-----------------------------------------------------------------------------
  22. static const char *s_pZapContext = "ZapContext";
  23. //-----------------------------------------------------------------------------
  24. // Save/load
  25. //-----------------------------------------------------------------------------
  26. BEGIN_DATADESC( CRagdollBoogie )
  27. DEFINE_FIELD( m_flStartTime, FIELD_TIME ),
  28. DEFINE_FIELD( m_flBoogieLength, FIELD_FLOAT ),
  29. DEFINE_FIELD( m_flMagnitude, FIELD_FLOAT ),
  30. // Think this should be handled by StartTouch/etc.
  31. // DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ),
  32. DEFINE_FUNCTION( BoogieThink ),
  33. DEFINE_FUNCTION( ZapThink ),
  34. END_DATADESC()
  35. LINK_ENTITY_TO_CLASS( env_ragdoll_boogie, CRagdollBoogie );
  36. //-----------------------------------------------------------------------------
  37. // Purpose: Creates a flame and attaches it to a target entity.
  38. // Input : pTarget -
  39. //-----------------------------------------------------------------------------
  40. CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude,
  41. float flStartTime, float flLengthTime, int nSpawnFlags )
  42. {
  43. CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( pTarget );
  44. if ( !pRagdoll )
  45. return NULL;
  46. CRagdollBoogie *pBoogie = (CRagdollBoogie *)CreateEntityByName( "env_ragdoll_boogie" );
  47. if ( pBoogie == NULL )
  48. return NULL;
  49. pBoogie->AddSpawnFlags( nSpawnFlags );
  50. pBoogie->AttachToEntity( pTarget );
  51. pBoogie->SetBoogieTime( flStartTime, flLengthTime );
  52. pBoogie->SetMagnitude( flMagnitude );
  53. pBoogie->Spawn();
  54. return pBoogie;
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Spawn
  58. //-----------------------------------------------------------------------------
  59. void CRagdollBoogie::Precache()
  60. {
  61. BaseClass::Precache();
  62. PrecacheEffect( "TeslaHitboxes" );
  63. #ifdef HL2_EPISODIC
  64. PrecacheScriptSound( "RagdollBoogie.Zap" );
  65. #endif
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Spawn
  69. //-----------------------------------------------------------------------------
  70. void CRagdollBoogie::Spawn()
  71. {
  72. Precache();
  73. BaseClass::Spawn();
  74. SetThink( &CRagdollBoogie::BoogieThink );
  75. SetNextThink( gpGlobals->curtime + 0.01f );
  76. if ( HasSpawnFlags( SF_RAGDOLL_BOOGIE_ELECTRICAL ) )
  77. {
  78. SetContextThink( &CRagdollBoogie::ZapThink, gpGlobals->curtime + random->RandomFloat( 0.1f, 0.3f ), s_pZapContext );
  79. }
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Zap!
  83. //-----------------------------------------------------------------------------
  84. void CRagdollBoogie::ZapThink()
  85. {
  86. if ( !GetMoveParent() )
  87. return;
  88. CBaseAnimating *pRagdoll = GetMoveParent()->GetBaseAnimating();
  89. if ( !pRagdoll )
  90. return;
  91. // Make electricity on the client
  92. CStudioHdr *pStudioHdr = pRagdoll->GetModelPtr( );
  93. if (!pStudioHdr)
  94. return;
  95. mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pRagdoll->GetHitboxSet() );
  96. if ( set->numhitboxes == 0 )
  97. return;
  98. if ( m_nSuppressionCount == 0 )
  99. {
  100. CEffectData data;
  101. data.m_nEntIndex = GetMoveParent()->entindex();
  102. data.m_flMagnitude = 4;
  103. data.m_flScale = HasSpawnFlags(SF_RAGDOLL_BOOGIE_ELECTRICAL_NARROW_BEAM) ? 1.0f : 2.0f;
  104. DispatchEffect( "TeslaHitboxes", data );
  105. }
  106. #ifdef HL2_EPISODIC
  107. EmitSound( "RagdollBoogie.Zap" );
  108. #endif
  109. SetContextThink( &CRagdollBoogie::ZapThink, gpGlobals->curtime + random->RandomFloat( 0.1f, 0.3f ), s_pZapContext );
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Suppression count
  113. //-----------------------------------------------------------------------------
  114. void CRagdollBoogie::IncrementSuppressionCount( CBaseEntity *pTarget )
  115. {
  116. // Look for other boogies on the ragdoll + kill them
  117. for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
  118. {
  119. CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild);
  120. if ( !pBoogie )
  121. continue;
  122. ++pBoogie->m_nSuppressionCount;
  123. }
  124. }
  125. void CRagdollBoogie::DecrementSuppressionCount( CBaseEntity *pTarget )
  126. {
  127. // Look for other boogies on the ragdoll + kill them
  128. CBaseEntity *pNext;
  129. for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext )
  130. {
  131. pNext = pChild->NextMovePeer();
  132. CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild);
  133. if ( !pBoogie )
  134. continue;
  135. if ( --pBoogie->m_nSuppressionCount <= 0 )
  136. {
  137. pBoogie->m_nSuppressionCount = 0;
  138. float dt = gpGlobals->curtime - pBoogie->m_flStartTime;
  139. if ( dt >= pBoogie->m_flBoogieLength )
  140. {
  141. PhysCallbackRemove( pBoogie->NetworkProp() );
  142. }
  143. }
  144. }
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Attach to an entity
  148. //-----------------------------------------------------------------------------
  149. void CRagdollBoogie::AttachToEntity( CBaseEntity *pTarget )
  150. {
  151. m_nSuppressionCount = 0;
  152. // Look for other boogies on the ragdoll + kill them
  153. CBaseEntity *pNext;
  154. for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext )
  155. {
  156. pNext = pChild->NextMovePeer();
  157. CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild);
  158. if ( !pBoogie )
  159. continue;
  160. m_nSuppressionCount = pBoogie->m_nSuppressionCount;
  161. UTIL_Remove( pChild );
  162. }
  163. FollowEntity( pTarget );
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose:
  167. // Input : lifetime -
  168. //-----------------------------------------------------------------------------
  169. void CRagdollBoogie::SetBoogieTime( float flStartTime, float flLengthTime )
  170. {
  171. m_flStartTime = flStartTime;
  172. m_flBoogieLength = flLengthTime;
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose: Burn targets around us
  176. //-----------------------------------------------------------------------------
  177. void CRagdollBoogie::SetMagnitude( float flMagnitude )
  178. {
  179. m_flMagnitude = flMagnitude;
  180. }
  181. //-----------------------------------------------------------------------------
  182. // Purpose: Burn targets around us
  183. //-----------------------------------------------------------------------------
  184. void CRagdollBoogie::BoogieThink( void )
  185. {
  186. CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() );
  187. if ( !pRagdoll )
  188. {
  189. UTIL_Remove( this );
  190. return;
  191. }
  192. float flMagnitude = m_flMagnitude;
  193. if ( m_flBoogieLength != 0 )
  194. {
  195. float dt = gpGlobals->curtime - m_flStartTime;
  196. if ( dt >= m_flBoogieLength )
  197. {
  198. // Don't remove while suppressed... this helps if we try to start another boogie
  199. if ( m_nSuppressionCount == 0 )
  200. {
  201. UTIL_Remove( this );
  202. }
  203. SetThink( NULL );
  204. return;
  205. }
  206. if ( dt < 0 )
  207. {
  208. SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) );
  209. return;
  210. }
  211. flMagnitude = SimpleSplineRemapVal( dt, 0.0f, m_flBoogieLength, m_flMagnitude, 0.0f );
  212. }
  213. if ( m_nSuppressionCount == 0 )
  214. {
  215. ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( );
  216. for ( int j = 0; j < pRagdollPhys->listCount; ++j )
  217. {
  218. float flMass = pRagdollPhys->list[j].pObject->GetMass();
  219. float flForce = m_flMagnitude * flMass;
  220. Vector vecForce;
  221. vecForce = RandomVector( -flForce, flForce );
  222. pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce );
  223. }
  224. }
  225. SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) );
  226. }