2023-10-03 17:23:56 +03:00
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
2020-04-22 12:56:21 -04:00
//
// Purpose: Precaches and defs for entities and other data that must always be available.
//
2023-10-03 17:23:56 +03:00
//===========================================================================
2020-04-22 12:56:21 -04:00
# include "cbase.h"
# include "soundent.h"
# include "client.h"
# include "decals.h"
2023-10-03 17:23:56 +03:00
# include "editor_sendcommand.h"
2020-04-22 12:56:21 -04:00
# include "EnvMessage.h"
# include "player.h"
# include "gamerules.h"
# include "teamplay_gamerules.h"
# include "physics.h"
# include "isaverestore.h"
# include "activitylist.h"
# include "eventlist.h"
# include "eventqueue.h"
# include "ai_network.h"
# include "ai_schedule.h"
# include "ai_networkmanager.h"
# include "ai_utils.h"
# include "basetempentity.h"
# include "world.h"
# include "mempool.h"
# include "igamesystem.h"
# include "engine/IEngineSound.h"
# include "globals.h"
# include "engine/IStaticPropMgr.h"
# include "particle_parse.h"
# include "globalstate.h"
2023-10-03 17:23:56 +03:00
# include "cvisibilitymonitor.h"
# include "model_types.h"
# include "vscript/ivscript.h"
# include "vscript_server.h"
2020-04-22 12:56:21 -04:00
// memdbgon must be the last include file in a .cpp file!!!
# include "tier0/memdbgon.h"
extern CBaseEntity * g_pLastSpawn ;
void InitBodyQue ( void ) ;
extern void W_Precache ( void ) ;
extern void ActivityList_Free ( void ) ;
extern CUtlMemoryPool g_EntityListPool ;
# define SF_DECAL_NOTINDEATHMATCH 2048
2023-10-03 17:23:56 +03:00
# if !defined( CLIENT_DLL )
# define SF_GAME_EVENT_PROXY_AUTO_VISIBILITY 1
//=========================================================
// Allows level designers to generate certain game events
// from entity i/o.
//=========================================================
class CInfoGameEventProxy : public CPointEntity
{
private :
string_t m_iszEventName ;
float m_flRange ;
public :
DECLARE_CLASS ( CInfoGameEventProxy , CPointEntity ) ;
void Spawn ( ) ;
int UpdateTransmitState ( ) ;
void InputGenerateGameEvent ( inputdata_t & inputdata ) ;
static bool GameEventProxyCallback ( CBaseEntity * pProxy , CBasePlayer * pViewingPlayer ) ;
DECLARE_DATADESC ( ) ;
} ;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CInfoGameEventProxy : : Spawn ( )
{
BaseClass : : Spawn ( ) ;
m_flRange * = 12.0f ; // Convert feet to inches
if ( GetSpawnFlags ( ) & SF_GAME_EVENT_PROXY_AUTO_VISIBILITY )
{
VisibilityMonitor_AddEntity ( this , m_flRange , & CInfoGameEventProxy : : GameEventProxyCallback , NULL ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose: Always transmitted to clients
//-----------------------------------------------------------------------------
int CInfoGameEventProxy : : UpdateTransmitState ( )
{
return SetTransmitState ( FL_EDICT_ALWAYS ) ;
}
//---------------------------------------------------------
//---------------------------------------------------------
void CInfoGameEventProxy : : InputGenerateGameEvent ( inputdata_t & inputdata )
{
CBasePlayer * pActivator = ToBasePlayer ( inputdata . pActivator ) ;
IGameEvent * event = gameeventmanager - > CreateEvent ( m_iszEventName . ToCStr ( ) ) ;
if ( event )
{
if ( pActivator )
{
event - > SetInt ( " userid " , pActivator - > GetUserID ( ) ) ;
}
event - > SetInt ( " subject " , entindex ( ) ) ;
gameeventmanager - > FireEvent ( event ) ;
}
}
//---------------------------------------------------------
// Callback for the visibility monitor.
//---------------------------------------------------------
bool CInfoGameEventProxy : : GameEventProxyCallback ( CBaseEntity * pProxy , CBasePlayer * pViewingPlayer )
{
CInfoGameEventProxy * pProxyPtr = dynamic_cast < CInfoGameEventProxy * > ( pProxy ) ;
if ( ! pProxyPtr )
return true ;
IGameEvent * event = gameeventmanager - > CreateEvent ( pProxyPtr - > m_iszEventName . ToCStr ( ) ) ;
if ( event )
{
event - > SetInt ( " userid " , pViewingPlayer - > GetUserID ( ) ) ;
event - > SetInt ( " subject " , pProxyPtr - > entindex ( ) ) ;
gameeventmanager - > FireEvent ( event ) ;
}
return false ;
}
LINK_ENTITY_TO_CLASS ( info_game_event_proxy , CInfoGameEventProxy ) ;
BEGIN_DATADESC ( CInfoGameEventProxy )
DEFINE_KEYFIELD ( m_iszEventName , FIELD_STRING , " event_name " ) ,
DEFINE_KEYFIELD ( m_flRange , FIELD_FLOAT , " range " ) ,
DEFINE_INPUTFUNC ( FIELD_STRING , " GenerateGameEvent " , InputGenerateGameEvent ) ,
END_DATADESC ( )
# endif
2020-04-22 12:56:21 -04:00
class CDecal : public CPointEntity
{
public :
DECLARE_CLASS ( CDecal , CPointEntity ) ;
void Spawn ( void ) ;
bool KeyValue ( const char * szKeyName , const char * szValue ) ;
// Need to apply static decals here to get them into the signon buffer for the server appropriately
virtual void Activate ( ) ;
void TriggerDecal ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
// Input handlers.
void InputActivate ( inputdata_t & inputdata ) ;
2023-10-03 17:23:56 +03:00
CBaseEntity * GetDecalEntityAndPosition ( Vector * pPosition , bool bStatic ) ;
2020-04-22 12:56:21 -04:00
DECLARE_DATADESC ( ) ;
public :
int m_nTexture ;
bool m_bLowPriority ;
2023-10-03 17:23:56 +03:00
string_t m_entityName ;
2020-04-22 12:56:21 -04:00
private :
void StaticDecal ( void ) ;
} ;
BEGIN_DATADESC ( CDecal )
DEFINE_FIELD ( m_nTexture , FIELD_INTEGER ) ,
DEFINE_KEYFIELD ( m_bLowPriority , FIELD_BOOLEAN , " LowPriority " ) , // Don't mark as FDECAL_PERMANENT so not save/restored and will be reused on the client preferentially
2023-10-03 17:23:56 +03:00
DEFINE_KEYFIELD ( m_entityName , FIELD_STRING , " ApplyEntity " ) , // Force apply to this entity instead of tracing
2020-04-22 12:56:21 -04:00
// Function pointers
DEFINE_FUNCTION ( StaticDecal ) ,
DEFINE_FUNCTION ( TriggerDecal ) ,
DEFINE_INPUTFUNC ( FIELD_VOID , " Activate " , InputActivate ) ,
END_DATADESC ( )
LINK_ENTITY_TO_CLASS ( infodecal , CDecal ) ;
// UNDONE: These won't get sent to joining players in multi-player
void CDecal : : Spawn ( void )
{
if ( m_nTexture < 0 | |
( gpGlobals - > deathmatch & & HasSpawnFlags ( SF_DECAL_NOTINDEATHMATCH ) ) )
{
UTIL_Remove ( this ) ;
return ;
}
}
void CDecal : : Activate ( )
{
BaseClass : : Activate ( ) ;
if ( ! GetEntityName ( ) )
{
StaticDecal ( ) ;
}
else
{
// if there IS a targetname, the decal sprays itself on when it is triggered.
SetThink ( & CDecal : : SUB_DoNothing ) ;
SetUse ( & CDecal : : TriggerDecal ) ;
}
}
2023-10-03 17:23:56 +03:00
class CTraceFilterValidForDecal : public CTraceFilterSimple
{
public :
CTraceFilterValidForDecal ( const IHandleEntity * passentity , int collisionGroup )
: CTraceFilterSimple ( passentity , collisionGroup )
{
}
virtual bool ShouldHitEntity ( IHandleEntity * pServerEntity , int contentsMask )
{
static const char * ppszIgnoredClasses [ ] =
{
" weapon_* " ,
" item_* " ,
" prop_ragdoll " ,
" prop_dynamic " ,
" prop_static " ,
" prop_physics " ,
" npc_bullseye " , // Tracker 15335
} ;
CBaseEntity * pEntity = EntityFromEntityHandle ( pServerEntity ) ;
// Tracker 15335: Never impact decals against entities which are not rendering, either.
if ( pEntity - > IsEffectActive ( EF_NODRAW ) )
return false ;
for ( int i = 0 ; i < ARRAYSIZE ( ppszIgnoredClasses ) ; i + + )
{
if ( pEntity - > ClassMatches ( ppszIgnoredClasses [ i ] ) )
return false ;
}
if ( modelinfo - > GetModelType ( pEntity - > GetModel ( ) ) ! = mod_brush )
return false ;
return CTraceFilterSimple : : ShouldHitEntity ( pServerEntity , contentsMask ) ;
}
} ;
CBaseEntity * CDecal : : GetDecalEntityAndPosition ( Vector * pPosition , bool bStatic )
{
CBaseEntity * pEntity = NULL ;
if ( ! m_entityName )
{
trace_t trace ;
Vector start = GetAbsOrigin ( ) ;
Vector direction ( 1 , 1 , 1 ) ;
if ( GetAbsAngles ( ) = = vec3_angle )
{
start - = direction * 5 ;
}
else
{
GetVectors ( & direction , NULL , NULL ) ;
}
Vector end = start + direction * 10 ;
if ( bStatic )
{
CTraceFilterValidForDecal traceFilter ( this , COLLISION_GROUP_NONE ) ;
UTIL_TraceLine ( start , end , MASK_SOLID , & traceFilter , & trace ) ;
}
else
{
UTIL_TraceLine ( start , end , MASK_SOLID_BRUSHONLY , this , COLLISION_GROUP_NONE , & trace ) ;
}
if ( trace . DidHitNonWorldEntity ( ) )
{
* pPosition = trace . endpos ;
return trace . m_pEnt ;
}
}
else
{
pEntity = gEntList . FindEntityByName ( NULL , m_entityName ) ;
}
* pPosition = GetAbsOrigin ( ) ;
return pEntity ;
}
2020-04-22 12:56:21 -04:00
void CDecal : : TriggerDecal ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value )
{
// this is set up as a USE function for info_decals that have targetnames, so that the
// decal doesn't get applied until it is fired. (usually by a scripted sequence)
trace_t trace ;
int entityIndex ;
2023-10-03 17:23:56 +03:00
Vector position ;
CBaseEntity * pEntity = GetDecalEntityAndPosition ( & position , false ) ;
entityIndex = pEntity ? pEntity - > entindex ( ) : 0 ;
2020-04-22 12:56:21 -04:00
CBroadcastRecipientFilter filter ;
2023-10-03 17:23:56 +03:00
te - > BSPDecal ( filter , 0.0 , & position , entityIndex , m_nTexture ) ;
2020-04-22 12:56:21 -04:00
SetThink ( & CDecal : : SUB_Remove ) ;
SetNextThink ( gpGlobals - > curtime + 0.1f ) ;
}
void CDecal : : InputActivate ( inputdata_t & inputdata )
{
TriggerDecal ( inputdata . pActivator , inputdata . pCaller , USE_ON , 0 ) ;
}
void CDecal : : StaticDecal ( void )
{
2023-10-03 17:23:56 +03:00
Vector position ;
CBaseEntity * pEntity = GetDecalEntityAndPosition ( & position , true ) ;
int entityIndex = 0 ;
int modelIndex = 0 ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
if ( pEntity )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
entityIndex = pEntity - > entindex ( ) ;
modelIndex = pEntity - > GetModelIndex ( ) ;
Vector worldspace = position ;
VectorITransform ( worldspace , pEntity - > EntityToWorldTransform ( ) , position ) ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
else
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
position = GetAbsOrigin ( ) ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
engine - > StaticDecal ( position , m_nTexture , entityIndex , modelIndex , m_bLowPriority ) ;
2020-04-22 12:56:21 -04:00
SUB_Remove ( ) ;
}
bool CDecal : : KeyValue ( const char * szKeyName , const char * szValue )
{
if ( FStrEq ( szKeyName , " texture " ) )
{
// FIXME: should decals all be preloaded?
m_nTexture = UTIL_PrecacheDecal ( szValue , true ) ;
// Found
if ( m_nTexture > = 0 )
return true ;
Warning ( " Can't find decal %s \n " , szValue ) ;
}
else
{
return BaseClass : : KeyValue ( szKeyName , szValue ) ;
}
return true ;
}
//-----------------------------------------------------------------------------
// Purpose: Projects a decal against a prop
//-----------------------------------------------------------------------------
class CProjectedDecal : public CPointEntity
{
public :
DECLARE_CLASS ( CProjectedDecal , CPointEntity ) ;
void Spawn ( void ) ;
bool KeyValue ( const char * szKeyName , const char * szValue ) ;
// Need to apply static decals here to get them into the signon buffer for the server appropriately
virtual void Activate ( ) ;
void TriggerDecal ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
// Input handlers.
void InputActivate ( inputdata_t & inputdata ) ;
DECLARE_DATADESC ( ) ;
public :
int m_nTexture ;
float m_flDistance ;
private :
void ProjectDecal ( CRecipientFilter & filter ) ;
void StaticDecal ( void ) ;
} ;
BEGIN_DATADESC ( CProjectedDecal )
DEFINE_FIELD ( m_nTexture , FIELD_INTEGER ) ,
DEFINE_KEYFIELD ( m_flDistance , FIELD_FLOAT , " Distance " ) ,
// Function pointers
DEFINE_FUNCTION ( StaticDecal ) ,
DEFINE_FUNCTION ( TriggerDecal ) ,
DEFINE_INPUTFUNC ( FIELD_VOID , " Activate " , InputActivate ) ,
END_DATADESC ( )
LINK_ENTITY_TO_CLASS ( info_projecteddecal , CProjectedDecal ) ;
// UNDONE: These won't get sent to joining players in multi-player
void CProjectedDecal : : Spawn ( void )
{
if ( m_nTexture < 0 | |
( gpGlobals - > deathmatch & & HasSpawnFlags ( SF_DECAL_NOTINDEATHMATCH ) ) )
{
UTIL_Remove ( this ) ;
return ;
}
}
void CProjectedDecal : : Activate ( )
{
BaseClass : : Activate ( ) ;
if ( ! GetEntityName ( ) )
{
StaticDecal ( ) ;
}
else
{
// if there IS a targetname, the decal sprays itself on when it is triggered.
SetThink ( & CProjectedDecal : : SUB_DoNothing ) ;
SetUse ( & CProjectedDecal : : TriggerDecal ) ;
}
}
void CProjectedDecal : : InputActivate ( inputdata_t & inputdata )
{
TriggerDecal ( inputdata . pActivator , inputdata . pCaller , USE_ON , 0 ) ;
}
void CProjectedDecal : : ProjectDecal ( CRecipientFilter & filter )
{
te - > ProjectDecal ( filter , 0.0 ,
& GetAbsOrigin ( ) , & GetAbsAngles ( ) , m_flDistance , m_nTexture ) ;
}
void CProjectedDecal : : TriggerDecal ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value )
{
CBroadcastRecipientFilter filter ;
ProjectDecal ( filter ) ;
SetThink ( & CProjectedDecal : : SUB_Remove ) ;
SetNextThink ( gpGlobals - > curtime + 0.1f ) ;
}
void CProjectedDecal : : StaticDecal ( void )
{
CBroadcastRecipientFilter initFilter ;
initFilter . MakeInitMessage ( ) ;
ProjectDecal ( initFilter ) ;
SUB_Remove ( ) ;
}
bool CProjectedDecal : : KeyValue ( const char * szKeyName , const char * szValue )
{
if ( FStrEq ( szKeyName , " texture " ) )
{
// FIXME: should decals all be preloaded?
m_nTexture = UTIL_PrecacheDecal ( szValue , true ) ;
// Found
if ( m_nTexture > = 0 )
return true ;
Warning ( " Can't find decal %s \n " , szValue ) ;
}
else
{
return BaseClass : : KeyValue ( szKeyName , szValue ) ;
}
return true ;
}
//=======================
// CWorld
//
// This spawns first when each level begins.
//=======================
LINK_ENTITY_TO_CLASS ( worldspawn , CWorld ) ;
BEGIN_DATADESC ( CWorld )
DEFINE_FIELD ( m_flWaveHeight , FIELD_FLOAT ) ,
// keyvalues are parsed from map, but not saved/loaded
DEFINE_KEYFIELD ( m_iszChapterTitle , FIELD_STRING , " chaptertitle " ) ,
DEFINE_KEYFIELD ( m_bStartDark , FIELD_BOOLEAN , " startdark " ) ,
DEFINE_KEYFIELD ( m_bDisplayTitle , FIELD_BOOLEAN , " gametitle " ) ,
DEFINE_FIELD ( m_WorldMins , FIELD_VECTOR ) ,
DEFINE_FIELD ( m_WorldMaxs , FIELD_VECTOR ) ,
2023-10-03 17:23:56 +03:00
// DEFINE_FIELD( m_flMaxOccludeeArea, FIELD_CLASSCHECK_IGNORE ) // do this or else we get a warning about multiply-defined fields
// DEFINE_FIELD( m_flMinOccluderArea, FIELD_CLASSCHECK_IGNORE ) // do this or else we get a warning about multiply-defined fields
2020-04-22 12:56:21 -04:00
# ifdef _X360
DEFINE_KEYFIELD ( m_flMaxOccludeeArea , FIELD_FLOAT , " maxoccludeearea_x360 " ) ,
DEFINE_KEYFIELD ( m_flMinOccluderArea , FIELD_FLOAT , " minoccluderarea_x360 " ) ,
# else
DEFINE_KEYFIELD ( m_flMaxOccludeeArea , FIELD_FLOAT , " maxoccludeearea " ) ,
DEFINE_KEYFIELD ( m_flMinOccluderArea , FIELD_FLOAT , " minoccluderarea " ) ,
# endif
DEFINE_KEYFIELD ( m_flMaxPropScreenSpaceWidth , FIELD_FLOAT , " maxpropscreenwidth " ) ,
DEFINE_KEYFIELD ( m_flMinPropScreenSpaceWidth , FIELD_FLOAT , " minpropscreenwidth " ) ,
DEFINE_KEYFIELD ( m_iszDetailSpriteMaterial , FIELD_STRING , " detailmaterial " ) ,
DEFINE_KEYFIELD ( m_bColdWorld , FIELD_BOOLEAN , " coldworld " ) ,
END_DATADESC ( )
// SendTable stuff.
IMPLEMENT_SERVERCLASS_ST ( CWorld , DT_WORLD )
SendPropFloat ( SENDINFO ( m_flWaveHeight ) , 8 , SPROP_ROUNDUP , 0.0f , 8.0f ) ,
SendPropVector ( SENDINFO ( m_WorldMins ) , - 1 , SPROP_COORD ) ,
SendPropVector ( SENDINFO ( m_WorldMaxs ) , - 1 , SPROP_COORD ) ,
SendPropInt ( SENDINFO ( m_bStartDark ) , 1 , SPROP_UNSIGNED ) ,
SendPropFloat ( SENDINFO ( m_flMaxOccludeeArea ) , 0 , SPROP_NOSCALE ) ,
SendPropFloat ( SENDINFO ( m_flMinOccluderArea ) , 0 , SPROP_NOSCALE ) ,
SendPropFloat ( SENDINFO ( m_flMaxPropScreenSpaceWidth ) , 0 , SPROP_NOSCALE ) ,
SendPropFloat ( SENDINFO ( m_flMinPropScreenSpaceWidth ) , 0 , SPROP_NOSCALE ) ,
SendPropStringT ( SENDINFO ( m_iszDetailSpriteMaterial ) ) ,
SendPropInt ( SENDINFO ( m_bColdWorld ) , 1 , SPROP_UNSIGNED ) ,
END_SEND_TABLE ( )
//
// Just to ignore the "wad" field.
//
bool CWorld : : KeyValue ( const char * szKeyName , const char * szValue )
{
if ( FStrEq ( szKeyName , " skyname " ) )
{
// Sent over net now.
ConVarRef skyname ( " sv_skyname " ) ;
skyname . SetValue ( szValue ) ;
}
else if ( FStrEq ( szKeyName , " newunit " ) )
{
// Single player only. Clear save directory if set
if ( atoi ( szValue ) )
{
extern void Game_SetOneWayTransition ( ) ;
Game_SetOneWayTransition ( ) ;
}
}
else if ( FStrEq ( szKeyName , " world_mins " ) )
{
Vector vec ;
sscanf ( szValue , " %f %f %f " , & vec . x , & vec . y , & vec . z ) ;
m_WorldMins = vec ;
}
else if ( FStrEq ( szKeyName , " world_maxs " ) )
{
Vector vec ;
sscanf ( szValue , " %f %f %f " , & vec . x , & vec . y , & vec . z ) ;
m_WorldMaxs = vec ;
}
2023-10-03 17:23:56 +03:00
else if ( FStrEq ( szKeyName , " timeofday " ) )
{
SetTimeOfDay ( atoi ( szValue ) ) ;
}
2020-04-22 12:56:21 -04:00
else
return BaseClass : : KeyValue ( szKeyName , szValue ) ;
return true ;
}
extern bool g_fGameOver ;
2023-10-03 17:23:56 +03:00
CWorld * g_WorldEntity = NULL ;
2020-04-22 12:56:21 -04:00
CWorld * GetWorldEntity ( )
{
return g_WorldEntity ;
}
CWorld : : CWorld ( )
{
AddEFlags ( EFL_NO_AUTO_EDICT_ATTACH | EFL_KEEP_ON_RECREATE_ENTITIES ) ;
NetworkProp ( ) - > AttachEdict ( INDEXENT ( RequiredEdictIndex ( ) ) ) ;
ActivityList_Init ( ) ;
EventList_Init ( ) ;
SetSolid ( SOLID_BSP ) ;
SetMoveType ( MOVETYPE_NONE ) ;
m_bColdWorld = false ;
2023-10-03 17:23:56 +03:00
// Set this in the constructor for legacy maps (sjb)
m_iTimeOfDay = TIME_MIDNIGHT ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
CWorld : : ~ CWorld ( )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
// If in edit mode tell Hammer I'm ending my session. This re-enables
// the Hammer UI so they can continue editing the map.
# ifdef _WIN32
Editor_EndSession ( false ) ;
# endif
2020-04-22 12:56:21 -04:00
EventList_Free ( ) ;
ActivityList_Free ( ) ;
if ( g_pGameRules )
{
g_pGameRules - > LevelShutdown ( ) ;
delete g_pGameRules ;
g_pGameRules = NULL ;
}
g_WorldEntity = NULL ;
}
//------------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
// Add a decal to the world
2020-04-22 12:56:21 -04:00
//------------------------------------------------------------------------------
void CWorld : : DecalTrace ( trace_t * pTrace , char const * decalName )
{
int index = decalsystem - > GetDecalIndexForName ( decalName ) ;
if ( index < 0 )
return ;
CBroadcastRecipientFilter filter ;
if ( pTrace - > hitbox ! = 0 )
{
te - > Decal ( filter , 0.0f , & pTrace - > endpos , & pTrace - > startpos , 0 , pTrace - > hitbox , index ) ;
}
else
{
te - > WorldDecal ( filter , 0.0 , & pTrace - > endpos , index ) ;
}
}
void CWorld : : RegisterSharedActivities ( void )
{
ActivityList_RegisterSharedActivities ( ) ;
}
void CWorld : : RegisterSharedEvents ( void )
{
EventList_RegisterSharedEvents ( ) ;
}
void CWorld : : Spawn ( void )
{
SetLocalOrigin ( vec3_origin ) ;
SetLocalAngles ( vec3_angle ) ;
// NOTE: SHOULD NEVER BE ANYTHING OTHER THAN 1!!!
SetModelIndex ( 1 ) ;
// world model
SetModelName ( AllocPooledString ( modelinfo - > GetModelName ( GetModel ( ) ) ) ) ;
AddFlag ( FL_WORLDBRUSH ) ;
g_EventQueue . Init ( ) ;
Precache ( ) ;
GlobalEntity_Add ( " is_console " , STRING ( gpGlobals - > mapname ) , ( IsConsole ( ) ) ? GLOBAL_ON : GLOBAL_OFF ) ;
GlobalEntity_Add ( " is_pc " , STRING ( gpGlobals - > mapname ) , ( ! IsConsole ( ) ) ? GLOBAL_ON : GLOBAL_OFF ) ;
}
static const char * g_DefaultLightstyles [ ] =
{
// 0 normal
" m " ,
// 1 FLICKER (first variety)
" mmnmmommommnonmmonqnmmo " ,
// 2 SLOW STRONG PULSE
" abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba " ,
// 3 CANDLE (first variety)
" mmmmmaaaaammmmmaaaaaabcdefgabcdefg " ,
// 4 FAST STROBE
" mamamamamama " ,
// 5 GENTLE PULSE 1
" jklmnopqrstuvwxyzyxwvutsrqponmlkj " ,
// 6 FLICKER (second variety)
" nmonqnmomnmomomno " ,
// 7 CANDLE (second variety)
" mmmaaaabcdefgmmmmaaaammmaamm " ,
// 8 CANDLE (third variety)
" mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa " ,
// 9 SLOW STROBE (fourth variety)
" aaaaaaaazzzzzzzz " ,
// 10 FLUORESCENT FLICKER
" mmamammmmammamamaaamammma " ,
// 11 SLOW PULSE NOT FADE TO BLACK
" abcdefghijklmnopqrrqponmlkjihgfedcba " ,
// 12 UNDERWATER LIGHT MUTATION
// this light only distorts the lightmap - no contribution
// is made to the brightness of affected surfaces
" mmnnmmnnnmmnn " ,
} ;
const char * GetDefaultLightstyleString ( int styleIndex )
{
if ( styleIndex < ARRAYSIZE ( g_DefaultLightstyles ) )
{
return g_DefaultLightstyles [ styleIndex ] ;
}
return " m " ;
}
2023-10-03 17:23:56 +03:00
//-----------------------------------------------------------------------------
string_t g_iszFuncBrushClassname = NULL_STRING ;
2020-04-22 12:56:21 -04:00
void CWorld : : Precache ( void )
{
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " CWorld::Precache - Start " ) ;
2020-04-22 12:56:21 -04:00
g_WorldEntity = this ;
g_fGameOver = false ;
g_pLastSpawn = NULL ;
2023-10-03 17:23:56 +03:00
g_Language . SetValue ( LANGUAGE_ENGLISH ) ; // TODO use VGUI to get current language
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
# ifndef INFESTED_DLL
2020-04-22 12:56:21 -04:00
ConVarRef stepsize ( " sv_stepsize " ) ;
stepsize . SetValue ( 18 ) ;
2023-10-03 17:23:56 +03:00
# endif
2020-04-22 12:56:21 -04:00
ConVarRef roomtype ( " room_type " ) ;
roomtype . SetValue ( 0 ) ;
// Set up game rules
Assert ( ! g_pGameRules ) ;
if ( g_pGameRules )
{
delete g_pGameRules ;
}
InstallGameRules ( ) ;
Assert ( g_pGameRules ) ;
g_pGameRules - > Init ( ) ;
CSoundEnt : : InitSoundEnt ( ) ;
// UNDONE: Make most of these things server systems or precache_registers
// =================================================
// Activities
// =================================================
ActivityList_Free ( ) ;
RegisterSharedActivities ( ) ;
EventList_Free ( ) ;
RegisterSharedEvents ( ) ;
2023-10-03 17:23:56 +03:00
// Only allow precaching between LevelInitPreEntity and PostEntity
CBaseEntity : : SetAllowPrecache ( true ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " IGameSystem::LevelInitPreEntityAllSystems " ) ;
IGameSystem : : LevelInitPreEntityAllSystems ( STRING ( GetModelName ( ) ) ) ;
COM_TimestampedLog ( " g_pGameRules->CreateStandardEntities() " ) ;
// Create the player resource
g_pGameRules - > CreateStandardEntities ( ) ;
COM_TimestampedLog ( " InitBodyQue() " ) ;
InitBodyQue ( ) ;
COM_TimestampedLog ( " SENTENCEG_Init() " ) ;
// init sentence group playback stuff from sentences.txt.
// ok to call this multiple times, calls after first are ignored.
2020-04-22 12:56:21 -04:00
SENTENCEG_Init ( ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " PrecacheStandardParticleSystems() " ) ;
2020-04-22 12:56:21 -04:00
// Precache standard particle systems
PrecacheStandardParticleSystems ( ) ;
2023-10-03 17:23:56 +03:00
// the area based ambient sounds MUST be the first precache_sounds
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " W_Precache() " ) ;
// player precaches
2020-04-22 12:56:21 -04:00
W_Precache ( ) ; // get weapon precaches
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " ClientPrecache() " ) ;
2020-04-22 12:56:21 -04:00
ClientPrecache ( ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " PrecacheTempEnts() " ) ;
2020-04-22 12:56:21 -04:00
// precache all temp ent stuff
CBaseTempEntity : : PrecacheTempEnts ( ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " LightStyles " ) ;
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//
2020-04-22 12:56:21 -04:00
for ( int i = 0 ; i < ARRAYSIZE ( g_DefaultLightstyles ) ; i + + )
{
engine - > LightStyle ( i , GetDefaultLightstyleString ( i ) ) ;
}
// styles 32-62 are assigned by the light program for switchable lights
// 63 testing
engine - > LightStyle ( 63 , " a " ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " InitializeAINetworks " ) ;
2020-04-22 12:56:21 -04:00
// =================================================
// Load and Init AI Networks
// =================================================
CAI_NetworkManager : : InitializeAINetworks ( ) ;
// =================================================
// Load and Init AI Schedules
// =================================================
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " LoadAllSchedules " ) ;
2020-04-22 12:56:21 -04:00
g_AI_SchedulesManager . LoadAllSchedules ( ) ;
// =================================================
// Initialize NPC Relationships
// =================================================
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " InitDefaultAIRelationships " ) ;
2020-04-22 12:56:21 -04:00
g_pGameRules - > InitDefaultAIRelationships ( ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " InitInteractionSystem " ) ;
2020-04-22 12:56:21 -04:00
CBaseCombatCharacter : : InitInteractionSystem ( ) ;
2023-10-03 17:23:56 +03:00
COM_TimestampedLog ( " g_pGameRules->Precache " ) ;
// Call the gamerules precache after the AI precache so that games can precache NPCs that are always loaded
g_pGameRules - > Precache ( ) ;
2020-04-22 12:56:21 -04:00
if ( m_iszChapterTitle ! = NULL_STRING )
{
DevMsg ( 2 , " Chapter title: %s \n " , STRING ( m_iszChapterTitle ) ) ;
CMessage * pMessage = ( CMessage * ) CBaseEntity : : Create ( " env_message " , vec3_origin , vec3_angle , NULL ) ;
if ( pMessage )
{
pMessage - > SetMessage ( m_iszChapterTitle ) ;
m_iszChapterTitle = NULL_STRING ;
// send the message entity a play message command, delayed by 1 second
pMessage - > AddSpawnFlags ( SF_MESSAGE_ONCE ) ;
pMessage - > SetThink ( & CMessage : : SUB_CallUseToggle ) ;
pMessage - > SetNextThink ( gpGlobals - > curtime + 1.0f ) ;
}
}
g_iszFuncBrushClassname = AllocPooledString ( " func_brush " ) ;
2023-10-03 17:23:56 +03:00
if ( m_iszDetailSpriteMaterial . Get ( ) ! = NULL_STRING )
{
PrecacheMaterial ( STRING ( m_iszDetailSpriteMaterial . Get ( ) ) ) ;
}
COM_TimestampedLog ( " CWorld::Precache - Finish " ) ;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CWorld : : UpdateOnRemove ( void )
{
BaseClass : : UpdateOnRemove ( ) ;
2020-04-22 12:56:21 -04:00
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float GetRealTime ( )
{
2023-10-03 17:23:56 +03:00
return Plat_FloatTime ( ) ;
2020-04-22 12:56:21 -04:00
}
bool CWorld : : GetDisplayTitle ( ) const
{
return m_bDisplayTitle ;
}
bool CWorld : : GetStartDark ( ) const
{
return m_bStartDark ;
}
void CWorld : : SetDisplayTitle ( bool display )
{
m_bDisplayTitle = display ;
}
void CWorld : : SetStartDark ( bool startdark )
{
m_bStartDark = startdark ;
}
bool CWorld : : IsColdWorld ( void )
{
return m_bColdWorld ;
}
2023-10-03 17:23:56 +03:00
int CWorld : : GetTimeOfDay ( ) const
{
return m_iTimeOfDay ;
}
void CWorld : : SetTimeOfDay ( int iTimeOfDay )
{
m_iTimeOfDay = iTimeOfDay ;
}