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.

235 lines
6.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Game-specific impact effect hooks
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "c_te_effect_dispatch.h"
  8. #include "tempent.h"
  9. #include "c_te_legacytempents.h"
  10. #include "c_cs_player.h"
  11. #include "c_rope.h"
  12. // NOTE: Always include this last!
  13. #include "tier0/memdbgon.h"
  14. extern int g_sModelXmasBulb; // holds the sprite index for splattered blood
  15. // Used for cycling so that they're sequencially ordered on each strand
  16. int g_nHolidayLightColor = 0;
  17. // 4 light colors
  18. Color g_rgbaHolidayRed( 255, 0, 0, 255 );
  19. Color g_rgbaHolidayYellow( 2, 110, 197, 255 );
  20. Color g_rgbaHolidayGreen( 117, 193, 8, 255 );
  21. Color g_rgbaHolidayBlue( 255, 151, 29, 255 );
  22. Color g_rgbaHalloweenOrange( 239, 136, 15, 255 );
  23. Color g_rgbaHalloweenPurple( 128, 46, 204, 255 );
  24. Color *(rgbaHolidayLightColors[]) = { &g_rgbaHolidayRed,
  25. &g_rgbaHolidayYellow,
  26. &g_rgbaHolidayGreen,
  27. &g_rgbaHolidayBlue };
  28. Color *( rgbaHalloweenLightColors[] ) = { &g_rgbaHalloweenOrange,
  29. &g_rgbaHalloweenPurple };
  30. struct HolidayLightData_t
  31. {
  32. Vector vOrigin;
  33. int nID;
  34. int nSubID;
  35. float fScale;
  36. };
  37. void CreateHolidayLight( const HolidayLightData_t &holidayLight );
  38. class CHolidayLightManager : public CAutoGameSystemPerFrame
  39. {
  40. public:
  41. explicit CHolidayLightManager( char const *name );
  42. // Methods of IGameSystem
  43. virtual void Update( float frametime );
  44. virtual void LevelInitPostEntity( void );
  45. virtual void LevelShutdownPreEntity();
  46. void AddHolidayLight( const CEffectData &data );
  47. private:
  48. CUtlVector< HolidayLightData_t > m_PendingLightData;
  49. };
  50. CHolidayLightManager g_CHolidayLightManager( "CHolidayLightManager" );
  51. CHolidayLightManager::CHolidayLightManager( char const *name ) : CAutoGameSystemPerFrame( name )
  52. {
  53. }
  54. // Methods of IGameSystem
  55. void CHolidayLightManager::Update( float frametime )
  56. {
  57. for ( int i = 0; i < m_PendingLightData.Count(); ++i )
  58. {
  59. CreateHolidayLight( m_PendingLightData[ i ] );
  60. }
  61. m_PendingLightData.RemoveAll();
  62. }
  63. void CHolidayLightManager::LevelInitPostEntity( void )
  64. {
  65. m_PendingLightData.RemoveAll();
  66. }
  67. void CHolidayLightManager::LevelShutdownPreEntity()
  68. {
  69. m_PendingLightData.RemoveAll();
  70. }
  71. void CHolidayLightManager::AddHolidayLight( const CEffectData &data )
  72. {
  73. C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer();
  74. if ( !pPlayer )
  75. return;
  76. Vector vecPlayerPos = pPlayer->GetNetworkOrigin();
  77. // Too far away?
  78. if ( vecPlayerPos.DistTo( data.m_vOrigin ) > 2000.0f )
  79. return;
  80. // In the skybox?
  81. sky3dparams_t *pSky = &(pPlayer->m_Local.m_skybox3d);
  82. if ( pSky->origin->DistTo( data.m_vOrigin ) < 2000.0f )
  83. return;
  84. HolidayLightData_t newData;
  85. newData.vOrigin = data.m_vOrigin;
  86. // HACK: Use these ints to ID the light later
  87. newData.nID = data.m_nMaterial;
  88. newData.nSubID = data.m_nHitBox;
  89. // Skybox lights pass in a smaller scale
  90. newData.fScale = data.m_flScale;
  91. if ( m_PendingLightData.Count() < CTempEnts::MAX_TEMP_ENTITIES / 2 )
  92. {
  93. m_PendingLightData.AddToTail( newData );
  94. }
  95. }
  96. void CS_HolidayLightCallback( const CEffectData &data )
  97. {
  98. g_CHolidayLightManager.AddHolidayLight( data );
  99. }
  100. #define XMAS_LIGHT_MODEL "models/props/holiday_light/holiday_light.mdl"
  101. void CreateHolidayLight( const HolidayLightData_t &holidayLight )
  102. {
  103. int nHolidayLightStyle = RopeManager()->GetHolidayLightStyle();
  104. model_t *pModel = ( nHolidayLightStyle == 0 ? (model_t *)engine->LoadModel( "effects/christmas_bulb.vmt" ) : (model_t *)engine->LoadModel( XMAS_LIGHT_MODEL ) );
  105. if ( !pModel )
  106. return;
  107. Assert( pModel );
  108. C_LocalTempEntity *pTemp = tempents->FindTempEntByID( holidayLight.nID, holidayLight.nSubID );
  109. if ( !pTemp )
  110. {
  111. // Didn't find one with that ID, so make a new one!
  112. // Randomize the angle
  113. QAngle angOrientation = ( nHolidayLightStyle == 0 ? QAngle( 0.0f, 0.0f, RandomFloat( -180.0f, 180.0f ) ) : vec3_angle );
  114. //pTemp = tempents->SpawnTempModel( pModel, holidayLight.vOrigin, angOrientation, vec3_origin, 2.0f, FTENT_NEVERDIE );
  115. pTemp = tempents->SpawnTempModel( pModel, holidayLight.vOrigin, angOrientation, vec3_origin, 2.0f, FTENT_NONE );
  116. if ( !pTemp )
  117. {
  118. return;
  119. }
  120. pTemp->clientIndex = 0;
  121. // HACK: Use these ints to ID the light later
  122. pTemp->m_nSkin = holidayLight.nID;
  123. pTemp->hitSound = holidayLight.nSubID;
  124. pTemp->SetDistanceFade( 1024, 1200 );
  125. // Skybox lights pass in a smaller scale
  126. pTemp->m_flSpriteScale = holidayLight.fScale;
  127. // Smuggle the color index here
  128. if ( nHolidayLightStyle == 0 )
  129. {
  130. pTemp->m_nHitboxSet = g_nHolidayLightColor;
  131. //Set the color
  132. {
  133. pTemp->SetRenderColor( rgbaHolidayLightColors[ g_nHolidayLightColor ]->r(),
  134. rgbaHolidayLightColors[ g_nHolidayLightColor ]->g(),
  135. rgbaHolidayLightColors[ g_nHolidayLightColor ]->b()/*,
  136. rgbaHolidayLightColors[ g_nHolidayLightColor ]->a() */);
  137. }
  138. }
  139. pTemp->SetRenderMode( kRenderTransColor );
  140. pTemp->SetProxyRandomValue( RandomFloat() );
  141. // Next color in the pattern
  142. g_nHolidayLightColor = ( g_nHolidayLightColor + 1 ) % ARRAYSIZE( rgbaHolidayLightColors );
  143. }
  144. else
  145. {
  146. // Update the position
  147. pTemp->SetAbsOrigin( holidayLight.vOrigin );
  148. // Every 10 light strands have a blink cycle
  149. if ( nHolidayLightStyle == 0 && pTemp->m_nSkin % 5 == 0 )
  150. {
  151. // Magic! Basically this makes the on/off cycle of each color different and offsets it by the segment index.
  152. // That way it looks like a timed pattern but is also chaotic.
  153. int nCycle = ( pTemp->hitSound + static_cast< int >( gpGlobals->curtime * 2.0f ) ) % ( pTemp->m_nHitboxSet + ARRAYSIZE( rgbaHolidayLightColors ) + 1 );
  154. pTemp->SetRenderAlpha( nCycle < ARRAYSIZE( rgbaHolidayLightColors ) ? 255 : 64 );
  155. }
  156. // Update the scale
  157. pTemp->m_flSpriteScale = holidayLight.fScale;
  158. Vector vecMin, vecMax;
  159. pTemp->GetRenderBounds( vecMin, vecMax );
  160. // Extend it's life
  161. pTemp->die = gpGlobals->curtime + 2.0f;
  162. }
  163. }
  164. DECLARE_CLIENT_EFFECT( CS_HolidayLight, CS_HolidayLightCallback );
  165. void RopesHolidayLightColor( const CCommand &args )
  166. {
  167. if ( args.ArgC() < 5 )
  168. return;
  169. int nLight = atoi( args[ 1 ] );
  170. {
  171. if ( nLight < 0 || nLight >= ARRAYSIZE( rgbaHolidayLightColors ) )
  172. return;
  173. rgbaHolidayLightColors[nLight]->SetColor( atoi( args[2] ), atoi( args[3] ), atoi( args[4] ) );
  174. }
  175. }
  176. ConCommand r_ropes_holiday_light_color( "r_ropes_holiday_light_color", RopesHolidayLightColor, "Set each light's color: [light0-3] [r0-255] [g0-255] [b0-255]", FCVAR_NONE );