Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.

327 lines
7.1 KiB

5 years ago
//========= Copyright 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;
entity.counter = 0;
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_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 );
}
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 const 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();
}