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.

221 lines
7.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #include "cbase.h"
  10. #include "c_basetempentity.h"
  11. #include "networkstringtable_clientdll.h"
  12. #include "effect_dispatch_data.h"
  13. #include "c_te_effect_dispatch.h"
  14. #include "tier1/KeyValues.h"
  15. #include "toolframework_client.h"
  16. #include "tier0/vprof.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. //-----------------------------------------------------------------------------
  20. // CClientEffectRegistration registration
  21. //-----------------------------------------------------------------------------
  22. CClientEffectRegistration *CClientEffectRegistration::s_pHead = NULL;
  23. CClientEffectRegistration::CClientEffectRegistration( const char *pEffectName, ClientEffectCallback fn )
  24. {
  25. m_pEffectName = pEffectName;
  26. m_pFunction = fn;
  27. m_pNext = s_pHead;
  28. s_pHead = this;
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Purpose: EffectDispatch TE
  32. //-----------------------------------------------------------------------------
  33. class C_TEEffectDispatch : public C_BaseTempEntity
  34. {
  35. public:
  36. DECLARE_CLASS( C_TEEffectDispatch, C_BaseTempEntity );
  37. DECLARE_CLIENTCLASS();
  38. C_TEEffectDispatch( void );
  39. virtual ~C_TEEffectDispatch( void );
  40. virtual void PostDataUpdate( DataUpdateType_t updateType );
  41. public:
  42. CEffectData m_EffectData;
  43. };
  44. //-----------------------------------------------------------------------------
  45. // Purpose:
  46. //-----------------------------------------------------------------------------
  47. C_TEEffectDispatch::C_TEEffectDispatch( void )
  48. {
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Purpose:
  52. //-----------------------------------------------------------------------------
  53. C_TEEffectDispatch::~C_TEEffectDispatch( void )
  54. {
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. //-----------------------------------------------------------------------------
  59. void DispatchEffectToCallback( const char *pEffectName, const CEffectData &m_EffectData )
  60. {
  61. // Look through all the registered callbacks
  62. for ( CClientEffectRegistration *pReg = CClientEffectRegistration::s_pHead; pReg; pReg = pReg->m_pNext )
  63. {
  64. // If the name matches, call it
  65. if ( Q_stricmp( pReg->m_pEffectName, pEffectName ) == 0 )
  66. {
  67. pReg->m_pFunction( m_EffectData );
  68. return;
  69. }
  70. }
  71. DevMsg("DispatchEffect: effect '%s' not found on client\n", pEffectName );
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Record effects
  75. //-----------------------------------------------------------------------------
  76. static void RecordEffect( const char *pEffectName, const CEffectData &data )
  77. {
  78. if ( !ToolsEnabled() )
  79. return;
  80. if ( clienttools->IsInRecordingMode() && ( (data.m_fFlags & EFFECTDATA_NO_RECORD) == 0 ) )
  81. {
  82. KeyValues *msg = new KeyValues( "TempEntity" );
  83. const char *pSurfacePropName = physprops->GetPropName( data.m_nSurfaceProp );
  84. char pName[1024];
  85. Q_snprintf( pName, sizeof(pName), "TE_DispatchEffect %s %s", pEffectName, pSurfacePropName );
  86. msg->SetInt( "te", TE_DISPATCH_EFFECT );
  87. msg->SetString( "name", pName );
  88. msg->SetFloat( "time", gpGlobals->curtime );
  89. msg->SetFloat( "originx", data.m_vOrigin.x );
  90. msg->SetFloat( "originy", data.m_vOrigin.y );
  91. msg->SetFloat( "originz", data.m_vOrigin.z );
  92. msg->SetFloat( "startx", data.m_vStart.x );
  93. msg->SetFloat( "starty", data.m_vStart.y );
  94. msg->SetFloat( "startz", data.m_vStart.z );
  95. msg->SetFloat( "normalx", data.m_vNormal.x );
  96. msg->SetFloat( "normaly", data.m_vNormal.y );
  97. msg->SetFloat( "normalz", data.m_vNormal.z );
  98. msg->SetFloat( "anglesx", data.m_vAngles.x );
  99. msg->SetFloat( "anglesy", data.m_vAngles.y );
  100. msg->SetFloat( "anglesz", data.m_vAngles.z );
  101. msg->SetInt( "flags", data.m_fFlags );
  102. msg->SetFloat( "scale", data.m_flScale );
  103. msg->SetFloat( "magnitude", data.m_flMagnitude );
  104. msg->SetFloat( "radius", data.m_flRadius );
  105. msg->SetString( "surfaceprop", pSurfacePropName );
  106. msg->SetInt( "color", data.m_nColor );
  107. msg->SetInt( "damagetype", data.m_nDamageType );
  108. msg->SetInt( "hitbox", data.m_nHitBox );
  109. msg->SetString( "effectname", pEffectName );
  110. // FIXME: Need to write the attachment name here
  111. msg->SetInt( "attachmentindex", data.m_nAttachmentIndex );
  112. // NOTE: Ptrs are our way of indicating it's an entindex
  113. msg->SetPtr( "entindex", (void*)data.entindex() );
  114. ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
  115. msg->deleteThis();
  116. }
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose:
  120. //-----------------------------------------------------------------------------
  121. void C_TEEffectDispatch::PostDataUpdate( DataUpdateType_t updateType )
  122. {
  123. VPROF( "C_TEEffectDispatch::PostDataUpdate" );
  124. // Find the effect name.
  125. const char *pEffectName = g_StringTableEffectDispatch->GetString( m_EffectData.GetEffectNameIndex() );
  126. if ( pEffectName )
  127. {
  128. DispatchEffectToCallback( pEffectName, m_EffectData );
  129. RecordEffect( pEffectName, m_EffectData );
  130. }
  131. }
  132. IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEEffectDispatch, DT_TEEffectDispatch, CTEEffectDispatch )
  133. RecvPropDataTable( RECVINFO_DT( m_EffectData ), 0, &REFERENCE_RECV_TABLE( DT_EffectData ) )
  134. END_RECV_TABLE()
  135. //-----------------------------------------------------------------------------
  136. // Purpose: Clientside version
  137. //-----------------------------------------------------------------------------
  138. void TE_DispatchEffect( IRecipientFilter& filter, float delay, const Vector &pos, const char *pName, const CEffectData &data )
  139. {
  140. DispatchEffectToCallback( pName, data );
  141. RecordEffect( pName, data );
  142. }
  143. // Client version of dispatch effect, for predicted weapons
  144. void DispatchEffect( const char *pName, const CEffectData &data )
  145. {
  146. CPASFilter filter( data.m_vOrigin );
  147. te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data );
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Playback
  151. //-----------------------------------------------------------------------------
  152. void TE_DispatchEffect( IRecipientFilter& filter, float delay, KeyValues *pKeyValues )
  153. {
  154. CEffectData data;
  155. data.m_nMaterial = 0;
  156. data.m_vOrigin.x = pKeyValues->GetFloat( "originx" );
  157. data.m_vOrigin.y = pKeyValues->GetFloat( "originy" );
  158. data.m_vOrigin.z = pKeyValues->GetFloat( "originz" );
  159. data.m_vStart.x = pKeyValues->GetFloat( "startx" );
  160. data.m_vStart.y = pKeyValues->GetFloat( "starty" );
  161. data.m_vStart.z = pKeyValues->GetFloat( "startz" );
  162. data.m_vNormal.x = pKeyValues->GetFloat( "normalx" );
  163. data.m_vNormal.y = pKeyValues->GetFloat( "normaly" );
  164. data.m_vNormal.z = pKeyValues->GetFloat( "normalz" );
  165. data.m_vAngles.x = pKeyValues->GetFloat( "anglesx" );
  166. data.m_vAngles.y = pKeyValues->GetFloat( "anglesy" );
  167. data.m_vAngles.z = pKeyValues->GetFloat( "anglesz" );
  168. data.m_fFlags = pKeyValues->GetInt( "flags" );
  169. data.m_flScale = pKeyValues->GetFloat( "scale" );
  170. data.m_flMagnitude = pKeyValues->GetFloat( "magnitude" );
  171. data.m_flRadius = pKeyValues->GetFloat( "radius" );
  172. const char *pSurfaceProp = pKeyValues->GetString( "surfaceprop" );
  173. data.m_nSurfaceProp = physprops->GetSurfaceIndex( pSurfaceProp );
  174. data.m_nDamageType = pKeyValues->GetInt( "damagetype" );
  175. data.m_nHitBox = pKeyValues->GetInt( "hitbox" );
  176. data.m_nColor = pKeyValues->GetInt( "color" );
  177. data.m_nAttachmentIndex = pKeyValues->GetInt( "attachmentindex" );
  178. // NOTE: Ptrs are our way of indicating it's an entindex
  179. ClientEntityHandle_t hWorld = ClientEntityList().EntIndexToHandle( 0 );
  180. data.m_hEntity = (int)pKeyValues->GetPtr( "entindex", (void*)hWorld.ToInt() );
  181. const char *pEffectName = pKeyValues->GetString( "effectname" );
  182. TE_DispatchEffect( filter, 0.0f, data.m_vOrigin, pEffectName, data );
  183. }