From d15f34b027d08e43713c98d2a27756df27164c34 Mon Sep 17 00:00:00 2001 From: terencehill Date: Wed, 2 Jan 2013 09:38:36 +0100 Subject: [PATCH] Add Arena to the mutator system, making use of round_handler. Also add support for g_arena_round_timelimit --- gamemodes.cfg | 1 + qcsrc/server/arena.qc | 217 +-------------------- qcsrc/server/autocvars.qh | 1 + qcsrc/server/cl_client.qc | 50 +---- qcsrc/server/cl_player.qc | 6 - qcsrc/server/cl_weapons.qc | 5 +- qcsrc/server/g_damage.qc | 3 - qcsrc/server/g_hook.qc | 12 +- qcsrc/server/mutators/gamemode_arena.qc | 246 ++++++++++++++++++++++++ qcsrc/server/mutators/gamemode_arena.qh | 15 ++ qcsrc/server/mutators/mutators.qh | 1 + qcsrc/server/progs.src | 2 + qcsrc/server/scores.qc | 1 - qcsrc/server/sv_main.qc | 3 - qcsrc/server/teamplay.qc | 5 +- 15 files changed, 283 insertions(+), 285 deletions(-) create mode 100644 qcsrc/server/mutators/gamemode_arena.qc create mode 100644 qcsrc/server/mutators/gamemode_arena.qh diff --git a/gamemodes.cfg b/gamemodes.cfg index 596477cca5..752787536e 100644 --- a/gamemodes.cfg +++ b/gamemodes.cfg @@ -149,6 +149,7 @@ set g_ft_weapon_stay 0 set g_arena 0 "Arena: many one-on-one rounds are played to find the winner" set g_arena_maxspawned 2 "maximum number of players to spawn at once (the rest is spectating, waiting for their turn)" set g_arena_roundbased 1 "if disabled, the next player will spawn as soon as someone dies" +set g_arena_round_timelimit 180 set g_arena_warmup 5 "time, newly spawned players have to prepare themselves in round based matches" diff --git a/qcsrc/server/arena.qc b/qcsrc/server/arena.qc index d31d2f4e79..8f744f839e 100644 --- a/qcsrc/server/arena.qc +++ b/qcsrc/server/arena.qc @@ -1,23 +1,7 @@ -float maxspawned; -float numspawned; -float arena_roundbased; -.float spawned; -.entity spawnqueue_next; -.entity spawnqueue_prev; -.float spawnqueue_in; -entity spawnqueue_first; -entity spawnqueue_last; -entity champion; -float warmup; - -void PutObserverInServer(); void PutClientInServer(); -float next_round; - /** * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map. - * Sets the 'warmup' global variable. */ void reset_map(float dorespawn) { @@ -27,13 +11,7 @@ void reset_map(float dorespawn) if(time <= game_starttime && round_handler_IsActive()) round_handler_Reset(game_starttime + 1); - if(g_arena) - { - warmup = max(time, game_starttime); - if(autocvar_g_arena_warmup > 0) - warmup += autocvar_g_arena_warmup; - } - else if(g_race || g_cts) + if(g_race || g_cts) race_ReadyRestart(); else MUTATOR_CALLHOOK(reset_map_global); @@ -74,14 +52,6 @@ void reset_map(float dorespawn) FOR_EACH_CLIENT(self) { if(self.flags & FL_CLIENT) // reset all players { - if(g_arena) - { - if(self.spawned) - PutClientInServer(); - else - PutObserverInServer(); - } - else { /* only reset players if a restart countdown is active @@ -111,191 +81,6 @@ void reset_map(float dorespawn) if(g_keyhunt) kh_Controller_SetThink_NoMsg(autocvar_g_balance_keyhunt_delay_round+(game_starttime - time), kh_StartRound); - if(g_arena) - if(champion && champion.classname == "player" && player_count > 1) - UpdateFrags(champion, +1); - self = oldself; } -void Spawnqueue_Insert(entity e) -{ - if(e.spawnqueue_in) - return; - dprint(strcat("Into queue: ", e.netname, "\n")); - e.spawnqueue_in = TRUE; - e.spawnqueue_prev = spawnqueue_last; - e.spawnqueue_next = world; - if(spawnqueue_last) - spawnqueue_last.spawnqueue_next = e; - spawnqueue_last = e; - if(!spawnqueue_first) - spawnqueue_first = e; -} - -void Spawnqueue_Remove(entity e) -{ - if(!e.spawnqueue_in) - return; - dprint(strcat("Out of queue: ", e.netname, "\n")); - e.spawnqueue_in = FALSE; - if(e == spawnqueue_first) - spawnqueue_first = e.spawnqueue_next; - if(e == spawnqueue_last) - spawnqueue_last = e.spawnqueue_prev; - if(e.spawnqueue_prev) - e.spawnqueue_prev.spawnqueue_next = e.spawnqueue_next; - if(e.spawnqueue_next) - e.spawnqueue_next.spawnqueue_prev = e.spawnqueue_prev; - e.spawnqueue_next = world; - e.spawnqueue_prev = world; -} - -void Spawnqueue_Unmark(entity e) -{ - if(!e.spawned) - return; - e.spawned = FALSE; - numspawned = numspawned - 1; -} - -void Spawnqueue_Mark(entity e) -{ - if(e.spawned) - return; - e.spawned = TRUE; - numspawned = numspawned + 1; -} - -/** - * If roundbased arena game mode is active, it centerprints the texts for the - * player when player is waiting for the countdown to finish. - * Blocks the players movement while countdown is active. - * Unblocks the player once the countdown is over. - * - * Called in StartFrame() - */ -float roundStartTime_prev; // prevent networkspam -void Arena_Warmup() -{ - float f; - entity e; - - if(gameover) - { - if(champion) - { - FOR_EACH_REALCLIENT(e) - centerprint(e, strcat("The Champion is ", champion.netname)); - champion = world; - } - return; - } - if(time < game_starttime) - return; - - f = ceil(warmup - time); - - if(time < warmup && !inWarmupStage) - { - if(champion) - { - FOR_EACH_REALCLIENT(e) - centerprint(e, strcat("The Champion is ", champion.netname)); - } - - if(f != roundStartTime_prev) { - roundStartTime_prev = f; - - if(f == 5) - Announce("prepareforbattle"); - else if(f == 3) - Announce("3"); - else if(f == 2) - Announce("2"); - else if(f == 1) - Announce("1"); - - FOR_EACH_REALCLIENT(e) - Send_CSQC_Centerprint_Generic(e, CPID_ROUND_STARTING, "Round will start in %d", 1, f); - } - - FOR_EACH_CLIENT(e) - { - if(e.spawned && e.classname == "player") - e.player_blocked = 1; - } - } - else if(f > -1 && f != roundStartTime_prev && !inWarmupStage) - { - roundStartTime_prev = f; - - Announce("begin"); - FOR_EACH_REALCLIENT(e) - Send_CSQC_Centerprint_Generic(e, CPID_ROUND_STARTING, "^1Begin!", 1, 0); - - FOR_EACH_CLIENT(e) - { - if(e.player_blocked) - e.player_blocked = 0; - } - } - - // clear champion to avoid centerprinting again the champion msg - if (champion) - champion = world; -} - -/** - * This function finds out whether an arena round is over 1 player is left. - * It determines the last player who's still alive and saves it's entity reference - * in the global variable 'champion'. Then the new enemy/enemies are put into the server. - * - * Gets called in StartFrame() - */ -void Spawnqueue_Check() -{ - if(time < warmup + 1 || inWarmupStage || intermission_running) - return; - - //extend next_round if it isn't set yet and only 1 player is spawned - if(!next_round) - if(numspawned < 2) - next_round = time + 3; - - if(!arena_roundbased || (next_round && next_round < time && player_count > 1)) - { - next_round = 0; - - if(arena_roundbased) - { - champion = find(world, classname, "player"); - while(champion && champion.deadflag) - champion = find(champion, classname, "player"); - reset_map(TRUE); - } - - while(numspawned < maxspawned && spawnqueue_first) - { - self = spawnqueue_first; - - bprint ("^4", self.netname, "^4 is the next challenger\n"); - - Spawnqueue_Remove(self); - Spawnqueue_Mark(self); - - self.classname = "player"; - PutClientInServer(); - } - } -} - -void Arena_Main() -{ - if(!g_arena) - return; - if(arena_roundbased) - Arena_Warmup(); - Spawnqueue_Check(); -} - diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 28387db04c..8130b78cb5 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -75,6 +75,7 @@ float autocvar_g_arena_maxspawned; float autocvar_g_arena_point_leadlimit; float autocvar_g_arena_point_limit; float autocvar_g_arena_roundbased; +float autocvar_g_arena_round_timelimit; float autocvar_g_arena_warmup; float autocvar_g_assault; float autocvar_g_balance_armor_blockpercent; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index fda52868a8..da4ed37a9b 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -401,19 +401,7 @@ void PutObserverInServer (void) WriteEntity(MSG_ONE, self); } - if(g_arena) - { - if(self.version_mismatch) - { - Spawnqueue_Unmark(self); - Spawnqueue_Remove(self); - } - else - { - Spawnqueue_Insert(self); - } - } - else if(g_lms) + if(g_lms) { // Only if the player cannot play at all if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666) @@ -654,8 +642,6 @@ void PutClientInServer (void) if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0) self.classname = "observer"; } - else if(g_arena && !self.spawned) - self.classname = "observer"; MUTATOR_CALLHOOK(PutClientInServer); @@ -822,12 +808,6 @@ void PutClientInServer (void) self.lastteleporttime = time; // prevent insane speeds due to changing origin self.hud = HUD_NORMAL; - if(g_arena) - { - Spawnqueue_Remove(self); - Spawnqueue_Mark(self); - } - self.event_damage = PlayerDamage; self.bot_attack = TRUE; @@ -1240,19 +1220,12 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 void ClientKill (void) { - if (gameover) - return; + if(gameover) return; + if(g_ca && player_count == 1) return; + if(self.player_blocked) return; + if(self.freezetag_frozen) return; - if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either - { - // do nothing - } - else if(self.freezetag_frozen) - { - // do nothing - } - else - ClientKill_TeamChange(0); + ClientKill_TeamChange(0); } void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed @@ -1646,12 +1619,6 @@ void ClientDisconnect (void) bot_relinkplayerlist(); - if(g_arena) - { - Spawnqueue_Unmark(self); - Spawnqueue_Remove(self); - } - accuracy_free(self); ClientData_Detach(); PlayerScore_Detach(self); @@ -2547,10 +2514,7 @@ void PlayerPreThink (void) self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam; self.stat_leadlimit = autocvar_leadlimit; - if(g_arena) - self.stat_respawn_time = 0; - else - self.stat_respawn_time = self.respawn_time; + self.stat_respawn_time = self.respawn_time; if(frametime) { diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 23294ed4ed..9300fe3e3f 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -439,9 +439,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht float valid_damage_for_weaponstats; float excess; - if((g_arena && numspawned < 2) && !inWarmupStage) - return; - dh = max(self.health, 0); da = max(self.armorvalue, 0); @@ -709,9 +706,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(defer_ClientKill_Now_TeamChange) ClientKill_Now_TeamChange(); // can turn player into spectator - if(g_arena) - Spawnqueue_Unmark(self); - // player could have been miraculously resuscitated ;) // e.g. players in freezetag get frozen, they don't really die if(self.health >= 1 || self.classname != "player") diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 81102d62da..a131576a86 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -372,12 +372,15 @@ void W_WeaponFrame() if (frametime) self.weapon_frametime = frametime; - if(((g_arena && arena_roundbased) && time < warmup) || ((time < game_starttime) && !autocvar_sv_ready_restart_after_countdown)) + if(time < game_starttime && !autocvar_sv_ready_restart_after_countdown) return; if(round_handler_IsActive() && !round_handler_IsRoundStarted()) return; + if(self.player_blocked) + return; + if(self.freezetag_frozen == 1) return; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 0528c7dbcf..b2da5df1a5 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -131,9 +131,6 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) PlayerScore_Add(targ, SP_DEATHS, 1); - if(g_arena && arena_roundbased) - return; - if(targ != attacker) // not for suicides if(g_weaponarena_random) { diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index 8867d0725b..0897c1c3a3 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -299,14 +299,10 @@ void FireGrapplingHook (void) float s; vector vs; - if((arena_roundbased && time < warmup) || (time < game_starttime)) - return; - - if(self.freezetag_frozen) - return; - - if(self.vehicle) - return; + if(time < game_starttime) return; + if(self.player_blocked) return; + if(self.freezetag_frozen) return; + if(self.vehicle) return; makevectors(self.v_angle); diff --git a/qcsrc/server/mutators/gamemode_arena.qc b/qcsrc/server/mutators/gamemode_arena.qc new file mode 100644 index 0000000000..86f449a736 --- /dev/null +++ b/qcsrc/server/mutators/gamemode_arena.qc @@ -0,0 +1,246 @@ +void Spawnqueue_Insert(entity e) +{ + if(e.spawnqueue_in) + return; + dprint(strcat("Into queue: ", e.netname, "\n")); + e.spawnqueue_in = TRUE; + e.spawnqueue_prev = spawnqueue_last; + e.spawnqueue_next = world; + if(spawnqueue_last) + spawnqueue_last.spawnqueue_next = e; + spawnqueue_last = e; + if(!spawnqueue_first) + spawnqueue_first = e; +} + +void Spawnqueue_Remove(entity e) +{ + if(!e.spawnqueue_in) + return; + dprint(strcat("Out of queue: ", e.netname, "\n")); + e.spawnqueue_in = FALSE; + if(e == spawnqueue_first) + spawnqueue_first = e.spawnqueue_next; + if(e == spawnqueue_last) + spawnqueue_last = e.spawnqueue_prev; + if(e.spawnqueue_prev) + e.spawnqueue_prev.spawnqueue_next = e.spawnqueue_next; + if(e.spawnqueue_next) + e.spawnqueue_next.spawnqueue_prev = e.spawnqueue_prev; + e.spawnqueue_next = world; + e.spawnqueue_prev = world; +} + +void Spawnqueue_Unmark(entity e) +{ + if(!e.spawned) + return; + e.spawned = FALSE; + numspawned = numspawned - 1; +} + +void Spawnqueue_Mark(entity e) +{ + if(e.spawned) + return; + e.spawned = TRUE; + numspawned = numspawned + 1; +} + +float Arena_CheckWinner() +{ + entity e; + + // FIXME do this only once (on round start) + FOR_EACH_PLAYER(e) + e.player_blocked = 0; + + if(round_handler_GetTimeLeft() <= 0) + { + FOR_EACH_REALCLIENT(e) + centerprint(e, "Round over, there's no winner"); + bprint("Round over, there's no winner\n"); + return 1; + } + + if(numspawned > 1) + return 0; + + entity champion; + champion = world; + FOR_EACH_CLIENT(e) + { + if(e.spawned && e.classname == "player") + champion = e; + } + + if(champion) + { + FOR_EACH_REALCLIENT(e) + centerprint(e, strcat("The Champion is ", champion.netname)); + bprint("The Champion is ", champion.netname, "\n"); + UpdateFrags(champion, +1); + } + else + { + FOR_EACH_REALCLIENT(e) + centerprint(e, "Round tied"); + bprint("Round tied\n"); + } + return 1; +} +void Arena_AddChallengers() +{ + entity e; + e = self; + while(numspawned < maxspawned && spawnqueue_first) + { + self = spawnqueue_first; + + bprint ("^4", self.netname, "^4 is the next challenger\n"); + + Spawnqueue_Remove(self); + Spawnqueue_Mark(self); + + self.classname = "player"; + PutClientInServer(); + } + self = e; +} + +float Arena_CheckPlayers() +{ + Arena_AddChallengers(); + + if(numspawned >= 2) + return 1; + + return 0; +} + +MUTATOR_HOOKFUNCTION(arena_ClientDisconnect) +{ + Spawnqueue_Unmark(self); + Spawnqueue_Remove(self); + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_reset_map_players) +{ + FOR_EACH_CLIENT(self) + { + if(self.spawned) + { + PutClientInServer(); + self.player_blocked = 1; + } + else + PutObserverInServer(); + } + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_MakePlayerObserver) +{ + self.frags = FRAGS_PLAYER; + if(self.version_mismatch) + { + Spawnqueue_Unmark(self); + Spawnqueue_Remove(self); + } + else + Spawnqueue_Insert(self); + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_PutClientInServer) +{ + if(!self.spawned) + self.classname = "observer"; + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_PlayerSpawn) +{ + Spawnqueue_Remove(self); + Spawnqueue_Mark(self); + if(arena_roundbased) + self.player_blocked = 1; + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_PlayerPreThink) +{ + self.stat_respawn_time = 0; + + // put dead players in the spawn queue + if(arena_roundbased) + if(self.deadflag && time - self.death_time >= 1.5) + PutClientInServer(); + + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_ForbidPlayerScore_Clear) +{ + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_GiveFragsForKill) +{ + if(arena_roundbased) + frag_score = 0; + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_PlayerDies) +{ + Spawnqueue_Unmark(self); + return 1; +} + +MUTATOR_HOOKFUNCTION(arena_SV_StartFrame) +{ + if(arena_roundbased) return 1; + if(time <= game_starttime) return 1; + if(gameover) return 1; + + Arena_AddChallengers(); + return 1; +} + +void arena_Initialize() +{ + maxspawned = max(2, autocvar_g_arena_maxspawned); + arena_roundbased = autocvar_g_arena_roundbased; + if(arena_roundbased) + round_handler_Spawn(Arena_CheckPlayers, Arena_CheckWinner, 5, autocvar_g_arena_warmup, autocvar_g_arena_round_timelimit); +} + +MUTATOR_DEFINITION(gamemode_arena) +{ + MUTATOR_HOOK(ClientDisconnect, arena_ClientDisconnect, CBC_ORDER_ANY); + MUTATOR_HOOK(reset_map_players, arena_reset_map_players, CBC_ORDER_ANY); + MUTATOR_HOOK(MakePlayerObserver, arena_MakePlayerObserver, CBC_ORDER_ANY); + MUTATOR_HOOK(PutClientInServer, arena_PutClientInServer, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerSpawn, arena_PlayerSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerPreThink, arena_PlayerPreThink, CBC_ORDER_ANY); + MUTATOR_HOOK(ForbidPlayerScore_Clear, arena_ForbidPlayerScore_Clear, CBC_ORDER_ANY); + MUTATOR_HOOK(GiveFragsForKill, arena_GiveFragsForKill, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerDies, arena_PlayerDies, CBC_ORDER_ANY); + MUTATOR_HOOK(SV_StartFrame, arena_SV_StartFrame, CBC_ORDER_ANY); + + MUTATOR_ONADD + { + if(time > 1) // game loads at time 1 + error("This is a game type and it cannot be added at runtime."); + arena_Initialize(); + } + + MUTATOR_ONREMOVE + { + error("This is a game type and it cannot be removed at runtime."); + } + + return 0; +} diff --git a/qcsrc/server/mutators/gamemode_arena.qh b/qcsrc/server/mutators/gamemode_arena.qh new file mode 100644 index 0000000000..2c455dbdd8 --- /dev/null +++ b/qcsrc/server/mutators/gamemode_arena.qh @@ -0,0 +1,15 @@ +float maxspawned; +float numspawned; +float arena_roundbased; +float arena_roundbased_state; +.float spawned; +.entity spawnqueue_next; +.entity spawnqueue_prev; +.float spawnqueue_in; +entity spawnqueue_first; +entity spawnqueue_last; + +void Spawnqueue_Insert(entity e); +void Spawnqueue_Remove(entity e); +void Spawnqueue_Unmark(entity e); +void Spawnqueue_Mark(entity e); diff --git a/qcsrc/server/mutators/mutators.qh b/qcsrc/server/mutators/mutators.qh index df479d9f93..3aa4d222e1 100644 --- a/qcsrc/server/mutators/mutators.qh +++ b/qcsrc/server/mutators/mutators.qh @@ -1,3 +1,4 @@ +MUTATOR_DECLARATION(gamemode_arena); MUTATOR_DECLARATION(gamemode_ca); MUTATOR_DECLARATION(gamemode_keyhunt); MUTATOR_DECLARATION(gamemode_freezetag); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index b077f2e4d4..624d5cd67d 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -29,6 +29,7 @@ defs.qh // Should rename this, it has fields and globals mutators/base.qh mutators/mutators.qh +mutators/gamemode_arena.qh mutators/gamemode_ca.qh mutators/gamemode_ctf.qh mutators/gamemode_keyhunt.qh // TODO fix this @@ -212,6 +213,7 @@ round_handler.qc ../common/explosion_equation.qc mutators/base.qc +mutators/gamemode_arena.qc mutators/gamemode_ca.qc mutators/gamemode_ctf.qc mutators/gamemode_freezetag.qc diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index 8f90cec59a..9895c5b042 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -254,7 +254,6 @@ void PlayerScore_Clear(entity player) if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return; if(g_lms) return; - if(g_arena) return; if(g_cts) return; // in CTS, you don't lose score by observing if(g_race && g_race_qualifying) return; // in qualifying, you don't lose score by observing diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index d2b2d594fe..3a9bec49ac 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -146,7 +146,6 @@ Called before each frame by the server float game_delay; float game_delay_last; -void Arena_Main(); void RuneMatchGivePoints(); float RedirectionThink(); entity SelectSpawnPoint (float anypoint); @@ -223,8 +222,6 @@ void StartFrame (void) return; } - Arena_Main(); - CreatureFrame (); CheckRules_World (); diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 674b1c8b7d..48ae809511 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -170,10 +170,7 @@ void InitGameplayMode() { fraglimit_override = autocvar_g_arena_point_limit; leadlimit_override = autocvar_g_arena_point_leadlimit; - maxspawned = autocvar_g_arena_maxspawned; - if(maxspawned < 2) - maxspawned = 2; - arena_roundbased = autocvar_g_arena_roundbased; + MUTATOR_ADD(gamemode_arena); } if(g_ca) -- 2.39.2