mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,713 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "quakedef.h"
|
||||
#include "bspfile.h"
|
||||
#include "host.h"
|
||||
#include "sys.h"
|
||||
#include "filesystem_engine.h"
|
||||
#include "utldict.h"
|
||||
#include "demo.h"
|
||||
#ifndef SWDS
|
||||
#include "vgui_baseui_interface.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Imported from other .cpp files
|
||||
void Host_Map_f( const CCommand &args );
|
||||
void Host_Map_Background_f( const CCommand &args );
|
||||
void Host_Map_Commentary_f( const CCommand &args );
|
||||
void Host_Changelevel_f( const CCommand &args );
|
||||
void Host_Changelevel2_f( const CCommand &args );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: For each map, stores when the map last changed on disk and whether
|
||||
// it is a valid map
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMapListItem
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
INVALID = 0,
|
||||
PENDING,
|
||||
VALID,
|
||||
};
|
||||
|
||||
CMapListItem( void );
|
||||
|
||||
void SetValid( int valid );
|
||||
int GetValid( void ) const;
|
||||
|
||||
void SetFileTimestamp( long ts );
|
||||
long GetFileTimestamp( void ) const;
|
||||
|
||||
bool IsSameTime( long ts ) const;
|
||||
|
||||
static long GetFSTimeStamp( char const *name );
|
||||
static int CheckFSHeaderVersion( char const *name );
|
||||
|
||||
private:
|
||||
int m_nValid;
|
||||
long m_lFileTimestamp;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMapListItem::CMapListItem( void )
|
||||
{
|
||||
m_nValid = PENDING;
|
||||
m_lFileTimestamp = 0L;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : valid -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListItem::SetValid( int valid )
|
||||
{
|
||||
m_nValid = valid;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMapListItem::GetValid( void ) const
|
||||
{
|
||||
return m_nValid;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : ts -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListItem::SetFileTimestamp( long ts )
|
||||
{
|
||||
m_lFileTimestamp = ts;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : long
|
||||
//-----------------------------------------------------------------------------
|
||||
long CMapListItem::GetFileTimestamp( void ) const
|
||||
{
|
||||
return m_lFileTimestamp;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check whether this map file has changed related to the passed in timestamp
|
||||
// Input : ts -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMapListItem::IsSameTime( long ts ) const
|
||||
{
|
||||
return ( m_lFileTimestamp == ts ) ? true : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get the timestamp for the file from the file system
|
||||
// Input : *name -
|
||||
// Output : long
|
||||
//-----------------------------------------------------------------------------
|
||||
long CMapListItem::GetFSTimeStamp( char const *name )
|
||||
{
|
||||
long ts = g_pFileSystem->GetFileTime( name );
|
||||
return ts;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check whether the specified map header version is up-to-date
|
||||
// Input : *name -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMapListItem::CheckFSHeaderVersion( char const *name )
|
||||
{
|
||||
dheader_t header;
|
||||
memset( &header, 0, sizeof( header ) );
|
||||
|
||||
FileHandle_t fp = g_pFileSystem->Open ( name, "rb" );
|
||||
if ( fp )
|
||||
{
|
||||
g_pFileSystem->Read( &header, sizeof( header ), fp );
|
||||
g_pFileSystem->Close( fp );
|
||||
}
|
||||
|
||||
return ( header.version >= MINBSPVERSION && header.version <= BSPVERSION ) ? VALID : INVALID;
|
||||
}
|
||||
|
||||
// How often to check the filesystem for updated map info
|
||||
#define MIN_REFRESH_INTERVAL 60.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Stores the current list of maps for the engine
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMapListManager
|
||||
{
|
||||
public:
|
||||
CMapListManager( void );
|
||||
~CMapListManager( void );
|
||||
|
||||
// See if it's time to revisit the items in the list
|
||||
void RefreshList( void );
|
||||
|
||||
// Get item count, etc
|
||||
int GetMapCount( void ) const;
|
||||
int IsMapValid( int index ) const;
|
||||
char const *GetMapName( int index ) const;
|
||||
|
||||
void Think( void );
|
||||
|
||||
private:
|
||||
// Clear list
|
||||
void ClearList( void );
|
||||
// Rebuild list from scratch
|
||||
void BuildList( void );
|
||||
|
||||
private:
|
||||
// Dictionary of items
|
||||
CUtlDict< CMapListItem, int > m_Items;
|
||||
|
||||
// Time of last update
|
||||
float m_flLastRefreshTime;
|
||||
|
||||
bool m_bDirty;
|
||||
};
|
||||
|
||||
// Singleton manager object
|
||||
static CMapListManager g_MapListMgr;
|
||||
|
||||
void Host_UpdateMapList( void )
|
||||
{
|
||||
g_MapListMgr.Think();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMapListManager::CMapListManager( void )
|
||||
{
|
||||
m_flLastRefreshTime = -1.0f;
|
||||
m_bDirty = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMapListManager::~CMapListManager( void )
|
||||
{
|
||||
ClearList();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListManager::Think( void )
|
||||
{
|
||||
return;
|
||||
|
||||
if ( !m_bDirty )
|
||||
return;
|
||||
|
||||
#ifndef SWDS
|
||||
// Only update pending files if console is visible to avoid slamming FS while in a map
|
||||
if ( !EngineVGui()->IsConsoleVisible() )
|
||||
return;
|
||||
#endif
|
||||
|
||||
int i;
|
||||
|
||||
m_bDirty = false;
|
||||
|
||||
for ( i = m_Items.Count() - 1; i >= 0 ; i-- )
|
||||
{
|
||||
CMapListItem *item = &m_Items[ i ];
|
||||
if ( item->GetValid() != CMapListItem::PENDING )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
char const *filename = m_Items.GetElementName( i );
|
||||
|
||||
item->SetValid( CMapListItem::CheckFSHeaderVersion( filename ) );
|
||||
|
||||
// Keep fixing things up next frame
|
||||
m_bDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: FIXME: Refresh doesn't notice maps that have been deleted... oh well
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListManager::RefreshList( void )
|
||||
{
|
||||
if ( m_flLastRefreshTime == -1.0f )
|
||||
{
|
||||
BuildList();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( realtime < m_flLastRefreshTime + MIN_REFRESH_INTERVAL )
|
||||
return;
|
||||
|
||||
ConDMsg( "Refreshing map list...\n" );
|
||||
|
||||
// Search the directory structure.
|
||||
char mapwild[MAX_QPATH];
|
||||
Q_strncpy(mapwild,"maps/*.bsp", sizeof( mapwild ) );
|
||||
char const *findfn = Sys_FindFirst( mapwild, NULL, 0 );
|
||||
while ( findfn )
|
||||
{
|
||||
if ( IsPC() && V_stristr( findfn, ".360.bsp" ) )
|
||||
{
|
||||
// ignore 360 bsp
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
continue;
|
||||
}
|
||||
else if ( IsX360() && !V_stristr( findfn, ".360.bsp" ) )
|
||||
{
|
||||
// ignore pc bsp
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make full fileame (maps/foo.bsp) and map name (foo)
|
||||
char szFileName[ MAX_QPATH ] = { 0 };
|
||||
V_snprintf( szFileName, sizeof( szFileName ), "maps/%s", findfn );
|
||||
|
||||
char szMapName[256] = { 0 };
|
||||
V_strncpy( szMapName, findfn, sizeof( szMapName ) );
|
||||
char *pExt = V_stristr( szMapName, ".bsp" );
|
||||
if ( pExt )
|
||||
{
|
||||
*pExt = '\0';
|
||||
}
|
||||
|
||||
int idx = m_Items.Find( szMapName );
|
||||
if ( idx == m_Items.InvalidIndex() )
|
||||
{
|
||||
CMapListItem item;
|
||||
item.SetFileTimestamp( item.GetFSTimeStamp( szFileName ) );
|
||||
item.SetValid( CMapListItem::PENDING );
|
||||
// Insert into dictionary
|
||||
m_Items.Insert( szMapName, item );
|
||||
|
||||
m_bDirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMapListItem *item = &m_Items[ idx ];
|
||||
Assert( item );
|
||||
|
||||
// Make sure data is up to date
|
||||
long timestamp = g_pFileSystem->GetFileTime( szFileName );
|
||||
if ( !item->IsSameTime( timestamp ) )
|
||||
{
|
||||
item->SetFileTimestamp( timestamp );
|
||||
item->SetValid( CMapListItem::PENDING );
|
||||
|
||||
m_bDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
}
|
||||
|
||||
Sys_FindClose();
|
||||
|
||||
m_flLastRefreshTime = realtime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMapListManager::GetMapCount( void ) const
|
||||
{
|
||||
return m_Items.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : index -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMapListManager::IsMapValid( int index ) const
|
||||
{
|
||||
if ( !m_Items.IsValidIndex( index ) )
|
||||
return false;
|
||||
|
||||
CMapListItem const *item = &m_Items[ index ];
|
||||
Assert( item );
|
||||
return item->GetValid();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : index -
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
char const *CMapListManager::GetMapName( int index ) const
|
||||
{
|
||||
if ( !m_Items.IsValidIndex( index ) )
|
||||
return "Invalid!!!";
|
||||
|
||||
return m_Items.GetElementName( index );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Wipe the list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListManager::ClearList( void )
|
||||
{
|
||||
m_Items.Purge();
|
||||
m_bDirty = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Rebuild the entire list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMapListManager::BuildList( void )
|
||||
{
|
||||
ClearList();
|
||||
|
||||
// Search the directory structure.
|
||||
char mapwild[MAX_QPATH];
|
||||
Q_strncpy(mapwild,"maps/*.bsp", sizeof( mapwild ) );
|
||||
char const *findfn = Sys_FindFirst( mapwild, NULL, 0 );
|
||||
while ( findfn )
|
||||
{
|
||||
if ( IsPC() && V_stristr( findfn, ".360.bsp" ) )
|
||||
{
|
||||
// ignore 360 bsp
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
continue;
|
||||
}
|
||||
else if ( IsX360() && !V_stristr( findfn, ".360.bsp" ) )
|
||||
{
|
||||
// ignore pc bsp
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make full fileame (maps/foo.bsp) and map name (foo)
|
||||
char szFileName[ MAX_QPATH ] = { 0 };
|
||||
V_snprintf( szFileName, sizeof( szFileName ), "maps/%s", findfn );
|
||||
|
||||
char szMapName[256] = { 0 };
|
||||
V_strncpy( szMapName, findfn, sizeof( szMapName ) );
|
||||
char *pExt = V_stristr( szMapName, ".bsp" );
|
||||
if ( pExt )
|
||||
{
|
||||
*pExt = '\0';
|
||||
}
|
||||
|
||||
CMapListItem item;
|
||||
item.SetFileTimestamp( item.GetFSTimeStamp( szFileName ) );
|
||||
item.SetValid( CMapListItem::PENDING );
|
||||
|
||||
// Insert into dictionary
|
||||
int idx = m_Items.Find( szMapName );
|
||||
if ( idx == m_Items.InvalidIndex() )
|
||||
{
|
||||
m_Items.Insert( szMapName, item );
|
||||
}
|
||||
|
||||
findfn = Sys_FindNext( NULL, 0 );
|
||||
}
|
||||
|
||||
Sys_FindClose();
|
||||
|
||||
// Remember time we build the list
|
||||
m_flLastRefreshTime = realtime;
|
||||
|
||||
m_bDirty = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pakorfilesys -
|
||||
// *mapname -
|
||||
// Output : static void
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool MapList_CheckPrintMap( const char *pakorfilesys, const char *mapname, int valid,
|
||||
bool showoutdated, bool verbose )
|
||||
{
|
||||
bool validorpending = ( valid != CMapListItem::INVALID ) ? true : false;
|
||||
|
||||
if ( !verbose )
|
||||
{
|
||||
return validorpending;
|
||||
}
|
||||
|
||||
char prefix[ 32 ];
|
||||
prefix[ 0 ] = 0;
|
||||
|
||||
switch ( valid )
|
||||
{
|
||||
default:
|
||||
case CMapListItem::VALID:
|
||||
break;
|
||||
case CMapListItem::PENDING:
|
||||
Q_strncpy( prefix, "PENDING: ", sizeof( prefix ) );
|
||||
break;
|
||||
case CMapListItem::INVALID:
|
||||
Q_strncpy( prefix, "OUTDATED: ", sizeof( prefix ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( validorpending ^ showoutdated )
|
||||
{
|
||||
ConMsg( "%s %s %s\n", prefix, pakorfilesys, mapname );
|
||||
}
|
||||
|
||||
return validorpending;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pszSubString -
|
||||
// listobsolete -
|
||||
// maxitemlength -
|
||||
// Output : static int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int MapList_CountMaps( const char *pszSubString, bool listobsolete, int& maxitemlength )
|
||||
{
|
||||
g_MapListMgr.RefreshList();
|
||||
|
||||
maxitemlength = 0;
|
||||
|
||||
int substringlength = 0;
|
||||
if ( pszSubString && pszSubString[0] )
|
||||
{
|
||||
substringlength = strlen(pszSubString);
|
||||
}
|
||||
|
||||
//
|
||||
// search through the path, one element at a time
|
||||
//
|
||||
int count = 0;
|
||||
int showOutdated;
|
||||
for( showOutdated = listobsolete ? 1 : 0; showOutdated >= 0; showOutdated-- )
|
||||
{
|
||||
for ( int i = 0; i < g_MapListMgr.GetMapCount(); i++ )
|
||||
{
|
||||
char const *mapname = g_MapListMgr.GetMapName( i );
|
||||
int valid = g_MapListMgr.IsMapValid( i );
|
||||
|
||||
if ( !substringlength || V_stristr( mapname, pszSubString ) )
|
||||
{
|
||||
if ( MapList_CheckPrintMap( "(fs)", mapname, valid, showOutdated ? true : false, false ) )
|
||||
{
|
||||
maxitemlength = max( maxitemlength, (int)( strlen( mapname ) + 1 ) );
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Lists all maps matching the substring
|
||||
// If the substring is empty, or "*", then lists all maps
|
||||
// Input : *pszSubString -
|
||||
//-----------------------------------------------------------------------------
|
||||
int MapList_ListMaps( const char *pszSubString, bool listobsolete, bool verbose, int maxcount, int maxitemlength, char maplist[][ 64 ] )
|
||||
{
|
||||
g_MapListMgr.RefreshList();
|
||||
int substringlength = 0;
|
||||
if (pszSubString && pszSubString[0])
|
||||
{
|
||||
substringlength = strlen(pszSubString);
|
||||
}
|
||||
|
||||
//
|
||||
// search through the path, one element at a time
|
||||
//
|
||||
|
||||
if ( verbose )
|
||||
{
|
||||
ConMsg( "-------------\n");
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
int showOutdated;
|
||||
for( showOutdated = listobsolete ? 1 : 0; showOutdated >= 0; showOutdated-- )
|
||||
{
|
||||
if ( count >= maxcount )
|
||||
break;
|
||||
|
||||
//search the directory structure.
|
||||
for ( int i = 0; i < g_MapListMgr.GetMapCount(); i++ )
|
||||
{
|
||||
if ( count >= maxcount )
|
||||
break;
|
||||
|
||||
char const *mapname = g_MapListMgr.GetMapName( i );
|
||||
int valid = g_MapListMgr.IsMapValid( i );
|
||||
|
||||
if ( !substringlength || V_stristr( mapname, pszSubString ) )
|
||||
{
|
||||
if ( MapList_CheckPrintMap( "(fs)", mapname, valid, showOutdated ? true : false, verbose ) )
|
||||
{
|
||||
if ( maxitemlength != 0 )
|
||||
{
|
||||
Q_strncpy( maplist[ count ], mapname, maxitemlength );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// context -
|
||||
// longest -
|
||||
// maxcommands -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int _Host_Map_f_CompletionFunc( char const *cmdname, char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
char *substring = (char *)partial;
|
||||
if ( Q_strstr( partial, cmdname ) )
|
||||
{
|
||||
substring = (char *)partial + strlen( cmdname );
|
||||
}
|
||||
|
||||
int longest = 0;
|
||||
int count = min( MapList_CountMaps( substring, false, longest ), COMMAND_COMPLETION_MAXITEMS );
|
||||
if ( count > 0 )
|
||||
{
|
||||
MapList_ListMaps( substring, false, false, COMMAND_COMPLETION_MAXITEMS, longest, commands );
|
||||
|
||||
// Now prepend maps * in front of all of the options
|
||||
int i;
|
||||
for ( i = 0; i < count ; i++ )
|
||||
{
|
||||
char old[ COMMAND_COMPLETION_ITEM_LENGTH ];
|
||||
Q_strncpy( old, commands[ i ], sizeof( old ) );
|
||||
Q_snprintf( commands[ i ], sizeof( commands[ i ] ), "%s%s", cmdname, old );
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// context -
|
||||
// longest -
|
||||
// maxcommands -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Host_Map_f_CompletionFunc( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
char const *cmdname = "map ";
|
||||
return _Host_Map_f_CompletionFunc( cmdname, partial, commands );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// context -
|
||||
// longest -
|
||||
// maxcommands -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Host_Map_Commentary_f_CompletionFunc( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
char const *cmdname = "map_commentary ";
|
||||
return _Host_Map_f_CompletionFunc( cmdname, partial, commands );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// context -
|
||||
// longest -
|
||||
// maxcommands -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Host_Changelevel_f_CompletionFunc( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
char const *cmdname = "changelevel ";
|
||||
return _Host_Map_f_CompletionFunc( cmdname, partial, commands );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *partial -
|
||||
// context -
|
||||
// longest -
|
||||
// maxcommands -
|
||||
// **commands -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Host_Changelevel2_f_CompletionFunc( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
char const *cmdname = "changelevel2 ";
|
||||
return _Host_Map_f_CompletionFunc( cmdname, partial, commands );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: do a dir of the maps dir
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Host_Maps_f( const CCommand &args )
|
||||
{
|
||||
const char *pszSubString = NULL;
|
||||
|
||||
if ( args.ArgC() != 2 && args.ArgC() != 3 )
|
||||
{
|
||||
ConMsg( "Usage: maps <substring>\nmaps * for full listing\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( args.ArgC() == 2 )
|
||||
{
|
||||
pszSubString = args[1];
|
||||
if (!pszSubString || !pszSubString[0])
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pszSubString && ( pszSubString[0] == '*' ))
|
||||
pszSubString = NULL;
|
||||
|
||||
int longest = 0;
|
||||
int count = MapList_CountMaps( pszSubString, true, longest );
|
||||
if ( count > 0 )
|
||||
{
|
||||
MapList_ListMaps( pszSubString, true, true, count, 0, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BENCHMARK
|
||||
static ConCommand maps("maps", Host_Maps_f, "Displays list of maps." );
|
||||
static ConCommand map("map", Host_Map_f, "Start playing on specified map.", FCVAR_DONTRECORD, Host_Map_f_CompletionFunc );
|
||||
static ConCommand map_background("map_background", Host_Map_Background_f, "Runs a map as the background to the main menu.", FCVAR_DONTRECORD, Host_Map_f_CompletionFunc );
|
||||
static ConCommand map_commentary("map_commentary", Host_Map_Commentary_f, "Start playing, with commentary, on a specified map.", FCVAR_DONTRECORD, Host_Map_Commentary_f_CompletionFunc );
|
||||
static ConCommand changelevel("changelevel", Host_Changelevel_f, "Change server to the specified map", FCVAR_DONTRECORD, Host_Changelevel_f_CompletionFunc );
|
||||
static ConCommand changelevel2("changelevel2", Host_Changelevel2_f, "Transition to the specified map in single player", FCVAR_DONTRECORD, Host_Changelevel2_f_CompletionFunc );
|
||||
#endif
|
||||
Reference in New Issue
Block a user