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.

396 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "basetempentity.h"
  8. #include "tf_fx.h"
  9. #include "tf_shareddefs.h"
  10. #include "coordsize.h"
  11. #define NUM_BULLET_SEED_BITS 8
  12. //-----------------------------------------------------------------------------
  13. // Purpose: Display a blood sprite
  14. //-----------------------------------------------------------------------------
  15. class CTEFireBullets : public CBaseTempEntity
  16. {
  17. public:
  18. DECLARE_CLASS( CTEFireBullets, CBaseTempEntity );
  19. DECLARE_SERVERCLASS();
  20. CTEFireBullets( const char *name );
  21. virtual ~CTEFireBullets( void );
  22. public:
  23. CNetworkVar( int, m_iPlayer );
  24. CNetworkVector( m_vecOrigin );
  25. CNetworkQAngle( m_vecAngles );
  26. CNetworkVar( int, m_iWeaponID );
  27. CNetworkVar( int, m_iMode );
  28. CNetworkVar( int, m_iSeed );
  29. CNetworkVar( float, m_flSpread );
  30. CNetworkVar( bool, m_bCritical );
  31. };
  32. //-----------------------------------------------------------------------------
  33. // Purpose:
  34. // Input : *name -
  35. //-----------------------------------------------------------------------------
  36. CTEFireBullets::CTEFireBullets( const char *name ) : CBaseTempEntity( name )
  37. {
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Purpose:
  41. //-----------------------------------------------------------------------------
  42. CTEFireBullets::~CTEFireBullets( void )
  43. {
  44. }
  45. IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEFireBullets, DT_TEFireBullets )
  46. SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD_MP_INTEGRAL ),
  47. SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 0 ), 7, 0 ),
  48. SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 1 ), 7, 0 ),
  49. SendPropInt( SENDINFO( m_iWeaponID ), Q_log2(TF_WEAPON_COUNT)+1, SPROP_UNSIGNED ),
  50. SendPropInt( SENDINFO( m_iMode ), 1, SPROP_UNSIGNED ),
  51. SendPropInt( SENDINFO( m_iSeed ), NUM_BULLET_SEED_BITS, SPROP_UNSIGNED ),
  52. SendPropInt( SENDINFO( m_iPlayer ), 6, SPROP_UNSIGNED ), // max 64 players, see MAX_PLAYERS
  53. SendPropFloat( SENDINFO( m_flSpread ), 8, 0, 0.0f, 1.0f ),
  54. SendPropBool( SENDINFO( m_bCritical ) ),
  55. END_SEND_TABLE()
  56. // Singleton
  57. static CTEFireBullets g_TEFireBullets( "Fire Bullets" );
  58. //-----------------------------------------------------------------------------
  59. // Purpose:
  60. //-----------------------------------------------------------------------------
  61. void TE_FireBullets( int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles,
  62. int iWeaponID, int iMode, int iSeed, float flSpread, bool bCritical )
  63. {
  64. CPASFilter filter( vOrigin );
  65. filter.UsePredictionRules();
  66. g_TEFireBullets.m_iPlayer = iPlayerIndex-1;
  67. g_TEFireBullets.m_vecOrigin = vOrigin;
  68. g_TEFireBullets.m_vecAngles = vAngles;
  69. g_TEFireBullets.m_iSeed = iSeed;
  70. g_TEFireBullets.m_flSpread = flSpread;
  71. g_TEFireBullets.m_iMode = iMode;
  72. g_TEFireBullets.m_iWeaponID = iWeaponID;
  73. g_TEFireBullets.m_bCritical = bCritical;
  74. Assert( iSeed < (1 << NUM_BULLET_SEED_BITS) );
  75. g_TEFireBullets.Create( filter, 0 );
  76. }
  77. //=============================================================================
  78. //
  79. // Explosions.
  80. //
  81. class CTETFExplosion : public CBaseTempEntity
  82. {
  83. public:
  84. DECLARE_CLASS( CTETFExplosion, CBaseTempEntity );
  85. DECLARE_SERVERCLASS();
  86. CTETFExplosion( const char *name );
  87. public:
  88. Vector m_vecOrigin;
  89. Vector m_vecNormal;
  90. int m_iWeaponID;
  91. int m_nEntIndex;
  92. int m_nDefID;
  93. int m_nSound;
  94. int m_iCustomParticleIndex;
  95. };
  96. // Singleton to fire explosion objects
  97. static CTETFExplosion g_TETFExplosion( "TFExplosion" );
  98. //-----------------------------------------------------------------------------
  99. // Purpose:
  100. // Input : *name -
  101. //-----------------------------------------------------------------------------
  102. CTETFExplosion::CTETFExplosion( const char *name ) : CBaseTempEntity( name )
  103. {
  104. m_vecOrigin.Init();
  105. m_vecNormal.Init();
  106. m_iWeaponID = TF_WEAPON_NONE;
  107. m_nEntIndex = kInvalidEHandleExplosion;
  108. m_nDefID = -1;
  109. m_nSound = SPECIAL1;
  110. m_iCustomParticleIndex = INVALID_STRING_INDEX;
  111. }
  112. IMPLEMENT_SERVERCLASS_ST( CTETFExplosion, DT_TETFExplosion )
  113. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[0] ), -1, SPROP_COORD_MP_INTEGRAL ),
  114. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[1] ), -1, SPROP_COORD_MP_INTEGRAL ),
  115. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[2] ), -1, SPROP_COORD_MP_INTEGRAL ),
  116. SendPropVector( SENDINFO_NOCHECK( m_vecNormal ), 6, 0, -1.0f, 1.0f ),
  117. SendPropInt( SENDINFO_NOCHECK( m_iWeaponID ), Q_log2( TF_WEAPON_COUNT )+1, SPROP_UNSIGNED ),
  118. SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ),
  119. SendPropInt( SENDINFO_NOCHECK( m_nDefID ), -1 ),
  120. SendPropInt( SENDINFO_NOCHECK( m_nSound ), -1 ),
  121. SendPropInt( SENDINFO_NOCHECK( m_iCustomParticleIndex ), -1 ),
  122. END_SEND_TABLE()
  123. void TE_TFExplosion( IRecipientFilter &filter, float flDelay, const Vector &vecOrigin, const Vector &vecNormal, int iWeaponID, int nEntIndex, int nDefID, int nSound, int iCustomParticleIndex )
  124. {
  125. VectorCopy( vecOrigin, g_TETFExplosion.m_vecOrigin );
  126. VectorCopy( vecNormal, g_TETFExplosion.m_vecNormal );
  127. g_TETFExplosion.m_iWeaponID = iWeaponID;
  128. g_TETFExplosion.m_nEntIndex = nEntIndex;
  129. g_TETFExplosion.m_nDefID = nDefID;
  130. g_TETFExplosion.m_nSound = nSound;
  131. g_TETFExplosion.m_iCustomParticleIndex = iCustomParticleIndex;
  132. // Send it over the wire
  133. g_TETFExplosion.Create( filter, flDelay );
  134. }
  135. void TE_TFExplosion( IRecipientFilter &filter, float flDelay, const Vector &vecOrigin, const Vector &vecNormal, int iWeaponID, int nEntIndex, int nDefID, int nSound )
  136. {
  137. TE_TFExplosion( filter, flDelay, vecOrigin, vecNormal, iWeaponID, nEntIndex, nDefID, nSound, INVALID_STRING_INDEX );
  138. }
  139. //=============================================================================
  140. //
  141. // TF ParticleEffect
  142. //
  143. class CTETFParticleEffect : public CBaseTempEntity
  144. {
  145. public:
  146. DECLARE_CLASS( CTETFParticleEffect, CBaseTempEntity );
  147. DECLARE_SERVERCLASS();
  148. CTETFParticleEffect( const char *name );
  149. void Init( void );
  150. public:
  151. Vector m_vecOrigin;
  152. Vector m_vecStart;
  153. QAngle m_vecAngles;
  154. int m_iParticleSystemIndex;
  155. int m_nEntIndex;
  156. int m_iAttachType;
  157. int m_iAttachmentPointIndex;
  158. bool m_bResetParticles;
  159. bool m_bCustomColors;
  160. te_tf_particle_effects_colors_t m_CustomColors;
  161. bool m_bControlPoint1;
  162. te_tf_particle_effects_control_point_t m_ControlPoint1;
  163. };
  164. // Singleton to fire explosion objects
  165. static CTETFParticleEffect g_TETFParticleEffect( "TFParticleEffect" );
  166. //-----------------------------------------------------------------------------
  167. // Purpose:
  168. // Input : *name -
  169. //-----------------------------------------------------------------------------
  170. CTETFParticleEffect::CTETFParticleEffect( const char *name ) : CBaseTempEntity( name )
  171. {
  172. Init();
  173. }
  174. void CTETFParticleEffect::Init( void )
  175. {
  176. m_vecOrigin.Init();
  177. m_vecStart.Init();
  178. m_vecAngles.Init();
  179. m_iParticleSystemIndex = 0;
  180. m_nEntIndex = kInvalidEHandleParticleEffect;
  181. m_iAttachType = PATTACH_ABSORIGIN;
  182. m_iAttachmentPointIndex = 0;
  183. m_bResetParticles = false;
  184. m_bCustomColors = false;
  185. m_CustomColors.m_vecColor1.Init();
  186. m_CustomColors.m_vecColor2.Init();
  187. m_bControlPoint1 = false;
  188. m_ControlPoint1.m_eParticleAttachment = PATTACH_ABSORIGIN;
  189. m_ControlPoint1.m_vecOffset.Init();
  190. }
  191. IMPLEMENT_SERVERCLASS_ST( CTETFParticleEffect, DT_TETFParticleEffect )
  192. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[0] ), -1, SPROP_COORD_MP_INTEGRAL ),
  193. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[1] ), -1, SPROP_COORD_MP_INTEGRAL ),
  194. SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[2] ), -1, SPROP_COORD_MP_INTEGRAL ),
  195. SendPropFloat( SENDINFO_NOCHECK( m_vecStart[0] ), -1, SPROP_COORD_MP_INTEGRAL ),
  196. SendPropFloat( SENDINFO_NOCHECK( m_vecStart[1] ), -1, SPROP_COORD_MP_INTEGRAL ),
  197. SendPropFloat( SENDINFO_NOCHECK( m_vecStart[2] ), -1, SPROP_COORD_MP_INTEGRAL ),
  198. SendPropQAngles( SENDINFO_NOCHECK( m_vecAngles ), 7 ),
  199. SendPropInt( SENDINFO_NOCHECK( m_iParticleSystemIndex ), 16, SPROP_UNSIGNED ), // probably way too high
  200. SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ),
  201. SendPropInt( SENDINFO_NOCHECK( m_iAttachType ), 5, SPROP_UNSIGNED ),
  202. SendPropInt( SENDINFO_NOCHECK( m_iAttachmentPointIndex ), -1 ),
  203. SendPropBool( SENDINFO_NOCHECK( m_bResetParticles ) ),
  204. SendPropBool( SENDINFO_NOCHECK( m_bCustomColors) ),
  205. SendPropVector( SENDINFO_NOCHECK( m_CustomColors.m_vecColor1 ), 8, 0, 0, 1 ),
  206. SendPropVector( SENDINFO_NOCHECK( m_CustomColors.m_vecColor2 ), 8, 0, 0, 1 ),
  207. SendPropBool( SENDINFO_NOCHECK( m_bControlPoint1) ),
  208. SendPropInt( SENDINFO_NOCHECK( m_ControlPoint1.m_eParticleAttachment ), 5, SPROP_UNSIGNED ),
  209. SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[0] ), -1, SPROP_COORD ),
  210. SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[1] ), -1, SPROP_COORD ),
  211. SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[2] ), -1, SPROP_COORD ),
  212. END_SEND_TABLE()
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity *pEntity, const char *pszAttachmentName, bool bResetAllParticlesOnEntity )
  217. {
  218. int iAttachment = -1;
  219. if ( pEntity && pEntity->GetBaseAnimating() )
  220. {
  221. // Find the attachment point index
  222. iAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pszAttachmentName );
  223. if ( iAttachment <= 0 )
  224. {
  225. Warning("Model '%s' doesn't have attachment '%s' to attach particle system '%s' to.\n", STRING(pEntity->GetBaseAnimating()->GetModelName()), pszAttachmentName, pszParticleName );
  226. return;
  227. }
  228. }
  229. TE_TFParticleEffect( filter, flDelay, pszParticleName, iAttachType, pEntity, iAttachment, bResetAllParticlesOnEntity );
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose: Yet another overload, lets us supply vecStart
  233. //-----------------------------------------------------------------------------
  234. void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity *pEntity )
  235. {
  236. int iIndex = GetParticleSystemIndex( pszParticleName );
  237. TE_TFParticleEffect( filter, flDelay, iIndex, vecOrigin, vecStart, vecAngles, pEntity );
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose:
  241. //-----------------------------------------------------------------------------
  242. void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity *pEntity, int iAttachmentPoint, bool bResetAllParticlesOnEntity )
  243. {
  244. g_TETFParticleEffect.Init();
  245. g_TETFParticleEffect.m_iParticleSystemIndex = GetParticleSystemIndex( pszParticleName );
  246. if ( pEntity )
  247. {
  248. g_TETFParticleEffect.m_nEntIndex = pEntity->entindex();
  249. }
  250. g_TETFParticleEffect.m_iAttachType = iAttachType;
  251. g_TETFParticleEffect.m_iAttachmentPointIndex = iAttachmentPoint;
  252. if ( bResetAllParticlesOnEntity )
  253. {
  254. g_TETFParticleEffect.m_bResetParticles = true;
  255. }
  256. // Send it over the wire
  257. g_TETFParticleEffect.Create( filter, flDelay );
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Purpose:
  261. //-----------------------------------------------------------------------------
  262. void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, Vector vecOrigin, QAngle vecAngles, CBaseEntity *pEntity /*= NULL*/, ParticleAttachment_t eAttachType /*= PATTACH_CUSTOMORIGIN*/ )
  263. {
  264. TE_TFParticleEffectComplex( filter, flDelay, pszParticleName, vecOrigin, vecAngles, NULL, NULL, pEntity, eAttachType );
  265. }
  266. //-----------------------------------------------------------------------------
  267. // Purpose:
  268. //-----------------------------------------------------------------------------
  269. void TE_TFParticleEffectComplex
  270. (
  271. IRecipientFilter &filter,
  272. float flDelay,
  273. const char *pszParticleName,
  274. Vector vecOrigin,
  275. QAngle vecAngles,
  276. te_tf_particle_effects_colors_t *pOptionalColors /*= NULL*/,
  277. te_tf_particle_effects_control_point_t *pOptionalControlPoint1 /*= NULL*/,
  278. CBaseEntity *pEntity /*= NULL*/,
  279. ParticleAttachment_t eAttachType /*= PATTACH_CUSTOMORIGIN*/,
  280. Vector vecStart /* = vec3_origin */
  281. )
  282. {
  283. g_TETFParticleEffect.Init();
  284. g_TETFParticleEffect.m_iParticleSystemIndex = GetParticleSystemIndex( pszParticleName );
  285. VectorCopy( vecOrigin, g_TETFParticleEffect.m_vecOrigin );
  286. VectorCopy( vecAngles, g_TETFParticleEffect.m_vecAngles );
  287. VectorCopy( vecStart, g_TETFParticleEffect.m_vecStart );
  288. if ( pEntity )
  289. {
  290. g_TETFParticleEffect.m_nEntIndex = pEntity->entindex();
  291. g_TETFParticleEffect.m_iAttachType = eAttachType;
  292. }
  293. if ( pOptionalColors )
  294. {
  295. g_TETFParticleEffect.m_bCustomColors = true;
  296. g_TETFParticleEffect.m_CustomColors.m_vecColor1 = pOptionalColors->m_vecColor1;
  297. g_TETFParticleEffect.m_CustomColors.m_vecColor2 = pOptionalColors->m_vecColor2;
  298. }
  299. if ( pOptionalControlPoint1 )
  300. {
  301. g_TETFParticleEffect.m_bControlPoint1 = true;
  302. g_TETFParticleEffect.m_ControlPoint1.m_eParticleAttachment = pOptionalControlPoint1->m_eParticleAttachment;
  303. g_TETFParticleEffect.m_ControlPoint1.m_vecOffset = pOptionalControlPoint1->m_vecOffset;
  304. }
  305. // Send it over the wire
  306. g_TETFParticleEffect.Create( filter, flDelay );
  307. }
  308. //-----------------------------------------------------------------------------
  309. // Purpose:
  310. //-----------------------------------------------------------------------------
  311. void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, int iEffectIndex, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity *pEntity )
  312. {
  313. g_TETFParticleEffect.Init();
  314. g_TETFParticleEffect.m_iParticleSystemIndex = iEffectIndex;
  315. VectorCopy( vecOrigin, g_TETFParticleEffect.m_vecOrigin );
  316. VectorCopy( vecStart, g_TETFParticleEffect.m_vecStart );
  317. VectorCopy( vecAngles, g_TETFParticleEffect.m_vecAngles );
  318. if ( pEntity )
  319. {
  320. g_TETFParticleEffect.m_nEntIndex = pEntity->entindex();
  321. g_TETFParticleEffect.m_iAttachType = PATTACH_CUSTOMORIGIN;
  322. }
  323. // Send it over the wire
  324. g_TETFParticleEffect.Create( filter, flDelay );
  325. }