forked from FWGS/Paranoia2
706 lines
17 KiB
C++
706 lines
17 KiB
C++
/***
|
|
*
|
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
*
|
|
* This product contains software technology licensed from Id
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
* without written permission from Valve LLC.
|
|
*
|
|
****/
|
|
/*
|
|
|
|
===== lights.cpp ========================================================
|
|
|
|
spawn and think functions for editor-placed lights
|
|
|
|
*/
|
|
|
|
#include "extdll.h"
|
|
#include "util.h"
|
|
#include "cbase.h"
|
|
|
|
//LRC
|
|
int GetStdLightStyle (int iStyle)
|
|
{
|
|
switch (iStyle)
|
|
{
|
|
// 0 normal
|
|
case 0: return MAKE_STRING("m");
|
|
|
|
// 1 FLICKER (first variety)
|
|
case 1: return MAKE_STRING("mmnmmommommnonmmonqnmmo");
|
|
|
|
// 2 SLOW STRONG PULSE
|
|
case 2: return MAKE_STRING("abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
|
|
|
|
// 3 CANDLE (first variety)
|
|
case 3: return MAKE_STRING("mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
|
|
|
|
// 4 FAST STROBE
|
|
case 4: return MAKE_STRING("mamamamamama");
|
|
|
|
// 5 GENTLE PULSE 1
|
|
case 5: return MAKE_STRING("jklmnopqrstuvwxyzyxwvutsrqponmlkj");
|
|
|
|
// 6 FLICKER (second variety)
|
|
case 6: return MAKE_STRING("nmonqnmomnmomomno");
|
|
|
|
// 7 CANDLE (second variety)
|
|
case 7: return MAKE_STRING("mmmaaaabcdefgmmmmaaaammmaamm");
|
|
|
|
// 8 CANDLE (third variety)
|
|
case 8: return MAKE_STRING("mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
|
|
|
|
// 9 SLOW STROBE (fourth variety)
|
|
case 9: return MAKE_STRING("aaaaaaaazzzzzzzz");
|
|
|
|
// 10 FLUORESCENT FLICKER
|
|
case 10: return MAKE_STRING("mmamammmmammamamaaamammma");
|
|
|
|
// 11 SLOW PULSE NOT FADE TO BLACK
|
|
case 11: return MAKE_STRING("abcdefghijklmnopqrrqponmlkjihgfedcba");
|
|
|
|
// 12 UNDERWATER LIGHT MUTATION
|
|
// this light only distorts the lightmap - no contribution
|
|
// is made to the brightness of affected surfaces
|
|
case 12: return MAKE_STRING("mmnnmmnnnmmnn");
|
|
|
|
// 13 OFF (LRC)
|
|
case 13: return MAKE_STRING("a");
|
|
|
|
// 14 SLOW FADE IN (LRC)
|
|
case 14: return MAKE_STRING("aabbccddeeffgghhiijjkkllmmmmmmmmmmmmmm");
|
|
|
|
// 15 MED FADE IN (LRC)
|
|
case 15: return MAKE_STRING("abcdefghijklmmmmmmmmmmmmmmmmmmmmmmmmmm");
|
|
|
|
// 16 FAST FADE IN (LRC)
|
|
case 16: return MAKE_STRING("acegikmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm");
|
|
|
|
// 17 SLOW FADE OUT (LRC)
|
|
case 17: return MAKE_STRING("llkkjjiihhggffeeddccbbaaaaaaaaaaaaaaaa");
|
|
|
|
// 18 MED FADE OUT (LRC)
|
|
case 18: return MAKE_STRING("lkjihgfedcbaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
|
|
|
// 19 FAST FADE OUT (LRC)
|
|
case 19: return MAKE_STRING("kigecaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
|
|
|
default: return MAKE_STRING("m");
|
|
}
|
|
}
|
|
|
|
|
|
class CLight : public CPointEntity
|
|
{
|
|
public:
|
|
virtual void KeyValue( KeyValueData* pkvd );
|
|
virtual void Spawn( void );
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
|
void Think( void );
|
|
|
|
virtual int Save( CSave &save );
|
|
virtual int Restore( CRestore &restore );
|
|
virtual STATE GetState(void) { return m_iState; }; //LRC
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
int GetStyle( void ) { return m_iszCurrentStyle; }; //LRC
|
|
void SetStyle( int iszPattern ); //LRC
|
|
|
|
void SetCorrectStyle( void ); //LRC
|
|
float m_flPitch;
|
|
private:
|
|
STATE m_iState; // current state
|
|
int m_iOnStyle; // style to use while on
|
|
int m_iOffStyle; // style to use while off
|
|
int m_iTurnOnStyle; // style to use while turning on
|
|
int m_iTurnOffStyle; // style to use while turning off
|
|
int m_iTurnOnTime; // time taken to turn on
|
|
int m_iTurnOffTime; // time taken to turn off
|
|
int m_iszPattern; // custom style to use while on
|
|
int m_iszCurrentStyle; // current style string
|
|
};
|
|
LINK_ENTITY_TO_CLASS( light, CLight );
|
|
|
|
TYPEDESCRIPTION CLight::m_SaveData[] =
|
|
{
|
|
DEFINE_FIELD( CLight, m_iState, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iszPattern, FIELD_STRING ),
|
|
DEFINE_FIELD( CLight, m_iszCurrentStyle, FIELD_STRING ),
|
|
DEFINE_FIELD( CLight, m_iOnStyle, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iOffStyle, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iTurnOnStyle, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iTurnOffStyle, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iTurnOnTime, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLight, m_iTurnOffTime, FIELD_INTEGER ),
|
|
};
|
|
|
|
IMPLEMENT_SAVERESTORE( CLight, CPointEntity );
|
|
|
|
|
|
//
|
|
// Cache user-entity-field values until spawn is called.
|
|
//
|
|
void CLight :: KeyValue( KeyValueData* pkvd)
|
|
{
|
|
if (FStrEq(pkvd->szKeyName, "m_iOnStyle"))
|
|
{
|
|
m_iOnStyle = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iOffStyle"))
|
|
{
|
|
m_iOffStyle = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iTurnOnStyle"))
|
|
{
|
|
m_iTurnOnStyle = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iTurnOffStyle"))
|
|
{
|
|
m_iTurnOffStyle = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iTurnOnTime"))
|
|
{
|
|
m_iTurnOnTime = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iTurnOffTime"))
|
|
{
|
|
m_iTurnOffTime = atoi(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "pitch"))
|
|
{
|
|
m_flPitch = atof(pkvd->szValue);
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "pattern"))
|
|
{
|
|
m_iszPattern = ALLOC_STRING( pkvd->szValue );
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "firetarget"))
|
|
{
|
|
pev->target = ALLOC_STRING( pkvd->szValue );
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else
|
|
{
|
|
CPointEntity::KeyValue( pkvd );
|
|
}
|
|
}
|
|
|
|
void CLight :: SetStyle ( int iszPattern )
|
|
{
|
|
if (m_iStyle < 32) // if it's using a global style, don't change it
|
|
return;
|
|
|
|
m_iszCurrentStyle = iszPattern;
|
|
LIGHT_STYLE(m_iStyle, (char *)STRING( iszPattern ));
|
|
}
|
|
|
|
// regardless of what's been set by trigger_lightstyle ents, set the style I think I need
|
|
void CLight :: SetCorrectStyle ( void )
|
|
{
|
|
if (m_iStyle >= 32)
|
|
{
|
|
switch (m_iState)
|
|
{
|
|
case STATE_ON:
|
|
if (m_iszPattern) // custom styles have priority over standard ones
|
|
SetStyle( m_iszPattern );
|
|
else if (m_iOnStyle)
|
|
SetStyle(GetStdLightStyle(m_iOnStyle));
|
|
else
|
|
SetStyle(MAKE_STRING("m"));
|
|
break;
|
|
case STATE_OFF:
|
|
if (m_iOffStyle)
|
|
SetStyle(GetStdLightStyle(m_iOffStyle));
|
|
else
|
|
SetStyle(MAKE_STRING("a"));
|
|
break;
|
|
case STATE_TURN_ON:
|
|
if (m_iTurnOnStyle)
|
|
SetStyle(GetStdLightStyle(m_iTurnOnStyle));
|
|
else
|
|
SetStyle(MAKE_STRING("a"));
|
|
break;
|
|
case STATE_TURN_OFF:
|
|
if (m_iTurnOffStyle)
|
|
SetStyle(GetStdLightStyle(m_iTurnOffStyle));
|
|
else
|
|
SetStyle(MAKE_STRING("m"));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_iszCurrentStyle = GetStdLightStyle( m_iStyle );
|
|
}
|
|
}
|
|
|
|
void CLight :: Think( void )
|
|
{
|
|
switch (GetState())
|
|
{
|
|
case STATE_TURN_ON:
|
|
m_iState = STATE_ON;
|
|
FireTargets(STRING(pev->target),this,this,USE_ON,0);
|
|
break;
|
|
case STATE_TURN_OFF:
|
|
m_iState = STATE_OFF;
|
|
FireTargets(STRING(pev->target),this,this,USE_OFF,0);
|
|
break;
|
|
}
|
|
|
|
SetCorrectStyle();
|
|
}
|
|
|
|
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF
|
|
Non-displayed light.
|
|
Default light value is 300
|
|
Default style is 0
|
|
If targeted, it will toggle between on or off.
|
|
*/
|
|
void CLight :: Spawn( void )
|
|
{
|
|
if (FStringNull(pev->targetname))
|
|
{
|
|
// inert light
|
|
REMOVE_ENTITY(ENT(pev));
|
|
return;
|
|
}
|
|
|
|
if (FBitSet(pev->spawnflags,SF_LIGHT_START_OFF))
|
|
m_iState = STATE_OFF;
|
|
else
|
|
m_iState = STATE_ON;
|
|
|
|
SetCorrectStyle();
|
|
}
|
|
|
|
void CLight :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
|
{
|
|
if (m_iStyle >= 32)
|
|
{
|
|
if ( !ShouldToggle( useType ) )
|
|
return;
|
|
|
|
switch (GetState())
|
|
{
|
|
case STATE_ON:
|
|
case STATE_TURN_ON:
|
|
if (m_iTurnOffTime)
|
|
{
|
|
m_iState = STATE_TURN_OFF;
|
|
SetNextThink( m_iTurnOffTime );
|
|
}
|
|
else
|
|
m_iState = STATE_OFF;
|
|
break;
|
|
case STATE_OFF:
|
|
case STATE_TURN_OFF:
|
|
if (m_iTurnOnTime)
|
|
{
|
|
m_iState = STATE_TURN_ON;
|
|
SetNextThink( m_iTurnOnTime );
|
|
}
|
|
else
|
|
m_iState = STATE_ON;
|
|
break;
|
|
}
|
|
SetCorrectStyle();
|
|
}
|
|
}
|
|
|
|
//
|
|
// shut up spawn functions for new spotlights
|
|
//
|
|
LINK_ENTITY_TO_CLASS( light_spot, CLight );
|
|
|
|
|
|
class CEnvLight : public CLight
|
|
{
|
|
public:
|
|
void KeyValue( KeyValueData* pkvd );
|
|
void Spawn( void );
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS( light_environment, CEnvLight );
|
|
|
|
void CEnvLight::KeyValue( KeyValueData* pkvd )
|
|
{
|
|
if (FStrEq(pkvd->szKeyName, "_light"))
|
|
{
|
|
int r, g, b, v, j;
|
|
char szColor[64];
|
|
j = sscanf( pkvd->szValue, "%d %d %d %d\n", &r, &g, &b, &v );
|
|
if (j == 1)
|
|
{
|
|
g = b = r;
|
|
}
|
|
else if (j == 4)
|
|
{
|
|
r = r * (v / 255.0);
|
|
g = g * (v / 255.0);
|
|
b = b * (v / 255.0);
|
|
}
|
|
|
|
// simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling
|
|
r = pow( r / 114.0, 0.6 ) * 264;
|
|
g = pow( g / 114.0, 0.6 ) * 264;
|
|
b = pow( b / 114.0, 0.6 ) * 264;
|
|
|
|
pkvd->fHandled = TRUE;
|
|
sprintf( szColor, "%d", r );
|
|
CVAR_SET_STRING( "sv_skycolor_r", szColor );
|
|
sprintf( szColor, "%d", g );
|
|
CVAR_SET_STRING( "sv_skycolor_g", szColor );
|
|
sprintf( szColor, "%d", b );
|
|
CVAR_SET_STRING( "sv_skycolor_b", szColor );
|
|
}
|
|
else
|
|
{
|
|
CLight::KeyValue( pkvd );
|
|
}
|
|
}
|
|
|
|
|
|
void CEnvLight :: Spawn( void )
|
|
{
|
|
if( !pev->angles.x )
|
|
pev->angles.x = m_flPitch;
|
|
|
|
char szVector[64];
|
|
UTIL_MakeAimVectors( pev->angles );
|
|
|
|
sprintf( szVector, "%f", gpGlobals->v_forward.x );
|
|
CVAR_SET_STRING( "sv_skyvec_x", szVector );
|
|
sprintf( szVector, "%f", gpGlobals->v_forward.y );
|
|
CVAR_SET_STRING( "sv_skyvec_y", szVector );
|
|
sprintf( szVector, "%f", gpGlobals->v_forward.z );
|
|
CVAR_SET_STRING( "sv_skyvec_z", szVector );
|
|
|
|
CLight::Spawn( );
|
|
}
|
|
|
|
//**********************************************************
|
|
//LRC- the CLightDynamic entity - works like the flashlight.
|
|
//**********************************************************
|
|
|
|
#define SF_LIGHTDYNAMIC_START_OFF 1
|
|
#define SF_LIGHTDYNAMIC_FLARE 2
|
|
|
|
class CLightDynamic : public CBaseEntity
|
|
{
|
|
public:
|
|
void Spawn( void );
|
|
void Precache( void );
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
|
int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
|
void SetEffects( void );
|
|
STATE GetState( void );
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS( light_glow, CLightDynamic );
|
|
|
|
void CLightDynamic::Spawn( void )
|
|
{
|
|
Precache( );
|
|
|
|
SET_MODEL(ENT(pev), "sprites/null.spr");
|
|
pev->solid = SOLID_NOT;
|
|
pev->movetype = MOVETYPE_NONE;
|
|
|
|
if (!(pev->spawnflags & SF_LIGHTDYNAMIC_START_OFF))
|
|
{
|
|
pev->health = 1;
|
|
SetEffects();
|
|
}
|
|
}
|
|
|
|
void CLightDynamic :: Precache( void )
|
|
{
|
|
PRECACHE_MODEL("sprites/null.spr");
|
|
}
|
|
|
|
void CLightDynamic::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
|
{
|
|
if (ShouldToggle(useType, pev->health))
|
|
{
|
|
if (pev->health)
|
|
pev->health = 0;
|
|
else
|
|
pev->health = 1;
|
|
SetEffects();
|
|
}
|
|
}
|
|
|
|
void CLightDynamic::SetEffects( void )
|
|
{
|
|
if (pev->health)
|
|
{
|
|
if (pev->frags == 2)
|
|
pev->effects |= EF_BRIGHTLIGHT;
|
|
else if (pev->frags)
|
|
pev->effects |= EF_DIMLIGHT;
|
|
|
|
if (pev->spawnflags & SF_LIGHTDYNAMIC_FLARE)
|
|
pev->effects |= EF_LIGHT;
|
|
}
|
|
else
|
|
{
|
|
pev->effects &= ~(EF_DIMLIGHT | EF_BRIGHTLIGHT | EF_LIGHT);
|
|
}
|
|
}
|
|
|
|
STATE CLightDynamic::GetState( void )
|
|
{
|
|
if (pev->health)
|
|
return STATE_ON;
|
|
else
|
|
return STATE_OFF;
|
|
}
|
|
|
|
//**********************************************************
|
|
//LRC- the CTriggerLightstyle entity - changes the style of a light temporarily.
|
|
//**********************************************************
|
|
class CLightFader : public CPointEntity
|
|
{
|
|
public:
|
|
void EXPORT FadeThink( void );
|
|
void EXPORT WaitThink( void );
|
|
virtual int Save( CSave &save );
|
|
virtual int Restore( CRestore &restore );
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
CLight *m_pLight;
|
|
char m_cFrom;
|
|
char m_cTo;
|
|
char m_szCurStyle[256];
|
|
float m_fEndTime;
|
|
string_t m_iszPattern;
|
|
float m_fStep;
|
|
int m_iWait;
|
|
int m_iHardwareLerped;
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS( lightfader, CLightFader );
|
|
|
|
TYPEDESCRIPTION CLightFader::m_SaveData[] =
|
|
{
|
|
DEFINE_FIELD( CLightFader, m_pLight, FIELD_CLASSPTR ),
|
|
DEFINE_FIELD( CLightFader, m_cFrom, FIELD_CHARACTER ),
|
|
DEFINE_FIELD( CLightFader, m_cTo, FIELD_CHARACTER ),
|
|
DEFINE_ARRAY( CLightFader, m_szCurStyle, FIELD_CHARACTER, 256 ),
|
|
DEFINE_FIELD( CLightFader, m_fEndTime, FIELD_FLOAT ),
|
|
DEFINE_FIELD( CLightFader, m_iszPattern, FIELD_STRING ),
|
|
DEFINE_FIELD( CLightFader, m_fStep, FIELD_FLOAT ),
|
|
DEFINE_FIELD( CLightFader, m_iWait, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CLightFader, m_iHardwareLerped, FIELD_BOOLEAN ),
|
|
};
|
|
|
|
IMPLEMENT_SAVERESTORE(CLightFader,CPointEntity);
|
|
|
|
void CLightFader::FadeThink( void )
|
|
{
|
|
if (m_fEndTime > gpGlobals->time)
|
|
{
|
|
if( !m_iHardwareLerped )
|
|
{
|
|
m_szCurStyle[0] = m_cTo + (char)((m_cFrom - m_cTo) * (m_fEndTime - gpGlobals->time) * m_fStep);
|
|
m_szCurStyle[1] = 0; // null terminator
|
|
m_pLight->SetStyle(MAKE_STRING(m_szCurStyle));
|
|
}
|
|
SetNextThink( 0.1 );
|
|
}
|
|
else
|
|
{
|
|
// fade is finished
|
|
m_pLight->SetStyle(m_iszPattern);
|
|
if (m_iWait > -1)
|
|
{
|
|
// wait until it's time to switch off
|
|
SetThink(&CLightFader:: WaitThink );
|
|
SetNextThink( m_iWait );
|
|
}
|
|
else
|
|
{
|
|
// we've finished, kill the fader
|
|
SetThink(&CLightFader:: SUB_Remove );
|
|
SetNextThink( 0.1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// we've finished. revert the light and kill the fader.
|
|
void CLightFader::WaitThink( void )
|
|
{
|
|
if( m_iszPattern )
|
|
m_pLight->SetStyle( m_iszPattern );
|
|
else m_pLight->SetCorrectStyle();
|
|
SetThink(&CLightFader:: SUB_Remove );
|
|
SetNextThink( 0.1 );
|
|
}
|
|
|
|
|
|
|
|
class CTriggerLightstyle : public CPointEntity
|
|
{
|
|
public:
|
|
void KeyValue( KeyValueData *pkvd );
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
|
virtual int Save( CSave &save );
|
|
virtual int Restore( CRestore &restore );
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
private:
|
|
char m_szOldPattern[256];
|
|
int m_iszPattern;
|
|
int m_iFade;
|
|
int m_iWait;
|
|
};
|
|
|
|
LINK_ENTITY_TO_CLASS( trigger_lightstyle, CTriggerLightstyle );
|
|
|
|
TYPEDESCRIPTION CTriggerLightstyle::m_SaveData[] =
|
|
{
|
|
DEFINE_FIELD( CTriggerLightstyle, m_iszPattern, FIELD_STRING ),
|
|
DEFINE_FIELD( CTriggerLightstyle, m_iFade, FIELD_INTEGER ),
|
|
DEFINE_FIELD( CTriggerLightstyle, m_iWait, FIELD_INTEGER ),
|
|
DEFINE_ARRAY( CTriggerLightstyle, m_szOldPattern, FIELD_CHARACTER, 256 ),
|
|
};
|
|
|
|
IMPLEMENT_SAVERESTORE(CTriggerLightstyle,CBaseEntity);
|
|
|
|
void CTriggerLightstyle::KeyValue( KeyValueData *pkvd )
|
|
{
|
|
if (FStrEq(pkvd->szKeyName, "pattern"))
|
|
{
|
|
m_iszPattern = ALLOC_STRING( pkvd->szValue );
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iFade"))
|
|
{
|
|
m_iFade = atoi( pkvd->szValue );
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else if (FStrEq(pkvd->szKeyName, "m_iWait"))
|
|
{
|
|
m_iWait = atoi( pkvd->szValue );
|
|
pkvd->fHandled = TRUE;
|
|
}
|
|
else
|
|
CBaseEntity::KeyValue( pkvd );
|
|
}
|
|
|
|
void CTriggerLightstyle::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
|
{
|
|
CBaseEntity *pTarget = NULL;
|
|
if ( !pev->target )
|
|
return;
|
|
|
|
//ALERT( at_console, "Lightstyle change for: (%s)\n", STRING(pev->target) );
|
|
bool fFisrt = true;
|
|
|
|
while( 1 )
|
|
{
|
|
pTarget = UTIL_FindEntityByTargetname(pTarget,STRING(pev->target), pActivator);
|
|
if (FNullEnt(pTarget))
|
|
break;
|
|
|
|
int iszPattern;
|
|
if (m_iszPattern)
|
|
iszPattern = m_iszPattern;
|
|
else
|
|
iszPattern = GetStdLightStyle(m_iStyle);
|
|
|
|
// not a light entity?
|
|
if (!FClassnameIs(pTarget->pev, "light") && !FClassnameIs(pTarget->pev, "light_spot") && !FClassnameIs(pTarget->pev, "light_environment"))
|
|
{
|
|
if (pTarget->m_iStyle >= 32)
|
|
LIGHT_STYLE(pTarget->m_iStyle, (char*)STRING(iszPattern));
|
|
}
|
|
else
|
|
{
|
|
CLight *pLight = (CLight*)pTarget;
|
|
|
|
if (m_iFade)
|
|
{
|
|
CLightFader *pFader = GetClassPtr( (CLightFader*)NULL );
|
|
pFader->pev->classname = MAKE_STRING( "lightfader" );
|
|
pFader->m_pLight = pLight;
|
|
pFader->m_cFrom = ((char*)STRING(pLight->GetStyle()))[0];
|
|
pFader->m_cTo = ((char*)STRING(iszPattern))[0];
|
|
pFader->m_iszPattern = iszPattern;
|
|
pFader->m_fEndTime = gpGlobals->time + m_iFade;
|
|
pFader->m_fStep = 1.0f / m_iFade;
|
|
pFader->m_iWait = m_iWait;
|
|
pFader->SetThink( &CLightFader::FadeThink );
|
|
pFader->SetNextThink( 0.1 );
|
|
|
|
float time = 1.0;
|
|
float end = time + m_iFade;
|
|
char lerpedPattern[256];
|
|
char *lpPattern = lerpedPattern;
|
|
pFader->m_iHardwareLerped = TRUE;
|
|
|
|
while( end > time )
|
|
{
|
|
*lpPattern = pFader->m_cTo + (char)((pFader->m_cFrom - pFader->m_cTo) * (end - time) * pFader->m_fStep);
|
|
time += 0.09; // to prevent loop the style
|
|
lpPattern++;
|
|
|
|
// exceed hardware pattern length?
|
|
if(( lpPattern - lerpedPattern ) > 250 )
|
|
{
|
|
pFader->m_iHardwareLerped = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
*lpPattern = '\0';
|
|
|
|
if( pFader->m_iHardwareLerped )
|
|
{
|
|
// build the lerped sequence and let the engine lerping the lightstyle
|
|
pFader->m_pLight->SetStyle( ALLOC_STRING( lerpedPattern ));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( fFisrt )
|
|
{
|
|
// save old pattern in case we needs to be restore it
|
|
Q_strncpy( m_szOldPattern, GET_LIGHT_STYLE( pLight->m_iStyle ), 256 );
|
|
fFisrt = false;
|
|
}
|
|
|
|
pLight->SetStyle( iszPattern );
|
|
|
|
if( m_iWait != -1 )
|
|
{
|
|
CLightFader *pFader = GetClassPtr( (CLightFader*)NULL );
|
|
pFader->pev->classname = MAKE_STRING( "lightfader" );
|
|
pFader->m_pLight = pLight;
|
|
// i'm hope somebody don't delete this entity from map :-)
|
|
pFader->m_iszPattern = MAKE_STRING( m_szOldPattern );
|
|
pFader->SetThink( &CLightFader::WaitThink );
|
|
pFader->SetNextThink( m_iWait );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|