diff options
Diffstat (limited to 'src/game/g_maprotation.c')
-rw-r--r-- | src/game/g_maprotation.c | 709 |
1 files changed, 0 insertions, 709 deletions
diff --git a/src/game/g_maprotation.c b/src/game/g_maprotation.c deleted file mode 100644 index fb98c4a8..00000000 --- a/src/game/g_maprotation.c +++ /dev/null @@ -1,709 +0,0 @@ -// g_maprotation.c -- the map rotation system - -/* - * Portions Copyright (C) 2000-2001 Tim Angus - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the OSML - Open Source Modification License v1.0 as - * described in the file COPYING which is distributed with this source - * code. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "g_local.h" - -static mapRotations_t mapRotations; - -/* -=============== -G_ParseCommandSection - -Parse a map rotation command section -=============== -*/ -static qboolean G_ParseMapCommandSection( mapRotationEntry_t *mre, char **text_p ) -{ - char *token; - - // read optional parameters - while( 1 ) - { - token = COM_Parse( text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "" ) ) - return qfalse; - - if( !Q_stricmp( token, "}" ) ) - return qtrue; //reached the end of this command section - - Q_strncpyz( mre->postCmds[ mre->numCmds ], token, sizeof( mre->postCmds[ 0 ] ) ); - Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), " " ); - - token = COM_ParseExt( text_p, qfalse ); - - while( token && token[ 0 ] != 0 ) - { - Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), token ); - Q_strcat( mre->postCmds[ mre->numCmds ], sizeof( mre->postCmds[ 0 ] ), " " ); - token = COM_ParseExt( text_p, qfalse ); - } - - if( mre->numCmds == MAX_MAP_COMMANDS ) - { - G_Printf( S_COLOR_RED "ERROR: maximum number of map commands (%d) reached\n", - MAX_MAP_COMMANDS ); - return qfalse; - } - else - mre->numCmds++; - } - - return qfalse; -} - -/* -=============== -G_ParseMapRotation - -Parse a map rotation section -=============== -*/ -static qboolean G_ParseMapRotation( mapRotation_t *mr, char **text_p ) -{ - char *token; - qboolean mnSet = qfalse; - mapRotationEntry_t *mre = NULL; - mapRotationCondition_t *mrc; - - // read optional parameters - while( 1 ) - { - token = COM_Parse( text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "" ) ) - return qfalse; - - if( !Q_stricmp( token, "{" ) ) - { - if( !mnSet ) - { - G_Printf( S_COLOR_RED "ERROR: map settings section with no name\n" ); - return qfalse; - } - - if( !G_ParseMapCommandSection( mre, text_p ) ) - { - G_Printf( S_COLOR_RED "ERROR: failed to parse map command section\n" ); - return qfalse; - } - - mnSet = qfalse; - continue; - } - else if( !Q_stricmp( token, "goto" ) ) - { - token = COM_Parse( text_p ); - - if( !token ) - break; - - mrc = &mre->conditions[ mre->numConditions ]; - mrc->unconditional = qtrue; - Q_strncpyz( mrc->dest, token, sizeof( mrc->dest ) ); - - if( mre->numConditions == MAX_MAP_ROTATION_CONDS ) - { - G_Printf( S_COLOR_RED "ERROR: maximum number of conditions for one map (%d) reached\n", - MAX_MAP_ROTATION_CONDS ); - return qfalse; - } - else - mre->numConditions++; - - continue; - } - else if( !Q_stricmp( token, "if" ) ) - { - token = COM_Parse( text_p ); - - if( !token ) - break; - - mrc = &mre->conditions[ mre->numConditions ]; - - if( !Q_stricmp( token, "numClients" ) ) - { - mrc->lhs = MCV_NUMCLIENTS; - - token = COM_Parse( text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "<" ) ) - mrc->op = MCO_LT; - else if( !Q_stricmp( token, ">" ) ) - mrc->op = MCO_GT; - else if( !Q_stricmp( token, "=" ) ) - mrc->op = MCO_EQ; - else - { - G_Printf( S_COLOR_RED "ERROR: invalid operator in expression: %s\n", token ); - return qfalse; - } - - token = COM_Parse( text_p ); - - if( !token ) - break; - - mrc->numClients = atoi( token ); - } - else if( !Q_stricmp( token, "lastWin" ) ) - { - mrc->lhs = MCV_LASTWIN; - - token = COM_Parse( text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "aliens" ) ) - mrc->lastWin = PTE_ALIENS; - else if( !Q_stricmp( token, "humans" ) ) - mrc->lastWin = PTE_HUMANS; - else - { - G_Printf( S_COLOR_RED "ERROR: invalid right hand side in expression: %s\n", token ); - return qfalse; - } - } - else if( !Q_stricmp( token, "random" ) ) - mrc->lhs = MCV_RANDOM; - else - { - G_Printf( S_COLOR_RED "ERROR: invalid left hand side in expression: %s\n", token ); - return qfalse; - } - - token = COM_Parse( text_p ); - - if( !token ) - break; - - mrc->unconditional = qfalse; - Q_strncpyz( mrc->dest, token, sizeof( mrc->dest ) ); - - if( mre->numConditions == MAX_MAP_ROTATION_CONDS ) - { - G_Printf( S_COLOR_RED "ERROR: maximum number of conditions for one map (%d) reached\n", - MAX_MAP_ROTATION_CONDS ); - return qfalse; - } - else - mre->numConditions++; - - continue; - } - else if( !Q_stricmp( token, "}" ) ) - return qtrue; //reached the end of this map rotation - - mre = &mr->maps[ mr->numMaps ]; - - if( mr->numMaps == MAX_MAP_ROTATION_MAPS ) - { - G_Printf( S_COLOR_RED "ERROR: maximum number of maps in one rotation (%d) reached\n", - MAX_MAP_ROTATION_MAPS ); - return qfalse; - } - else - mr->numMaps++; - - Q_strncpyz( mre->name, token, sizeof( mre->name ) ); - mnSet = qtrue; - } - - return qfalse; -} - -/* -=============== -G_ParseMapRotationFile - -Load the map rotations from a map rotation file -=============== -*/ -static qboolean G_ParseMapRotationFile( const char *fileName ) -{ - char *text_p; - int i; - int len; - char *token; - char text[ 20000 ]; - char mrName[ MAX_QPATH ]; - qboolean mrNameSet = qfalse; - fileHandle_t f; - - // load the file - len = trap_FS_FOpenFile( fileName, &f, FS_READ ); - if( len <= 0 ) - return qfalse; - - if( len >= sizeof( text ) - 1 ) - { - G_Printf( S_COLOR_RED "ERROR: map rotation file %s too long\n", fileName ); - return qfalse; - } - - trap_FS_Read( text, len, f ); - text[ len ] = 0; - trap_FS_FCloseFile( f ); - - // parse the text - text_p = text; - - // read optional parameters - while( 1 ) - { - token = COM_Parse( &text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "" ) ) - break; - - if( !Q_stricmp( token, "{" ) ) - { - if( mrNameSet ) - { - //check for name space clashes - for( i = 0; i < mapRotations.numRotations; i++ ) - { - if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) ) - { - G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName ); - return qfalse; - } - } - - Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH ); - - if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) ) - { - G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName ); - return qfalse; - } - - //start parsing particle systems again - mrNameSet = qfalse; - - if( mapRotations.numRotations == MAX_MAP_ROTATIONS ) - { - G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n", - MAX_MAP_ROTATIONS ); - return qfalse; - } - else - mapRotations.numRotations++; - - continue; - } - else - { - G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" ); - return qfalse; - } - } - - if( !mrNameSet ) - { - Q_strncpyz( mrName, token, sizeof( mrName ) ); - mrNameSet = qtrue; - } - else - { - G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" ); - return qfalse; - } - } - - return qtrue; -} - -/* -=============== -G_PrintRotations - -Print the parsed map rotations -=============== -*/ -void G_PrintRotations( void ) -{ - int i, j, k; - - G_Printf( "Map rotations as parsed:\n\n" ); - - for( i = 0; i < mapRotations.numRotations; i++ ) - { - G_Printf( "rotation: %s\n{\n", mapRotations.rotations[ i ].name ); - - for( j = 0; j < mapRotations.rotations[ i ].numMaps; j++ ) - { - G_Printf( " map: %s\n {\n", mapRotations.rotations[ i ].maps[ j ].name ); - - for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numCmds; k++ ) - { - G_Printf( " command: %s\n", - mapRotations.rotations[ i ].maps[ j ].postCmds[ k ] ); - } - - G_Printf( " }\n" ); - - for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numConditions; k++ ) - { - G_Printf( " conditional: %s\n", - mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ); - } - - } - - G_Printf( "}\n" ); - } - - G_Printf( "Total memory used: %d bytes\n", sizeof( mapRotations ) ); -} - -/* -=============== -G_GetCurrentMapArray - -Fill a static array with the current map of each rotation -=============== -*/ -static int *G_GetCurrentMapArray( void ) -{ - static int currentMap[ MAX_MAP_ROTATIONS ]; - int i = 0; - char text[ MAX_MAP_ROTATIONS * 2 ]; - char *text_p, *token; - - Q_strncpyz( text, g_currentMap.string, sizeof( text ) ); - - text_p = text; - - while( 1 ) - { - token = COM_Parse( &text_p ); - - if( !token ) - break; - - if( !Q_stricmp( token, "" ) ) - break; - - currentMap[ i++ ] = atoi( token ); - } - - return currentMap; -} - -/* -=============== -G_SetCurrentMap - -Set the current map in some rotation -=============== -*/ -static void G_SetCurrentMap( int currentMap, int rotation ) -{ - char text[ MAX_MAP_ROTATIONS * 2 ] = { 0 }; - int *p = G_GetCurrentMapArray( ); - int i; - - p[ rotation ] = currentMap; - - for( i = 0; i < mapRotations.numRotations; i++ ) - Q_strcat( text, sizeof( text ), va( "%d ", p[ i ] ) ); - - trap_Cvar_Set( "g_currentMap", text ); - trap_Cvar_Update( &g_currentMap ); -} - -/* -=============== -G_GetCurrentMap - -Return the current map in some rotation -=============== -*/ -static int G_GetCurrentMap( int rotation ) -{ - int *p = G_GetCurrentMapArray( ); - - return p[ rotation ]; -} - -/* -=============== -G_IssueMapChange - -Send commands to the server to actually change the map -=============== -*/ -static void G_IssueMapChange( int rotation ) -{ - int i; - int map = G_GetCurrentMap( rotation ); - char cmd[ MAX_TOKEN_CHARS ]; - - trap_SendConsoleCommand( EXEC_APPEND, va( "map %s\n", - mapRotations.rotations[ rotation ].maps[ map ].name ) ); - - for( i = 0; i < mapRotations.rotations[ rotation ].maps[ map ].numCmds; i++ ) - { - Q_strncpyz( cmd, mapRotations.rotations[ rotation ].maps[ map ].postCmds[ i ], - sizeof( cmd ) ); - Q_strcat( cmd, sizeof( cmd ), "\n" ); - trap_SendConsoleCommand( EXEC_APPEND, cmd ); - } -} - -/* -=============== -G_ResolveConditionDestination - -Resolve the destination of some condition -=============== -*/ -static mapConditionType_t G_ResolveConditionDestination( int *n, char *name ) -{ - int i; - - //search the current rotation first... - for( i = 0; i < mapRotations.rotations[ g_currentMapRotation.integer ].numMaps; i++ ) - { - if( !Q_stricmp( mapRotations.rotations[ g_currentMapRotation.integer ].maps[ i ].name, name ) ) - { - *n = i; - return MCT_MAP; - } - } - - //...then search the rotation names - for( i = 0; i < mapRotations.numRotations; i++ ) - { - if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) - { - *n = i; - return MCT_ROTATION; - } - } - - //this should probably be prevented by a 2nd pass at compile time - //but i'm lazy (FIXME) - return MCT_ERR; -} - -/* -=============== -G_EvaluateMapCondition - -Evaluate a map condition -=============== -*/ -static qboolean G_EvaluateMapCondition( mapRotationCondition_t *mrc ) -{ - switch( mrc->lhs ) - { - case MCV_RANDOM: - return rand( ) & 1; - break; - - case MCV_NUMCLIENTS: - switch( mrc->op ) - { - case MCO_LT: - return level.numConnectedClients < mrc->numClients; - break; - - case MCO_GT: - return level.numConnectedClients > mrc->numClients; - break; - - case MCO_EQ: - return level.numConnectedClients == mrc->numClients; - break; - } - break; - - case MCV_LASTWIN: - return level.lastWin == mrc->lastWin; - break; - - default: - case MCV_ERR: - G_Printf( S_COLOR_RED "ERROR: malformed map switch condition\n" ); - break; - } - - return qfalse; -} - -/* -=============== -G_AdvanceMapRotation - -Increment the current map rotation -=============== -*/ -qboolean G_AdvanceMapRotation( void ) -{ - mapRotation_t *mr; - mapRotationEntry_t *mre; - mapRotationCondition_t *mrc; - int currentRotation, currentMap, nextMap; - int i, n; - mapConditionType_t mct; - - if( ( currentRotation = g_currentMapRotation.integer ) == NOT_ROTATING ) - return qfalse; - - currentMap = G_GetCurrentMap( currentRotation ); - - mr = &mapRotations.rotations[ currentRotation ]; - mre = &mr->maps[ currentMap ]; - nextMap = ( currentMap + 1 ) % mr->numMaps; - - for( i = 0; i < mre->numConditions; i++ ) - { - mrc = &mre->conditions[ i ]; - - if( mrc->unconditional || G_EvaluateMapCondition( mrc ) ) - { - mct = G_ResolveConditionDestination( &n, mrc->dest ); - - switch( mct ) - { - case MCT_MAP: - nextMap = n; - break; - - case MCT_ROTATION: - G_StartMapRotation( mrc->dest, qtrue ); - return qtrue; - break; - - default: - case MCT_ERR: - G_Printf( S_COLOR_YELLOW "WARNING: map switch destination could not be resolved: %s\n", - mrc->dest ); - break; - } - } - } - - G_SetCurrentMap( nextMap, currentRotation ); - G_IssueMapChange( currentRotation ); - - return qtrue; -} - -/* -=============== -G_StartMapRotation - -Switch to a new map rotation -=============== -*/ -qboolean G_StartMapRotation( char *name, qboolean changeMap ) -{ - int i; - - for( i = 0; i < mapRotations.numRotations; i++ ) - { - if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) - { - trap_Cvar_Set( "g_currentMapRotation", va( "%d", i ) ); - trap_Cvar_Update( &g_currentMapRotation ); - - if( changeMap ) - G_IssueMapChange( i ); - break; - } - } - - if( i == mapRotations.numRotations ) - return qfalse; - else - return qtrue; -} - -/* -=============== -G_StopMapRotation - -Stop the current map rotation -=============== -*/ -void G_StopMapRotation( void ) -{ - trap_Cvar_Set( "g_currentMapRotation", va( "%d", NOT_ROTATING ) ); - trap_Cvar_Update( &g_currentMapRotation ); -} - -/* -=============== -G_MapRotationActive - -Test if any map rotation is currently active -=============== -*/ -qboolean G_MapRotationActive( void ) -{ - return ( g_currentMapRotation.integer != NOT_ROTATING ); -} - -/* -=============== -G_InitMapRotations - -Load and intialise the map rotations -=============== -*/ -void G_InitMapRotations( void ) -{ - const char *fileName = "maprotation.cfg"; - fileHandle_t f; - - //load the file if it exists - if( trap_FS_FOpenFile( fileName, &f, FS_READ ) > 0 ) - { - trap_FS_FCloseFile( f ); - - if( !G_ParseMapRotationFile( fileName ) ) - G_Printf( S_COLOR_RED "ERROR: failed to parse %s file\n", fileName ); - } - else - G_Printf( "%s file not found.\n", fileName ); - - if( g_currentMapRotation.integer == NOT_ROTATING ) - { - if( g_initialMapRotation.string[ 0 ] != 0 ) - { - G_StartMapRotation( g_initialMapRotation.string, qfalse ); - - trap_Cvar_Set( "g_initialMapRotation", "" ); - trap_Cvar_Update( &g_initialMapRotation ); - } - } -} |