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.

339 lines
9.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "c_prop_combine_ball.h"
  8. #include "materialsystem/imaterial.h"
  9. #include "model_types.h"
  10. #include "c_physicsprop.h"
  11. #include "c_te_effect_dispatch.h"
  12. #include "fx_quad.h"
  13. #include "fx.h"
  14. #include "clienteffectprecachesystem.h"
  15. #include "view.h"
  16. #include "view_scene.h"
  17. #include "beamdraw.h"
  18. // Precache our effects
  19. CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCombineBall )
  20. CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
  21. CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
  22. CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" )
  23. CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
  24. CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
  25. CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
  26. CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
  27. CLIENTEFFECT_REGISTER_END()
  28. IMPLEMENT_CLIENTCLASS_DT( C_PropCombineBall, DT_PropCombineBall, CPropCombineBall )
  29. RecvPropBool( RECVINFO( m_bEmit ) ),
  30. RecvPropFloat( RECVINFO( m_flRadius ) ),
  31. RecvPropBool( RECVINFO( m_bHeld ) ),
  32. RecvPropBool( RECVINFO( m_bLaunched ) ),
  33. END_RECV_TABLE()
  34. //-----------------------------------------------------------------------------
  35. // Purpose:
  36. //-----------------------------------------------------------------------------
  37. C_PropCombineBall::C_PropCombineBall( void )
  38. {
  39. m_pFlickerMaterial = NULL;
  40. m_pBodyMaterial = NULL;
  41. m_pBlurMaterial = NULL;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose:
  45. // Input : updateType -
  46. //-----------------------------------------------------------------------------
  47. void C_PropCombineBall::OnDataChanged( DataUpdateType_t updateType )
  48. {
  49. BaseClass::OnDataChanged( updateType );
  50. if ( updateType == DATA_UPDATE_CREATED )
  51. {
  52. m_vecLastOrigin = GetAbsOrigin();
  53. InitMaterials();
  54. }
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. // Output : RenderGroup_t
  59. //-----------------------------------------------------------------------------
  60. RenderGroup_t C_PropCombineBall::GetRenderGroup( void )
  61. {
  62. return RENDER_GROUP_TRANSLUCENT_ENTITY;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose: Cache the material handles
  66. // Output : Returns true on success, false on failure.
  67. //-----------------------------------------------------------------------------
  68. bool C_PropCombineBall::InitMaterials( void )
  69. {
  70. // Motion blur
  71. if ( m_pBlurMaterial == NULL )
  72. {
  73. m_pBlurMaterial = materials->FindMaterial( "effects/ar2_altfire1b", NULL, false );
  74. if ( m_pBlurMaterial == NULL )
  75. return false;
  76. }
  77. // Main body of the ball
  78. if ( m_pBodyMaterial == NULL )
  79. {
  80. m_pBodyMaterial = materials->FindMaterial( "effects/ar2_altfire1", NULL, false );
  81. if ( m_pBodyMaterial == NULL )
  82. return false;
  83. }
  84. // Flicker material
  85. if ( m_pFlickerMaterial == NULL )
  86. {
  87. m_pFlickerMaterial = materials->FindMaterial( "effects/combinemuzzle1", NULL, false );
  88. if ( m_pFlickerMaterial == NULL )
  89. return false;
  90. }
  91. return true;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Purpose:
  95. //-----------------------------------------------------------------------------
  96. void C_PropCombineBall::DrawMotionBlur( void )
  97. {
  98. float color[3];
  99. Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
  100. float speed = VectorNormalize( vecDir );
  101. speed = clamp( speed, 0, 32 );
  102. float stepSize = MIN( ( speed * 0.5f ), 4.0f );
  103. Vector spawnPos = GetAbsOrigin();
  104. Vector spawnStep = -vecDir * stepSize;
  105. float base = RemapValClamped( speed, 4, 32, 0.0f, 1.0f );
  106. CMatRenderContextPtr pRenderContext( materials );
  107. pRenderContext->Bind( m_pBlurMaterial );
  108. // Draw the motion blurred trail
  109. for ( int i = 0; i < 8; i++ )
  110. {
  111. spawnPos += spawnStep;
  112. color[0] = color[1] = color[2] = base * ( 1.0f - ( (float) i / 12.0f ) );
  113. DrawHalo( m_pBlurMaterial, spawnPos, m_flRadius, color );
  114. }
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. //-----------------------------------------------------------------------------
  119. void C_PropCombineBall::DrawFlicker( void )
  120. {
  121. float rand1 = random->RandomFloat( 0.2f, 0.3f );
  122. float rand2 = random->RandomFloat( 1.5f, 2.5f );
  123. if ( gpGlobals->frametime == 0.0f )
  124. {
  125. rand1 = 0.2f;
  126. rand2 = 1.5f;
  127. }
  128. float color[3];
  129. color[0] = color[1] = color[2] = rand1;
  130. // Draw the flickering glow
  131. CMatRenderContextPtr pRenderContext( materials );
  132. pRenderContext->Bind( m_pFlickerMaterial );
  133. DrawHalo( m_pFlickerMaterial, GetAbsOrigin(), m_flRadius * rand2, color );
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose:
  137. // Input : pMaterial -
  138. // source -
  139. // color -
  140. //-----------------------------------------------------------------------------
  141. void DrawHaloOriented( const Vector& source, float scale, float const *color, float roll )
  142. {
  143. Vector point, screen;
  144. CMatRenderContextPtr pRenderContext( materials );
  145. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  146. CMeshBuilder meshBuilder;
  147. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  148. // Transform source into screen space
  149. ScreenTransform( source, screen );
  150. Vector right, up;
  151. float sr, cr;
  152. SinCos( roll, &sr, &cr );
  153. for ( int i = 0; i < 3; i++ )
  154. {
  155. right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr;
  156. up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr;
  157. }
  158. meshBuilder.Color3fv (color);
  159. meshBuilder.TexCoord2f (0, 0, 1);
  160. VectorMA (source, -scale, up, point);
  161. VectorMA (point, -scale, right, point);
  162. meshBuilder.Position3fv (point.Base());
  163. meshBuilder.AdvanceVertex();
  164. meshBuilder.Color3fv (color);
  165. meshBuilder.TexCoord2f (0, 0, 0);
  166. VectorMA (source, scale, up, point);
  167. VectorMA (point, -scale, right, point);
  168. meshBuilder.Position3fv (point.Base());
  169. meshBuilder.AdvanceVertex();
  170. meshBuilder.Color3fv (color);
  171. meshBuilder.TexCoord2f (0, 1, 0);
  172. VectorMA (source, scale, up, point);
  173. VectorMA (point, scale, right, point);
  174. meshBuilder.Position3fv (point.Base());
  175. meshBuilder.AdvanceVertex();
  176. meshBuilder.Color3fv (color);
  177. meshBuilder.TexCoord2f (0, 1, 1);
  178. VectorMA (source, -scale, up, point);
  179. VectorMA (point, scale, right, point);
  180. meshBuilder.Position3fv (point.Base());
  181. meshBuilder.AdvanceVertex();
  182. meshBuilder.End();
  183. pMesh->Draw();
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Purpose:
  187. // Input : flags -
  188. // Output : int
  189. //-----------------------------------------------------------------------------
  190. int C_PropCombineBall::DrawModel( int flags )
  191. {
  192. if ( !m_bEmit )
  193. return 0;
  194. // Make sure our materials are cached
  195. if ( !InitMaterials() )
  196. {
  197. //NOTENOTE: This means that a material was not found for the combine ball, so it may not render!
  198. AssertOnce( 0 );
  199. return 0;
  200. }
  201. // Draw the flickering overlay
  202. DrawFlicker();
  203. // Draw the motion blur from movement
  204. if ( m_bHeld || m_bLaunched )
  205. {
  206. DrawMotionBlur();
  207. }
  208. // Draw the model if we're being held
  209. if ( m_bHeld )
  210. {
  211. QAngle angles;
  212. VectorAngles( -CurrentViewForward(), angles );
  213. // Always orient towards the camera!
  214. SetAbsAngles( angles );
  215. BaseClass::DrawModel( flags );
  216. }
  217. else
  218. {
  219. float color[3];
  220. color[0] = color[1] = color[2] = 1.0f;
  221. float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 );
  222. float roll = SpawnTime();
  223. // Draw the main ball body
  224. CMatRenderContextPtr pRenderContext( materials );
  225. pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this );
  226. DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll );
  227. }
  228. m_vecLastOrigin = GetAbsOrigin();
  229. return 1;
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose:
  233. // Input : &data -
  234. //-----------------------------------------------------------------------------
  235. void CombineBallImpactCallback( const CEffectData &data )
  236. {
  237. // Quick flash
  238. FX_AddQuad( data.m_vOrigin,
  239. data.m_vNormal,
  240. data.m_flRadius * 10.0f,
  241. 0,
  242. 0.75f,
  243. 1.0f,
  244. 0.0f,
  245. 0.4f,
  246. random->RandomInt( 0, 360 ),
  247. 0,
  248. Vector( 1.0f, 1.0f, 1.0f ),
  249. 0.25f,
  250. "effects/combinemuzzle1_nocull",
  251. (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
  252. // Lingering burn
  253. FX_AddQuad( data.m_vOrigin,
  254. data.m_vNormal,
  255. data.m_flRadius * 2.0f,
  256. data.m_flRadius * 4.0f,
  257. 0.75f,
  258. 1.0f,
  259. 0.0f,
  260. 0.4f,
  261. random->RandomInt( 0, 360 ),
  262. 0,
  263. Vector( 1.0f, 1.0f, 1.0f ),
  264. 0.5f,
  265. "effects/combinemuzzle2_nocull",
  266. (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
  267. // Throw sparks
  268. FX_ElectricSpark( data.m_vOrigin, 2, 1, &data.m_vNormal );
  269. }
  270. DECLARE_CLIENT_EFFECT( "cball_bounce", CombineBallImpactCallback );
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. // Input : &data -
  274. //-----------------------------------------------------------------------------
  275. void CombineBallExplosionCallback( const CEffectData &data )
  276. {
  277. Vector normal(0,0,1);
  278. // Throw sparks
  279. FX_ElectricSpark( data.m_vOrigin, 4, 1, &normal );
  280. }
  281. DECLARE_CLIENT_EFFECT( "cball_explode", CombineBallExplosionCallback );