From 9578f5e05d3c76ffd6fc6959f31d9a7a6e17afbc Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 26 Feb 2023 01:57:49 -0800 Subject: [PATCH 1/4] Reset viewpoint to local player if last viewed player spectates or leaves --- src/d_clisrv.c | 12 +++--------- src/d_netcmd.c | 17 ++--------------- src/g_game.c | 13 ++++++++++--- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f53d1f35a..860f14b04 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2608,15 +2608,6 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) LUA_HookPlayerQuit(&players[playernum], reason); // Lua hook for player quitting - // don't look through someone's view who isn't there - if (playernum == displayplayers[0] && !demo.playback) - { - // Call ViewpointSwitch hooks here. - // The viewpoint was forcibly changed. - LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); - displayplayers[0] = consoleplayer; - } - G_RemovePartyMember(playernum); // Reset player data @@ -2636,6 +2627,9 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) LUA_InvalidatePlayer(&players[playernum]); + // don't look through someone's view who isn't there + G_ResetViews(); + K_CheckBumpers(); P_CheckRacers(); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 53fe94b64..e0491a74c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1589,21 +1589,8 @@ static void FinalisePlaystateChange(INT32 playernum) K_StripItems(&players[playernum]); } - // Reset away view (some code referenced from P_SpectatorJoinGame) - { - UINT8 i = 0; - INT32 *localplayertable = (splitscreen_partied[consoleplayer] ? splitscreen_party[consoleplayer] : g_localplayers); - - for (i = 0; i <= r_splitscreen; i++) - { - if (localplayertable[i] == playernum) - { - LUA_HookViewpointSwitch(players+playernum, players+playernum, true); - displayplayers[i] = playernum; - break; - } - } - } + // Reset away view + G_ResetViews(); K_CheckBumpers(); // SRB2Kart P_CheckRacers(); // also SRB2Kart diff --git a/src/g_game.c b/src/g_game.c index 441f9e6c6..46be75843 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2035,7 +2035,14 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive) /* Check if anyone is available to view. */ if (( playernum = G_FindView(playernum, viewnum, onlyactive, playernum < olddisplayplayer) ) == -1) - return; + { + /* Fall back on true self */ + playernum = g_localplayers[viewnum-1]; + } + + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUA_HookViewpointSwitch(&players[g_localplayers[viewnum - 1]], &players[playernum], true); /* Focus our target view first so that we don't take its player. */ (*displayplayerp) = playernum; @@ -2097,8 +2104,8 @@ void G_ResetViews(void) /* Demote splits */ if (playersviewable < splits) { - splits = playersviewable; - r_splitscreen = max(splits-1, 0); + splits = max(playersviewable, splitscreen + 1); // don't delete local players + r_splitscreen = splits - 1; R_ExecuteSetViewSize(); } From 5fe55f54a1a3e862cf70743ee10a87c102600cc4 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 26 Feb 2023 02:21:49 -0800 Subject: [PATCH 2/4] Reset camera interpolation when switching viewpoints Fixes a 1-frame jitter of the camera moving across the level and turning around to match the new viewpoint. --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 46be75843..0e7e4cac4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2050,6 +2050,10 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive) { camerap = &camera[viewnum-1]; P_ResetCamera(&players[(*displayplayerp)], camerap); + + // Why does it need to be done twice? + R_ResetViewInterpolation(viewnum); + R_ResetViewInterpolation(viewnum); } if (viewnum > splits) From 14e89d3f424dacca3acbf8a1bb3c56d47c73bab7 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 26 Feb 2023 02:23:47 -0800 Subject: [PATCH 3/4] Let director focus 1P if no more players are in game --- src/k_director.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/k_director.c b/src/k_director.c index a35c3da84..4f5737b4b 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -238,6 +238,13 @@ void K_UpdateDirector(void) return; } + // if there's only one player left in the list, just switch to that player + if (directorinfo.sortedplayers[0] != -1 && directorinfo.sortedplayers[1] == -1) + { + K_DirectorSwitch(directorinfo.sortedplayers[0], false); + return; + } + // aaight, time to walk through the standings to find the first interesting pair // NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default. // we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out @@ -291,4 +298,4 @@ void K_UpdateDirector(void) break; } -} \ No newline at end of file +} From 7a67aa2f35ed00d977cc00f090bf531c1e218d3d Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 26 Feb 2023 02:19:19 -0800 Subject: [PATCH 4/4] Let viewpoints underwrap This means that if you're currently viewing the first player in game and try to switch view to the player before them, it will wrap around and view the last player in game. --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 0e7e4cac4..0be648c30 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1964,7 +1964,7 @@ boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive) INT32 G_FindView(INT32 startview, UINT8 viewnum, boolean onlyactive, boolean reverse) { INT32 i, dir = reverse ? -1 : 1; - startview = min(max(startview, 0), MAXPLAYERS); + startview = min(max(startview, -1), MAXPLAYERS); for (i = startview; i < MAXPLAYERS && i >= 0; i += dir) { if (G_CanView(i, viewnum, onlyactive))