From adebfb000c9b277e2f35c3406db2ccb9e120ed97 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 1 Mar 2024 06:05:52 -0800 Subject: [PATCH] Replays: keep party in sync with current viewpoints - More and more parts of the game rely on parties - Parties are assumed to match the displayplayers - This fixes A/B/C/D nametags --- src/d_netcmd.c | 11 +++++++++-- src/g_demo.cpp | 31 ++++++++++++++++++++++++++++++ src/g_demo.h | 2 ++ src/g_game.c | 9 +++++++-- src/menus/transient/pause-replay.c | 6 +++--- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5f68e5961..768c461de 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1838,8 +1838,15 @@ static void Command_SetViews_f(void) // Even if the splits go beyond the real number of // splitscreen players, displayplayers was filled // with duplicates of P1 (see Got_AddPlayer). - r_splitscreen = newsplits-1; - R_ExecuteSetViewSize(); + if (demo.playback) + { + G_SyncDemoParty(consoleplayer, newsplits-1); + } + else + { + r_splitscreen = newsplits-1; + R_ExecuteSetViewSize(); + } // If promoting (outside of replays), make sure the // camera is in the correct position. diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 650aa4d53..c649320df 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -47,6 +47,7 @@ #include "lua_hook.h" #include "md5.h" // demo checksums #include "p_saveg.h" // savebuffer_t +#include "g_party.h" // SRB2Kart #include "d_netfil.h" // nameonly @@ -4096,3 +4097,33 @@ boolean G_CheckDemoTitleEntry(void) return true; } + +void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen) +{ + int r_splitscreen_copy = r_splitscreen; + INT32 displayplayers_copy[MAXSPLITSCREENPLAYERS]; + memcpy(displayplayers_copy, displayplayers, sizeof displayplayers); + + // If we switch away from someone's view, that player + // should be removed from the party. + // However, it is valid to have the player on multiple + // viewports. + + // Remove this player + G_LeaveParty(rem); + + // And reset the rest of the party + for (int i = 0; i <= r_splitscreen_copy; ++i) + G_LeaveParty(displayplayers_copy[i]); + + // Restore the party, without the removed player, and + // with the order matching displayplayers + for (int i = 0; i <= newsplitscreen; ++i) + G_JoinParty(consoleplayer, displayplayers_copy[i]); + + // memcpy displayplayers back to preserve duplicates + // (G_JoinParty will not create duplicates itself) + r_splitscreen = newsplitscreen; + memcpy(displayplayers, displayplayers_copy, sizeof displayplayers); + R_ExecuteSetViewSize(); +} diff --git a/src/g_demo.h b/src/g_demo.h index 68d7bb6ed..4405589e1 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -243,6 +243,8 @@ typedef enum DEMO_ATTRACT_CREDITS } demoAttractMode_t; +void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/g_game.c b/src/g_game.c index 1ce8c1dbe..26a2c387a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1685,8 +1685,13 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive) } } - if (viewnum == 1 && demo.playback) - consoleplayer = displayplayers[0]; + if (demo.playback) + { + if (viewnum == 1) + consoleplayer = displayplayers[0]; + + G_SyncDemoParty(olddisplayplayer, r_splitscreen); + } // change statusbar also if playing back demo if (demo.quitafterplaying) diff --git a/src/menus/transient/pause-replay.c b/src/menus/transient/pause-replay.c index 138127e8e..9c0c777a7 100644 --- a/src/menus/transient/pause-replay.c +++ b/src/menus/transient/pause-replay.c @@ -9,6 +9,7 @@ #include "../../p_local.h" // P_InitCameraCmd #include "../../d_main.h" // D_StartTitle #include "../../k_credits.h" +#include "../../g_demo.h" static void M_PlaybackTick(void); @@ -220,13 +221,12 @@ void M_PlaybackSetViews(INT32 choice) { if (choice == 0) { - r_splitscreen--; + G_SyncDemoParty(displayplayers[r_splitscreen], r_splitscreen - 1); } else { - r_splitscreen = 0; + G_SyncDemoParty(consoleplayer, 0); } - R_ExecuteSetViewSize(); } }