From 0d7640b411a07f42106e6ef5d4220ac2a47a57f7 Mon Sep 17 00:00:00 2001 From: terencehill Date: Mon, 16 Aug 2021 20:41:01 +0200 Subject: [PATCH] LMS: improve handling of forced spectators in warmup and countdown to game start (e.g. by movetospec or sv_maxidle_playertospectator timer) --- .../gamemode/clanarena/sv_clanarena.qc | 4 ++++ qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc | 10 ++++++++-- qcsrc/common/minigames/sv_minigames.qc | 4 +--- qcsrc/server/client.qc | 18 +++++++----------- qcsrc/server/client.qh | 2 +- qcsrc/server/clientkill.qc | 2 +- qcsrc/server/command/sv_cmd.qc | 6 ++---- qcsrc/server/mutators/events.qh | 1 + 8 files changed, 25 insertions(+), 22 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index ba2402f27..c7ba41984 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -302,6 +302,10 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver) { entity player = M_ARGV(0, entity); + bool is_forced = M_ARGV(1, bool); + if (is_forced && player.caplayer) + player.caplayer = 0; + if (IS_PLAYER(player) && !IS_DEAD(player)) ca_LastPlayerForTeam_Notify(player); if (player.killindicator_teamchange == -2) // player wants to spectate diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc index b05a960dd..556f76294 100644 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc @@ -310,6 +310,7 @@ MUTATOR_HOOKFUNCTION(lms, ClientDisconnect) MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) { entity player = M_ARGV(0, entity); + bool is_forced = M_ARGV(1, bool); if (!IS_PLAYER(player)) return true; @@ -321,8 +322,13 @@ MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) TRANSMUTE(Observer, player); player.lmsplayer = 0; } - else if (!GameRules_scoring_add(player, LMS_RANK, 0)) - lms_RemovePlayer(player); + else + { + if (is_forced) + player.lms_spectate_warning = 2; + if (!GameRules_scoring_add(player, LMS_RANK, 0)) + lms_RemovePlayer(player); + } return true; // prevent team reset } diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index 21f81055a..a1fb3631d 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -148,9 +148,7 @@ int minigame_addplayer(entity minigame_session, entity player) Net_LinkEntity(player_pointer, false, 0, minigame_SendEntity); if ( !IS_OBSERVER(player) && autocvar_sv_minigames_observer ) - { - PutObserverInServer(player); - } + PutObserverInServer(player, true); if ( autocvar_sv_minigames_observer == 2 ) Player_SetForcedTeamIndex(player, TEAM_FORCE_SPECTATOR); diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index a9758146f..943404e02 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -236,9 +235,9 @@ void setplayermodel(entity e, string modelname) } /** putting a client as observer in the server */ -void PutObserverInServer(entity this) +void PutObserverInServer(entity this, bool is_forced) { - bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver, this); + bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver, this, is_forced); PlayerState_detach(this); if (IS_PLAYER(this)) @@ -820,7 +819,7 @@ void PutClientInServer(entity this) MUTATOR_CALLHOOK(PutClientInServer, this); if (IS_OBSERVER(this)) { - PutObserverInServer(this); + PutObserverInServer(this, false); } else if (IS_PLAYER(this)) { PutPlayerInServer(this); } @@ -1789,7 +1788,7 @@ bool SpectateSet(entity this) accuracy_resend(this); if(!SpectateUpdate(this)) - PutObserverInServer(this); + PutObserverInServer(this, false); return true; } @@ -2293,7 +2292,7 @@ void ObserverOrSpectatorThink(entity this) TRANSMUTE(Observer, this); PutClientInServer(this); } else if(!SpectateUpdate(this) && !SpectateNext(this)) { - PutObserverInServer(this); + PutObserverInServer(this, false); this.would_spectate = true; } } @@ -2319,7 +2318,7 @@ void ObserverOrSpectatorThink(entity this) } } if(is_spec && !SpectateUpdate(this)) - PutObserverInServer(this); + PutObserverInServer(this, false); } if (is_spec) this.flags |= FL_CLIENT | FL_NOTARGET; @@ -2677,10 +2676,7 @@ void PlayerPostThink (entity this) if (IS_PLAYER(this) && autocvar_sv_maxidle_playertospectator > 0) { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MOVETOSPEC_IDLING, this.netname, maxidle_time); - if (this.caplayer) - this.caplayer = 0; - this.lms_spectate_warning = 2; // TODO: mutator hook for players forcibly moved to spectator? - PutObserverInServer(this); + PutObserverInServer(this, true); } else { diff --git a/qcsrc/server/client.qh b/qcsrc/server/client.qh index 3199d155a..2f7bfbb0b 100644 --- a/qcsrc/server/client.qh +++ b/qcsrc/server/client.qh @@ -381,7 +381,7 @@ bool Spectate(entity this, entity pl); void ClientInit_Spawn(); -void PutObserverInServer(entity this); +void PutObserverInServer(entity this, bool is_forced); void SetSpectatee(entity this, entity spectatee); void SetSpectatee_status(entity this, int spectatee_num); diff --git a/qcsrc/server/clientkill.qc b/qcsrc/server/clientkill.qc index e87a2b118..9b29273a6 100644 --- a/qcsrc/server/clientkill.qc +++ b/qcsrc/server/clientkill.qc @@ -24,7 +24,7 @@ void ClientKill_Now_TeamChange(entity this) { if (blockSpectators) Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); - PutObserverInServer(this); + PutObserverInServer(this, false); } else { diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 5a9fae567..47e9f922a 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -184,8 +184,7 @@ void GameCommand_allspec(int request, int argc) string reason = argv(1); int n = 0; FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { - if (it.caplayer) it.caplayer = 0; - PutObserverInServer(it); + PutObserverInServer(it, true); ++n; }); if (n) bprint(strcat("Successfully forced all (", ftos(n), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n")); @@ -1009,8 +1008,7 @@ void GameCommand_moveplayer(int request, int argc) string pl_name = playername(client.netname, client.team, false); if (!IS_SPEC(client) && !IS_OBSERVER(client)) { - if (client.caplayer) client.caplayer = 0; - PutObserverInServer(client); + PutObserverInServer(client, true); successful = strcat(successful, (successful ? ", " : ""), pl_name); } diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index f33fc4598..ee5d18a69 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -10,6 +10,7 @@ /** called when a player becomes observer, after shared setup */ #define EV_MakePlayerObserver(i, o) \ /** player */ i(entity, MUTATOR_ARGV_0_entity) \ + /** is_forced */ i(bool, MUTATOR_ARGV_1_bool) \ /**/ MUTATOR_HOOKABLE(MakePlayerObserver, EV_MakePlayerObserver) -- 2.39.2