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

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Precaches and defs for entities and other data that must always be available.
  4. //
  5. //===========================================================================
  6. #include "cbase.h"
  7. #include "soundent.h"
  8. #include "client.h"
  9. #include "decals.h"
  10. #include "editor_sendcommand.h"
  11. #include "EnvMessage.h"
  12. #include "player.h"
  13. #include "gamerules.h"
  14. #include "teamplay_gamerules.h"
  15. #include "physics.h"
  16. #include "isaverestore.h"
  17. #include "activitylist.h"
  18. #include "eventlist.h"
  19. #include "eventqueue.h"
  20. #include "ai_network.h"
  21. #include "ai_schedule.h"
  22. #include "ai_networkmanager.h"
  23. #include "ai_utils.h"
  24. #include "basetempentity.h"
  25. #include "world.h"
  26. #include "mempool.h"
  27. #include "igamesystem.h"
  28. #include "engine/IEngineSound.h"
  29. #include "globals.h"
  30. #include "engine/IStaticPropMgr.h"
  31. #include "particle_parse.h"
  32. #include "globalstate.h"
  33. #include "cvisibilitymonitor.h"
  34. #include "model_types.h"
  35. #include "vscript/ivscript.h"
  36. #include "vscript_server.h"
  37. #if defined( TERROR )
  38. #include "music.h"
  39. #endif
  40. #if defined( CSTRIKE15 )
  41. #include "gametypes.h"
  42. #endif
  43. #ifdef PORTAL2
  44. #include "paint_stream_manager.h"
  45. #endif
  46. // memdbgon must be the last include file in a .cpp file!!!
  47. #include "tier0/memdbgon.h"
  48. extern CBaseEntity *g_pLastSpawn;
  49. void InitBodyQue(void);
  50. extern void W_Precache(void);
  51. extern void ActivityList_Free( void );
  52. extern CUtlMemoryPool g_EntityListPool;
  53. #define SF_DECAL_NOTINDEATHMATCH 2048
  54. #if !defined( CLIENT_DLL )
  55. #define SF_GAME_EVENT_PROXY_AUTO_VISIBILITY 1
  56. //=========================================================
  57. // Allows level designers to generate certain game events
  58. // from entity i/o.
  59. //=========================================================
  60. class CInfoGameEventProxy : public CPointEntity
  61. {
  62. private:
  63. string_t m_iszEventName;
  64. float m_flRange;
  65. bool m_bDisabled;
  66. public:
  67. DECLARE_CLASS( CInfoGameEventProxy, CPointEntity );
  68. void Spawn();
  69. int UpdateTransmitState();
  70. void InputGenerateGameEvent( inputdata_t &inputdata );
  71. void InputEnable( inputdata_t &inputdata ) { m_bDisabled = false; }
  72. void InputDisable( inputdata_t &inputdata ) { m_bDisabled = true; }
  73. static bool GameEventProxyCallback( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer );
  74. static bool GameEventProxyEvaluator( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer );
  75. DECLARE_DATADESC();
  76. };
  77. //-----------------------------------------------------------------------------
  78. //-----------------------------------------------------------------------------
  79. void CInfoGameEventProxy::Spawn()
  80. {
  81. BaseClass::Spawn();
  82. if( GetSpawnFlags() & SF_GAME_EVENT_PROXY_AUTO_VISIBILITY )
  83. {
  84. VisibilityMonitor_AddEntity( this, m_flRange, &CInfoGameEventProxy::GameEventProxyCallback, &CInfoGameEventProxy::GameEventProxyEvaluator );
  85. }
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose: Always transmitted to clients
  89. //-----------------------------------------------------------------------------
  90. int CInfoGameEventProxy::UpdateTransmitState()
  91. {
  92. return SetTransmitState( FL_EDICT_ALWAYS );
  93. }
  94. //---------------------------------------------------------
  95. //---------------------------------------------------------
  96. void CInfoGameEventProxy::InputGenerateGameEvent( inputdata_t &inputdata )
  97. {
  98. CBasePlayer *pActivator = ToBasePlayer( inputdata.pActivator );
  99. IGameEvent *event = gameeventmanager->CreateEvent( m_iszEventName.ToCStr() );
  100. if ( event )
  101. {
  102. if ( pActivator )
  103. {
  104. event->SetInt( "userid", pActivator->GetUserID() );
  105. }
  106. event->SetInt( "subject", entindex() );
  107. gameeventmanager->FireEvent( event );
  108. }
  109. }
  110. //---------------------------------------------------------
  111. // Callback for the visibility monitor.
  112. //---------------------------------------------------------
  113. bool CInfoGameEventProxy::GameEventProxyCallback( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer )
  114. {
  115. CInfoGameEventProxy *pProxyPtr = assert_cast <CInfoGameEventProxy *>(pProxy);
  116. if( !pProxyPtr )
  117. return true;
  118. IGameEvent * event = gameeventmanager->CreateEvent( pProxyPtr->m_iszEventName.ToCStr() );
  119. if ( event )
  120. {
  121. event->SetInt( "userid", pViewingPlayer->GetUserID() );
  122. event->SetInt( "subject", pProxyPtr->entindex() );
  123. gameeventmanager->FireEvent( event );
  124. }
  125. return false;
  126. }
  127. bool CInfoGameEventProxy::GameEventProxyEvaluator( CBaseEntity *pProxy, CBasePlayer *pViewingPlayer )
  128. {
  129. CInfoGameEventProxy *pProxyPtr = assert_cast <CInfoGameEventProxy *>(pProxy);
  130. if( !pProxyPtr )
  131. return false;
  132. return !pProxyPtr->m_bDisabled;
  133. }
  134. LINK_ENTITY_TO_CLASS( info_game_event_proxy, CInfoGameEventProxy );
  135. BEGIN_DATADESC( CInfoGameEventProxy )
  136. DEFINE_KEYFIELD( m_iszEventName, FIELD_STRING, "event_name" ),
  137. DEFINE_KEYFIELD( m_flRange, FIELD_FLOAT, "range" ),
  138. DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
  139. DEFINE_INPUTFUNC( FIELD_VOID, "GenerateGameEvent", InputGenerateGameEvent ),
  140. DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
  141. DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
  142. END_DATADESC()
  143. #endif
  144. class CDecal : public CPointEntity
  145. {
  146. public:
  147. DECLARE_CLASS( CDecal, CPointEntity );
  148. void Spawn( void );
  149. bool KeyValue( const char *szKeyName, const char *szValue );
  150. // Need to apply static decals here to get them into the signon buffer for the server appropriately
  151. virtual void Activate();
  152. void TriggerDecal( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  153. // Input handlers.
  154. void InputActivate( inputdata_t &inputdata );
  155. CBaseEntity *GetDecalEntityAndPosition( Vector *pPosition, bool bStatic );
  156. DECLARE_DATADESC();
  157. public:
  158. int m_nTexture;
  159. bool m_bLowPriority;
  160. string_t m_entityName;
  161. private:
  162. void StaticDecal( void );
  163. };
  164. BEGIN_DATADESC( CDecal )
  165. DEFINE_FIELD( m_nTexture, FIELD_INTEGER ),
  166. 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
  167. DEFINE_KEYFIELD( m_entityName, FIELD_STRING, "ApplyEntity" ), // Force apply to this entity instead of tracing
  168. // Function pointers
  169. DEFINE_FUNCTION( StaticDecal ),
  170. DEFINE_FUNCTION( TriggerDecal ),
  171. DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ),
  172. END_DATADESC()
  173. LINK_ENTITY_TO_CLASS( infodecal, CDecal );
  174. // UNDONE: These won't get sent to joining players in multi-player
  175. void CDecal::Spawn( void )
  176. {
  177. if ( m_nTexture < 0 ||
  178. (gpGlobals->deathmatch && HasSpawnFlags( SF_DECAL_NOTINDEATHMATCH )) )
  179. {
  180. UTIL_Remove( this );
  181. return;
  182. }
  183. }
  184. void CDecal::Activate()
  185. {
  186. BaseClass::Activate();
  187. if ( !GetEntityName() )
  188. {
  189. StaticDecal();
  190. }
  191. else
  192. {
  193. // if there IS a targetname, the decal sprays itself on when it is triggered.
  194. SetThink ( &CDecal::SUB_DoNothing );
  195. SetUse(&CDecal::TriggerDecal);
  196. }
  197. }
  198. class CTraceFilterValidForDecal : public CTraceFilterSimple
  199. {
  200. public:
  201. CTraceFilterValidForDecal(const IHandleEntity *passentity, int collisionGroup )
  202. : CTraceFilterSimple( passentity, collisionGroup )
  203. {
  204. }
  205. virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
  206. {
  207. static const char *ppszIgnoredClasses[] =
  208. {
  209. "weapon_*",
  210. "item_*",
  211. "prop_ragdoll",
  212. "prop_dynamic",
  213. "prop_dynamic_glow",
  214. "prop_static",
  215. "prop_physics",
  216. "npc_bullseye", // Tracker 15335
  217. };
  218. CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
  219. // Tracker 15335: Never impact decals against entities which are not rendering, either.
  220. if ( pEntity->IsEffectActive( EF_NODRAW ) )
  221. return false;
  222. for ( int i = 0; i < ARRAYSIZE(ppszIgnoredClasses); i++ )
  223. {
  224. if ( pEntity->ClassMatches( ppszIgnoredClasses[i] ) )
  225. return false;
  226. }
  227. if ( modelinfo->GetModelType( pEntity->GetModel() ) != mod_brush )
  228. return false;
  229. return CTraceFilterSimple::ShouldHitEntity( pServerEntity, contentsMask );
  230. }
  231. };
  232. CBaseEntity *CDecal::GetDecalEntityAndPosition( Vector *pPosition, bool bStatic )
  233. {
  234. CBaseEntity *pEntity = NULL;
  235. if ( !m_entityName )
  236. {
  237. trace_t trace;
  238. Vector start = GetAbsOrigin();
  239. Vector direction(1,1,1);
  240. if ( GetAbsAngles() == vec3_angle )
  241. {
  242. start -= direction * 5;
  243. }
  244. else
  245. {
  246. GetVectors( &direction, NULL, NULL );
  247. }
  248. Vector end = start + direction * 10;
  249. if ( bStatic )
  250. {
  251. CTraceFilterValidForDecal traceFilter( this, COLLISION_GROUP_NONE );
  252. UTIL_TraceLine( start, end, MASK_SOLID, &traceFilter, &trace );
  253. }
  254. else
  255. {
  256. UTIL_TraceLine( start, end, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace );
  257. }
  258. if ( trace.DidHitNonWorldEntity() )
  259. {
  260. *pPosition = trace.endpos;
  261. return trace.m_pEnt;
  262. }
  263. }
  264. else
  265. {
  266. pEntity = gEntList.FindEntityByName( NULL, m_entityName );
  267. }
  268. *pPosition = GetAbsOrigin();
  269. return pEntity;
  270. }
  271. void CDecal::TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
  272. {
  273. // this is set up as a USE function for info_decals that have targetnames, so that the
  274. // decal doesn't get applied until it is fired. (usually by a scripted sequence)
  275. trace_t trace;
  276. int entityIndex;
  277. Vector position;
  278. CBaseEntity *pEntity = GetDecalEntityAndPosition(&position, false);
  279. entityIndex = pEntity ? pEntity->entindex() : 0;
  280. CBroadcastRecipientFilter filter;
  281. te->BSPDecal( filter, 0.0, &position, entityIndex, m_nTexture );
  282. SetThink( &CDecal::SUB_Remove );
  283. SetNextThink( gpGlobals->curtime + 0.1f );
  284. }
  285. void CDecal::InputActivate( inputdata_t &inputdata )
  286. {
  287. TriggerDecal( inputdata.pActivator, inputdata.pCaller, USE_ON, 0 );
  288. }
  289. void CDecal::StaticDecal( void )
  290. {
  291. Vector position;
  292. CBaseEntity *pEntity = GetDecalEntityAndPosition(&position, true);
  293. int entityIndex = 0;
  294. int modelIndex = 0;
  295. if ( pEntity )
  296. {
  297. entityIndex = pEntity->entindex();
  298. modelIndex = pEntity->GetModelIndex();
  299. Vector worldspace = position;
  300. VectorITransform( worldspace, pEntity->EntityToWorldTransform(), position );
  301. }
  302. else
  303. {
  304. position = GetAbsOrigin();
  305. }
  306. engine->StaticDecal( position, m_nTexture, entityIndex, modelIndex, m_bLowPriority );
  307. SUB_Remove();
  308. }
  309. bool CDecal::KeyValue( const char *szKeyName, const char *szValue )
  310. {
  311. if (FStrEq(szKeyName, "texture"))
  312. {
  313. // FIXME: should decals all be preloaded?
  314. m_nTexture = UTIL_PrecacheDecal( szValue, true );
  315. // Found
  316. if (m_nTexture >= 0 )
  317. return true;
  318. Warning( "Can't find decal %s\n", szValue );
  319. }
  320. else
  321. {
  322. return BaseClass::KeyValue( szKeyName, szValue );
  323. }
  324. return true;
  325. }
  326. //-----------------------------------------------------------------------------
  327. // Purpose: Projects a decal against a prop
  328. //-----------------------------------------------------------------------------
  329. class CProjectedDecal : public CPointEntity
  330. {
  331. public:
  332. DECLARE_CLASS( CProjectedDecal, CPointEntity );
  333. void Spawn( void );
  334. bool KeyValue( const char *szKeyName, const char *szValue );
  335. // Need to apply static decals here to get them into the signon buffer for the server appropriately
  336. virtual void Activate();
  337. void TriggerDecal( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  338. // Input handlers.
  339. void InputActivate( inputdata_t &inputdata );
  340. DECLARE_DATADESC();
  341. public:
  342. int m_nTexture;
  343. float m_flDistance;
  344. private:
  345. void ProjectDecal( CRecipientFilter& filter );
  346. void StaticDecal( void );
  347. };
  348. BEGIN_DATADESC( CProjectedDecal )
  349. DEFINE_FIELD( m_nTexture, FIELD_INTEGER ),
  350. DEFINE_KEYFIELD( m_flDistance, FIELD_FLOAT, "Distance" ),
  351. // Function pointers
  352. DEFINE_FUNCTION( StaticDecal ),
  353. DEFINE_FUNCTION( TriggerDecal ),
  354. DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ),
  355. END_DATADESC()
  356. LINK_ENTITY_TO_CLASS( info_projecteddecal, CProjectedDecal );
  357. // UNDONE: These won't get sent to joining players in multi-player
  358. void CProjectedDecal::Spawn( void )
  359. {
  360. if ( m_nTexture < 0 ||
  361. (gpGlobals->deathmatch && HasSpawnFlags( SF_DECAL_NOTINDEATHMATCH )) )
  362. {
  363. UTIL_Remove( this );
  364. return;
  365. }
  366. }
  367. void CProjectedDecal::Activate()
  368. {
  369. BaseClass::Activate();
  370. if ( !GetEntityName() )
  371. {
  372. StaticDecal();
  373. }
  374. else
  375. {
  376. // if there IS a targetname, the decal sprays itself on when it is triggered.
  377. SetThink ( &CProjectedDecal::SUB_DoNothing );
  378. SetUse(&CProjectedDecal::TriggerDecal);
  379. }
  380. }
  381. void CProjectedDecal::InputActivate( inputdata_t &inputdata )
  382. {
  383. TriggerDecal( inputdata.pActivator, inputdata.pCaller, USE_ON, 0 );
  384. }
  385. void CProjectedDecal::ProjectDecal( CRecipientFilter& filter )
  386. {
  387. te->ProjectDecal( filter, 0.0,
  388. &GetAbsOrigin(), &GetAbsAngles(), m_flDistance, m_nTexture );
  389. }
  390. void CProjectedDecal::TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
  391. {
  392. CBroadcastRecipientFilter filter;
  393. ProjectDecal( filter );
  394. SetThink( &CProjectedDecal::SUB_Remove );
  395. SetNextThink( gpGlobals->curtime + 0.1f );
  396. }
  397. void CProjectedDecal::StaticDecal( void )
  398. {
  399. CBroadcastRecipientFilter initFilter;
  400. initFilter.MakeInitMessage();
  401. ProjectDecal( initFilter );
  402. SUB_Remove();
  403. }
  404. bool CProjectedDecal::KeyValue( const char *szKeyName, const char *szValue )
  405. {
  406. if (FStrEq(szKeyName, "texture"))
  407. {
  408. // FIXME: should decals all be preloaded?
  409. m_nTexture = UTIL_PrecacheDecal( szValue, true );
  410. // Found
  411. if (m_nTexture >= 0 )
  412. return true;
  413. Warning( "Can't find decal %s\n", szValue );
  414. }
  415. else
  416. {
  417. return BaseClass::KeyValue( szKeyName, szValue );
  418. }
  419. return true;
  420. }
  421. //=======================
  422. // CWorld
  423. //
  424. // This spawns first when each level begins.
  425. //=======================
  426. LINK_ENTITY_TO_CLASS( worldspawn, CWorld );
  427. BEGIN_DATADESC( CWorld )
  428. DEFINE_FIELD( m_flWaveHeight, FIELD_FLOAT ),
  429. // keyvalues are parsed from map, but not saved/loaded
  430. DEFINE_KEYFIELD( m_iszChapterTitle, FIELD_STRING, "chaptertitle" ),
  431. DEFINE_KEYFIELD( m_bStartDark, FIELD_BOOLEAN, "startdark" ),
  432. DEFINE_KEYFIELD( m_bDisplayTitle, FIELD_BOOLEAN, "gametitle" ),
  433. DEFINE_FIELD( m_WorldMins, FIELD_VECTOR ),
  434. DEFINE_FIELD( m_WorldMaxs, FIELD_VECTOR ),
  435. // DEFINE_FIELD( m_flMaxOccludeeArea, FIELD_CLASSCHECK_IGNORE ) // do this or else we get a warning about multiply-defined fields
  436. // DEFINE_FIELD( m_flMinOccluderArea, FIELD_CLASSCHECK_IGNORE ) // do this or else we get a warning about multiply-defined fields
  437. #ifdef _GAMECONSOLE
  438. DEFINE_KEYFIELD( m_flMaxOccludeeArea, FIELD_FLOAT, "maxoccludeearea_x360" ),
  439. DEFINE_KEYFIELD( m_flMinOccluderArea, FIELD_FLOAT, "minoccluderarea_x360" ),
  440. #else
  441. DEFINE_KEYFIELD( m_flMaxOccludeeArea, FIELD_FLOAT, "maxoccludeearea" ),
  442. DEFINE_KEYFIELD( m_flMinOccluderArea, FIELD_FLOAT, "minoccluderarea" ),
  443. #endif
  444. DEFINE_KEYFIELD( m_flMaxPropScreenSpaceWidth, FIELD_FLOAT, "maxpropscreenwidth" ),
  445. DEFINE_KEYFIELD( m_flMinPropScreenSpaceWidth, FIELD_FLOAT, "minpropscreenwidth" ),
  446. DEFINE_KEYFIELD( m_iszDetailSpriteMaterial, FIELD_STRING, "detailmaterial" ),
  447. DEFINE_KEYFIELD( m_bColdWorld, FIELD_BOOLEAN, "coldworld" ),
  448. #ifdef PORTAL2
  449. DEFINE_KEYFIELD( m_nMaxBlobCount, FIELD_INTEGER, "maxblobcount" ),
  450. #endif
  451. END_DATADESC()
  452. // SendTable stuff.
  453. IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD)
  454. SendPropFloat (SENDINFO(m_flWaveHeight), 8, SPROP_ROUNDUP, 0.0f, 8.0f),
  455. SendPropVector (SENDINFO(m_WorldMins), -1, SPROP_COORD),
  456. SendPropVector (SENDINFO(m_WorldMaxs), -1, SPROP_COORD),
  457. SendPropInt (SENDINFO(m_bStartDark), 1, SPROP_UNSIGNED ),
  458. SendPropFloat (SENDINFO(m_flMaxOccludeeArea), 0, SPROP_NOSCALE ),
  459. SendPropFloat (SENDINFO(m_flMinOccluderArea), 0, SPROP_NOSCALE ),
  460. SendPropFloat (SENDINFO(m_flMaxPropScreenSpaceWidth), 0, SPROP_NOSCALE ),
  461. SendPropFloat (SENDINFO(m_flMinPropScreenSpaceWidth), 0, SPROP_NOSCALE ),
  462. SendPropStringT (SENDINFO(m_iszDetailSpriteMaterial) ),
  463. SendPropInt (SENDINFO(m_bColdWorld), 1, SPROP_UNSIGNED ),
  464. #ifdef PORTAL2
  465. SendPropInt (SENDINFO(m_nMaxBlobCount), 0, SPROP_UNSIGNED),
  466. #endif
  467. END_SEND_TABLE()
  468. //
  469. // Just to ignore the "wad" field.
  470. //
  471. bool CWorld::KeyValue( const char *szKeyName, const char *szValue )
  472. {
  473. if ( FStrEq(szKeyName, "skyname") )
  474. {
  475. // Sent over net now.
  476. ConVarRef skyname( "sv_skyname" );
  477. skyname.SetValue( szValue );
  478. }
  479. else if ( FStrEq(szKeyName, "newunit") )
  480. {
  481. // Single player only. Clear save directory if set
  482. if ( atoi(szValue) )
  483. {
  484. extern void Game_SetOneWayTransition();
  485. Game_SetOneWayTransition();
  486. }
  487. }
  488. else if ( FStrEq(szKeyName, "world_mins") )
  489. {
  490. Vector vec;
  491. sscanf( szValue, "%f %f %f", &vec.x, &vec.y, &vec.z );
  492. m_WorldMins = vec;
  493. }
  494. else if ( FStrEq(szKeyName, "world_maxs") )
  495. {
  496. Vector vec;
  497. sscanf( szValue, "%f %f %f", &vec.x, &vec.y, &vec.z );
  498. m_WorldMaxs = vec;
  499. }
  500. else if ( FStrEq(szKeyName, "timeofday" ) )
  501. {
  502. SetTimeOfDay( atoi( szValue ) );
  503. }
  504. #ifdef PORTAL2
  505. else if ( FStrEq(szKeyName, "maxblobcount" ) )
  506. {
  507. m_nMaxBlobCount = atoi( szValue );
  508. PaintStreamManager.AllocatePaintBlobPool( m_nMaxBlobCount );
  509. }
  510. #endif
  511. else
  512. return BaseClass::KeyValue( szKeyName, szValue );
  513. return true;
  514. }
  515. #ifdef PORTAL2
  516. int CWorld::Restore( IRestore &restore )
  517. {
  518. if ( !BaseClass::Restore( restore ) )
  519. return 0;
  520. // world is the first thing that gets loaded, so we want to do our pool allocation here
  521. PaintStreamManager.AllocatePaintBlobPool( m_nMaxBlobCount );
  522. return 1;
  523. }
  524. #endif
  525. extern bool g_fGameOver;
  526. CWorld *g_WorldEntity = NULL;
  527. CWorld* GetWorldEntity()
  528. {
  529. return g_WorldEntity;
  530. }
  531. CWorld::CWorld( )
  532. {
  533. AddEFlags( EFL_NO_AUTO_EDICT_ATTACH | EFL_KEEP_ON_RECREATE_ENTITIES );
  534. NetworkProp()->AttachEdict( INDEXENT(RequiredEdictIndex()) );
  535. ActivityList_Init();
  536. EventList_Init();
  537. SetSolid( SOLID_BSP );
  538. SetMoveType( MOVETYPE_NONE );
  539. m_bColdWorld = false;
  540. // Set this in the constructor for legacy maps (sjb)
  541. m_iTimeOfDay.Set( TIME_MIDNIGHT );
  542. }
  543. CWorld::~CWorld()
  544. {
  545. // If in edit mode tell Hammer I'm ending my session. This re-enables
  546. // the Hammer UI so they can continue editing the map.
  547. #ifdef _WIN32
  548. Editor_EndSession(false);
  549. #endif
  550. EventList_Free();
  551. ActivityList_Free();
  552. if ( g_pGameRules )
  553. {
  554. g_pGameRules->LevelShutdown();
  555. delete g_pGameRules;
  556. g_pGameRules = NULL;
  557. }
  558. g_WorldEntity = NULL;
  559. }
  560. //------------------------------------------------------------------------------
  561. // Add a decal to the world
  562. //------------------------------------------------------------------------------
  563. void CWorld::DecalTrace( trace_t *pTrace, char const *decalName)
  564. {
  565. int index = decalsystem->GetDecalIndexForName( decalName );
  566. if ( index < 0 )
  567. return;
  568. CBroadcastRecipientFilter filter;
  569. if ( pTrace->hitbox != 0 )
  570. {
  571. te->Decal( filter, 0.0f, &pTrace->endpos, &pTrace->startpos, 0, pTrace->hitbox, index );
  572. }
  573. else
  574. {
  575. te->WorldDecal( filter, 0.0, &pTrace->endpos, index );
  576. }
  577. }
  578. void CWorld::RegisterSharedActivities( void )
  579. {
  580. ActivityList_RegisterSharedActivities();
  581. }
  582. void CWorld::RegisterSharedEvents( void )
  583. {
  584. EventList_RegisterSharedEvents();
  585. }
  586. void CWorld::Spawn( void )
  587. {
  588. SetLocalOrigin( vec3_origin );
  589. SetLocalAngles( vec3_angle );
  590. // NOTE: SHOULD NEVER BE ANYTHING OTHER THAN 1!!!
  591. SetModelIndex( 1 );
  592. // world model
  593. SetModelName( AllocPooledString( modelinfo->GetModelName( GetModel() ) ) );
  594. AddFlag( FL_WORLDBRUSH );
  595. #if defined( CSTRIKE15 )
  596. // 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
  597. g_pGameTypes->Initialize( true );
  598. #endif
  599. g_EventQueue.Init();
  600. Precache( );
  601. GlobalEntity_Add( "is_console", STRING(gpGlobals->mapname), ( IsGameConsole() ) ? GLOBAL_ON : GLOBAL_OFF );
  602. GlobalEntity_Add( "is_pc", STRING(gpGlobals->mapname), ( !IsGameConsole() ) ? GLOBAL_ON : GLOBAL_OFF );
  603. }
  604. static const char *g_DefaultLightstyles[] =
  605. {
  606. // 0 normal
  607. "m",
  608. // 1 FLICKER (first variety)
  609. "mmnmmommommnonmmonqnmmo",
  610. // 2 SLOW STRONG PULSE
  611. "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba",
  612. // 3 CANDLE (first variety)
  613. "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
  614. // 4 FAST STROBE
  615. "mamamamamama",
  616. // 5 GENTLE PULSE 1
  617. "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
  618. // 6 FLICKER (second variety)
  619. "nmonqnmomnmomomno",
  620. // 7 CANDLE (second variety)
  621. "mmmaaaabcdefgmmmmaaaammmaamm",
  622. // 8 CANDLE (third variety)
  623. "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
  624. // 9 SLOW STROBE (fourth variety)
  625. "aaaaaaaazzzzzzzz",
  626. // 10 FLUORESCENT FLICKER
  627. "mmamammmmammamamaaamammma",
  628. // 11 SLOW PULSE NOT FADE TO BLACK
  629. "abcdefghijklmnopqrrqponmlkjihgfedcba",
  630. // 12 UNDERWATER LIGHT MUTATION
  631. // this light only distorts the lightmap - no contribution
  632. // is made to the brightness of affected surfaces
  633. "mmnnmmnnnmmnn",
  634. };
  635. const char *GetDefaultLightstyleString( int styleIndex )
  636. {
  637. if ( styleIndex < ARRAYSIZE(g_DefaultLightstyles) )
  638. {
  639. return g_DefaultLightstyles[styleIndex];
  640. }
  641. return "m";
  642. }
  643. //-----------------------------------------------------------------------------
  644. string_t g_iszFuncBrushClassname = NULL_STRING;
  645. void CWorld::Precache( void )
  646. {
  647. COM_TimestampedLog( "CWorld::Precache - Start" );
  648. g_WorldEntity = this;
  649. g_fGameOver = false;
  650. g_pLastSpawn = NULL;
  651. g_Language.SetValue( LANGUAGE_ENGLISH ); // TODO use VGUI to get current language
  652. #ifndef INFESTED_DLL
  653. ConVarRef stepsize( "sv_stepsize" );
  654. stepsize.SetValue( 18 );
  655. #endif
  656. ConVarRef roomtype( "room_type" );
  657. roomtype.SetValue( 0 );
  658. // Set up game rules
  659. Assert( !g_pGameRules );
  660. if (g_pGameRules)
  661. {
  662. delete g_pGameRules;
  663. }
  664. InstallGameRules();
  665. Assert( g_pGameRules );
  666. g_pGameRules->Init();
  667. #ifndef DOTA_DLL
  668. CSoundEnt::InitSoundEnt();
  669. #endif
  670. // UNDONE: Make most of these things server systems or precache_registers
  671. // =================================================
  672. // Activities
  673. // =================================================
  674. ActivityList_Free();
  675. RegisterSharedActivities();
  676. EventList_Free();
  677. RegisterSharedEvents();
  678. // Only allow precaching between LevelInitPreEntity and PostEntity
  679. CBaseEntity::SetAllowPrecache( true );
  680. COM_TimestampedLog( "IGameSystem::LevelInitPreEntityAllSystems" );
  681. IGameSystem::LevelInitPreEntityAllSystems( STRING( GetModelName() ) );
  682. COM_TimestampedLog( "g_pGameRules->CreateStandardEntities()" );
  683. // Create the player resource
  684. g_pGameRules->CreateStandardEntities();
  685. COM_TimestampedLog( "InitBodyQue()" );
  686. InitBodyQue();
  687. COM_TimestampedLog( "SENTENCEG_Init()" );
  688. // init sentence group playback stuff from sentences.txt.
  689. // ok to call this multiple times, calls after first are ignored.
  690. SENTENCEG_Init();
  691. COM_TimestampedLog( "PrecacheStandardParticleSystems()" );
  692. // Precache standard particle systems
  693. PrecacheStandardParticleSystems( );
  694. // the area based ambient sounds MUST be the first precache_sounds
  695. COM_TimestampedLog( "W_Precache()" );
  696. // player precaches
  697. W_Precache (); // get weapon precaches
  698. COM_TimestampedLog( "ClientPrecache()" );
  699. ClientPrecache();
  700. COM_TimestampedLog( "PrecacheTempEnts()" );
  701. // precache all temp ent stuff
  702. CBaseTempEntity::PrecacheTempEnts();
  703. COM_TimestampedLog( "LightStyles" );
  704. //
  705. // Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
  706. //
  707. for ( int i = 0; i < ARRAYSIZE(g_DefaultLightstyles); i++ )
  708. {
  709. engine->LightStyle( i, GetDefaultLightstyleString(i) );
  710. }
  711. // styles 32-62 are assigned by the light program for switchable lights
  712. // 63 testing
  713. engine->LightStyle(63, "a");
  714. COM_TimestampedLog( "InitializeAINetworks" );
  715. // =================================================
  716. // Load and Init AI Networks
  717. // =================================================
  718. CAI_NetworkManager::InitializeAINetworks();
  719. // =================================================
  720. // Load and Init AI Schedules
  721. // =================================================
  722. COM_TimestampedLog( "LoadAllSchedules" );
  723. g_AI_SchedulesManager.LoadAllSchedules();
  724. // =================================================
  725. // Initialize NPC Relationships
  726. // =================================================
  727. COM_TimestampedLog( "InitDefaultAIRelationships" );
  728. g_pGameRules->InitDefaultAIRelationships();
  729. COM_TimestampedLog( "InitInteractionSystem" );
  730. CBaseCombatCharacter::InitInteractionSystem();
  731. COM_TimestampedLog( "g_pGameRules->Precache" );
  732. // Call the gamerules precache after the AI precache so that games can precache NPCs that are always loaded
  733. g_pGameRules->Precache();
  734. if ( m_iszChapterTitle != NULL_STRING )
  735. {
  736. DevMsg( 2, "Chapter title: %s\n", STRING(m_iszChapterTitle) );
  737. CMessage *pMessage = (CMessage *)CBaseEntity::Create( "env_message", vec3_origin, vec3_angle, NULL );
  738. if ( pMessage )
  739. {
  740. pMessage->SetMessage( m_iszChapterTitle );
  741. m_iszChapterTitle = NULL_STRING;
  742. // send the message entity a play message command, delayed by 1 second
  743. pMessage->AddSpawnFlags( SF_MESSAGE_ONCE );
  744. pMessage->SetThink( &CMessage::SUB_CallUseToggle );
  745. pMessage->SetNextThink( gpGlobals->curtime + 1.0f );
  746. }
  747. }
  748. g_iszFuncBrushClassname = AllocPooledString("func_brush");
  749. if ( m_iszDetailSpriteMaterial.Get() != NULL_STRING )
  750. {
  751. PrecacheMaterial( STRING( m_iszDetailSpriteMaterial.Get() ) );
  752. }
  753. COM_TimestampedLog( "CWorld::Precache - Finish" );
  754. }
  755. //-----------------------------------------------------------------------------
  756. //-----------------------------------------------------------------------------
  757. void CWorld::UpdateOnRemove( void )
  758. {
  759. BaseClass::UpdateOnRemove();
  760. }
  761. //-----------------------------------------------------------------------------
  762. // Purpose:
  763. // Output : float
  764. //-----------------------------------------------------------------------------
  765. float GetRealTime()
  766. {
  767. return Plat_FloatTime();
  768. }
  769. bool CWorld::GetDisplayTitle() const
  770. {
  771. return m_bDisplayTitle;
  772. }
  773. bool CWorld::GetStartDark() const
  774. {
  775. return m_bStartDark;
  776. }
  777. void CWorld::SetDisplayTitle( bool display )
  778. {
  779. m_bDisplayTitle = display;
  780. }
  781. void CWorld::SetStartDark( bool startdark )
  782. {
  783. m_bStartDark = startdark;
  784. }
  785. bool CWorld::IsColdWorld( void )
  786. {
  787. return m_bColdWorld;
  788. }
  789. int CWorld::GetTimeOfDay() const
  790. {
  791. return m_iTimeOfDay;
  792. }
  793. void CWorld::SetTimeOfDay( int iTimeOfDay )
  794. {
  795. m_iTimeOfDay = iTimeOfDay;
  796. }