summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_fx_christmaslights.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_fx_christmaslights.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_fx_christmaslights.cpp')
-rw-r--r--game/client/tf/tf_fx_christmaslights.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/game/client/tf/tf_fx_christmaslights.cpp b/game/client/tf/tf_fx_christmaslights.cpp
new file mode 100644
index 0000000..3d93d95
--- /dev/null
+++ b/game/client/tf/tf_fx_christmaslights.cpp
@@ -0,0 +1,214 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Game-specific impact effect hooks
+//
+//=============================================================================//
+#include "cbase.h"
+
+#include "c_te_effect_dispatch.h"
+#include "tempent.h"
+#include "c_te_legacytempents.h"
+#include "tf_shareddefs.h"
+#include "c_rope.h"
+
+// NOTE: Always include this last!
+#include "tier0/memdbgon.h"
+
+
+// Used for cycling so that they're sequencially ordered on each strand
+int g_nHolidayLightColor = 0;
+
+// 4 light colors
+Color g_rgbaHolidayRed( 255, 0, 0, 255 );
+Color g_rgbaHolidayYellow( 2, 110, 197, 255 );
+Color g_rgbaHolidayGreen( 117, 193, 8, 255 );
+Color g_rgbaHolidayBlue( 255, 151, 29, 255 );
+
+Color *(rgbaHolidayLightColors[]) = { &g_rgbaHolidayRed,
+ &g_rgbaHolidayYellow,
+ &g_rgbaHolidayGreen,
+ &g_rgbaHolidayBlue };
+
+
+struct HolidayLightData_t
+{
+ Vector vOrigin;
+ int nID;
+ int nSubID;
+ float fScale;
+};
+
+
+void CreateHolidayLight( const HolidayLightData_t &holidayLight );
+
+
+class CHolidayLightManager : public CAutoGameSystemPerFrame
+{
+public:
+ CHolidayLightManager( char const *name );
+
+ // Methods of IGameSystem
+ virtual void Update( float frametime );
+
+ virtual void LevelInitPostEntity( void );
+ virtual void LevelShutdownPreEntity();
+
+ void AddHolidayLight( const CEffectData &data );
+
+private:
+
+ CUtlVector< HolidayLightData_t > m_PendingLightData;
+};
+
+CHolidayLightManager g_CHolidayLightManager( "CHolidayLightManager" );
+
+
+CHolidayLightManager::CHolidayLightManager( char const *name ) : CAutoGameSystemPerFrame( name )
+{
+}
+
+// Methods of IGameSystem
+void CHolidayLightManager::Update( float frametime )
+{
+ for ( int i = 0; i < m_PendingLightData.Count(); ++i )
+ {
+ CreateHolidayLight( m_PendingLightData[ i ] );
+ }
+
+ m_PendingLightData.RemoveAll();
+}
+
+void CHolidayLightManager::LevelInitPostEntity( void )
+{
+ m_PendingLightData.RemoveAll();
+}
+
+void CHolidayLightManager::LevelShutdownPreEntity()
+{
+ m_PendingLightData.RemoveAll();
+}
+
+void CHolidayLightManager::AddHolidayLight( const CEffectData &data )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ // Too far away?
+ if ( pPlayer->GetAbsOrigin().DistTo( data.m_vOrigin ) > 2000.0f )
+ return;
+
+ // In the skybox?
+ sky3dparams_t *pSky = &(pPlayer->m_Local.m_skybox3d);
+ if ( pSky->origin->DistTo( data.m_vOrigin ) < 2000.0f )
+ return;
+
+ HolidayLightData_t newData;
+
+ newData.vOrigin = data.m_vOrigin;
+
+ // HACK: Use these ints to ID the light later
+ newData.nID = data.m_nMaterial;
+ newData.nSubID = data.m_nHitBox;
+
+ // Skybox lights pass in a smaller scale
+ newData.fScale = data.m_flScale;
+
+ if ( m_PendingLightData.Count() < CTempEnts::MAX_TEMP_ENTITIES / 2 )
+ {
+ m_PendingLightData.AddToTail( newData );
+ }
+}
+
+
+void TF_HolidayLightCallback( const CEffectData &data )
+{
+ g_CHolidayLightManager.AddHolidayLight( data );
+}
+
+void CreateHolidayLight( const HolidayLightData_t &holidayLight )
+{
+ int nHolidayLightStyle = RopeManager()->GetHolidayLightStyle();
+
+ const model_t *pModel = ( nHolidayLightStyle == 0 ? engine->LoadModel( "effects/christmas_bulb.vmt" ) : engine->LoadModel( "effects/mtp_fluff.vmt" ) );
+ if ( !pModel )
+ return;
+
+ Assert( pModel );
+
+ C_LocalTempEntity *pTemp = tempents->FindTempEntByID( holidayLight.nID, holidayLight.nSubID );
+
+ if ( !pTemp )
+ {
+ // Didn't find one with that ID, so make a new one!
+ // Randomize the angle
+ QAngle angOrientation = ( nHolidayLightStyle == 0 ? QAngle( 0.0f, 0.0f, RandomFloat( -180.0f, 180.0f ) ) : vec3_angle );
+ pTemp = tempents->SpawnTempModel( pModel, holidayLight.vOrigin, angOrientation, vec3_origin, 2.0f, FTENT_NEVERDIE );
+ if ( !pTemp )
+ {
+ return;
+ }
+
+ pTemp->clientIndex = 0;
+
+ // HACK: Use these ints to ID the light later
+ pTemp->m_nSkin = holidayLight.nID;
+ pTemp->hitSound = holidayLight.nSubID;
+
+ // Skybox lights pass in a smaller scale
+ pTemp->m_flSpriteScale = holidayLight.fScale;
+
+ // Smuggle the color index here
+ pTemp->m_nHitboxSet = g_nHolidayLightColor;
+
+ // Set the color
+ pTemp->SetRenderColor( rgbaHolidayLightColors[ g_nHolidayLightColor ]->r(),
+ rgbaHolidayLightColors[ g_nHolidayLightColor ]->g(),
+ rgbaHolidayLightColors[ g_nHolidayLightColor ]->b(),
+ rgbaHolidayLightColors[ g_nHolidayLightColor ]->a() );
+
+ // Next color in the pattern
+ g_nHolidayLightColor = ( g_nHolidayLightColor + 1 ) % ARRAYSIZE( rgbaHolidayLightColors );
+
+ // Animate if needed
+ pTemp->m_flFrameMax = modelinfo->GetModelFrameCount( pModel ) - 1;
+ pTemp->flags = ( FTENT_SPRANIMATE | FTENT_SPRANIMATELOOP );
+ pTemp->m_flFrameRate = 10;
+ }
+ else
+ {
+ // Update the position
+ pTemp->SetAbsOrigin( holidayLight.vOrigin );
+
+ // Every 10 light strands have a blink cycle
+ if ( pTemp->m_nSkin % 5 == 0 )
+ {
+ // Magic! Basically this makes the on/off cycle of each color different and offsets it by the segment index.
+ // That way it looks like a timed pattern but is also chaotic.
+ int nCycle = ( pTemp->hitSound + static_cast< int >( gpGlobals->curtime * 2.0f ) ) % ( pTemp->m_nHitboxSet + ARRAYSIZE( rgbaHolidayLightColors ) + 1 );
+ pTemp->SetRenderColorA( nCycle < ARRAYSIZE( rgbaHolidayLightColors ) ? 255 : 64 );
+ }
+
+ // Update the scale
+ pTemp->m_flSpriteScale = holidayLight.fScale;
+
+ // Extend it's life
+ pTemp->die = gpGlobals->curtime + 2.0f;
+ }
+}
+
+DECLARE_CLIENT_EFFECT( "TF_HolidayLight", TF_HolidayLightCallback );
+
+void RopesHolidayLightColor( const CCommand &args )
+{
+ if ( args.ArgC() < 5 )
+ return;
+
+ int nLight = atoi( args[ 1 ] );
+
+ if ( nLight < 0 || nLight >= ARRAYSIZE( rgbaHolidayLightColors ) )
+ return;
+
+ rgbaHolidayLightColors[ nLight ]->SetColor( atoi( args[ 2 ] ), atoi( args[ 3 ] ), atoi( args[ 4 ] ) );
+}
+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 ); \ No newline at end of file