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.

264 lines
8.3 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "cbase.h"
  14. #include "basetempentity.h"
  15. #include "cstrike15/cs_gamerules.h"
  16. #include "playerdecals_signature.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. //-----------------------------------------------------------------------------
  20. // Purpose: Dispatches decal tempentity
  21. //-----------------------------------------------------------------------------
  22. class CTEPlayerDecal : public CBaseTempEntity
  23. {
  24. public:
  25. DECLARE_CLASS( CTEPlayerDecal, CBaseTempEntity );
  26. CTEPlayerDecal( const char *name );
  27. virtual ~CTEPlayerDecal( void );
  28. virtual void Test( const Vector& current_origin, const QAngle& current_angles );
  29. DECLARE_SERVERCLASS();
  30. public:
  31. CNetworkVar( int, m_nPlayer );
  32. CNetworkVector( m_vecOrigin );
  33. CNetworkVector( m_vecStart );
  34. CNetworkVector( m_vecRight );
  35. CNetworkVar( int, m_nEntity );
  36. CNetworkVar( int, m_nHitbox );
  37. };
  38. class CFEPlayerDecal : public CBaseEntity
  39. {
  40. public:
  41. DECLARE_CLASS( CFEPlayerDecal, CBaseEntity );
  42. CFEPlayerDecal() {
  43. static int s_nUniqueID = 0;
  44. m_nUniqueID = ++ s_nUniqueID;
  45. if ( s_nUniqueID >= ( (1<<16) - 1 ) )
  46. s_nUniqueID = 1;
  47. m_unAccountID = 0;
  48. m_unTraceID = 0;
  49. m_rtGcTime = 0;
  50. SetEffects( EF_NOINTERP );
  51. SetPredictionEligible( false );
  52. m_vecEndPos.Init();
  53. m_vecStart.Init();
  54. m_vecRight.Init();
  55. m_vecNormal.Init();
  56. m_nPlayer = 0;
  57. m_nEntity = 0;
  58. m_nHitbox = 0;
  59. m_nTintID = 0;
  60. m_flCreationTime = gpGlobals->curtime;
  61. m_nVersion = 0;
  62. for ( int k = 0; k < PLAYERDECALS_SIGNATURE_BYTELEN; ++ k ) m_ubSignature.Set( k, 0 );
  63. SetThink( &CBaseEntity::SUB_Remove );
  64. SetNextThink( gpGlobals->curtime + PLAYERDECALS_DURATION_SOLID + PLAYERDECALS_DURATION_FADE2 );
  65. // Add us to the list
  66. s_arrFEPlayerDecals.AddToTail( this );
  67. // If we have too many then force expire older ones
  68. while ( s_arrFEPlayerDecals.Count() >
  69. PLAYERDECALS_LIMIT_COUNT
  70. )
  71. {
  72. CFEPlayerDecal *pOther = s_arrFEPlayerDecals.Head();
  73. s_arrFEPlayerDecals.RemoveMultipleFromHead( 1 );
  74. pOther->SetNextThink( gpGlobals->curtime ); // must be SUB_Remove
  75. }
  76. }
  77. virtual ~CFEPlayerDecal( void )
  78. {
  79. // Remove us from the list
  80. // Normally we would be first in the list anyways,
  81. // and even if we are not it's a small number of entries to scan
  82. ( void ) s_arrFEPlayerDecals.FindAndRemove( this );
  83. }
  84. // Make sure clients get all the spray entities in the same order
  85. virtual int UpdateTransmitState() { return SetTransmitState( FL_EDICT_ALWAYS ); }
  86. DECLARE_SERVERCLASS();
  87. public:
  88. CNetworkVar( int, m_nUniqueID );
  89. CNetworkVar( uint32, m_unAccountID );
  90. CNetworkVar( uint32, m_unTraceID );
  91. CNetworkVar( uint32, m_rtGcTime );
  92. CNetworkVector( m_vecEndPos );
  93. CNetworkVector( m_vecStart );
  94. CNetworkVector( m_vecRight );
  95. CNetworkVector( m_vecNormal );
  96. CNetworkVar( int, m_nPlayer );
  97. CNetworkVar( int, m_nEntity );
  98. CNetworkVar( int, m_nHitbox );
  99. CNetworkVar( float, m_flCreationTime );
  100. CNetworkVar( int, m_nTintID );
  101. CNetworkVar( uint8, m_nVersion );
  102. CNetworkArray( uint8, m_ubSignature, PLAYERDECALS_SIGNATURE_BYTELEN );
  103. private:
  104. static CUtlVector< CFEPlayerDecal * > s_arrFEPlayerDecals;
  105. };
  106. CUtlVector< CFEPlayerDecal * > CFEPlayerDecal::s_arrFEPlayerDecals;
  107. //-----------------------------------------------------------------------------
  108. // Purpose:
  109. // Input : *name -
  110. //-----------------------------------------------------------------------------
  111. CTEPlayerDecal::CTEPlayerDecal( const char *name ) :
  112. CBaseTempEntity( name )
  113. {
  114. m_nPlayer = 0;
  115. m_vecOrigin.Init();
  116. m_vecStart.Init();
  117. m_vecRight.Init();
  118. m_nEntity = 0;
  119. m_nHitbox = 0;
  120. }
  121. //-----------------------------------------------------------------------------
  122. // Purpose:
  123. //-----------------------------------------------------------------------------
  124. CTEPlayerDecal::~CTEPlayerDecal( void )
  125. {
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Purpose:
  129. // Input : *current_origin -
  130. // *current_angles -
  131. //-----------------------------------------------------------------------------
  132. void CTEPlayerDecal::Test( const Vector& current_origin, const QAngle& current_angles )
  133. {
  134. // Fill in data
  135. m_nPlayer = 1;
  136. m_nEntity = 0;
  137. m_vecOrigin = current_origin;
  138. Vector vecEnd;
  139. Vector forward;
  140. m_vecOrigin.GetForModify()[2] += 24;
  141. AngleVectors( current_angles, &forward );
  142. forward[2] = 0.0;
  143. VectorNormalize( forward );
  144. VectorMA( m_vecOrigin, 50.0, forward, m_vecOrigin.GetForModify() );
  145. VectorMA( m_vecOrigin, 1024.0, forward, vecEnd );
  146. trace_t tr;
  147. UTIL_TraceLine( m_vecOrigin, vecEnd, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
  148. m_vecOrigin = tr.endpos;
  149. CBroadcastRecipientFilter filter;
  150. Create( filter, 0.0 );
  151. }
  152. IMPLEMENT_SERVERCLASS_ST(CTEPlayerDecal, DT_TEPlayerDecal)
  153. SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD),
  154. SendPropVector( SENDINFO(m_vecStart), -1, SPROP_COORD),
  155. SendPropVector( SENDINFO(m_vecRight), -1, SPROP_COORD),
  156. SendPropInt( SENDINFO(m_nEntity), MAX_EDICT_BITS, SPROP_UNSIGNED ),
  157. SendPropInt( SENDINFO(m_nPlayer), -1, SPROP_UNSIGNED ),
  158. SendPropInt( SENDINFO(m_nHitbox), 16, SPROP_UNSIGNED ), // this is the max number of static props that can be decalled
  159. END_SEND_TABLE()
  160. IMPLEMENT_SERVERCLASS_ST(CFEPlayerDecal, DT_FEPlayerDecal)
  161. SendPropInt( SENDINFO(m_nUniqueID), -1, SPROP_UNSIGNED ),
  162. SendPropInt( SENDINFO(m_unAccountID), -1, SPROP_UNSIGNED ),
  163. SendPropInt( SENDINFO(m_unTraceID), -1, SPROP_UNSIGNED ),
  164. SendPropInt( SENDINFO(m_rtGcTime), -1, SPROP_UNSIGNED ),
  165. SendPropVector( SENDINFO(m_vecEndPos), -1, SPROP_NOSCALE),
  166. SendPropVector( SENDINFO(m_vecStart), -1, SPROP_NOSCALE),
  167. SendPropVector( SENDINFO(m_vecRight), -1, SPROP_NOSCALE),
  168. SendPropVector( SENDINFO(m_vecNormal), -1, SPROP_NOSCALE),
  169. SendPropInt( SENDINFO(m_nEntity), MAX_EDICT_BITS, SPROP_UNSIGNED ),
  170. SendPropInt( SENDINFO(m_nPlayer), -1, SPROP_UNSIGNED ),
  171. SendPropInt( SENDINFO(m_nHitbox), 16, SPROP_UNSIGNED ), // this is the max number of static props that can be decalled
  172. SendPropInt( SENDINFO( m_nTintID ), -1, SPROP_UNSIGNED ),
  173. SendPropFloat( SENDINFO( m_flCreationTime ), 0, SPROP_NOSCALE ),
  174. SendPropInt( SENDINFO( m_nVersion ), 3, SPROP_UNSIGNED ), // support versions 0..7 initially
  175. SendPropArray3( SENDINFO_ARRAY3( m_ubSignature ), SendPropInt( SENDINFO_ARRAY( m_ubSignature ), 8, SPROP_UNSIGNED ) ),
  176. END_SEND_TABLE()
  177. LINK_ENTITY_TO_CLASS( cfe_player_decal, CFEPlayerDecal );
  178. void FE_PlayerDecal( CCSGameRules::ServerPlayerDecalData_t const &data, std::string const &signature )
  179. {
  180. CFEPlayerDecal *pEnt = ( CFEPlayerDecal * ) CBaseEntity::Create( "cfe_player_decal", data.m_vecOrigin, vec3_angle );
  181. pEnt->m_unAccountID = data.m_unAccountID;
  182. pEnt->m_unTraceID = data.m_nTraceID;
  183. pEnt->m_rtGcTime = data.m_rtGcTime;
  184. pEnt->m_nPlayer = data.m_nPlayer;
  185. pEnt->m_vecEndPos = data.m_vecOrigin;
  186. pEnt->m_vecStart = data.m_vecStart;
  187. pEnt->m_vecRight = data.m_vecRight;
  188. pEnt->m_vecNormal = data.m_vecNormal;
  189. pEnt->m_nEntity = data.m_nEntity;
  190. pEnt->m_nHitbox = data.m_nHitbox;
  191. pEnt->m_nTintID = data.m_nTintID;
  192. pEnt->m_flCreationTime = data.m_flCreationTime;
  193. pEnt->m_nVersion = PLAYERDECALS_SIGNATURE_VERSION;
  194. if ( signature.size() == PLAYERDECALS_SIGNATURE_BYTELEN )
  195. {
  196. for ( int k = 0; k < PLAYERDECALS_SIGNATURE_BYTELEN; ++ k )
  197. pEnt->m_ubSignature.Set( k, signature[k] );
  198. }
  199. }
  200. // Singleton to fire TEPlayerDecal objects
  201. static CTEPlayerDecal g_TEPlayerDecal( "Player Decal" );
  202. //-----------------------------------------------------------------------------
  203. // Purpose:
  204. // Input : msg_dest -
  205. // delay -
  206. // *origin -
  207. // *recipient -
  208. // *pos -
  209. // player -
  210. // entity -
  211. // index -
  212. //-----------------------------------------------------------------------------
  213. void TE_PlayerDecal( IRecipientFilter& filter, float delay,
  214. const Vector* pos, const Vector* start, const Vector* right, int player, int entity, int hitbox )
  215. {
  216. g_TEPlayerDecal.m_vecOrigin = *pos;
  217. g_TEPlayerDecal.m_vecStart = *start;
  218. g_TEPlayerDecal.m_vecRight = *right;
  219. g_TEPlayerDecal.m_nPlayer = player;
  220. g_TEPlayerDecal.m_nEntity = entity;
  221. g_TEPlayerDecal.m_nHitbox = hitbox;
  222. // Send it over the wire
  223. g_TEPlayerDecal.Create( filter, delay );
  224. }