diff options
-rw-r--r-- | misc/server.cfg | 2 | ||||
-rw-r--r-- | src/cgame/cg_servercmds.c | 18 | ||||
-rw-r--r-- | src/game/bg_public.h | 2 | ||||
-rw-r--r-- | src/game/g_buildable.c | 48 | ||||
-rw-r--r-- | src/game/g_cmds.c | 5 | ||||
-rw-r--r-- | src/game/g_local.h | 6 | ||||
-rw-r--r-- | src/game/g_main.c | 35 | ||||
-rw-r--r-- | src/game/g_svcmds.c | 14 |
8 files changed, 130 insertions, 0 deletions
diff --git a/misc/server.cfg b/misc/server.cfg index 184e9ea..3897452 100644 --- a/misc/server.cfg +++ b/misc/server.cfg @@ -18,6 +18,8 @@ set sv_allowdownload 0 //greater than 24 is not recommended from a gameplay point of view set sv_maxclients 24 +//after 25 minutes, refineries/collonies are disallowed +set g_weakSuddenDeathTime 25 //after 50 minutes, all build points are removed set g_suddenDeathTime 50 //after 60 minutes, the game will end as a draw diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index a5de53d..084e3f1 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -648,6 +648,24 @@ void CG_Menu( int menu, int arg ) + case MN_B_WSD_INBASE: + longMsg = "Neither team has prevailed after a certain time and the " + "game has entered Weak Sudden Death. During Sudden Death " + "building creep colonies or refineries is not allowed, " + "and neither is allowed building near the Overmind or the Reactor."; + shortMsg = "^5Cannot build near the Reactor/Overmind during Weak Sudden Death"; + type = DT_BUILD; + break; + + case MN_B_WSD_REFSCOLS: + longMsg = "Neither team has prevailed after a certain time and the " + "game has entered Weak Sudden Death. During Weak Sudden Death " + "building creep colonies or refineries is not allowed, " + "and neither is allowed building near the Overmind or the Reactor."; + shortMsg = "^5Cannot build refineries/colonies during Weak Sudden Death"; + type = DT_BUILD; + break; + case MN_B_SUDDENDEATH: longMsg = "Neither team has prevailed after a certain time and the " "game has entered Sudden Death. During Sudden Death " diff --git a/src/game/bg_public.h b/src/game/bg_public.h index f8a2f9d..b7df340 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -606,6 +606,8 @@ typedef enum MN_B_NORMAL, MN_B_CANNOT, MN_B_LASTSPAWN, + MN_B_WSD_INBASE, + MN_B_WSD_REFSCOLS, MN_B_SUDDENDEATH, MN_B_REVOKED, MN_B_SURRENDER, diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 65e7077..841038f 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -3894,6 +3894,46 @@ static itemBuildError_t G_SufficientBPAvailable( buildable_t buildable, return IBE_NONE; } + if( G_TimeTilWeakSuddenDeath( ) <= 0 ) + { + // No refineries/colonies after WSD + if( ( buildable == BA_H_REFINERY ) || ( buildable == BA_A_CREEPCOLONY ) ) + return IBE_WSD_REFSCOLS; + + // No building near OM/RC after WSD, unless it's a replacement + if( buildable != core ) + { + vec3_t temp_v; + + // Iterate through entities + distance = 0; + for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ ) + { + if( ent->s.eType != ET_BUILDABLE ) + continue; + + // If entity is a power item calculate the distance to it + if( ent->s.modelindex == core ) + { + if( ent->spawned && ent->health > 0 ) + { + VectorSubtract( origin, ent->s.origin, temp_v ); + distance = VectorLength( temp_v ); + } + break; + } + } + + if( distance > 0 ) // RC/OM found and it's alive + { + if( ( team == TEAM_ALIENS ) && ( distance <= CREEP_BASESIZE ) ) + return IBE_WSD_INBASE; + if( ( team == TEAM_HUMANS ) && ( distance <= REACTOR_BASESIZE ) ) + return IBE_WSD_INBASE; + } + } + } + // Simple non-marking case if( !g_markDeconstruct.integer ) { @@ -4776,6 +4816,14 @@ qboolean G_BuildIfValid( gentity_t *ent, buildable_t buildable ) G_TriggerMenu( ent->client->ps.clientNum, MN_B_GTHRBLOCKED ); return qfalse; + case IBE_WSD_INBASE: + G_TriggerMenu( ent->client->ps.clientNum, MN_B_WSD_INBASE ); + return qfalse; + + case IBE_WSD_REFSCOLS: + G_TriggerMenu( ent->client->ps.clientNum, MN_B_WSD_REFSCOLS ); + return qfalse; + default: break; } diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index fa6b6c9..39a87b9 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -2742,6 +2742,7 @@ void Cmd_Build_f( gentity_t *ent ) case IBE_NOPOWERHERE: case IBE_BLOCKEDBYENEMY: case IBE_GTHRBLOCKED: + case IBE_WSD_INBASE: err = MN_NONE; break; @@ -2778,6 +2779,10 @@ void Cmd_Build_f( gentity_t *ent ) err = MN_B_LASTSPAWN; break; + case IBE_WSD_REFSCOLS: + err = MN_B_WSD_REFSCOLS; + break; + default: err = -1; // stop uninitialised warning break; diff --git a/src/game/g_local.h b/src/game/g_local.h index 522bdb7..4e6cec1 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -666,6 +666,8 @@ typedef struct team_t lastWin; + int weakSuddenDeathBeginTime; + timeWarning_t weakSuddenDeathWarning; int suddenDeathBeginTime; timeWarning_t suddenDeathWarning; timeWarning_t timelimitWarning; @@ -812,6 +814,9 @@ typedef enum IBE_LASTSPAWN, IBE_BLOCKEDBYENEMY, IBE_GTHRBLOCKED, + IBE_WSD_INBASE, + IBE_WSD_REFSCOLS, + IBE_MAXERRORS } itemBuildError_t; @@ -1159,6 +1164,7 @@ extern vmCvar_t g_minNameChangePeriod; extern vmCvar_t g_maxNameChanges; extern vmCvar_t g_timelimit; extern vmCvar_t g_suddenDeathTime; +extern vmCvar_t g_weakSuddenDeathTime; extern vmCvar_t g_armageddonTimeStep; extern vmCvar_t g_armageddonInitialTimeStep; extern vmCvar_t g_armageddonDefensiveKillPercent; diff --git a/src/game/g_main.c b/src/game/g_main.c index 965fdc0..481e1d1 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -51,6 +51,7 @@ gclient_t g_clients[ MAX_CLIENTS ]; vmCvar_t g_timelimit; vmCvar_t g_suddenDeathTime; +vmCvar_t g_weakSuddenDeathTime; vmCvar_t g_armageddonTimeStep; vmCvar_t g_armageddonInitialTimeStep; vmCvar_t g_armageddonDefensiveKillPercent; @@ -225,6 +226,7 @@ static cvarTable_t gameCvarTable[ ] = { &g_humanMedkitRange, "g_humanMedkitRange", "200", CVAR_ARCHIVE, 0, qfalse }, { &g_humanMedkitWidth, "g_humanMedkitWidth", "20", CVAR_ARCHIVE, 0, qfalse }, { &g_suddenDeathTime, "g_suddenDeathTime", "40", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, + { &g_weakSuddenDeathTime, "g_weakSuddenDeathTime", "25", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, { &g_armageddonTimeStep, "g_armageddonTimeStep", "5", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, { &g_armageddonInitialTimeStep, "g_armageddonInitialTimeStep", "10", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, { &g_armageddonDefensiveKillPercent, "g_armageddonDefensiveKillPercent", "10", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue }, @@ -726,6 +728,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) if( g_ForceRandomTeams.integer == 2) trap_Cvar_Set( "g_ForceRandomTeams", 0 ); level.suddenDeathBeginTime = g_suddenDeathTime.integer * 60000; + level.weakSuddenDeathBeginTime = g_weakSuddenDeathTime.integer * 60000; level.nextArmageddonKillTime = (g_suddenDeathTime.integer+g_armageddonInitialTimeStep.integer) * 60000; level.nextCommandTime = g_TimerPeriod.integer; G_Printf( "-----------------------------------\n" ); @@ -1168,6 +1171,20 @@ void G_CountSpawns( void ) /* ============ +G_TimeTilWeakSuddenDeath +============ +*/ +#define WEAKSUDDENDEATHWARNING 60000 +int G_TimeTilWeakSuddenDeath( void ) +{ + if( ( !g_weakSuddenDeathTime.integer && level.weakSuddenDeathBeginTime == 0 ) || + ( level.weakSuddenDeathBeginTime < 0 ) ) + return WEAKSUDDENDEATHWARNING + 1; // Always some time away + return ( ( level.weakSuddenDeathBeginTime ) - ( level.time - level.startTime ) ); +} + +/* +============ G_TimeTilSuddenDeath ============ */ @@ -1259,6 +1276,24 @@ void G_CalculateBuildPoints( void ) g_humanBuildQueueTime.integer ); } + // Weak Sudden Death checks + if( G_TimeTilWeakSuddenDeath( ) <= 0 && level.weakSuddenDeathWarning < TW_PASSED ) + { + G_LogPrintf( "^5Beginning Weak Sudden Death\n" ); + trap_SendServerCommand( -1, "cp \"^5Weak Sudden Death!\"" ); + trap_SendServerCommand( -1, "print \"^5Beginning Weak Sudden Death.\n\"" ); + level.weakSuddenDeathWarning = TW_PASSED; + } + else if( G_TimeTilWeakSuddenDeath( ) <= WEAKSUDDENDEATHWARNING && + level.weakSuddenDeathWarning < TW_IMMINENT ) + { + trap_SendServerCommand( -1, va( "cp \"Weak Sudden Death in %d seconds!\"", + (int)( G_TimeTilSuddenDeath( ) / 1000 ) ) ); + trap_SendServerCommand( -1, va( "print \"Weak Sudden Death will begin in %d seconds.\n\"", + (int)( G_TimeTilSuddenDeath( ) / 1000 ) ) ); + level.weakSuddenDeathWarning = TW_IMMINENT; + } + // Sudden Death checks if( G_TimeTilSuddenDeath( ) <= 0 && level.suddenDeathWarning < TW_PASSED ) { diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c index 915709d..775b4ed 100644 --- a/src/game/g_svcmds.c +++ b/src/game/g_svcmds.c @@ -541,6 +541,19 @@ static void Svcmd_MapLogWrapper( void ) Cmd_MapLog_f( NULL ); } +static void Svcmd_WeakSuddenDeath_f( void ) +{ + char secs[ 5 ]; + int offset; + trap_Argv( 1, secs, sizeof( secs ) ); + offset = atoi( secs ); + + level.weakSuddenDeathBeginTime = level.time - level.startTime + offset * 1000; + trap_SendServerCommand( -1, + va( "cp \"Weak Sudden Death will begin in %d second%s\"", + offset, offset == 1 ? "" : "s" ) ); +} + static void Svcmd_SuddenDeath_f( void ) { char secs[ 5 ]; @@ -646,6 +659,7 @@ struct svcmd { "say_team", qtrue, Svcmd_TeamMessage_f }, { "status", qfalse, Svcmd_Status_f }, { "stopMapRotation", qfalse, G_StopMapRotation }, + { "weaksuddendeath", qfalse, Svcmd_WeakSuddenDeath_f }, { "suddendeath", qfalse, Svcmd_SuddenDeath_f } }; |