|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "basetypes.h"
#include "saverestore.h"
#include "saverestore_utlvector.h"
#include "saverestore_utlsymbol.h"
#include "globalstate.h"
#include "igamesystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
struct globalentity_t { DECLARE_SIMPLE_DATADESC();
CUtlSymbol name; CUtlSymbol levelName; GLOBALESTATE state; int counter; };
class CGlobalState : public CAutoGameSystem { public: CGlobalState( char const *name ) : CAutoGameSystem( name ), m_disableStateUpdates(false) { }
// IGameSystem
virtual void LevelShutdownPreEntity() { // don't allow state updates during shutdowns
Assert( !m_disableStateUpdates ); m_disableStateUpdates = true; } virtual void LevelShutdownPostEntity() { Assert( m_disableStateUpdates ); m_disableStateUpdates = false; }
void EnableStateUpdates( bool bEnable ) { m_disableStateUpdates = !bEnable; }
void SetState( int globalIndex, GLOBALESTATE state ) { if ( m_disableStateUpdates || !m_list.IsValidIndex(globalIndex) ) return; m_list[globalIndex].state = state; }
GLOBALESTATE GetState( int globalIndex ) { if ( !m_list.IsValidIndex(globalIndex) ) return GLOBAL_OFF; return m_list[globalIndex].state; }
void SetCounter( int globalIndex, int counter ) { if ( m_disableStateUpdates || !m_list.IsValidIndex(globalIndex) ) return; m_list[globalIndex].counter = counter; }
int AddToCounter( int globalIndex, int delta ) { if ( m_disableStateUpdates || !m_list.IsValidIndex(globalIndex) ) return 0; return ( m_list[globalIndex].counter += delta ); }
int GetCounter( int globalIndex ) { if ( !m_list.IsValidIndex(globalIndex) ) return 0; return m_list[globalIndex].counter; }
void SetMap( int globalIndex, string_t mapname ) { if ( !m_list.IsValidIndex(globalIndex) ) return; m_list[globalIndex].levelName = m_nameList.AddString( STRING(mapname) ); }
const char *GetMap( int globalIndex ) { if ( !m_list.IsValidIndex(globalIndex) ) return NULL; return m_nameList.String( m_list[globalIndex].levelName ); }
const char *GetName( int globalIndex ) { if ( !m_list.IsValidIndex(globalIndex) ) return NULL; return m_nameList.String( m_list[globalIndex].name ); }
int GetIndex( const char *pGlobalname ) { CUtlSymbol symName = m_nameList.Find( pGlobalname );
if ( symName.IsValid() ) { for ( int i = m_list.Count() - 1; i >= 0; --i ) { if ( m_list[i].name == symName ) return i; } }
return -1; }
int AddEntity( const char *pGlobalname, const char *pMapName, GLOBALESTATE state ) { globalentity_t entity; entity.name = m_nameList.AddString( pGlobalname ); entity.levelName = m_nameList.AddString( pMapName ); entity.state = state;
int index = GetIndex( m_nameList.String( entity.name ) ); if ( index >= 0 ) return index; return m_list.AddToTail( entity ); }
int GetNumGlobals( void ) { return m_list.Count(); }
void Reset( void ); int Save( ISave &save ); int Restore( IRestore &restore ); DECLARE_SIMPLE_DATADESC();
//#ifdef _DEBUG
void DumpGlobals( void ); //#endif
public: CUtlSymbolTable m_nameList; private: bool m_disableStateUpdates; CUtlVector<globalentity_t> m_list; };
static CGlobalState gGlobalState( "CGlobalState" );
static CUtlSymbolDataOps g_GlobalSymbolDataOps( gGlobalState.m_nameList );
void GlobalEntity_SetState( int globalIndex, GLOBALESTATE state ) { gGlobalState.SetState( globalIndex, state ); }
void GlobalEntity_SetCounter( int globalIndex, int counter ) { gGlobalState.SetCounter( globalIndex, counter ); }
int GlobalEntity_AddToCounter( int globalIndex, int delta ) { return gGlobalState.AddToCounter( globalIndex, delta ); }
void GlobalEntity_SetFlags( int globalIndex, int flags ) { // Flags are stored in counter var
gGlobalState.SetCounter( globalIndex, flags ); }
void GlobalEntity_AddFlags( int globalIndex, int flags ) { // Flags are stored in counter var
gGlobalState.SetCounter( globalIndex, gGlobalState.GetCounter( globalIndex ) | flags ); }
void GlobalEntity_RemoveFlags( int globalIndex, int flags ) { // Flags are stored in counter var
gGlobalState.SetCounter( globalIndex, gGlobalState.GetCounter( globalIndex ) & ~flags ); }
void GlobalEntity_EnableStateUpdates( bool bEnable ) { gGlobalState.EnableStateUpdates( bEnable ); }
void GlobalEntity_SetMap( int globalIndex, string_t mapname ) { gGlobalState.SetMap( globalIndex, mapname ); }
int GlobalEntity_Add( const char *pGlobalname, const char *pMapName, GLOBALESTATE state ) { return gGlobalState.AddEntity( pGlobalname, pMapName, state ); }
int GlobalEntity_GetIndex( const char *pGlobalname ) { return gGlobalState.GetIndex( pGlobalname ); }
GLOBALESTATE GlobalEntity_GetState( int globalIndex ) { return gGlobalState.GetState( globalIndex ); }
int GlobalEntity_GetCounter( int globalIndex ) { return gGlobalState.GetCounter( globalIndex ); }
int GlobalEntity_GetFlags( int globalIndex ) { // Flags are stored in counter var
return gGlobalState.GetCounter( globalIndex ); }
const char *GlobalEntity_GetMap( int globalIndex ) { return gGlobalState.GetMap( globalIndex ); }
const char *GlobalEntity_GetName( int globalIndex ) { return gGlobalState.GetName( globalIndex ); }
int GlobalEntity_GetNumGlobals( void ) { return gGlobalState.GetNumGlobals(); }
CON_COMMAND(dump_globals, "Dump all global entities/states") { if ( !UTIL_IsCommandIssuedByServerAdmin() ) return;
gGlobalState.DumpGlobals(); }
// This is available all the time now on impulse 104, remove later
//#ifdef _DEBUG
void CGlobalState::DumpGlobals( void ) { static char *estates[] = { "Off", "On", "Dead" };
Msg( "-- Globals --\n" ); for ( int i = 0; i < m_list.Count(); i++ ) { Msg( "%s: %s (%s) = %d\n", m_nameList.String( m_list[i].name ), m_nameList.String( m_list[i].levelName ), estates[m_list[i].state], m_list[i].counter ); } } //#endif
// Global state Savedata
BEGIN_SIMPLE_DATADESC( CGlobalState ) DEFINE_UTLVECTOR( m_list, FIELD_EMBEDDED ), // DEFINE_FIELD( m_nameList, CUtlSymbolTable ),
// DEFINE_FIELD( m_disableStateUpdates, FIELD_BOOLEAN ),
END_DATADESC()
BEGIN_SIMPLE_DATADESC( globalentity_t ) DEFINE_CUSTOM_FIELD( name, &g_GlobalSymbolDataOps ), DEFINE_CUSTOM_FIELD( levelName, &g_GlobalSymbolDataOps ), DEFINE_FIELD( state, FIELD_INTEGER ), DEFINE_FIELD( counter, FIELD_INTEGER ), END_DATADESC()
int CGlobalState::Save( ISave &save ) { if ( !save.WriteFields( "GLOBAL", this, NULL, m_DataMap.dataDesc, m_DataMap.dataNumFields ) ) return 0; return 1; }
int CGlobalState::Restore( IRestore &restore ) { Reset(); if ( !restore.ReadFields( "GLOBAL", this, NULL, m_DataMap.dataDesc, m_DataMap.dataNumFields ) ) return 0; return 1; }
void CGlobalState::Reset( void ) { m_list.Purge(); m_nameList.RemoveAll(); }
void SaveGlobalState( CSaveRestoreData *pSaveData ) { CSave saveHelper( pSaveData ); gGlobalState.Save( saveHelper ); }
void RestoreGlobalState( CSaveRestoreData *pSaveData ) { CRestore restoreHelper( pSaveData ); gGlobalState.Restore( restoreHelper ); }
//-----------------------------------------------------------------------------
// Purpose: This gets called when a level is shut down
//-----------------------------------------------------------------------------
void ResetGlobalState( void ) { gGlobalState.Reset(); }
void ShowServerGameTime() { Msg( "Server game time: %f\n", gpGlobals->curtime ); }
CON_COMMAND(server_game_time, "Gives the game time in seconds (server's curtime)") { if ( !UTIL_IsCommandIssuedByServerAdmin() ) return;
ShowServerGameTime(); }
|