From 0d6b195077bb046e596abe5f1b881443f18da9d2 Mon Sep 17 00:00:00 2001 From: terencehill Date: Thu, 10 Feb 2022 23:35:22 +0100 Subject: [PATCH] When switching from spectator to observer don't place the camera in a random spawnpoint but keep it in its current location so you don't lose sight of the spectated player --- qcsrc/common/minigames/sv_minigames.qc | 2 +- qcsrc/server/client.qc | 29 ++++++++++++++++---------- qcsrc/server/client.qh | 2 +- qcsrc/server/clientkill.qc | 2 +- qcsrc/server/command/sv_cmd.qc | 4 ++-- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index a1fb3631d..57f6f46b6 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -148,7 +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, true); + PutObserverInServer(player, true, 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 daabb84c9..3af147c21 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -235,7 +235,7 @@ void setplayermodel(entity e, string modelname) } /** putting a client as observer in the server */ -void PutObserverInServer(entity this, bool is_forced) +void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint) { bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver, this, is_forced); PlayerState_detach(this); @@ -257,12 +257,18 @@ void PutObserverInServer(entity this, bool is_forced) entcs_update_players(this); } - entity spot = SelectSpawnPoint(this, true); - if (!spot) LOG_FATAL("No spawnpoints for observers?!?"); - this.angles = vec2(spot.angles); + if (use_spawnpoint) + { + entity spot = SelectSpawnPoint(this, true); + if (!spot) LOG_FATAL("No spawnpoints for observers?!?"); + this.angles = vec2(spot.angles); + // offset it so that the spectator spawns higher off the ground, looks better this way + setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this)); + } + else // change origin to restore previous view origin + setorigin(this, this.origin + STAT(PL_VIEW_OFS, this) - STAT(PL_CROUCH_VIEW_OFS, this)); this.fixangle = true; - // offset it so that the spectator spawns higher off the ground, looks better this way - setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this)); + if (IS_REAL_CLIENT(this)) { msg_entity = this; @@ -809,6 +815,7 @@ void PutClientInServer(entity this) if (game_stopped) TRANSMUTE(Observer, this); + bool use_spawnpoint = (!this.enemy); // check this.enemy here since SetSpectatee will clear it SetSpectatee(this, NULL); // reset player keys @@ -818,7 +825,7 @@ void PutClientInServer(entity this) MUTATOR_CALLHOOK(PutClientInServer, this); if (IS_OBSERVER(this)) { - PutObserverInServer(this, false); + PutObserverInServer(this, false, use_spawnpoint); } else if (IS_PLAYER(this)) { PutPlayerInServer(this); } @@ -1797,7 +1804,7 @@ bool SpectateSet(entity this) accuracy_resend(this); if(!SpectateUpdate(this)) - PutObserverInServer(this, false); + PutObserverInServer(this, false, true); return true; } @@ -2300,7 +2307,7 @@ void ObserverOrSpectatorThink(entity this) TRANSMUTE(Observer, this); PutClientInServer(this); } else if(!SpectateUpdate(this) && !SpectateNext(this)) { - PutObserverInServer(this, false); + PutObserverInServer(this, false, true); this.would_spectate = true; } } @@ -2326,7 +2333,7 @@ void ObserverOrSpectatorThink(entity this) } } if(is_spec && !SpectateUpdate(this)) - PutObserverInServer(this, false); + PutObserverInServer(this, false, true); } if (is_spec) this.flags |= FL_CLIENT | FL_NOTARGET; @@ -2697,7 +2704,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); - PutObserverInServer(this, true); + PutObserverInServer(this, true, true); } else { diff --git a/qcsrc/server/client.qh b/qcsrc/server/client.qh index 8f7b9c4f3..cca687aeb 100644 --- a/qcsrc/server/client.qh +++ b/qcsrc/server/client.qh @@ -385,7 +385,7 @@ bool Spectate(entity this, entity pl); void ClientInit_Spawn(); -void PutObserverInServer(entity this, bool is_forced); +void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint); 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 474f15af1..296a95bfe 100644 --- a/qcsrc/server/clientkill.qc +++ b/qcsrc/server/clientkill.qc @@ -25,7 +25,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, false); + PutObserverInServer(this, false, true); } else { diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index ca6b268e2..e09458f79 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -191,7 +191,7 @@ void GameCommand_allspec(int request, int argc) string reason = argv(1); int n = 0; FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { - PutObserverInServer(it, true); + PutObserverInServer(it, true, true); ++n; }); if (n) bprint(strcat("Successfully forced all (", ftos(n), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n")); @@ -1016,7 +1016,7 @@ void GameCommand_moveplayer(int request, int argc) string pl_name = playername(client.netname, client.team, false); if (!IS_SPEC(client) && !IS_OBSERVER(client)) { - PutObserverInServer(client, true); + PutObserverInServer(client, true, true); successful = strcat(successful, (successful ? ", " : ""), pl_name); } -- 2.39.2