diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/g_local.h | 6 | ||||
-rw-r--r-- | src/game/g_main.c | 6 | ||||
-rw-r--r-- | src/game/g_maprotation.c | 190 | ||||
-rw-r--r-- | src/game/g_svcmds.c | 4 |
4 files changed, 168 insertions, 38 deletions
diff --git a/src/game/g_local.h b/src/game/g_local.h index bca6708c..933028cd 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -985,12 +985,13 @@ void G_WriteSessionData( void ); // void G_PrintRotations( void ); void G_AdvanceMapRotation( void ); -qboolean G_StartMapRotation( char *name, qboolean changeMap ); +qboolean G_StartMapRotation( char *name, qboolean advance, qboolean putOnStack ); void G_StopMapRotation( void ); qboolean G_MapRotationActive( void ); void G_InitMapRotations( void ); void G_ShutdownMapRotations( void ); qboolean G_MapExists( char *name ); +void G_ClearRotationStack( void ); // // g_ptr.c @@ -1083,7 +1084,8 @@ extern vmCvar_t g_markDeconstruct; extern vmCvar_t g_debugMapRotation; extern vmCvar_t g_currentMapRotation; -extern vmCvar_t g_currentNode; +extern vmCvar_t g_mapRotationNodes; +extern vmCvar_t g_mapRotationStack; extern vmCvar_t g_nextMap; extern vmCvar_t g_initialMapRotation; extern vmCvar_t g_chatTeamPrefix; diff --git a/src/game/g_main.c b/src/game/g_main.c index 2cc268d2..cca612bc 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -112,7 +112,8 @@ vmCvar_t g_markDeconstruct; vmCvar_t g_debugMapRotation; vmCvar_t g_currentMapRotation; -vmCvar_t g_currentNode; +vmCvar_t g_mapRotationNodes; +vmCvar_t g_mapRotationStack; vmCvar_t g_nextMap; vmCvar_t g_initialMapRotation; @@ -252,7 +253,8 @@ static cvarTable_t gameCvarTable[ ] = { &g_debugMapRotation, "g_debugMapRotation", "0", 0, 0, qfalse }, { &g_currentMapRotation, "g_currentMapRotation", "-1", 0, 0, qfalse }, // -1 = NOT_ROTATING - { &g_currentNode, "g_currentNode", "0", 0, 0, qfalse }, + { &g_mapRotationNodes, "g_mapRotationNodes", "", CVAR_ROM, 0, qfalse }, + { &g_mapRotationStack, "g_mapRotationStack", "", CVAR_ROM, 0, qfalse }, { &g_nextMap, "g_nextMap", "", 0 , 0, qtrue }, { &g_initialMapRotation, "g_initialMapRotation", "", CVAR_ARCHIVE, 0, qfalse }, { &g_debugVoices, "g_debugVoices", "0", 0, 0, qfalse }, diff --git a/src/game/g_maprotation.c b/src/game/g_maprotation.c index b1ab34bd..7d905c9b 100644 --- a/src/game/g_maprotation.c +++ b/src/game/g_maprotation.c @@ -74,7 +74,8 @@ typedef struct destination_s typedef enum { NT_DESTINATION, - NT_CONDITION + NT_CONDITION, + NT_RETURN } nodeType_t; typedef struct node_s @@ -305,8 +306,12 @@ static qboolean G_ParseNode( node_t **node, char *token, char **text_p ) condition->target = G_AllocateNode( ); *node = condition->target; - if( !G_ParseNode( node, token, text_p ) ) - return qfalse; + + return G_ParseNode( node, token, text_p ); + } + else if( !Q_stricmp( token, "return" ) ) + { + (*node)->type = NT_RETURN; } else { @@ -500,6 +505,8 @@ static qboolean G_ParseMapRotationFile( const char *fileName ) if( node->type == NT_DESTINATION ) destinationCount++; + else if( node->type == NT_RETURN ) + continue; else while( node->type == NT_CONDITION ) node = node->u.condition.target; @@ -577,11 +584,23 @@ void G_PrintRotations( void ) } G_PrintSpaces( indentation ); - G_Printf( " %s\n", node->u.destination.name ); - if( strlen( node->u.destination.postCommand ) > 0 ) + switch( node->type ) { - G_Printf( " command: %s", node->u.destination.postCommand ); + case NT_DESTINATION: + G_Printf( " %s\n", node->u.destination.name ); + + if( strlen( node->u.destination.postCommand ) > 0 ) + G_Printf( " command: %s", node->u.destination.postCommand ); + + break; + + case NT_RETURN: + G_Printf( " return\n" ); + break; + + default: + break; } } @@ -593,6 +612,91 @@ void G_PrintRotations( void ) /* =============== +G_ClearRotationStack + +Clear the rotation stack +=============== +*/ +void G_ClearRotationStack( void ) +{ + trap_Cvar_Set( "g_mapRotationStack", "" ); + trap_Cvar_Update( &g_mapRotationStack ); +} + +/* +=============== +G_PushRotationStack + +Push the rotation stack +=============== +*/ +static void G_PushRotationStack( int rotation ) +{ + char text[ MAX_CVAR_VALUE_STRING ]; + + Q_strncpyz( text, g_mapRotationStack.string, sizeof( text ) ); + Q_strcat( text, sizeof( text ), va( "%d ", rotation ) ); + + trap_Cvar_Set( "g_mapRotationStack", text ); + trap_Cvar_Update( &g_mapRotationStack ); +} + +/* +=============== +G_PopRotationStack + +Pop the rotation stack +=============== +*/ +static int G_PopRotationStack( void ) +{ + int values[ MAX_MAP_ROTATIONS ]; + int i, count = 0; + char text[ MAX_CVAR_VALUE_STRING ]; + char *text_p, *token; + + Q_strncpyz( text, g_mapRotationStack.string, sizeof( text ) ); + + text_p = text; + + while( count < MAX_MAP_ROTATIONS ) + { + token = COM_Parse( &text_p ); + + if( !*token ) + break; + + if( !Q_stricmp( token, "" ) ) + break; + + values[ count++ ] = atoi( token ); + } + + G_ClearRotationStack( ); + + for( i = 0; i < count - 1; i++ ) + G_PushRotationStack( values[ i ] ); + + if( count > 0 ) + return values[ count - 1 ]; + else + return -1; +} + +/* +=============== +G_RotationNameByIndex + +Returns the name of a rotation by its index +=============== +*/ +static char *G_RotationNameByIndex( int index ) +{ + return mapRotations.rotations[ index ].name; +} + +/* +=============== G_CurrentNodeIndexArray Fill a static array with the current node of each rotation @@ -605,7 +709,7 @@ static int *G_CurrentNodeIndexArray( void ) char text[ MAX_MAP_ROTATIONS * 2 ]; char *text_p, *token; - Q_strncpyz( text, g_currentNode.string, sizeof( text ) ); + Q_strncpyz( text, g_mapRotationNodes.string, sizeof( text ) ); text_p = text; @@ -643,8 +747,8 @@ static void G_SetCurrentNodeByIndex( int currentNode, int rotation ) for( i = 0; i < mapRotations.numRotations; i++ ) Q_strcat( text, sizeof( text ), va( "%d ", p[ i ] ) ); - trap_Cvar_Set( "g_currentNode", text ); - trap_Cvar_Update( &g_currentNode ); + trap_Cvar_Set( "g_mapRotationNodes", text ); + trap_Cvar_Update( &g_mapRotationNodes ); } /* @@ -714,7 +818,7 @@ static void G_GotoDestination( int currentRotation, char *name ) G_Printf( "G_GotoDestination( %s )\n", name ); // Search the rotation names... - if( G_StartMapRotation( name, qtrue ) ) + if( G_StartMapRotation( name, qtrue, qtrue ) ) return; // ...then try maps in the current rotation @@ -808,7 +912,7 @@ void G_AdvanceMapRotation( void ) { node_t *node; condition_t *condition; - int rotation, nodeIndex; + int rotation, returnRotation, nodeIndex; if( ( rotation = g_currentMapRotation.integer ) == NOT_ROTATING ) return; @@ -816,24 +920,43 @@ void G_AdvanceMapRotation( void ) nodeIndex = G_CurrentNodeIndex( rotation ); node = G_NodeByIndex( nodeIndex, rotation ); - while( node->type == NT_CONDITION ) + while( 1 ) { - condition = &node->u.condition; - - if( G_EvaluateMapCondition( &condition ) ) - { - node = condition->target; - } - else + switch( node->type ) { - nodeIndex = G_NodeIndexAfter( nodeIndex, rotation ); - node = G_NodeByIndex( nodeIndex, rotation ); + case NT_CONDITION: + condition = &node->u.condition; + + if( G_EvaluateMapCondition( &condition ) ) + { + node = condition->target; + continue; + } + break; + + case NT_RETURN: + returnRotation = G_PopRotationStack( ); + if( returnRotation >= 0 ) + { + G_StartMapRotation( G_RotationNameByIndex( returnRotation ), + qtrue, qfalse ); + G_SetCurrentNodeByIndex( + G_NodeIndexAfter( nodeIndex, rotation ), rotation ); + return; + } + break; + + case NT_DESTINATION: + G_GotoDestination( rotation, node->u.destination.name ); + G_SetCurrentNodeByIndex( + G_NodeIndexAfter( nodeIndex, rotation ), rotation ); + return; } - } - G_GotoDestination( rotation, node->u.destination.name ); - G_SetCurrentNodeByIndex( - G_NodeIndexAfter( nodeIndex, rotation ), rotation ); + // Move on to the next node + nodeIndex = G_NodeIndexAfter( nodeIndex, rotation ); + node = G_NodeByIndex( nodeIndex, rotation ); + } } /* @@ -843,23 +966,24 @@ G_StartMapRotation Switch to a new map rotation =============== */ -qboolean G_StartMapRotation( char *name, qboolean changeMap ) +qboolean G_StartMapRotation( char *name, qboolean advance, qboolean putOnStack ) { int i; + int currentRotation = g_currentMapRotation.integer; for( i = 0; i < mapRotations.numRotations; i++ ) { if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) { + if( putOnStack && currentRotation >= 0 ) + G_PushRotationStack( currentRotation ); + trap_Cvar_Set( "g_currentMapRotation", va( "%d", i ) ); trap_Cvar_Update( &g_currentMapRotation ); - if( changeMap ) - { - G_IssueMapChange( 0, i ); - G_SetCurrentNodeByIndex( G_NodeIndexAfter( - G_CurrentNodeIndex( i ), i ), i ); - } + if( advance ) + G_AdvanceMapRotation( ); + break; } } @@ -919,7 +1043,7 @@ void G_InitMapRotations( void ) { if( g_initialMapRotation.string[ 0 ] != 0 ) { - G_StartMapRotation( g_initialMapRotation.string, qfalse ); + G_StartMapRotation( g_initialMapRotation.string, qfalse, qtrue ); trap_Cvar_Set( "g_initialMapRotation", "" ); trap_Cvar_Update( &g_initialMapRotation ); diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c index 72523331..acef3b18 100644 --- a/src/game/g_svcmds.c +++ b/src/game/g_svcmds.c @@ -344,8 +344,10 @@ static void Svcmd_MapRotation_f( void ) return; } + G_ClearRotationStack( ); + trap_Argv( 1, rotationName, sizeof( rotationName ) ); - if( !G_StartMapRotation( rotationName, qfalse ) ) + if( !G_StartMapRotation( rotationName, qfalse, qtrue ) ) G_Printf( "maprotation: invalid map rotation \"%s\"\n", rotationName ); } |