diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/g_cmds.c | 44 | ||||
-rw-r--r-- | src/game/g_local.h | 56 | ||||
-rw-r--r-- | src/game/g_main.c | 15 | ||||
-rw-r--r-- | src/game/g_maprotation.c | 271 | ||||
-rw-r--r-- | src/game/g_svcmds.c | 2 |
5 files changed, 364 insertions, 24 deletions
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 137a5f67..6bc84ed9 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1647,6 +1647,46 @@ void Cmd_Test_f( gentity_t *ent ) /* ================= +Cmd_AlienWin_f +================= +*/ +void Cmd_AlienWin_f( gentity_t *ent ) +{ + int i; + gentity_t *e; + + if( !CheatsOk( ent ) ) + return; + + for( i = 1, e = g_entities+i; i < level.num_entities; i++, e++ ) + { + if( e->s.modelindex == BA_H_SPAWN ) + G_Damage( e, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); + } +} + +/* +================= +Cmd_HumanWin_f +================= +*/ +void Cmd_HumanWin_f( gentity_t *ent ) +{ + int i; + gentity_t *e; + + if( !CheatsOk( ent ) ) + return; + + for( i = 1, e = g_entities+i; i < level.num_entities; i++, e++ ) + { + if( e->s.modelindex == BA_A_SPAWN ) + G_Damage( e, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE ); + } +} + +/* +================= ClientCommand ================= */ @@ -1742,6 +1782,10 @@ void ClientCommand( int clientNum ) Cmd_SetViewpos_f( ent ); else if( Q_stricmp( cmd, "test" ) == 0 ) Cmd_Test_f( ent ); + else if( Q_stricmp( cmd, "alienWin" ) == 0 ) + Cmd_AlienWin_f( ent ); + else if( Q_stricmp( cmd, "humanWin" ) == 0 ) + Cmd_HumanWin_f( ent ); else trap_SendServerCommand( clientNum, va( "print \"unknown cmd %s\n\"", cmd ) ); } diff --git a/src/game/g_local.h b/src/game/g_local.h index cba54933..81e6c7cd 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -515,6 +515,8 @@ typedef struct int alienKills; int humanKills; + + pTeam_t lastWin; } level_locals_t; // @@ -780,18 +782,57 @@ void G_WriteSessionData( void ); // // g_maprotation.c // -#define MAX_MAP_ROTATIONS 16 -#define MAX_MAP_ROTATION_MAPS 32 -#define MAX_MAP_COMMANDS 16 +#define MAX_MAP_ROTATIONS 16 +#define MAX_MAP_ROTATION_MAPS 64 +#define MAX_MAP_COMMANDS 16 +#define MAX_MAP_ROTATION_CONDS 4 #define NOT_ROTATING -1 +typedef enum +{ + MCV_ERR, + MCV_RANDOM, + MCV_NUMCLIENTS, + MCV_LASTWIN +} mapConditionVariable_t; + +typedef enum +{ + MCO_LT, + MCO_EQ, + MCO_GT +} mapConditionOperator_t; + +typedef enum +{ + MCT_ERR, + MCT_MAP, + MCT_ROTATION +} mapConditionType_t; + +typedef struct mapRotationCondition_s +{ + char dest[ MAX_QPATH ]; + + qboolean unconditional; + + mapConditionVariable_t lhs; + mapConditionOperator_t op; + + int numClients; + pTeam_t lastWin; +} mapRotationCondition_t; + typedef struct mapRotationEntry_s { - char name[ MAX_QPATH ]; + char name[ MAX_QPATH ]; - char postCmds[ MAX_QPATH ][ MAX_MAP_COMMANDS ]; - int numCmds; + char postCmds[ MAX_QPATH ][ MAX_MAP_COMMANDS ]; + int numCmds; + + mapRotationCondition_t conditions[ MAX_MAP_ROTATION_CONDS ]; + int numConditions; } mapRotationEntry_t; typedef struct mapRotation_s @@ -811,7 +852,7 @@ typedef struct mapRotations_s void G_PrintRotations( void ); qboolean G_AdvanceMapRotation( void ); -qboolean G_StartMapRotation( char *name ); +qboolean G_StartMapRotation( char *name, qboolean changeMap ); void G_StopMapRotation( void ); qboolean G_MapRotationActive( void ); void G_InitMapRotations( void ); @@ -877,6 +918,7 @@ extern vmCvar_t g_alienStage3Threshold; extern vmCvar_t g_debugMapRotation; extern vmCvar_t g_currentMapRotation; extern vmCvar_t g_currentMap; +extern vmCvar_t g_initialMapRotation; void trap_Printf( const char *fmt ); void trap_Error( const char *fmt ); diff --git a/src/game/g_main.c b/src/game/g_main.c index 31b45e09..23677497 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -89,6 +89,7 @@ vmCvar_t g_alienStage3Threshold; vmCvar_t g_debugMapRotation; vmCvar_t g_currentMapRotation; vmCvar_t g_currentMap; +vmCvar_t g_initialMapRotation; static cvarTable_t gameCvarTable[ ] = { @@ -168,6 +169,7 @@ static cvarTable_t gameCvarTable[ ] = { &g_debugMapRotation, "g_debugMapRotation", "0", 0, 0, qfalse }, { &g_currentMapRotation, "g_currentMapRotation", "-1", 0, 0, qfalse }, // -1 = NOT_ROTATING { &g_currentMap, "g_currentMap", "0", 0, 0, qfalse }, + { &g_initialMapRotation, "g_initialMapRotation", "", CVAR_ARCHIVE, 0, qfalse }, { &g_rankings, "g_rankings", "0", 0, 0, qfalse} }; @@ -1307,7 +1309,8 @@ void CheckExitRules( void ) ( level.numAlienSpawns == 0 ) && ( level.numLiveAlienClients == 0 ) ) { - //aliens lose + //humans win + level.lastWin = PTE_HUMANS; trap_SendServerCommand( -1, "print \"Humans win.\n\""); LogExit( "Humans win." ); return; @@ -1316,7 +1319,8 @@ void CheckExitRules( void ) ( level.numHumanSpawns == 0 ) && ( level.numLiveHumanClients == 0 ) ) { - //humans lose + //aliens win + level.lastWin = PTE_ALIENS; trap_SendServerCommand( -1, "print \"Aliens win.\n\""); LogExit( "Aliens win." ); return; @@ -1347,7 +1351,12 @@ void CheckVote( void ) if( level.voteExecuteTime && level.voteExecuteTime < level.time ) { level.voteExecuteTime = 0; - trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) ); + + //SUPAR HAK + if( !Q_stricmp( level.voteString, "vstr nextmap" ) ) + LogExit( "Vote for next map." ); + else + trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) ); } if( !level.voteTime ) diff --git a/src/game/g_maprotation.c b/src/game/g_maprotation.c index e9039346..38bbc325 100644 --- a/src/game/g_maprotation.c +++ b/src/game/g_maprotation.c @@ -76,9 +76,10 @@ Parse a map rotation section */ static qboolean G_ParseMapRotation( mapRotation_t *mr, char **text_p ) { - char *token; - qboolean mnSet = qfalse; - mapRotationEntry_t *mre; + char *token; + qboolean mnSet = qfalse; + mapRotationEntry_t *mre; + mapRotationCondition_t *mrc; // read optional parameters while( 1 ) @@ -108,6 +109,111 @@ static qboolean G_ParseMapRotation( mapRotation_t *mr, char **text_p ) 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 @@ -262,6 +368,13 @@ void G_PrintRotations( void ) } 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" ); @@ -367,6 +480,87 @@ static void G_IssueMapChange( int rotation ) /* =============== +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 @@ -374,16 +568,52 @@ Increment the current map rotation */ qboolean G_AdvanceMapRotation( void ) { - mapRotation_t *mr; - int nextMap; - - if( g_currentMapRotation.integer == NOT_ROTATING ) + 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; - mr = &mapRotations.rotations[ g_currentMapRotation.integer ]; - nextMap = ( G_GetCurrentMap( g_currentMapRotation.integer ) + 1 ) % mr->numMaps; - G_SetCurrentMap( nextMap, g_currentMapRotation.integer ); - G_IssueMapChange( g_currentMapRotation.integer ); + 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; } @@ -395,7 +625,7 @@ G_StartMapRotation Switch to a new map rotation =============== */ -qboolean G_StartMapRotation( char *name ) +qboolean G_StartMapRotation( char *name, qboolean changeMap ) { int i; @@ -404,7 +634,10 @@ qboolean G_StartMapRotation( char *name ) if( !Q_stricmp( mapRotations.rotations[ i ].name, name ) ) { trap_Cvar_Set( "g_currentMapRotation", va( "%d", i ) ); - G_IssueMapChange( i ); + trap_Cvar_Update( &g_currentMapRotation ); + + if( changeMap ) + G_IssueMapChange( i ); break; } } @@ -425,6 +658,7 @@ Stop the current map rotation void G_StopMapRotation( void ) { trap_Cvar_Set( "g_currentMapRotation", va( "%d", NOT_ROTATING ) ); + trap_Cvar_Update( &g_currentMapRotation ); } /* @@ -461,4 +695,15 @@ void G_InitMapRotations( void ) } 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 ); + } + } } diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c index a589734a..b0ec757b 100644 --- a/src/game/g_svcmds.c +++ b/src/game/g_svcmds.c @@ -522,7 +522,7 @@ qboolean ConsoleCommand( void ) { char *rotationName = ConcatArgs( 1 ); - if( !G_StartMapRotation( rotationName ) ) + if( !G_StartMapRotation( rotationName, qfalse ) ) G_Printf( "Can't find map rotation %s\n", rotationName ); return qtrue; |