Counter Strike : Global Offensive Source Code
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.
 
 
 
 
 
 

980 lines
25 KiB

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Precaches and defs for entities and other data that must always be available.
//
//===========================================================================
#include "cbase.h"
#include "soundent.h"
#include "client.h"
#include "decals.h"
#include "editor_sendcommand.h"
#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"
#include "cvisibilitymonitor.h"
#include "model_types.h"
#include "vscript/ivscript.h"
#include "vscript_server.h"
#if defined( TERROR )
#include "music.h"
#endif
#if defined( CSTRIKE15 )
#include "gametypes.h"
#endif
#ifdef PORTAL2
#include "paint_stream_manager.h"
#endif
// 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
#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;
bool m_bDisabled;
public:
DECLARE_CLASS( CInfoGameEventProxy, CPointEntity );
void Spawn();
int UpdateTransmitState();
void InputGenerateGameEvent( inputdata_t &inputdata );
void InputEnable( inputdata_t &inputdata ) { m_bDisabled = false; }
void InputDisable( inputdata_t &inputdata ) { m_bDisabled = true; }
static bool GameEventProxyCallback( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer );
static bool GameEventProxyEvaluator( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer );
DECLARE_DATADESC();
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CInfoGameEventProxy::Spawn()
{
BaseClass::Spawn();
if( GetSpawnFlags() & SF_GAME_EVENT_PROXY_AUTO_VISIBILITY )
{
VisibilityMonitor_AddEntity( this, m_flRange, &CInfoGameEventProxy::GameEventProxyCallback, &CInfoGameEventProxy::GameEventProxyEvaluator );
}
}
//-----------------------------------------------------------------------------
// 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 = assert_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;
}
bool CInfoGameEventProxy::GameEventProxyEvaluator( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer )
{
CInfoGameEventProxy *pProxyPtr = assert_cast <CInfoGameEventProxy *>(pProxy);
if( !pProxyPtr )
return false;
return !pProxyPtr->m_bDisabled;
}
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_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
DEFINE_INPUTFUNC( FIELD_VOID, "GenerateGameEvent", InputGenerateGameEvent ),
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
END_DATADESC()
#endif
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 );
CBaseEntity *GetDecalEntityAndPosition( Vector *pPosition, bool bStatic );
DECLARE_DATADESC();
public:
int m_nTexture;
bool m_bLowPriority;
string_t m_entityName;
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
DEFINE_KEYFIELD( m_entityName, FIELD_STRING, "ApplyEntity" ), // Force apply to this entity instead of tracing
// 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);
}
}
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_dynamic_glow",
"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;
}
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;
Vector position;
CBaseEntity *pEntity = GetDecalEntityAndPosition(&position, false);
entityIndex = pEntity ? pEntity->entindex() : 0;
CBroadcastRecipientFilter filter;
te->BSPDecal( filter, 0.0, &position, entityIndex, m_nTexture );
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 )
{
Vector position;
CBaseEntity *pEntity = GetDecalEntityAndPosition(&position, true);
int entityIndex = 0;
int modelIndex = 0;
if ( pEntity )
{
entityIndex = pEntity->entindex();
modelIndex = pEntity->GetModelIndex();
Vector worldspace = position;
VectorITransform( worldspace, pEntity->EntityToWorldTransform(), position );
}
else
{
position = GetAbsOrigin();
}
engine->StaticDecal( position, m_nTexture, entityIndex, modelIndex, m_bLowPriority );
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 ),
// 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
#ifdef _GAMECONSOLE
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" ),
#ifdef PORTAL2
DEFINE_KEYFIELD( m_nMaxBlobCount, FIELD_INTEGER, "maxblobcount" ),
#endif
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 ),
#ifdef PORTAL2
SendPropInt (SENDINFO(m_nMaxBlobCount), 0, SPROP_UNSIGNED),
#endif
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;
}
else if ( FStrEq(szKeyName, "timeofday" ) )
{
SetTimeOfDay( atoi( szValue ) );
}
#ifdef PORTAL2
else if ( FStrEq(szKeyName, "maxblobcount" ) )
{
m_nMaxBlobCount = atoi( szValue );
PaintStreamManager.AllocatePaintBlobPool( m_nMaxBlobCount );
}
#endif
else
return BaseClass::KeyValue( szKeyName, szValue );
return true;
}
#ifdef PORTAL2
int CWorld::Restore( IRestore &restore )
{
if ( !BaseClass::Restore( restore ) )
return 0;
// world is the first thing that gets loaded, so we want to do our pool allocation here
PaintStreamManager.AllocatePaintBlobPool( m_nMaxBlobCount );
return 1;
}
#endif
extern bool g_fGameOver;
CWorld *g_WorldEntity = NULL;
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;
// Set this in the constructor for legacy maps (sjb)
m_iTimeOfDay.Set( TIME_MIDNIGHT );
}
CWorld::~CWorld()
{
// 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
EventList_Free();
ActivityList_Free();
if ( g_pGameRules )
{
g_pGameRules->LevelShutdown();
delete g_pGameRules;
g_pGameRules = NULL;
}
g_WorldEntity = NULL;
}
//------------------------------------------------------------------------------
// Add a decal to the world
//------------------------------------------------------------------------------
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 );
#if defined( CSTRIKE15 )
// reinitialize all of the game type kv file data because we may have new things availible to us in the filesystem mounted from the bsp that we didn't have when the gamemodes.txt was first parsed
g_pGameTypes->Initialize( true );
#endif
g_EventQueue.Init();
Precache( );
GlobalEntity_Add( "is_console", STRING(gpGlobals->mapname), ( IsGameConsole() ) ? GLOBAL_ON : GLOBAL_OFF );
GlobalEntity_Add( "is_pc", STRING(gpGlobals->mapname), ( !IsGameConsole() ) ? 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";
}
//-----------------------------------------------------------------------------
string_t g_iszFuncBrushClassname = NULL_STRING;
void CWorld::Precache( void )
{
COM_TimestampedLog( "CWorld::Precache - Start" );
g_WorldEntity = this;
g_fGameOver = false;
g_pLastSpawn = NULL;
g_Language.SetValue( LANGUAGE_ENGLISH ); // TODO use VGUI to get current language
#ifndef INFESTED_DLL
ConVarRef stepsize( "sv_stepsize" );
stepsize.SetValue( 18 );
#endif
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();
#ifndef DOTA_DLL
CSoundEnt::InitSoundEnt();
#endif
// UNDONE: Make most of these things server systems or precache_registers
// =================================================
// Activities
// =================================================
ActivityList_Free();
RegisterSharedActivities();
EventList_Free();
RegisterSharedEvents();
// Only allow precaching between LevelInitPreEntity and PostEntity
CBaseEntity::SetAllowPrecache( true );
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.
SENTENCEG_Init();
COM_TimestampedLog( "PrecacheStandardParticleSystems()" );
// Precache standard particle systems
PrecacheStandardParticleSystems( );
// the area based ambient sounds MUST be the first precache_sounds
COM_TimestampedLog( "W_Precache()" );
// player precaches
W_Precache (); // get weapon precaches
COM_TimestampedLog( "ClientPrecache()" );
ClientPrecache();
COM_TimestampedLog( "PrecacheTempEnts()" );
// precache all temp ent stuff
CBaseTempEntity::PrecacheTempEnts();
COM_TimestampedLog( "LightStyles" );
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//
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");
COM_TimestampedLog( "InitializeAINetworks" );
// =================================================
// Load and Init AI Networks
// =================================================
CAI_NetworkManager::InitializeAINetworks();
// =================================================
// Load and Init AI Schedules
// =================================================
COM_TimestampedLog( "LoadAllSchedules" );
g_AI_SchedulesManager.LoadAllSchedules();
// =================================================
// Initialize NPC Relationships
// =================================================
COM_TimestampedLog( "InitDefaultAIRelationships" );
g_pGameRules->InitDefaultAIRelationships();
COM_TimestampedLog( "InitInteractionSystem" );
CBaseCombatCharacter::InitInteractionSystem();
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();
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");
if ( m_iszDetailSpriteMaterial.Get() != NULL_STRING )
{
PrecacheMaterial( STRING( m_iszDetailSpriteMaterial.Get() ) );
}
COM_TimestampedLog( "CWorld::Precache - Finish" );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CWorld::UpdateOnRemove( void )
{
BaseClass::UpdateOnRemove();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float GetRealTime()
{
return Plat_FloatTime();
}
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;
}
int CWorld::GetTimeOfDay() const
{
return m_iTimeOfDay;
}
void CWorld::SetTimeOfDay( int iTimeOfDay )
{
m_iTimeOfDay = iTimeOfDay;
}