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.

335 lines
9.2 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "engine/IEngineSound.h"
  10. #include "view.h"
  11. #include "fx_line.h"
  12. #include "fx_discreetline.h"
  13. #include "fx_quad.h"
  14. #include "clientsideeffects.h"
  15. #include "SoundEmitterSystem/isoundemittersystembase.h"
  16. #include "tier0/vprof.h"
  17. #include "collisionutils.h"
  18. #include "precache_register.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. //FIXME: All these functions will be moved out to FX_Main.CPP or a individual folder
  22. PRECACHE_REGISTER_BEGIN( GLOBAL, PrecacheEffectsTest )
  23. PRECACHE( MATERIAL, "effects/spark" )
  24. PRECACHE( MATERIAL, "effects/gunshiptracer" )
  25. PRECACHE( MATERIAL, "effects/bluespark" )
  26. PRECACHE_REGISTER_END()
  27. //-----------------------------------------------------------------------------
  28. // Purpose:
  29. // Input : &data -
  30. //-----------------------------------------------------------------------------
  31. void FX_AddLine( const FXLineData_t &data )
  32. {
  33. CFXLine *t = new CFXLine( "Line", data );
  34. assert( t );
  35. //Throw it into the list
  36. clienteffects->AddEffect( t );
  37. }
  38. /*
  39. ==================================================
  40. FX_AddStaticLine
  41. ==================================================
  42. */
  43. void FX_AddStaticLine( const Vector& start, const Vector& end, float scale, float life, const char *materialName, unsigned char flags )
  44. {
  45. CFXStaticLine *t = new CFXStaticLine( "StaticLine", start, end, scale, life, materialName, flags );
  46. assert( t );
  47. //Throw it into the list
  48. clienteffects->AddEffect( t );
  49. }
  50. /*
  51. ==================================================
  52. FX_AddDiscreetLine
  53. ==================================================
  54. */
  55. void FX_AddDiscreetLine( const Vector& start, const Vector& direction, float velocity, float length, float clipLength, float scale, float life, const char *shader )
  56. {
  57. CFXDiscreetLine *t = new CFXDiscreetLine( "Line", start, direction, velocity, length, clipLength, scale, life, shader );
  58. assert( t );
  59. //Throw it into the list
  60. clienteffects->AddEffect( t );
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. void FX_AddQuad( const FXQuadData_t &data )
  66. {
  67. CFXQuad *quad = new CFXQuad( data );
  68. Assert( quad != NULL );
  69. clienteffects->AddEffect( quad );
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Purpose: Parameter heavy version
  73. //-----------------------------------------------------------------------------
  74. void FX_AddQuad( const Vector &origin,
  75. const Vector &normal,
  76. float startSize,
  77. float endSize,
  78. float sizeBias,
  79. float startAlpha,
  80. float endAlpha,
  81. float alphaBias,
  82. float yaw,
  83. float deltaYaw,
  84. const Vector &color,
  85. float lifeTime,
  86. const char *shader,
  87. unsigned int flags )
  88. {
  89. FXQuadData_t data;
  90. //Setup the data
  91. data.SetAlpha( startAlpha, endAlpha );
  92. data.SetScale( startSize, endSize );
  93. data.SetFlags( flags );
  94. data.SetMaterial( shader );
  95. data.SetNormal( normal );
  96. data.SetOrigin( origin );
  97. data.SetLifeTime( lifeTime );
  98. data.SetColor( color[0], color[1], color[2] );
  99. data.SetScaleBias( sizeBias );
  100. data.SetAlphaBias( alphaBias );
  101. data.SetYaw( yaw, deltaYaw );
  102. //Output it
  103. FX_AddQuad( data );
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Purpose: Creates a test effect
  107. //-----------------------------------------------------------------------------
  108. void CreateTestEffect( void )
  109. {
  110. //NOTENOTE: Add any test effects here
  111. //FX_BulletPass( NULL, NULL );
  112. }
  113. /*
  114. ==================================================
  115. FX_PlayerTracer
  116. ==================================================
  117. */
  118. #define TRACER_BASE_OFFSET 8
  119. void FX_PlayerTracer( Vector& start, Vector& end )
  120. {
  121. VPROF_BUDGET( "FX_PlayerTracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  122. Vector shotDir, dStart, dEnd;
  123. float length;
  124. //Find the direction of the tracer
  125. VectorSubtract( end, start, shotDir );
  126. length = VectorNormalize( shotDir );
  127. //We don't want to draw them if they're too close to us
  128. if ( length < 256 )
  129. return;
  130. //Randomly place the tracer along this line, with a random length
  131. VectorMA( start, TRACER_BASE_OFFSET + random->RandomFloat( -24.0f, 64.0f ), shotDir, dStart );
  132. VectorMA( dStart, ( length * random->RandomFloat( 0.1f, 0.6f ) ), shotDir, dEnd );
  133. //Create the line
  134. CFXStaticLine *t;
  135. const char *materialName;
  136. //materialName = ( random->RandomInt( 0, 1 ) ) ? "effects/tracer_middle" : "effects/tracer_middle2";
  137. materialName = "effects/spark";
  138. t = new CFXStaticLine( "Tracer", dStart, dEnd, random->RandomFloat( 0.5f, 0.75f ), 0.01f, materialName, 0 );
  139. assert( t );
  140. //Throw it into the list
  141. clienteffects->AddEffect( t );
  142. }
  143. /*
  144. ==================================================
  145. FX_Tracer
  146. ==================================================
  147. */
  148. // Tracer must be this close to be considered for hearing
  149. #define TRACER_MAX_HEAR_DIST (6*12)
  150. #define TRACER_SOUND_TIME_MIN 0.1f
  151. #define TRACER_SOUND_TIME_MAX 0.1f
  152. class CBulletWhizTimer : public CAutoGameSystem
  153. {
  154. public:
  155. CBulletWhizTimer( char const *name ) : CAutoGameSystem( name )
  156. {
  157. }
  158. void LevelInitPreEntity()
  159. {
  160. m_nextWhizTime = 0;
  161. }
  162. float m_nextWhizTime;
  163. };
  164. // Client-side tracking for whiz noises
  165. CBulletWhizTimer g_BulletWhiz( "CBulletWhizTimer" );
  166. //-----------------------------------------------------------------------------
  167. // Purpose:
  168. // Input : &vecStart -
  169. // &vecDir -
  170. // iTracerType -
  171. //-----------------------------------------------------------------------------
  172. #define LISTENER_HEIGHT 24
  173. ConVar cl_tracer_whiz_distance( "cl_tracer_whiz_distance", "72" ); // putting TRACER_MAX_HEAR_DIST on a cvar, so KellyT can find a good value
  174. void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType )
  175. {
  176. const char *pszSoundName = NULL;
  177. float flWhizDist = TRACER_MAX_HEAR_DIST;
  178. float flMinWhizTime = TRACER_SOUND_TIME_MIN;
  179. float flMaxWhizTime = TRACER_SOUND_TIME_MAX;
  180. HACK_GETLOCALPLAYER_GUARD( "FX_TracerSound" );
  181. Vector vecListenOrigin = MainViewOrigin(GET_ACTIVE_SPLITSCREEN_SLOT());
  182. switch( iTracerType )
  183. {
  184. case TRACER_TYPE_DEFAULT:
  185. {
  186. pszSoundName = "Bullets.DefaultNearmiss";
  187. flWhizDist = cl_tracer_whiz_distance.GetFloat(); // was 24
  188. Ray_t bullet, listener;
  189. bullet.Init( start, end );
  190. Vector vecLower = vecListenOrigin;
  191. vecLower.z -= LISTENER_HEIGHT;
  192. listener.Init( vecListenOrigin, vecLower );
  193. float s, t;
  194. IntersectRayWithRay( bullet, listener, s, t );
  195. t = clamp( t, 0, 1 );
  196. vecListenOrigin.z -= t * LISTENER_HEIGHT;
  197. }
  198. break;
  199. case TRACER_TYPE_GUNSHIP:
  200. pszSoundName = "Bullets.GunshipNearmiss";
  201. break;
  202. case TRACER_TYPE_STRIDER:
  203. pszSoundName = "Bullets.StriderNearmiss";
  204. break;
  205. case TRACER_TYPE_WATERBULLET:
  206. pszSoundName = "Underwater.BulletImpact";
  207. flWhizDist = 48;
  208. flMinWhizTime = 0.3f;
  209. flMaxWhizTime = 0.6f;
  210. break;
  211. default:
  212. return;
  213. }
  214. if( !pszSoundName )
  215. return;
  216. // Is it time yet?
  217. float dt = g_BulletWhiz.m_nextWhizTime - gpGlobals->curtime;
  218. if ( dt > 0 )
  219. return;
  220. // Did the thing pass close enough to our head?
  221. float vDist = CalcDistanceSqrToLineSegment( vecListenOrigin, start, end );
  222. if ( vDist >= (flWhizDist * flWhizDist) )
  223. return;
  224. CSoundParameters params;
  225. if( C_BaseEntity::GetParametersForSound( pszSoundName, params, NULL ) )
  226. {
  227. // Get shot direction
  228. Vector shotDir;
  229. VectorSubtract( end, start, shotDir );
  230. VectorNormalize( shotDir );
  231. CLocalPlayerFilter filter;
  232. enginesound->EmitSound( filter, SOUND_FROM_WORLD, CHAN_STATIC, pszSoundName, SOUNDEMITTER_INVALID_HASH, params.soundname,
  233. params.volume, SNDLVL_TO_ATTN(params.soundlevel), params.m_nRandomSeed, 0, params.pitch, &start, &shotDir, NULL);
  234. }
  235. // FIXME: This has a bad behavior when both bullet + strider shots are whizzing by at the same time
  236. // Could use different timers for the different types.
  237. // Don't play another bullet whiz for this client until this time has run out
  238. g_BulletWhiz.m_nextWhizTime = gpGlobals->curtime + random->RandomFloat( flMinWhizTime, flMaxWhizTime );
  239. }
  240. void FX_Tracer( Vector& start, Vector& end, int velocity, bool makeWhiz )
  241. {
  242. VPROF_BUDGET( "FX_Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
  243. //Don't make small tracers
  244. float dist;
  245. Vector dir;
  246. VectorSubtract( end, start, dir );
  247. dist = VectorNormalize( dir );
  248. int minDist;
  249. float flMinWidth;
  250. float flMaxWidth;
  251. #if defined( CSTRIKE2_DLL )
  252. // we want short tracers for CS2 - mtw
  253. // NOTE: should this all be done with the new particle system now?
  254. minDist = 128;
  255. // testing fatter tracers for CS2 - mtw
  256. flMinWidth = 3.75;
  257. flMaxWidth = 5.0;
  258. #else
  259. // Don't make short tracers.
  260. minDist = 256;
  261. flMinWidth = 0.75;
  262. flMaxWidth = 0.9;
  263. #endif
  264. if ( dist >= minDist )
  265. {
  266. float length = random->RandomFloat( 64.0f, 128.0f );
  267. float life = ( dist + length ) / velocity; //NOTENOTE: We want the tail to finish its run as well
  268. //Add it
  269. FX_AddDiscreetLine( start, dir, velocity, length, dist, random->RandomFloat( flMinWidth, flMaxWidth ), life, "effects/spark" );
  270. }
  271. if( makeWhiz )
  272. {
  273. FX_TracerSound( start, end, TRACER_TYPE_DEFAULT );
  274. }
  275. }