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.
733 lines
18 KiB
733 lines
18 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Precaches and defs for entities and other data that must always be available. |
|
// |
|
// $NoKeywords: $ |
|
//===========================================================================// |
|
|
|
#include "cbase.h" |
|
#include "soundent.h" |
|
#include "client.h" |
|
#include "decals.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" |
|
|
|
// 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 |
|
|
|
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 ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
public: |
|
int m_nTexture; |
|
bool m_bLowPriority; |
|
|
|
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 |
|
|
|
// 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); |
|
} |
|
} |
|
|
|
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; |
|
|
|
UTIL_TraceLine( GetAbsOrigin() - Vector(5,5,5), GetAbsOrigin() + Vector(5,5,5), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace ); |
|
|
|
entityIndex = trace.m_pEnt ? trace.m_pEnt->entindex() : 0; |
|
|
|
CBroadcastRecipientFilter filter; |
|
|
|
te->BSPDecal( filter, 0.0, |
|
&GetAbsOrigin(), 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 ) |
|
{ |
|
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; |
|
} |
|
|
|
|
|
return CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask ); |
|
} |
|
}; |
|
|
|
trace_t trace; |
|
CTraceFilterValidForDecal traceFilter( this, COLLISION_GROUP_NONE ); |
|
int entityIndex, modelIndex = 0; |
|
|
|
Vector position = GetAbsOrigin(); |
|
UTIL_TraceLine( position - Vector(5,5,5), position + Vector(5,5,5), MASK_SOLID, &traceFilter, &trace ); |
|
|
|
bool canDraw = true; |
|
|
|
entityIndex = trace.m_pEnt ? (short)trace.m_pEnt->entindex() : 0; |
|
if ( entityIndex ) |
|
{ |
|
CBaseEntity *ent = trace.m_pEnt; |
|
if ( ent ) |
|
{ |
|
modelIndex = ent->GetModelIndex(); |
|
VectorITransform( GetAbsOrigin(), ent->EntityToWorldTransform(), position ); |
|
|
|
canDraw = ( modelIndex != 0 ); |
|
if ( !canDraw ) |
|
{ |
|
Warning( "Suppressed StaticDecal which would have hit entity %i (class:%s, name:%s) with modelindex = 0\n", |
|
ent->entindex(), |
|
ent->GetClassname(), |
|
STRING( ent->GetEntityName() ) ); |
|
} |
|
} |
|
} |
|
|
|
if ( canDraw ) |
|
{ |
|
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 ), |
|
#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; |
|
} |
|
else |
|
return BaseClass::KeyValue( szKeyName, szValue ); |
|
|
|
return true; |
|
} |
|
|
|
|
|
extern bool g_fGameOver; |
|
static 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; |
|
} |
|
|
|
CWorld::~CWorld( ) |
|
{ |
|
EventList_Free(); |
|
ActivityList_Free(); |
|
if ( g_pGameRules ) |
|
{ |
|
g_pGameRules->LevelShutdown(); |
|
delete g_pGameRules; |
|
g_pGameRules = NULL; |
|
} |
|
g_WorldEntity = NULL; |
|
} |
|
|
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : Add a decal to the world |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
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"; |
|
} |
|
|
|
void CWorld::Precache( void ) |
|
{ |
|
g_WorldEntity = this; |
|
g_fGameOver = false; |
|
g_pLastSpawn = NULL; |
|
|
|
ConVarRef stepsize( "sv_stepsize" ); |
|
stepsize.SetValue( 18 ); |
|
|
|
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(); |
|
|
|
// Only allow precaching between LevelInitPreEntity and PostEntity |
|
CBaseEntity::SetAllowPrecache( true ); |
|
IGameSystem::LevelInitPreEntityAllSystems( STRING( GetModelName() ) ); |
|
|
|
// Create the player resource |
|
g_pGameRules->CreateStandardEntities(); |
|
|
|
// UNDONE: Make most of these things server systems or precache_registers |
|
// ================================================= |
|
// Activities |
|
// ================================================= |
|
ActivityList_Free(); |
|
RegisterSharedActivities(); |
|
|
|
EventList_Free(); |
|
RegisterSharedEvents(); |
|
|
|
InitBodyQue(); |
|
// init sentence group playback stuff from sentences.txt. |
|
// ok to call this multiple times, calls after first are ignored. |
|
|
|
SENTENCEG_Init(); |
|
|
|
// Precache standard particle systems |
|
PrecacheStandardParticleSystems( ); |
|
|
|
// the area based ambient sounds MUST be the first precache_sounds |
|
|
|
// player precaches |
|
W_Precache (); // get weapon precaches |
|
ClientPrecache(); |
|
g_pGameRules->Precache(); |
|
// precache all temp ent stuff |
|
CBaseTempEntity::PrecacheTempEnts(); |
|
|
|
g_Language.SetValue( LANGUAGE_ENGLISH ); // TODO use VGUI to get current language |
|
|
|
if ( g_Language.GetInt() == LANGUAGE_GERMAN ) |
|
{ |
|
PrecacheModel( "models/germangibs.mdl" ); |
|
} |
|
else |
|
{ |
|
PrecacheModel( "models/gibs/hgibs.mdl" ); |
|
} |
|
|
|
PrecacheScriptSound( "BaseEntity.EnterWater" ); |
|
PrecacheScriptSound( "BaseEntity.ExitWater" ); |
|
|
|
// |
|
// 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"); |
|
|
|
// ================================================= |
|
// Load and Init AI Networks |
|
// ================================================= |
|
CAI_NetworkManager::InitializeAINetworks(); |
|
// ================================================= |
|
// Load and Init AI Schedules |
|
// ================================================= |
|
g_AI_SchedulesManager.LoadAllSchedules(); |
|
// ================================================= |
|
// Initialize NPC Relationships |
|
// ================================================= |
|
g_pGameRules->InitDefaultAIRelationships(); |
|
CBaseCombatCharacter::InitInteractionSystem(); |
|
|
|
// Call all registered precachers. |
|
CPrecacheRegister::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"); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float GetRealTime() |
|
{ |
|
return engine->Time(); |
|
} |
|
|
|
|
|
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; |
|
}
|
|
|