From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- .../server/hl2/info_darknessmode_lightsource.cpp | 908 ++++++++++----------- 1 file changed, 454 insertions(+), 454 deletions(-) (limited to 'mp/src/game/server/hl2/info_darknessmode_lightsource.cpp') diff --git a/mp/src/game/server/hl2/info_darknessmode_lightsource.cpp b/mp/src/game/server/hl2/info_darknessmode_lightsource.cpp index 08eff25d..03df7e3f 100644 --- a/mp/src/game/server/hl2/info_darknessmode_lightsource.cpp +++ b/mp/src/game/server/hl2/info_darknessmode_lightsource.cpp @@ -1,454 +1,454 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//============================================================================= - -#include "cbase.h" -#include "info_darknessmode_lightsource.h" -#include "ai_debug_shared.h" - -void CV_Debug_Darkness( IConVar *var, const char *pOldString, float flOldValue ); -ConVar g_debug_darkness( "g_debug_darkness", "0", FCVAR_NONE, "Show darkness mode lightsources.", CV_Debug_Darkness ); -ConVar darkness_ignore_LOS_to_sources( "darkness_ignore_LOS_to_sources", "1", FCVAR_NONE ); - -class CInfoDarknessLightSource; - -//----------------------------------------------------------------------------- -// Purpose: Manages entities that provide light while in darkness mode -//----------------------------------------------------------------------------- -class CDarknessLightSourcesSystem : public CAutoGameSystem -{ -public: - CDarknessLightSourcesSystem() : CAutoGameSystem( "CDarknessLightSourcesSystem" ) - { - } - - void LevelInitPreEntity(); - - void AddLightSource( CInfoDarknessLightSource *pEntity, float flRadius ); - void RemoveLightSource( CInfoDarknessLightSource *pEntity ); - bool IsEntityVisibleToTarget( CBaseEntity *pLooker, CBaseEntity *pTarget ); - bool AreThereLightSourcesWithinRadius( CBaseEntity *pLooker, float flRadius ); - void SetDebug( bool bDebug ); - -private: - struct lightsource_t - { - float flLightRadiusSqr; - CHandle hEntity; - }; - - CUtlVector m_LightSources; -}; - -CDarknessLightSourcesSystem *DarknessLightSourcesSystem(); - -//----------------------------------------------------------------------------- -// Darkness mode light source entity -//----------------------------------------------------------------------------- -class CInfoDarknessLightSource : public CBaseEntity -{ - DECLARE_CLASS( CInfoDarknessLightSource, CBaseEntity ); -public: - DECLARE_DATADESC(); - - virtual void Activate() - { - if ( m_bDisabled == false ) - { - DarknessLightSourcesSystem()->AddLightSource( this, m_flLightRadius ); - - if ( g_debug_darkness.GetBool() ) - { - SetThink( &CInfoDarknessLightSource::DebugThink ); - SetNextThink( gpGlobals->curtime ); - } - } - - BaseClass::Activate(); - } - virtual void UpdateOnRemove() - { - DarknessLightSourcesSystem()->RemoveLightSource( this ); - BaseClass::UpdateOnRemove(); - } - void SetLightRadius( float flRadius ) - { - m_flLightRadius = flRadius; - } - - void InputEnable( inputdata_t &inputdata ) - { - DarknessLightSourcesSystem()->AddLightSource( this, m_flLightRadius ); - m_bDisabled = false; - } - - void InputDisable( inputdata_t &inputdata ) - { - DarknessLightSourcesSystem()->RemoveLightSource( this ); - m_bDisabled = true; - } - - void DebugThink( void ) - { - Vector vecRadius( m_flLightRadius, m_flLightRadius, m_flLightRadius ); - NDebugOverlay::Box( GetAbsOrigin(), -vecRadius, vecRadius, 255,255,255, 8, 0.1 ); - NDebugOverlay::Box( GetAbsOrigin(), -Vector(5,5,5), Vector(5,5,5), 255,0,0, 8, 0.1 ); - SetNextThink( gpGlobals->curtime + 0.1 ); - - int textoffset = 0; - EntityText( textoffset, UTIL_VarArgs("Org: %.2f %.2f %.2f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z ), 0.1 ); - textoffset++; - EntityText( textoffset, UTIL_VarArgs("Radius %.2f", m_flLightRadius), 0.1 ); - textoffset++; - if ( m_bIgnoreLOS ) - { - EntityText( textoffset, "Ignoring LOS", 0.1 ); - textoffset++; - } - if ( m_bDisabled ) - { - EntityText( textoffset, "DISABLED", 0.1 ); - textoffset++; - } - } - - void IgnoreLOS( void ) - { - m_bIgnoreLOS = true; - } - - bool ShouldIgnoreLOS( void ) - { - return m_bIgnoreLOS; - } - -private: - float m_flLightRadius; - bool m_bDisabled; - bool m_bIgnoreLOS; -}; - -LINK_ENTITY_TO_CLASS( info_darknessmode_lightsource, CInfoDarknessLightSource ); - -BEGIN_DATADESC( CInfoDarknessLightSource ) - DEFINE_KEYFIELD( m_flLightRadius, FIELD_FLOAT, "LightRadius" ), - DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), - DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), - DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), - DEFINE_FIELD( m_bIgnoreLOS, FIELD_BOOLEAN ), - - DEFINE_THINKFUNC( DebugThink ), -END_DATADESC() - -CDarknessLightSourcesSystem g_DarknessLightSourcesSystem; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CDarknessLightSourcesSystem *DarknessLightSourcesSystem() -{ - return &g_DarknessLightSourcesSystem; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDarknessLightSourcesSystem::LevelInitPreEntity() -{ - m_LightSources.Purge(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDarknessLightSourcesSystem::AddLightSource( CInfoDarknessLightSource *pEntity, float flRadius ) -{ - lightsource_t sNewSource; - sNewSource.hEntity = pEntity; - sNewSource.flLightRadiusSqr = flRadius * flRadius; - m_LightSources.AddToTail( sNewSource ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDarknessLightSourcesSystem::RemoveLightSource( CInfoDarknessLightSource *pEntity ) -{ - for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) - { - if ( m_LightSources[i].hEntity == pEntity ) - { - m_LightSources.Remove(i); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CDarknessLightSourcesSystem::IsEntityVisibleToTarget( CBaseEntity *pLooker, CBaseEntity *pTarget ) -{ - if ( pTarget->IsEffectActive( EF_BRIGHTLIGHT ) || pTarget->IsEffectActive( EF_DIMLIGHT ) ) - return true; - - bool bDebug = g_debug_darkness.GetBool(); - if ( bDebug && pLooker ) - { - bDebug = (pLooker->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) != 0; - } - - trace_t tr; - - // Loop through all the light sources. Do it backwards, so we can remove dead ones. - for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) - { - // Removed? - if ( m_LightSources[i].hEntity == NULL || m_LightSources[i].hEntity->IsMarkedForDeletion() ) - { - m_LightSources.FastRemove( i ); - continue; - } - - CInfoDarknessLightSource *pLightSource = m_LightSources[i].hEntity; - - // Close enough to a light source? - float flDistanceSqr = (pTarget->WorldSpaceCenter() - pLightSource->GetAbsOrigin()).LengthSqr(); - if ( flDistanceSqr < m_LightSources[i].flLightRadiusSqr ) - { - if ( pLightSource->ShouldIgnoreLOS() ) - { - if ( bDebug ) - { - NDebugOverlay::Line( pTarget->WorldSpaceCenter(), pLightSource->GetAbsOrigin(), 0,255,0,true, 0.1); - } - return true; - } - - // Check LOS from the light to the target - CTraceFilterSkipTwoEntities filter( pTarget, pLooker, COLLISION_GROUP_NONE ); - AI_TraceLine( pTarget->WorldSpaceCenter(), pLightSource->GetAbsOrigin(), MASK_BLOCKLOS, &filter, &tr ); - if ( tr.fraction == 1.0 ) - { - if ( bDebug ) - { - NDebugOverlay::Line( tr.startpos, tr.endpos, 0,255,0,true, 0.1); - } - return true; - } - - if ( bDebug ) - { - NDebugOverlay::Line( tr.startpos, tr.endpos, 255,0,0,true, 0.1); - NDebugOverlay::Line( tr.endpos, pLightSource->GetAbsOrigin(), 128,0,0,true, 0.1); - } - - // If the target is within the radius of the light, don't do sillhouette checks - continue; - } - - if ( !pLooker ) - continue; - - // Between a light source and the looker? - Vector vecLookerToLight = (pLightSource->GetAbsOrigin() - pLooker->WorldSpaceCenter()); - Vector vecLookerToTarget = (pTarget->WorldSpaceCenter() - pLooker->WorldSpaceCenter()); - float flDistToSource = VectorNormalize( vecLookerToLight ); - float flDistToTarget = VectorNormalize( vecLookerToTarget ); - float flDot = DotProduct( vecLookerToLight, vecLookerToTarget ); - if ( flDot > 0 ) - { - // Make sure the target is in front of the lightsource - if ( flDistToTarget < flDistToSource ) - { - if ( bDebug ) - { - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), pLooker->WorldSpaceCenter() + (vecLookerToLight * 128), 255,255,255,true, 0.1); - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), pLooker->WorldSpaceCenter() + (vecLookerToTarget * 128), 255,0,0,true, 0.1); - } - - // Now, we need to find out if the light source is obscured by anything. - // To do this, we want to calculate the point of intersection between the light source - // sphere and the line from the looker through the target. - float flASqr = (flDistToSource * flDistToSource); - float flB = -2 * flDistToSource * flDot; - float flCSqr = m_LightSources[i].flLightRadiusSqr; - float flDesc = (flB * flB) - (4 * (flASqr - flCSqr)); - if ( flDesc >= 0 ) - { - float flLength = (-flB - sqrt(flDesc)) / 2; - Vector vecSpherePoint = pLooker->WorldSpaceCenter() + (vecLookerToTarget * flLength); - - // We've got the point of intersection. See if we can see it. - CTraceFilterSkipTwoEntities filter( pTarget, pLooker, COLLISION_GROUP_NONE ); - AI_TraceLine( pLooker->EyePosition(), vecSpherePoint, MASK_SOLID_BRUSHONLY, &filter, &tr ); - - if ( bDebug ) - { - if (tr.fraction != 1.0) - { - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), vecSpherePoint, 255,0,0,true, 0.1); - } - else - { - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), vecSpherePoint, 0,255,0,true, 0.1); - NDebugOverlay::Line( pLightSource->GetAbsOrigin(), vecSpherePoint, 255,0,0,true, 0.1); - } - } - - if ( tr.fraction == 1.0 ) - return true; - } - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CDarknessLightSourcesSystem::AreThereLightSourcesWithinRadius( CBaseEntity *pLooker, float flRadius ) -{ - float flRadiusSqr = (flRadius * flRadius); - for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) - { - // Removed? - if ( m_LightSources[i].hEntity == NULL || m_LightSources[i].hEntity->IsMarkedForDeletion() ) - { - m_LightSources.FastRemove( i ); - continue; - } - - CBaseEntity *pLightSource = m_LightSources[i].hEntity; - - // Close enough to a light source? - float flDistanceSqr = (pLooker->WorldSpaceCenter() - pLightSource->GetAbsOrigin()).LengthSqr(); - if ( flDistanceSqr < flRadiusSqr ) - { - trace_t tr; - AI_TraceLine( pLooker->EyePosition(), pLightSource->GetAbsOrigin(), MASK_SOLID_BRUSHONLY, pLooker, COLLISION_GROUP_NONE, &tr ); - - if ( g_debug_darkness.GetBool() ) - { - if (tr.fraction != 1.0) - { - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), tr.endpos, 255,0,0,true, 0.1); - } - else - { - NDebugOverlay::Line( pLooker->WorldSpaceCenter(), tr.endpos, 0,255,0,true, 0.1); - NDebugOverlay::Line( pLightSource->GetAbsOrigin(), tr.endpos, 255,0,0,true, 0.1); - } - } - - if ( tr.fraction == 1.0 ) - return true; - } - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CDarknessLightSourcesSystem::SetDebug( bool bDebug ) -{ - for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) - { - CInfoDarknessLightSource *pLightSource = dynamic_cast(m_LightSources[i].hEntity.Get()); - if ( pLightSource ) - { - if ( bDebug ) - { - pLightSource->SetThink( &CInfoDarknessLightSource::DebugThink ); - pLightSource->SetNextThink( gpGlobals->curtime ); - } - else - { - pLightSource->SetThink( NULL ); - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CV_Debug_Darkness( IConVar *pConVar, const char *pOldString, float flOldValue ) -{ - ConVarRef var( pConVar ); - DarknessLightSourcesSystem()->SetDebug( var.GetBool() ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pEntity - -//----------------------------------------------------------------------------- -void AddEntityToDarknessCheck( CBaseEntity *pEntity, float flLightRadius /*=DARKNESS_LIGHTSOURCE_SIZE*/ ) -{ - // Create a light source, and attach it to the entity - CInfoDarknessLightSource *pLightSource = (CInfoDarknessLightSource *) CreateEntityByName( "info_darknessmode_lightsource" ); - if ( pLightSource ) - { - pLightSource->SetLightRadius( flLightRadius ); - DispatchSpawn( pLightSource ); - pLightSource->SetAbsOrigin( pEntity->WorldSpaceCenter() ); - pLightSource->SetParent( pEntity ); - pLightSource->Activate(); - - // Dynamically created darkness sources can ignore LOS - // to match the (broken) visual representation of our dynamic lights. - if ( darkness_ignore_LOS_to_sources.GetBool() ) - { - pLightSource->IgnoreLOS(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pEntity - -//----------------------------------------------------------------------------- -void RemoveEntityFromDarknessCheck( CBaseEntity *pEntity ) -{ - // Find any light sources parented to this entity, and remove them - CBaseEntity *pChild = pEntity->FirstMoveChild(); - while ( pChild ) - { - CBaseEntity *pPrevChild = pChild; - pChild = pChild->NextMovePeer(); - - if ( dynamic_cast(pPrevChild) ) - { - UTIL_Remove( pPrevChild ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pEntity - -//----------------------------------------------------------------------------- -bool LookerCouldSeeTargetInDarkness( CBaseEntity *pLooker, CBaseEntity *pTarget ) -{ - if ( DarknessLightSourcesSystem()->IsEntityVisibleToTarget( pLooker, pTarget ) ) - { - //NDebugOverlay::Line( pTarget->WorldSpaceCenter(), pLooker->WorldSpaceCenter(), 0,255,0,true, 0.1); - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Return true if there is at least 1 darkness light source within -// the specified radius of the looker. -//----------------------------------------------------------------------------- -bool DarknessLightSourceWithinRadius( CBaseEntity *pLooker, float flRadius ) -{ - return DarknessLightSourcesSystem()->AreThereLightSourcesWithinRadius( pLooker, flRadius ); -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "info_darknessmode_lightsource.h" +#include "ai_debug_shared.h" + +void CV_Debug_Darkness( IConVar *var, const char *pOldString, float flOldValue ); +ConVar g_debug_darkness( "g_debug_darkness", "0", FCVAR_NONE, "Show darkness mode lightsources.", CV_Debug_Darkness ); +ConVar darkness_ignore_LOS_to_sources( "darkness_ignore_LOS_to_sources", "1", FCVAR_NONE ); + +class CInfoDarknessLightSource; + +//----------------------------------------------------------------------------- +// Purpose: Manages entities that provide light while in darkness mode +//----------------------------------------------------------------------------- +class CDarknessLightSourcesSystem : public CAutoGameSystem +{ +public: + CDarknessLightSourcesSystem() : CAutoGameSystem( "CDarknessLightSourcesSystem" ) + { + } + + void LevelInitPreEntity(); + + void AddLightSource( CInfoDarknessLightSource *pEntity, float flRadius ); + void RemoveLightSource( CInfoDarknessLightSource *pEntity ); + bool IsEntityVisibleToTarget( CBaseEntity *pLooker, CBaseEntity *pTarget ); + bool AreThereLightSourcesWithinRadius( CBaseEntity *pLooker, float flRadius ); + void SetDebug( bool bDebug ); + +private: + struct lightsource_t + { + float flLightRadiusSqr; + CHandle hEntity; + }; + + CUtlVector m_LightSources; +}; + +CDarknessLightSourcesSystem *DarknessLightSourcesSystem(); + +//----------------------------------------------------------------------------- +// Darkness mode light source entity +//----------------------------------------------------------------------------- +class CInfoDarknessLightSource : public CBaseEntity +{ + DECLARE_CLASS( CInfoDarknessLightSource, CBaseEntity ); +public: + DECLARE_DATADESC(); + + virtual void Activate() + { + if ( m_bDisabled == false ) + { + DarknessLightSourcesSystem()->AddLightSource( this, m_flLightRadius ); + + if ( g_debug_darkness.GetBool() ) + { + SetThink( &CInfoDarknessLightSource::DebugThink ); + SetNextThink( gpGlobals->curtime ); + } + } + + BaseClass::Activate(); + } + virtual void UpdateOnRemove() + { + DarknessLightSourcesSystem()->RemoveLightSource( this ); + BaseClass::UpdateOnRemove(); + } + void SetLightRadius( float flRadius ) + { + m_flLightRadius = flRadius; + } + + void InputEnable( inputdata_t &inputdata ) + { + DarknessLightSourcesSystem()->AddLightSource( this, m_flLightRadius ); + m_bDisabled = false; + } + + void InputDisable( inputdata_t &inputdata ) + { + DarknessLightSourcesSystem()->RemoveLightSource( this ); + m_bDisabled = true; + } + + void DebugThink( void ) + { + Vector vecRadius( m_flLightRadius, m_flLightRadius, m_flLightRadius ); + NDebugOverlay::Box( GetAbsOrigin(), -vecRadius, vecRadius, 255,255,255, 8, 0.1 ); + NDebugOverlay::Box( GetAbsOrigin(), -Vector(5,5,5), Vector(5,5,5), 255,0,0, 8, 0.1 ); + SetNextThink( gpGlobals->curtime + 0.1 ); + + int textoffset = 0; + EntityText( textoffset, UTIL_VarArgs("Org: %.2f %.2f %.2f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z ), 0.1 ); + textoffset++; + EntityText( textoffset, UTIL_VarArgs("Radius %.2f", m_flLightRadius), 0.1 ); + textoffset++; + if ( m_bIgnoreLOS ) + { + EntityText( textoffset, "Ignoring LOS", 0.1 ); + textoffset++; + } + if ( m_bDisabled ) + { + EntityText( textoffset, "DISABLED", 0.1 ); + textoffset++; + } + } + + void IgnoreLOS( void ) + { + m_bIgnoreLOS = true; + } + + bool ShouldIgnoreLOS( void ) + { + return m_bIgnoreLOS; + } + +private: + float m_flLightRadius; + bool m_bDisabled; + bool m_bIgnoreLOS; +}; + +LINK_ENTITY_TO_CLASS( info_darknessmode_lightsource, CInfoDarknessLightSource ); + +BEGIN_DATADESC( CInfoDarknessLightSource ) + DEFINE_KEYFIELD( m_flLightRadius, FIELD_FLOAT, "LightRadius" ), + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ), + DEFINE_FIELD( m_bIgnoreLOS, FIELD_BOOLEAN ), + + DEFINE_THINKFUNC( DebugThink ), +END_DATADESC() + +CDarknessLightSourcesSystem g_DarknessLightSourcesSystem; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CDarknessLightSourcesSystem *DarknessLightSourcesSystem() +{ + return &g_DarknessLightSourcesSystem; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDarknessLightSourcesSystem::LevelInitPreEntity() +{ + m_LightSources.Purge(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDarknessLightSourcesSystem::AddLightSource( CInfoDarknessLightSource *pEntity, float flRadius ) +{ + lightsource_t sNewSource; + sNewSource.hEntity = pEntity; + sNewSource.flLightRadiusSqr = flRadius * flRadius; + m_LightSources.AddToTail( sNewSource ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDarknessLightSourcesSystem::RemoveLightSource( CInfoDarknessLightSource *pEntity ) +{ + for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) + { + if ( m_LightSources[i].hEntity == pEntity ) + { + m_LightSources.Remove(i); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDarknessLightSourcesSystem::IsEntityVisibleToTarget( CBaseEntity *pLooker, CBaseEntity *pTarget ) +{ + if ( pTarget->IsEffectActive( EF_BRIGHTLIGHT ) || pTarget->IsEffectActive( EF_DIMLIGHT ) ) + return true; + + bool bDebug = g_debug_darkness.GetBool(); + if ( bDebug && pLooker ) + { + bDebug = (pLooker->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) != 0; + } + + trace_t tr; + + // Loop through all the light sources. Do it backwards, so we can remove dead ones. + for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) + { + // Removed? + if ( m_LightSources[i].hEntity == NULL || m_LightSources[i].hEntity->IsMarkedForDeletion() ) + { + m_LightSources.FastRemove( i ); + continue; + } + + CInfoDarknessLightSource *pLightSource = m_LightSources[i].hEntity; + + // Close enough to a light source? + float flDistanceSqr = (pTarget->WorldSpaceCenter() - pLightSource->GetAbsOrigin()).LengthSqr(); + if ( flDistanceSqr < m_LightSources[i].flLightRadiusSqr ) + { + if ( pLightSource->ShouldIgnoreLOS() ) + { + if ( bDebug ) + { + NDebugOverlay::Line( pTarget->WorldSpaceCenter(), pLightSource->GetAbsOrigin(), 0,255,0,true, 0.1); + } + return true; + } + + // Check LOS from the light to the target + CTraceFilterSkipTwoEntities filter( pTarget, pLooker, COLLISION_GROUP_NONE ); + AI_TraceLine( pTarget->WorldSpaceCenter(), pLightSource->GetAbsOrigin(), MASK_BLOCKLOS, &filter, &tr ); + if ( tr.fraction == 1.0 ) + { + if ( bDebug ) + { + NDebugOverlay::Line( tr.startpos, tr.endpos, 0,255,0,true, 0.1); + } + return true; + } + + if ( bDebug ) + { + NDebugOverlay::Line( tr.startpos, tr.endpos, 255,0,0,true, 0.1); + NDebugOverlay::Line( tr.endpos, pLightSource->GetAbsOrigin(), 128,0,0,true, 0.1); + } + + // If the target is within the radius of the light, don't do sillhouette checks + continue; + } + + if ( !pLooker ) + continue; + + // Between a light source and the looker? + Vector vecLookerToLight = (pLightSource->GetAbsOrigin() - pLooker->WorldSpaceCenter()); + Vector vecLookerToTarget = (pTarget->WorldSpaceCenter() - pLooker->WorldSpaceCenter()); + float flDistToSource = VectorNormalize( vecLookerToLight ); + float flDistToTarget = VectorNormalize( vecLookerToTarget ); + float flDot = DotProduct( vecLookerToLight, vecLookerToTarget ); + if ( flDot > 0 ) + { + // Make sure the target is in front of the lightsource + if ( flDistToTarget < flDistToSource ) + { + if ( bDebug ) + { + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), pLooker->WorldSpaceCenter() + (vecLookerToLight * 128), 255,255,255,true, 0.1); + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), pLooker->WorldSpaceCenter() + (vecLookerToTarget * 128), 255,0,0,true, 0.1); + } + + // Now, we need to find out if the light source is obscured by anything. + // To do this, we want to calculate the point of intersection between the light source + // sphere and the line from the looker through the target. + float flASqr = (flDistToSource * flDistToSource); + float flB = -2 * flDistToSource * flDot; + float flCSqr = m_LightSources[i].flLightRadiusSqr; + float flDesc = (flB * flB) - (4 * (flASqr - flCSqr)); + if ( flDesc >= 0 ) + { + float flLength = (-flB - sqrt(flDesc)) / 2; + Vector vecSpherePoint = pLooker->WorldSpaceCenter() + (vecLookerToTarget * flLength); + + // We've got the point of intersection. See if we can see it. + CTraceFilterSkipTwoEntities filter( pTarget, pLooker, COLLISION_GROUP_NONE ); + AI_TraceLine( pLooker->EyePosition(), vecSpherePoint, MASK_SOLID_BRUSHONLY, &filter, &tr ); + + if ( bDebug ) + { + if (tr.fraction != 1.0) + { + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), vecSpherePoint, 255,0,0,true, 0.1); + } + else + { + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), vecSpherePoint, 0,255,0,true, 0.1); + NDebugOverlay::Line( pLightSource->GetAbsOrigin(), vecSpherePoint, 255,0,0,true, 0.1); + } + } + + if ( tr.fraction == 1.0 ) + return true; + } + } + } + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDarknessLightSourcesSystem::AreThereLightSourcesWithinRadius( CBaseEntity *pLooker, float flRadius ) +{ + float flRadiusSqr = (flRadius * flRadius); + for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) + { + // Removed? + if ( m_LightSources[i].hEntity == NULL || m_LightSources[i].hEntity->IsMarkedForDeletion() ) + { + m_LightSources.FastRemove( i ); + continue; + } + + CBaseEntity *pLightSource = m_LightSources[i].hEntity; + + // Close enough to a light source? + float flDistanceSqr = (pLooker->WorldSpaceCenter() - pLightSource->GetAbsOrigin()).LengthSqr(); + if ( flDistanceSqr < flRadiusSqr ) + { + trace_t tr; + AI_TraceLine( pLooker->EyePosition(), pLightSource->GetAbsOrigin(), MASK_SOLID_BRUSHONLY, pLooker, COLLISION_GROUP_NONE, &tr ); + + if ( g_debug_darkness.GetBool() ) + { + if (tr.fraction != 1.0) + { + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), tr.endpos, 255,0,0,true, 0.1); + } + else + { + NDebugOverlay::Line( pLooker->WorldSpaceCenter(), tr.endpos, 0,255,0,true, 0.1); + NDebugOverlay::Line( pLightSource->GetAbsOrigin(), tr.endpos, 255,0,0,true, 0.1); + } + } + + if ( tr.fraction == 1.0 ) + return true; + } + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDarknessLightSourcesSystem::SetDebug( bool bDebug ) +{ + for ( int i = m_LightSources.Count() - 1; i >= 0; i-- ) + { + CInfoDarknessLightSource *pLightSource = dynamic_cast(m_LightSources[i].hEntity.Get()); + if ( pLightSource ) + { + if ( bDebug ) + { + pLightSource->SetThink( &CInfoDarknessLightSource::DebugThink ); + pLightSource->SetNextThink( gpGlobals->curtime ); + } + else + { + pLightSource->SetThink( NULL ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CV_Debug_Darkness( IConVar *pConVar, const char *pOldString, float flOldValue ) +{ + ConVarRef var( pConVar ); + DarknessLightSourcesSystem()->SetDebug( var.GetBool() ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pEntity - +//----------------------------------------------------------------------------- +void AddEntityToDarknessCheck( CBaseEntity *pEntity, float flLightRadius /*=DARKNESS_LIGHTSOURCE_SIZE*/ ) +{ + // Create a light source, and attach it to the entity + CInfoDarknessLightSource *pLightSource = (CInfoDarknessLightSource *) CreateEntityByName( "info_darknessmode_lightsource" ); + if ( pLightSource ) + { + pLightSource->SetLightRadius( flLightRadius ); + DispatchSpawn( pLightSource ); + pLightSource->SetAbsOrigin( pEntity->WorldSpaceCenter() ); + pLightSource->SetParent( pEntity ); + pLightSource->Activate(); + + // Dynamically created darkness sources can ignore LOS + // to match the (broken) visual representation of our dynamic lights. + if ( darkness_ignore_LOS_to_sources.GetBool() ) + { + pLightSource->IgnoreLOS(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pEntity - +//----------------------------------------------------------------------------- +void RemoveEntityFromDarknessCheck( CBaseEntity *pEntity ) +{ + // Find any light sources parented to this entity, and remove them + CBaseEntity *pChild = pEntity->FirstMoveChild(); + while ( pChild ) + { + CBaseEntity *pPrevChild = pChild; + pChild = pChild->NextMovePeer(); + + if ( dynamic_cast(pPrevChild) ) + { + UTIL_Remove( pPrevChild ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pEntity - +//----------------------------------------------------------------------------- +bool LookerCouldSeeTargetInDarkness( CBaseEntity *pLooker, CBaseEntity *pTarget ) +{ + if ( DarknessLightSourcesSystem()->IsEntityVisibleToTarget( pLooker, pTarget ) ) + { + //NDebugOverlay::Line( pTarget->WorldSpaceCenter(), pLooker->WorldSpaceCenter(), 0,255,0,true, 0.1); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Return true if there is at least 1 darkness light source within +// the specified radius of the looker. +//----------------------------------------------------------------------------- +bool DarknessLightSourceWithinRadius( CBaseEntity *pLooker, float flRadius ) +{ + return DarknessLightSourcesSystem()->AreThereLightSourcesWithinRadius( pLooker, flRadius ); +} -- cgit v1.2.3