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.
734 lines
18 KiB
734 lines
18 KiB
5 years ago
|
//========= 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;
|
||
|
}
|