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.

695 lines
21 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Game-specific impact effect hooks
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "fx.h"
  8. #include "c_te_effect_dispatch.h"
  9. #include "tier0/vprof.h"
  10. #include "fx_line.h"
  11. #include "fx_quad.h"
  12. #include "view.h"
  13. #include "particles_localspace.h"
  14. #include "dlight.h"
  15. #include "iefx.h"
  16. #include "clienteffectprecachesystem.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. extern Vector GetTracerOrigin( const CEffectData &data );
  20. extern void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType );
  21. extern ConVar muzzleflash_light;
  22. CLIENTEFFECT_REGISTER_BEGIN( PrecacheTracers )
  23. CLIENTEFFECT_MATERIAL( "effects/gunshiptracer" )
  24. CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
  25. CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
  26. CLIENTEFFECT_REGISTER_END()
  27. //-----------------------------------------------------------------------------
  28. // Purpose: Gunship's Tracer
  29. //-----------------------------------------------------------------------------
  30. void GunshipTracerCallback( const CEffectData &data )
  31. {
  32. float flVelocity = data.m_flScale;
  33. bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
  34. FX_GunshipTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
  35. }
  36. DECLARE_CLIENT_EFFECT( "GunshipTracer", GunshipTracerCallback );
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Strider's Tracer
  39. //-----------------------------------------------------------------------------
  40. void StriderTracerCallback( const CEffectData &data )
  41. {
  42. float flVelocity = data.m_flScale;
  43. bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
  44. FX_StriderTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
  45. }
  46. DECLARE_CLIENT_EFFECT( "StriderTracer", StriderTracerCallback );
  47. //-----------------------------------------------------------------------------
  48. // Purpose: Hunter's Tracer
  49. //-----------------------------------------------------------------------------
  50. void HunterTracerCallback( const CEffectData &data )
  51. {
  52. float flVelocity = data.m_flScale;
  53. bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
  54. FX_HunterTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
  55. }
  56. DECLARE_CLIENT_EFFECT( "HunterTracer", HunterTracerCallback );
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Gauss Gun's Tracer
  59. //-----------------------------------------------------------------------------
  60. void GaussTracerCallback( const CEffectData &data )
  61. {
  62. float flVelocity = data.m_flScale;
  63. bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
  64. FX_GaussTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
  65. }
  66. DECLARE_CLIENT_EFFECT( "GaussTracer", GaussTracerCallback );
  67. //-----------------------------------------------------------------------------
  68. // Purpose: Airboat gun tracers
  69. //-----------------------------------------------------------------------------
  70. void AirboatGunHeavyTracerCallback( const CEffectData &data )
  71. {
  72. // Grab the data
  73. Vector vecStart = GetTracerOrigin( data );
  74. float flVelocity = data.m_flScale;
  75. // Use default velocity if none specified
  76. if ( !flVelocity )
  77. {
  78. flVelocity = 8000;
  79. }
  80. //Get out shot direction and length
  81. Vector vecShotDir;
  82. VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
  83. float flTotalDist = VectorNormalize( vecShotDir );
  84. // Don't make small tracers
  85. if ( flTotalDist <= 64 )
  86. return;
  87. float flLength = random->RandomFloat( 300.0f, 400.0f );
  88. float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
  89. // Add it
  90. FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
  91. }
  92. DECLARE_CLIENT_EFFECT( "AirboatGunHeavyTracer", AirboatGunHeavyTracerCallback );
  93. //-----------------------------------------------------------------------------
  94. // Purpose: Airboat gun tracers
  95. //-----------------------------------------------------------------------------
  96. void AirboatGunTracerCallback( const CEffectData &data )
  97. {
  98. // Grab the data
  99. Vector vecStart = GetTracerOrigin( data );
  100. float flVelocity = data.m_flScale;
  101. // Use default velocity if none specified
  102. if ( !flVelocity )
  103. {
  104. flVelocity = 10000;
  105. }
  106. //Get out shot direction and length
  107. Vector vecShotDir;
  108. VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
  109. float flTotalDist = VectorNormalize( vecShotDir );
  110. // Don't make small tracers
  111. if ( flTotalDist <= 64 )
  112. return;
  113. float flLength = random->RandomFloat( 256.0f, 384.0f );
  114. float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
  115. // Add it
  116. FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 2.0f, flLife, "effects/gunshiptracer" );
  117. }
  118. DECLARE_CLIENT_EFFECT( "AirboatGunTracer", AirboatGunTracerCallback );
  119. //-----------------------------------------------------------------------------
  120. // Purpose: Airboat gun tracers
  121. //-----------------------------------------------------------------------------
  122. void HelicopterTracerCallback( const CEffectData &data )
  123. {
  124. // Grab the data
  125. Vector vecStart = GetTracerOrigin( data );
  126. float flVelocity = data.m_flScale;
  127. // Use default velocity if none specified
  128. if ( !flVelocity )
  129. {
  130. flVelocity = 8000;
  131. }
  132. //Get out shot direction and length
  133. Vector vecShotDir;
  134. VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
  135. float flTotalDist = VectorNormalize( vecShotDir );
  136. // Don't make small tracers
  137. if ( flTotalDist <= 256 )
  138. return;
  139. float flLength = random->RandomFloat( 256.0f, 384.0f );
  140. float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
  141. // Add it
  142. FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
  143. if (data.m_fFlags & TRACER_FLAG_WHIZ)
  144. {
  145. FX_TracerSound( vecStart, data.m_vOrigin, TRACER_TYPE_GUNSHIP );
  146. }
  147. }
  148. DECLARE_CLIENT_EFFECT( "HelicopterTracer", HelicopterTracerCallback );
  149. //-----------------------------------------------------------------------------
  150. // Purpose:
  151. // Input : start -
  152. // end -
  153. //-----------------------------------------------------------------------------
  154. void FX_PlayerAR2Tracer( const Vector &start, const Vector &end )
  155. {
  156. VPROF_BUDGET( "FX_PlayerAR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  157. Vector shotDir, dStart, dEnd;
  158. float length;
  159. //Find the direction of the tracer
  160. VectorSubtract( end, start, shotDir );
  161. length = VectorNormalize( shotDir );
  162. //We don't want to draw them if they're too close to us
  163. if ( length < 128 )
  164. return;
  165. //Randomly place the tracer along this line, with a random length
  166. VectorMA( start, random->RandomFloat( 0.0f, 8.0f ), shotDir, dStart );
  167. VectorMA( dStart, MIN( length, random->RandomFloat( 256.0f, 1024.0f ) ), shotDir, dEnd );
  168. //Create the line
  169. CFXStaticLine *tracerLine = new CFXStaticLine( "Tracer", dStart, dEnd, random->RandomFloat( 6.0f, 12.0f ), 0.01f, "effects/gunshiptracer", 0 );
  170. assert( tracerLine );
  171. //Throw it into the list
  172. clienteffects->AddEffect( tracerLine );
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose:
  176. // Input : start -
  177. // end -
  178. // velocity -
  179. // makeWhiz -
  180. //-----------------------------------------------------------------------------
  181. void FX_AR2Tracer( Vector& start, Vector& end, int velocity, bool makeWhiz )
  182. {
  183. VPROF_BUDGET( "FX_AR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  184. //Don't make small tracers
  185. float dist;
  186. Vector dir;
  187. VectorSubtract( end, start, dir );
  188. dist = VectorNormalize( dir );
  189. // Don't make short tracers.
  190. if ( dist < 128 )
  191. return;
  192. float length = random->RandomFloat( 128.0f, 256.0f );
  193. float life = ( dist + length ) / velocity; //NOTENOTE: We want the tail to finish its run as well
  194. //Add it
  195. FX_AddDiscreetLine( start, dir, velocity, length, dist, random->RandomFloat( 0.5f, 1.5f ), life, "effects/gunshiptracer" );
  196. if( makeWhiz )
  197. {
  198. FX_TracerSound( start, end, TRACER_TYPE_GUNSHIP );
  199. }
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose:
  203. //-----------------------------------------------------------------------------
  204. void AR2TracerCallback( const CEffectData &data )
  205. {
  206. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  207. if ( player == NULL )
  208. return;
  209. // Grab the data
  210. Vector vecStart = GetTracerOrigin( data );
  211. float flVelocity = data.m_flScale;
  212. bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
  213. int iEntIndex = data.entindex();
  214. if ( iEntIndex && iEntIndex == player->index )
  215. {
  216. Vector foo = data.m_vStart;
  217. QAngle vangles;
  218. Vector vforward, vright, vup;
  219. engine->GetViewAngles( vangles );
  220. AngleVectors( vangles, &vforward, &vright, &vup );
  221. VectorMA( data.m_vStart, 4, vright, foo );
  222. foo[2] -= 0.5f;
  223. FX_PlayerAR2Tracer( foo, (Vector&)data.m_vOrigin );
  224. return;
  225. }
  226. // Use default velocity if none specified
  227. if ( !flVelocity )
  228. {
  229. flVelocity = 8000;
  230. }
  231. // Do tracer effect
  232. FX_AR2Tracer( (Vector&)vecStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
  233. }
  234. DECLARE_CLIENT_EFFECT( "AR2Tracer", AR2TracerCallback );
  235. //-----------------------------------------------------------------------------
  236. // Purpose:
  237. // Input : &data -
  238. //-----------------------------------------------------------------------------
  239. void AR2ExplosionCallback( const CEffectData &data )
  240. {
  241. float lifetime = random->RandomFloat( 0.4f, 0.75f );
  242. // Ground splash
  243. FX_AddQuad( data.m_vOrigin,
  244. data.m_vNormal,
  245. data.m_flRadius,
  246. data.m_flRadius * 4.0f,
  247. 0.85f,
  248. 1.0f,
  249. 0.0f,
  250. 0.25f,
  251. random->RandomInt( 0, 360 ),
  252. random->RandomFloat( -4, 4 ),
  253. Vector( 1.0f, 1.0f, 1.0f ),
  254. lifetime,
  255. "effects/combinemuzzle1",
  256. (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
  257. Vector vRight, vUp;
  258. VectorVectors( data.m_vNormal, vRight, vUp );
  259. Vector start, end;
  260. float radius = data.m_flRadius * 0.15f;
  261. // Base vertical shaft
  262. FXLineData_t lineData;
  263. start = data.m_vOrigin;
  264. end = start + ( data.m_vNormal * random->RandomFloat( radius*2.0f, radius*4.0f ) );
  265. lineData.m_flDieTime = lifetime;
  266. lineData.m_flStartAlpha= 1.0f;
  267. lineData.m_flEndAlpha = 0.0f;
  268. lineData.m_flStartScale = radius*4;
  269. lineData.m_flEndScale = radius*5;
  270. lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
  271. lineData.m_vecStart = start;
  272. lineData.m_vecStartVelocity = vec3_origin;
  273. lineData.m_vecEnd = end;
  274. lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 200, 350 );
  275. FX_AddLine( lineData );
  276. // Inner filler shaft
  277. start = data.m_vOrigin;
  278. end = start + ( data.m_vNormal * random->RandomFloat( 16, radius*0.25f ) );
  279. lineData.m_flDieTime = lifetime - 0.1f;
  280. lineData.m_flStartAlpha= 1.0f;
  281. lineData.m_flEndAlpha = 0.0f;
  282. lineData.m_flStartScale = radius*2;
  283. lineData.m_flEndScale = radius*4;
  284. lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
  285. lineData.m_vecStart = start;
  286. lineData.m_vecStartVelocity = vec3_origin;
  287. lineData.m_vecEnd = end;
  288. lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 64, 128 );
  289. FX_AddLine( lineData );
  290. }
  291. DECLARE_CLIENT_EFFECT( "AR2Explosion", AR2ExplosionCallback );
  292. //-----------------------------------------------------------------------------
  293. // Purpose:
  294. // Input : &data -
  295. //-----------------------------------------------------------------------------
  296. void AR2ImpactCallback( const CEffectData &data )
  297. {
  298. FX_AddQuad( data.m_vOrigin,
  299. data.m_vNormal,
  300. random->RandomFloat( 24, 32 ),
  301. 0,
  302. 0.75f,
  303. 1.0f,
  304. 0.0f,
  305. 0.4f,
  306. random->RandomInt( 0, 360 ),
  307. 0,
  308. Vector( 1.0f, 1.0f, 1.0f ),
  309. 0.25f,
  310. "effects/combinemuzzle2_nocull",
  311. (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
  312. }
  313. DECLARE_CLIENT_EFFECT( "AR2Impact", AR2ImpactCallback );
  314. //-----------------------------------------------------------------------------
  315. // Creates a muzzleflash elight
  316. //-----------------------------------------------------------------------------
  317. void CreateMuzzleflashELight( const Vector &origin, int exponent, int nMinRadius, int nMaxRadius, ClientEntityHandle_t hEntity )
  318. {
  319. if ( muzzleflash_light.GetInt() )
  320. {
  321. int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
  322. if ( entityIndex >= 0 )
  323. {
  324. dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
  325. el->origin = origin;
  326. el->color.r = 255;
  327. el->color.g = 192;
  328. el->color.b = 64;
  329. el->color.exponent = exponent;
  330. el->radius = random->RandomInt( nMinRadius, nMaxRadius );
  331. el->decay = el->radius / 0.05f;
  332. el->die = gpGlobals->curtime + 0.1f;
  333. }
  334. }
  335. }
  336. //-----------------------------------------------------------------------------
  337. // Airboat muzzle flashes
  338. //-----------------------------------------------------------------------------
  339. void MuzzleFlash_Airboat( ClientEntityHandle_t hEntity, int attachmentIndex )
  340. {
  341. VPROF_BUDGET( "MuzzleFlash_Airboat", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  342. CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
  343. SimpleParticle *pParticle;
  344. Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
  345. float flScale = random->RandomFloat( 0.75f, IsXbox() ? 2.0f : 2.5f );
  346. PMaterialHandle pMuzzle[2];
  347. pMuzzle[0] = pSimple->GetPMaterial( "effects/combinemuzzle1" );
  348. pMuzzle[1] = pSimple->GetPMaterial( "effects/combinemuzzle2" );
  349. // Flash
  350. for ( int i = 1; i < 7; i++ )
  351. {
  352. offset = (forward * (i*6.0f*flScale));
  353. pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pMuzzle[random->RandomInt(0,1)], offset );
  354. if ( pParticle == NULL )
  355. return;
  356. pParticle->m_flLifetime = 0.0f;
  357. pParticle->m_flDieTime = IsXbox() ? 0.0001f : 0.01f;
  358. pParticle->m_vecVelocity.Init();
  359. pParticle->m_uchColor[0] = 255;
  360. pParticle->m_uchColor[1] = 255;
  361. pParticle->m_uchColor[2] = 255;
  362. pParticle->m_uchStartAlpha = 255;
  363. pParticle->m_uchEndAlpha = 128;
  364. pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (9-(i))/7) * flScale );
  365. pParticle->m_uchEndSize = pParticle->m_uchStartSize;
  366. pParticle->m_flRoll = random->RandomInt( 0, 360 );
  367. pParticle->m_flRollDelta = 0.0f;
  368. }
  369. // Tack on the smoke
  370. pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "sprites/ar2_muzzle1" ), vec3_origin );
  371. if ( pParticle == NULL )
  372. return;
  373. pParticle->m_flLifetime = 0.0f;
  374. pParticle->m_flDieTime = 0.05f;
  375. pParticle->m_vecVelocity.Init();
  376. pParticle->m_uchColor[0] = 255;
  377. pParticle->m_uchColor[1] = 255;
  378. pParticle->m_uchColor[2] = 255;
  379. pParticle->m_uchStartAlpha = 255;
  380. pParticle->m_uchEndAlpha = 128;
  381. pParticle->m_uchStartSize = random->RandomFloat( 16.0f, 24.0f );
  382. pParticle->m_uchEndSize = pParticle->m_uchStartSize;
  383. float spokePos = random->RandomInt( 0, 5 );
  384. pParticle->m_flRoll = (360.0/6.0f)*spokePos;
  385. pParticle->m_flRollDelta = 0.0f;
  386. #ifndef _XBOX
  387. // Grab the origin out of the transform for the attachment
  388. if ( muzzleflash_light.GetInt() )
  389. {
  390. // If the client hasn't seen this entity yet, bail.
  391. matrix3x4_t matAttachment;
  392. if ( FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
  393. {
  394. Vector origin;
  395. MatrixGetColumn( matAttachment, 3, &origin );
  396. CreateMuzzleflashELight( origin, 5, 64, 128, hEntity );
  397. }
  398. }
  399. #endif
  400. }
  401. //-----------------------------------------------------------------------------
  402. // Purpose:
  403. //-----------------------------------------------------------------------------
  404. void AirboatMuzzleFlashCallback( const CEffectData &data )
  405. {
  406. MuzzleFlash_Airboat( data.m_hEntity, data.m_nAttachmentIndex );
  407. }
  408. DECLARE_CLIENT_EFFECT( "AirboatMuzzleFlash", AirboatMuzzleFlashCallback );
  409. //-----------------------------------------------------------------------------
  410. // Chopper muzzle flashes
  411. //-----------------------------------------------------------------------------
  412. void MuzzleFlash_Chopper( ClientEntityHandle_t hEntity, int attachmentIndex )
  413. {
  414. VPROF_BUDGET( "MuzzleFlash_Chopper", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  415. matrix3x4_t matAttachment;
  416. // If the client hasn't seen this entity yet, bail.
  417. if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
  418. return;
  419. CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
  420. SimpleParticle *pParticle;
  421. Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
  422. float flScale = random->RandomFloat( 2.5f, 4.5f );
  423. // Flash
  424. for ( int i = 1; i < 7; i++ )
  425. {
  426. offset = (forward * (i*2.0f*flScale));
  427. pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
  428. if ( pParticle == NULL )
  429. return;
  430. pParticle->m_flLifetime = 0.0f;
  431. pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
  432. pParticle->m_vecVelocity.Init();
  433. pParticle->m_uchColor[0] = 255;
  434. pParticle->m_uchColor[1] = 255;
  435. pParticle->m_uchColor[2] = 255;
  436. pParticle->m_uchStartAlpha = 255;
  437. pParticle->m_uchEndAlpha = 128;
  438. pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (10-(i))/7) * flScale );
  439. pParticle->m_uchEndSize = pParticle->m_uchStartSize;
  440. pParticle->m_flRoll = random->RandomInt( 0, 360 );
  441. pParticle->m_flRollDelta = 0.0f;
  442. }
  443. // Grab the origin out of the transform for the attachment
  444. Vector origin;
  445. MatrixGetColumn( matAttachment, 3, &origin );
  446. CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Purpose:
  450. //-----------------------------------------------------------------------------
  451. void ChopperMuzzleFlashCallback( const CEffectData &data )
  452. {
  453. MuzzleFlash_Chopper( data.m_hEntity, data.m_nAttachmentIndex );
  454. }
  455. DECLARE_CLIENT_EFFECT( "ChopperMuzzleFlash", ChopperMuzzleFlashCallback );
  456. //-----------------------------------------------------------------------------
  457. // Gunship muzzle flashes
  458. //-----------------------------------------------------------------------------
  459. void MuzzleFlash_Gunship( ClientEntityHandle_t hEntity, int attachmentIndex )
  460. {
  461. VPROF_BUDGET( "MuzzleFlash_Gunship", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  462. // If the client hasn't seen this entity yet, bail.
  463. matrix3x4_t matAttachment;
  464. if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
  465. return;
  466. CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
  467. SimpleParticle *pParticle;
  468. Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
  469. float flScale = random->RandomFloat( 2.5f, 4.5f );
  470. // Flash
  471. offset = (forward * (2.0f*flScale));
  472. pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/gunshipmuzzle" ), offset );
  473. if ( pParticle == NULL )
  474. return;
  475. pParticle->m_flLifetime = 0.0f;
  476. pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
  477. pParticle->m_vecVelocity.Init();
  478. pParticle->m_uchColor[0] = 255;
  479. pParticle->m_uchColor[1] = 255;
  480. pParticle->m_uchColor[2] = 255;
  481. pParticle->m_uchStartAlpha = 255;
  482. pParticle->m_uchEndAlpha = 128;
  483. pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * 10.0/7.0) * flScale );
  484. pParticle->m_uchEndSize = pParticle->m_uchStartSize;
  485. pParticle->m_flRoll = random->RandomInt( 0, 360 );
  486. pParticle->m_flRollDelta = 0.0f;
  487. // Grab the origin out of the transform for the attachment
  488. Vector origin;
  489. MatrixGetColumn( matAttachment, 3, &origin );
  490. CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
  491. }
  492. //-----------------------------------------------------------------------------
  493. // Purpose:
  494. //-----------------------------------------------------------------------------
  495. void GunshipMuzzleFlashCallback( const CEffectData &data )
  496. {
  497. MuzzleFlash_Gunship( data.m_hEntity, data.m_nAttachmentIndex );
  498. }
  499. DECLARE_CLIENT_EFFECT( "GunshipMuzzleFlash", GunshipMuzzleFlashCallback );
  500. //-----------------------------------------------------------------------------
  501. // Hunter muzzle flashes
  502. //-----------------------------------------------------------------------------
  503. void MuzzleFlash_Hunter( ClientEntityHandle_t hEntity, int attachmentIndex )
  504. {
  505. VPROF_BUDGET( "MuzzleFlash_Hunter", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  506. // If the client hasn't seen this entity yet, bail.
  507. matrix3x4_t matAttachment;
  508. if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
  509. return;
  510. // Grab the origin out of the transform for the attachment
  511. Vector origin;
  512. MatrixGetColumn( matAttachment, 3, &origin );
  513. dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH );
  514. el->origin = origin;// + Vector( 12.0f, 0, 0 );
  515. el->color.r = 50;
  516. el->color.g = 222;
  517. el->color.b = 213;
  518. el->color.exponent = 5;
  519. el->radius = random->RandomInt( 120, 200 );
  520. el->decay = el->radius / 0.05f;
  521. el->die = gpGlobals->curtime + 0.05f;
  522. }
  523. //-----------------------------------------------------------------------------
  524. // Purpose:
  525. //-----------------------------------------------------------------------------
  526. void HunterMuzzleFlashCallback( const CEffectData &data )
  527. {
  528. MuzzleFlash_Hunter( data.m_hEntity, data.m_nAttachmentIndex );
  529. }
  530. DECLARE_CLIENT_EFFECT( "HunterMuzzleFlash", HunterMuzzleFlashCallback );