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.

306 lines
7.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "fx.h"
  8. #include "c_gib.h"
  9. #include "c_te_effect_dispatch.h"
  10. #include "iefx.h"
  11. #include "decals.h"
  12. #define HUMAN_GIBS 1
  13. #define ALIEN_GIBS 2
  14. #define MAX_GIBS 4
  15. #define HUMAN_GIB_COUNT 6
  16. #define ALIEN_GIB_COUNT 4
  17. const char *pHumanGibsModel = "models/gibs/hgibs.mdl";
  18. const char *pAlienGibsModel = "models/gibs/agibs.mdl";
  19. void GetBloodColorHL1( int bloodtype, unsigned char &r, unsigned char &g, unsigned char &b )
  20. {
  21. if (bloodtype == BLOOD_COLOR_RED)
  22. {
  23. r = 64;
  24. g = 0;
  25. b = 0;
  26. }
  27. else if ( bloodtype == BLOOD_COLOR_GREEN )
  28. {
  29. r = 195;
  30. g = 195;
  31. b = 0;
  32. }
  33. else if ( bloodtype == BLOOD_COLOR_YELLOW )
  34. {
  35. r = 0;
  36. g = 195;
  37. b = 195;
  38. }
  39. }
  40. class C_HL1Gib : public C_Gib
  41. {
  42. typedef C_BaseAnimating BaseClass;
  43. public:
  44. static C_HL1Gib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp )
  45. {
  46. C_HL1Gib *pGib = new C_HL1Gib;
  47. if ( pGib == NULL )
  48. return NULL;
  49. if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp ) == false )
  50. return NULL;
  51. return pGib;
  52. }
  53. // Decal the surface
  54. virtual void HitSurface( C_BaseEntity *pOther )
  55. {
  56. int index = -1;
  57. if ( m_iType == HUMAN_GIBS )
  58. {
  59. if ( !UTIL_IsLowViolence() ) // no blood decals if we're low violence.
  60. {
  61. index = decalsystem->GetDecalIndexForName( "Blood" );
  62. }
  63. }
  64. else
  65. {
  66. index = decalsystem->GetDecalIndexForName( "YellowBlood" );
  67. }
  68. if ( index >= 0 )
  69. {
  70. effects->DecalShoot( index, pOther->entindex(), pOther->GetModel(), pOther->GetAbsOrigin(), pOther->GetAbsAngles(), GetAbsOrigin(), 0, 0 );
  71. }
  72. if ( GetFlags() & FL_ONGROUND )
  73. {
  74. QAngle vAngles = GetAbsAngles();
  75. QAngle vAngularVelocity = GetLocalAngularVelocity();
  76. SetAbsVelocity( GetAbsVelocity() * 0.9 );
  77. vAngles.x = 0;
  78. vAngles.z = 0;
  79. vAngularVelocity.x = 0;
  80. vAngularVelocity.z = 0;
  81. SetAbsAngles( vAngles );
  82. SetLocalAngularVelocity( vAngularVelocity );
  83. }
  84. }
  85. virtual void ClientThink( void );
  86. int m_iType;
  87. };
  88. void C_HL1Gib::ClientThink( void )
  89. {
  90. SetRenderMode( kRenderTransAlpha );
  91. m_nRenderFX = kRenderFxFadeSlow;
  92. if ( m_clrRender->a == 5 )
  93. {
  94. Release();
  95. return;
  96. }
  97. SetNextClientThink( gpGlobals->curtime + 1.0f );
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. // Input : &origin -
  102. //-----------------------------------------------------------------------------
  103. void FX_HL1Gib( const Vector &origin, const Vector &direction, float scale, int iType, int iHealth, int iColor )
  104. {
  105. Vector offset;
  106. int i;
  107. offset = RandomVector( -16, 16 ) + origin;
  108. if ( iType == HUMAN_GIBS )
  109. {
  110. Vector vVelocity;
  111. AngularImpulse aImpulse;
  112. // mix in some noise
  113. vVelocity.x = random->RandomFloat( -100,100 );
  114. vVelocity.y = random->RandomFloat ( -100,100 );
  115. vVelocity.z = random->RandomFloat ( 200,300 );
  116. aImpulse.x = random->RandomFloat ( 100, 200 );
  117. aImpulse.y = random->RandomFloat ( 100, 300 );
  118. if ( iHealth > -50)
  119. {
  120. vVelocity = vVelocity * 0.7;
  121. }
  122. else if ( iHealth > -200)
  123. {
  124. vVelocity = vVelocity * 2;
  125. }
  126. else
  127. {
  128. vVelocity = vVelocity * 4;
  129. }
  130. C_HL1Gib *pGib = C_HL1Gib::CreateClientsideGib( pHumanGibsModel, offset, vVelocity * 2, aImpulse );
  131. //Spawn a head.
  132. if ( pGib )
  133. {
  134. pGib->m_nBody = 0;
  135. pGib->m_iType = iType;
  136. }
  137. }
  138. // Spawn all the unique gibs
  139. for ( i = 0; i < MAX_GIBS; i++ )
  140. {
  141. const char *pModelName = NULL;
  142. int iNumBody = 0;
  143. offset = RandomVector( -16, 16 ) + origin;
  144. //TODO
  145. Vector vVelocity = direction;
  146. AngularImpulse aAImpulse;
  147. // mix in some noise
  148. vVelocity.x += random->RandomFloat( -0.25, 0.25 );
  149. vVelocity.y += random->RandomFloat ( -0.25, 0.25 );
  150. vVelocity.z += random->RandomFloat ( -0.25, 0.25 );
  151. vVelocity = vVelocity * random->RandomFloat ( 300, 400 );
  152. if ( iHealth > -50)
  153. {
  154. vVelocity = vVelocity * 0.7;
  155. }
  156. else if ( iHealth > -200)
  157. {
  158. vVelocity = vVelocity * 2;
  159. }
  160. else
  161. {
  162. vVelocity = vVelocity * 4;
  163. }
  164. aAImpulse.x = random->RandomFloat ( 100, 200 );
  165. aAImpulse.y = random->RandomFloat ( 100, 300 );
  166. if ( iType == HUMAN_GIBS )
  167. {
  168. pModelName = pHumanGibsModel;
  169. iNumBody = HUMAN_GIB_COUNT;
  170. }
  171. else
  172. {
  173. pModelName = pAlienGibsModel;
  174. iNumBody = ALIEN_GIB_COUNT;
  175. }
  176. C_HL1Gib *pGib = C_HL1Gib::CreateClientsideGib( pModelName, offset, vVelocity * 2, aAImpulse );
  177. if ( pGib )
  178. {
  179. if ( iType == HUMAN_GIBS )
  180. pGib->m_nBody = random->RandomInt( 1, iNumBody-1 );
  181. else
  182. pGib->m_nBody = random->RandomInt( 0, iNumBody-1 );
  183. pGib->m_iType = iType;
  184. }
  185. }
  186. //
  187. // Throw some blood (unless we're low violence, then we're done)
  188. //
  189. if ( iColor == BLOOD_COLOR_RED && UTIL_IsLowViolence() )
  190. return;
  191. CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_HL1Gib" );
  192. pSimple->SetSortOrigin( origin );
  193. Vector vDir;
  194. vDir.Random( -1.0f, 1.0f );
  195. for ( i = 0; i < 4; i++ )
  196. {
  197. SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
  198. if ( sParticle == NULL )
  199. return;
  200. sParticle->m_flLifetime = 0.0f;
  201. sParticle->m_flDieTime = 1;
  202. float speed = random->RandomFloat( 32.0f, 128.0f );
  203. sParticle->m_vecVelocity = vDir * -speed;
  204. sParticle->m_vecVelocity[2] -= 16.0f;
  205. GetBloodColorHL1( iColor, sParticle->m_uchColor[0], sParticle->m_uchColor[1], sParticle->m_uchColor[2] );
  206. sParticle->m_uchStartAlpha = 255;
  207. sParticle->m_uchEndAlpha = 0;
  208. sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
  209. sParticle->m_uchEndSize = sParticle->m_uchStartSize*random->RandomInt( 1, 4 );
  210. sParticle->m_flRoll = random->RandomInt( 0, 360 );
  211. sParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f );
  212. }
  213. for ( i = 0; i < 4; i++ )
  214. {
  215. SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[1], origin );
  216. if ( sParticle == NULL )
  217. {
  218. return;
  219. }
  220. sParticle->m_flLifetime = 0.0f;
  221. sParticle->m_flDieTime = 1;
  222. float speed = random->RandomFloat( 16.0f, 128.0f );
  223. sParticle->m_vecVelocity = vDir * -speed;
  224. sParticle->m_vecVelocity[2] -= 16.0f;
  225. GetBloodColorHL1( iColor, sParticle->m_uchColor[0], sParticle->m_uchColor[1], sParticle->m_uchColor[2] );
  226. sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
  227. sParticle->m_uchEndAlpha = 0;
  228. sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
  229. sParticle->m_uchEndSize = sParticle->m_uchStartSize*random->RandomInt( 1, 4 );
  230. sParticle->m_flRoll = random->RandomInt( 0, 360 );
  231. sParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f );
  232. }
  233. }
  234. //-----------------------------------------------------------------------------
  235. // Purpose:
  236. // Input : &data -
  237. //-----------------------------------------------------------------------------
  238. void HL1GibCallback( const CEffectData &data )
  239. {
  240. FX_HL1Gib( data.m_vOrigin, data.m_vNormal, data.m_flScale, data.m_nMaterial, -data.m_nHitBox, data.m_nColor );
  241. }
  242. DECLARE_CLIENT_EFFECT( "HL1Gib", HL1GibCallback );