From: z411 Date: Wed, 30 Nov 2022 15:41:11 +0000 (+0000) Subject: Add option to disable freecam (observer) in Clan Arena (enabled by default in XPM) X-Git-Tag: xonotic-v0.8.6~281^2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=7168faa474b2d4a2a4c004776551207d188e36c7;p=xonotic%2Fxonotic-data.pk3dir.git Add option to disable freecam (observer) in Clan Arena (enabled by default in XPM) --- diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index 4afd6310f..a822fc9a6 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -222,7 +222,7 @@ set g_assault 0 "Assault: attack the enemy base as fast as you can, then defend set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round" set g_ca_point_limit -1 "Clan Arena point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" set g_ca_point_leadlimit -1 "Clan Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" -set g_ca_spectate_enemies 0 "allow eliminated players to spectate enemy players during Clan Arena games" +set g_ca_spectate_enemies 0 "allow eliminated players to spectate enemy players during Clan Arena games. -1 blocks freeroam camera. Changes to this cvar take effect from the next round" set g_ca_warmup 10 "time players get to run around before the round starts" set g_ca_damage2score 100 "every this amount of damage done give players 1 point" set g_ca_round_timelimit 180 "round time limit in seconds" diff --git a/qcsrc/client/hud/panel/infomessages.qc b/qcsrc/client/hud/panel/infomessages.qc index 9db3bf72e..e054bd94f 100644 --- a/qcsrc/client/hud/panel/infomessages.qc +++ b/qcsrc/client/hud/panel/infomessages.qc @@ -109,8 +109,10 @@ void HUD_InfoMessages() case 1: if(spectatee_status == -1) s = sprintf(_("^1Use ^3%s^1 or ^3%s^1 to change the speed"), getcommandkey(_("next weapon"), "weapnext"), getcommandkey(_("previous weapon"), "weapprev")); - else + else if(!observe_blocked) s = sprintf(_("^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"), getcommandkey(_("secondary fire"), "+fire2"), getcommandkey(_("drop weapon"), "dropweapon")); + else + s = sprintf(_("^1Press ^3%s^1 to change camera mode"), getcommandkey(_("drop weapon"), "dropweapon")); break; case 2: s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey(_("server info"), "+show_info")); diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 69214ee8a..9c610aabc 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -657,6 +657,7 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew) newspectatee_status = 0; spectatorbutton_zoom = (f & BIT(2)); + observe_blocked = (f & BIT(3)); if(f & BIT(4)) { diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 1f1c29002..00dd14963 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -97,6 +97,7 @@ vector view_origin, view_forward, view_right, view_up; bool button_zoom; bool spectatorbutton_zoom; +bool observe_blocked; bool button_attack2; float current_viewzoom; diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index d64ce3604..7a16141fc 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -1,7 +1,6 @@ #include "sv_clanarena.qh" float autocvar_g_ca_damage2score = 100; -bool autocvar_g_ca_spectate_enemies; bool autocvar_g_ca_prevent_stalemate; float autocvar_g_ca_start_health = 200; @@ -275,6 +274,11 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer) MUTATOR_HOOKFUNCTION(ca, reset_map_players) { + g_ca_spectate_enemies = autocvar_g_ca_spectate_enemies; + observe_blocked_if_eliminated = (g_ca_spectate_enemies == -1); + // we can avoid sending observe_blocked_if_eliminated to all clients here (with ClientData_Touch) + // since it will get sent whenever the client spectates someone anyway + FOREACH_CLIENT(true, { CS(it).killcount = 0; if (INGAME(it) || IS_BOT_CLIENT(it)) @@ -367,7 +371,10 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver) INGAME_STATUS_CLEAR(player); } if (INGAME(player)) + { player.frags = FRAGS_PLAYER_OUT_OF_GAME; + player.would_spectate = observe_blocked_if_eliminated; // if blocked from observing force to spectate now + } if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; if (!INGAME(player)) @@ -508,7 +515,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectateSet) entity client = M_ARGV(0, entity); entity targ = M_ARGV(1, entity); - if (!autocvar_g_ca_spectate_enemies && INGAME(client)) + if (g_ca_spectate_enemies != 1 && INGAME(client)) if (DIFF_TEAM(targ, client)) return true; } @@ -517,7 +524,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectateNext) { entity client = M_ARGV(0, entity); - if (!autocvar_g_ca_spectate_enemies && INGAME(client) + if (g_ca_spectate_enemies != 1 && INGAME(client) && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client))) { entity targ = M_ARGV(1, entity); @@ -532,7 +539,7 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev) entity targ = M_ARGV(1, entity); entity first = M_ARGV(2, entity); - if (!autocvar_g_ca_spectate_enemies && INGAME(client) + if (g_ca_spectate_enemies != 1 && INGAME(client) && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client))) { do { targ = targ.chain; } diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh index da93badef..3a9931e43 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh @@ -3,8 +3,10 @@ #include #include #include +#include #include +int autocvar_g_ca_spectate_enemies; int autocvar_g_ca_point_limit; int autocvar_g_ca_point_leadlimit; float autocvar_g_ca_round_timelimit; @@ -16,6 +18,7 @@ string autocvar_g_ca_weaponarena = "most"; int ca_teams; bool allowed_to_spawn; +bool g_ca_spectate_enemies; // updated on map reset const int ST_CA_ROUNDS = 1; @@ -44,6 +47,8 @@ REGISTER_MUTATOR(ca, false) }); allowed_to_spawn = true; + g_ca_spectate_enemies = autocvar_g_ca_spectate_enemies; + observe_blocked_if_eliminated = (g_ca_spectate_enemies == -1); round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart); round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit); EliminatedPlayers_Init(ca_isEliminated); diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index eb2ba1dcf..58fda9a01 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -138,6 +138,8 @@ bool ClientData_Send(entity this, entity to, int sf) if (CS(e).race_completed) sf |= BIT(0); // forced scoreboard if (CS(to).spectatee_status) sf |= BIT(1); // spectator ent number follows if (CS(e).zoomstate) sf |= BIT(2); // zoomed + if (observe_blocked_if_eliminated && INGAME(to)) + sf |= BIT(3); // observing blocked if (autocvar_sv_showspectators == 1 || (autocvar_sv_showspectators && IS_SPEC(to))) sf |= BIT(4); // show spectators @@ -2253,10 +2255,12 @@ void ObserverOrSpectatorThink(entity this) } CS(this).impulse = 0; } else if(PHYS_INPUT_BUTTON_ATCK2(this)) { - this.would_spectate = false; - this.flags &= ~FL_JUMPRELEASED; - TRANSMUTE(Observer, this); - PutClientInServer(this); + if(!observe_blocked_if_eliminated || !INGAME(this)) { + this.would_spectate = false; + this.flags &= ~FL_JUMPRELEASED; + TRANSMUTE(Observer, this); + PutClientInServer(this); + } } else if(!SpectateUpdate(this) && !SpectateNext(this)) { PutObserverInServer(this, false, true); this.would_spectate = true; diff --git a/qcsrc/server/world.qh b/qcsrc/server/world.qh index 48c0e38d4..57b240d2a 100644 --- a/qcsrc/server/world.qh +++ b/qcsrc/server/world.qh @@ -164,3 +164,5 @@ void droptofloor(entity this); IntrusiveList g_moveables; STATIC_INIT(g_moveables) { g_moveables = IL_NEW(); } + +bool observe_blocked_if_eliminated = false; // forbids eliminated players from observing diff --git a/ruleset-XPM.cfg b/ruleset-XPM.cfg index 0a89a01de..2629ceb7a 100644 --- a/ruleset-XPM.cfg +++ b/ruleset-XPM.cfg @@ -27,3 +27,4 @@ g_vehicles 0 sv_showspectators 0 sv_taunt 0 sv_maxidle_playertospectator 0 +g_ca_spectate_enemies -1 // block freeroam camera in CA matches