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.
214 lines
5.8 KiB
214 lines
5.8 KiB
//========= 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 ); |