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.

207 lines
6.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Drops particles where the entity was.
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "EntityParticleTrail.h"
  8. #include "networkstringtable_gamedll.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. //-----------------------------------------------------------------------------
  12. // Used to retire the entity
  13. //-----------------------------------------------------------------------------
  14. static const char *s_pRetireContext = "RetireContext";
  15. //-----------------------------------------------------------------------------
  16. // Save/load
  17. //-----------------------------------------------------------------------------
  18. BEGIN_DATADESC( CEntityParticleTrail )
  19. DEFINE_FIELD( m_iMaterialName, FIELD_MATERIALINDEX ),
  20. DEFINE_EMBEDDED( m_Info ),
  21. DEFINE_FIELD( m_hConstraintEntity, FIELD_EHANDLE ),
  22. // Think this should be handled by StartTouch/etc.
  23. // DEFINE_FIELD( m_nRefCount, FIELD_INTEGER ),
  24. END_DATADESC()
  25. //-----------------------------------------------------------------------------
  26. // Networking
  27. //-----------------------------------------------------------------------------
  28. IMPLEMENT_SERVERCLASS_ST( CEntityParticleTrail, DT_EntityParticleTrail )
  29. SendPropInt(SENDINFO(m_iMaterialName), MAX_MATERIAL_STRING_BITS, SPROP_UNSIGNED ),
  30. SendPropDataTable( SENDINFO_DT( m_Info ), &REFERENCE_SEND_TABLE( DT_EntityParticleTrailInfo ) ),
  31. SendPropEHandle(SENDINFO(m_hConstraintEntity)),
  32. END_SEND_TABLE()
  33. LINK_ENTITY_TO_CLASS( env_particle_trail, CEntityParticleTrail );
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Creates a flame and attaches it to a target entity.
  36. // Input : pTarget -
  37. //-----------------------------------------------------------------------------
  38. CEntityParticleTrail *CEntityParticleTrail::Create( CBaseEntity *pTarget, const EntityParticleTrailInfo_t &info, CBaseEntity *pConstraintEntity )
  39. {
  40. int iMaterialName = GetMaterialIndex( STRING(info.m_strMaterialName) );
  41. // Look for other particle trails on the entity + copy state to the new entity
  42. CEntityParticleTrail *pTrail;
  43. CBaseEntity *pNext;
  44. for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext )
  45. {
  46. pNext = pChild->NextMovePeer();
  47. pTrail = dynamic_cast<CEntityParticleTrail*>(pChild);
  48. if ( pTrail && (pTrail->m_iMaterialName == iMaterialName) )
  49. {
  50. // Prevent destruction if it re-enters the field
  51. pTrail->IncrementRefCount();
  52. return pTrail;
  53. }
  54. }
  55. pTrail = (CEntityParticleTrail *)CreateEntityByName( "env_particle_trail" );
  56. if ( pTrail == NULL )
  57. return NULL;
  58. pTrail->m_hConstraintEntity = pConstraintEntity;
  59. pTrail->m_iMaterialName = iMaterialName;
  60. pTrail->m_Info.CopyFrom(info);
  61. pTrail->m_nRefCount = 1;
  62. pTrail->AttachToEntity( pTarget );
  63. pTrail->Spawn();
  64. return pTrail;
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Spawn
  68. //-----------------------------------------------------------------------------
  69. void CEntityParticleTrail::Spawn()
  70. {
  71. BaseClass::Spawn();
  72. /*
  73. SetThink( &CEntityParticleTrail::BoogieThink );
  74. SetNextThink( gpGlobals->curtime + 0.01f );
  75. if ( HasSpawnFlags( SF_RAGDOLL_BOOGIE_ELECTRICAL ) )
  76. {
  77. SetContextThink( ZapThink, gpGlobals->curtime + random->RandomFloat( 0.1f, 0.3f ), s_pZapContext );
  78. }
  79. */
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Spawn
  83. //-----------------------------------------------------------------------------
  84. void CEntityParticleTrail::UpdateOnRemove()
  85. {
  86. g_pNotify->ClearEntity( this );
  87. BaseClass::UpdateOnRemove();
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Force our constraint entity to be trasmitted
  91. //-----------------------------------------------------------------------------
  92. void CEntityParticleTrail::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
  93. {
  94. // Are we already marked for transmission?
  95. if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
  96. return;
  97. BaseClass::SetTransmit( pInfo, bAlways );
  98. // Force our constraint entity to be sent too.
  99. if ( m_hConstraintEntity )
  100. {
  101. m_hConstraintEntity->SetTransmit( pInfo, bAlways );
  102. }
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Retire
  106. //-----------------------------------------------------------------------------
  107. void CEntityParticleTrail::IncrementRefCount()
  108. {
  109. if ( m_nRefCount == 0 )
  110. {
  111. SetContextThink( NULL, gpGlobals->curtime, s_pRetireContext );
  112. }
  113. ++m_nRefCount;
  114. }
  115. void CEntityParticleTrail::DecrementRefCount()
  116. {
  117. --m_nRefCount;
  118. Assert( m_nRefCount >= 0 );
  119. if ( m_nRefCount == 0 )
  120. {
  121. FollowEntity( NULL );
  122. g_pNotify->ClearEntity( this );
  123. SetContextThink( &CEntityParticleTrail::SUB_Remove, gpGlobals->curtime + m_Info.m_flLifetime, s_pRetireContext );
  124. }
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Clean up when the entity goes away.
  128. //-----------------------------------------------------------------------------
  129. void CEntityParticleTrail::NotifySystemEvent( CBaseEntity *pNotify, notify_system_event_t eventType, const notify_system_event_params_t &params )
  130. {
  131. BaseClass::NotifySystemEvent( pNotify, eventType, params );
  132. Assert( pNotify == GetMoveParent() );
  133. if ( eventType == NOTIFY_EVENT_DESTROY )
  134. {
  135. FollowEntity( NULL );
  136. g_pNotify->ClearEntity( this );
  137. if ( m_nRefCount != 0 )
  138. {
  139. m_nRefCount = 0;
  140. SetContextThink( &CEntityParticleTrail::SUB_Remove, gpGlobals->curtime + m_Info.m_flLifetime, s_pRetireContext );
  141. }
  142. }
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Suppression count
  146. //-----------------------------------------------------------------------------
  147. void CEntityParticleTrail::Destroy( CBaseEntity *pTarget, const EntityParticleTrailInfo_t &info )
  148. {
  149. int iMaterialName = GetMaterialIndex( STRING(info.m_strMaterialName) );
  150. // Look for the particle trail attached to this entity + decrease refcount
  151. CBaseEntity *pNext;
  152. for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext )
  153. {
  154. pNext = pChild->NextMovePeer();
  155. CEntityParticleTrail *pTrail = dynamic_cast<CEntityParticleTrail*>(pChild);
  156. if ( !pTrail || (pTrail->m_iMaterialName != iMaterialName) )
  157. continue;
  158. pTrail->DecrementRefCount();
  159. }
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Attach to an entity
  163. //-----------------------------------------------------------------------------
  164. void CEntityParticleTrail::AttachToEntity( CBaseEntity *pTarget )
  165. {
  166. FollowEntity( pTarget );
  167. g_pNotify->AddEntity( this, pTarget );
  168. }