From af09ba91ec701b6d25d24b5c9d9011402ab9de3c Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 25 Mar 2023 20:05:38 -0700 Subject: [PATCH] Completely rewrite party management code Replaces g_splitscreen.c with g_party.cpp. Simplifies party management functions. Moves externs out of already bloated doomstat.h and g_game.h into g_party.h. Cuts down on globals spam. --- src/Sourcefile | 2 +- src/d_clisrv.c | 14 +-- src/d_netcmd.c | 52 ++++------- src/doomstat.h | 12 --- src/g_game.c | 5 +- src/g_game.h | 4 - src/g_party.cpp | 53 ++++++----- src/g_party.h | 84 ++++++++++++++++++ src/g_splitscreen.c | 210 -------------------------------------------- src/k_hud.c | 1 + src/p_saveg.c | 75 ++++++++++++---- src/p_user.c | 23 ++--- 12 files changed, 209 insertions(+), 326 deletions(-) create mode 100644 src/g_party.h delete mode 100644 src/g_splitscreen.c diff --git a/src/Sourcefile b/src/Sourcefile index ceb12918b..c3d4bca7e 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -15,7 +15,7 @@ f_wipe.c g_demo.c g_game.c g_input.c -g_splitscreen.c +g_party.cpp am_map.c command.c console.c diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e9a0abf9d..b541c8c59 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -58,6 +58,8 @@ #include "doomstat.h" #include "s_sound.h" // sfx_syfail #include "r_fps.h" +#include "m_cond.h" // netUnlocked +#include "g_party.h" // cl loading screen #include "v_video.h" @@ -2525,6 +2527,7 @@ void CL_ClearPlayer(INT32 playernum) splitscreen_invitations[playernum] = -1; playerconsole[playernum] = playernum; + G_DestroyParty(playernum); // Wipe the struct. memset(&players[playernum], 0, sizeof (player_t)); @@ -2575,7 +2578,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) displayplayers[0] = consoleplayer; } - G_RemovePartyMember(playernum); + G_LeaveParty(playernum); // Reset player data CL_ClearPlayer(playernum); @@ -3436,9 +3439,9 @@ void SV_ResetServer(void) Schedule_Clear(); Automate_Clear(); K_ClearClientPowerLevels(); + G_ObliterateParties(); memset(splitscreen_invitations, -1, sizeof splitscreen_invitations); - memset(splitscreen_partied, 0, sizeof splitscreen_partied); memset(player_name_changes, 0, sizeof player_name_changes); mynode = 0; @@ -3525,6 +3528,7 @@ void D_QuitNetGame(void) Schedule_Clear(); Automate_Clear(); K_ClearClientPowerLevels(); + G_ObliterateParties(); DEBFILE("===========================================================================\n" " Log finish\n" @@ -3603,7 +3607,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) displayplayers[i] = newplayernum; g_localplayers[i] = newplayernum; } - splitscreen_partied[newplayernum] = true; DEBFILE("spawning me\n"); } @@ -3617,10 +3620,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) players[newplayernum].bot = false; playerconsole[newplayernum] = console; - splitscreen_original_party_size[console] = - ++splitscreen_party_size[console]; - splitscreen_original_party[console][splitscreenplayer] = - splitscreen_party[console][splitscreenplayer] = newplayernum; + G_BuildLocalSplitscreenParty(newplayernum); if (netgame) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 798b7bcd7..3b914bfc3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -64,6 +64,7 @@ #include "doomstat.h" #include "deh_tables.h" #include "m_perfstats.h" +#include "g_party.h" #define CV_RESTRICT CV_NETVAR @@ -1492,14 +1493,12 @@ static void ForceAllSkins(INT32 forcedskin) } static const char * -VaguePartyDescription (int playernum, int *party_sizes, int default_color) +VaguePartyDescription (int playernum, int size, int default_color) { static char party_description [1 + MAXPLAYERNAME + 1 + sizeof " and x others"]; const char *name; - int size; name = player_names[playernum]; - size = party_sizes[playernum]; /* less than check for the dumb compiler because I KNOW it'll complain about "writing x bytes into an area of y bytes"!!! @@ -1914,7 +1913,7 @@ static void Got_PartyInvite(UINT8 **cp,INT32 playernum) HU_AddChatText(va( "\x82*You have been invited to join %s.", VaguePartyDescription( - playernum, splitscreen_party_size, '\x82') + playernum, G_PartySize(playernum), '\x82') ), true); } } @@ -1923,8 +1922,6 @@ static void Got_PartyInvite(UINT8 **cp,INT32 playernum) static void Got_AcceptPartyInvite(UINT8 **cp,INT32 playernum) { int invitation; - int old_party_size; - int views; (void)cp; @@ -1940,12 +1937,12 @@ static void Got_AcceptPartyInvite(UINT8 **cp,INT32 playernum) if (invitation >= 0) { - if (splitscreen_partied[invitation]) + if (G_IsPartyLocal(invitation)) { HU_AddChatText(va( "\x82*%s joined your party!", VaguePartyDescription( - playernum, splitscreen_original_party_size, '\x82') + playernum, G_LocalSplitscreenPartySize(playernum), '\x82') ), true); } else if (playernum == consoleplayer) @@ -1953,18 +1950,11 @@ static void Got_AcceptPartyInvite(UINT8 **cp,INT32 playernum) HU_AddChatText(va( "\x82*You joined %s's party!", VaguePartyDescription( - invitation, splitscreen_party_size, '\x82') + invitation, G_PartySize(invitation), '\x82') ), true); } - old_party_size = splitscreen_party_size[invitation]; - views = splitscreen_original_party_size[playernum]; - - if (( old_party_size + views ) <= MAXSPLITSCREENPLAYERS) - { - G_RemovePartyMember(playernum); - G_AddPartyMember(invitation, playernum); - } + G_JoinParty(invitation, playernum); splitscreen_invitations[playernum] = -1; } @@ -2022,21 +2012,16 @@ static void Got_LeaveParty(UINT8 **cp,INT32 playernum) splitscreen_invitations[playernum] = -1; - if (splitscreen_party_size[playernum] > - splitscreen_original_party_size[playernum]) + if (G_IsPartyLocal(playernum) && playernum != consoleplayer) { - if (splitscreen_partied[playernum] && playernum != consoleplayer) - { - HU_AddChatText(va( - "\x85*%s left your party.", - VaguePartyDescription( - playernum, splitscreen_original_party_size, '\x85') - ), true); - } - - G_RemovePartyMember(playernum); - G_ResetSplitscreen(playernum); + HU_AddChatText(va( + "\x85*%s left your party.", + VaguePartyDescription( + playernum, G_LocalSplitscreenPartySize(playernum), '\x85') + ), true); } + + G_LeaveParty(playernum); } void D_SendPlayerConfig(UINT8 n) @@ -2354,8 +2339,7 @@ Command_Invite_f (void) "That player has already been invited to join another party.\n"); } - if (( splitscreen_party_size[consoleplayer] + - splitscreen_original_party_size[invitee] ) > MAXSPLITSCREENPLAYERS) + if ((G_PartySize(consoleplayer) + G_LocalSplitscreenPartySize(invitee)) > MAXSPLITSCREENPLAYERS) { CONS_Alert(CONS_WARNING, "That player joined with too many " @@ -2365,7 +2349,7 @@ Command_Invite_f (void) CONS_Printf( "Inviting %s...\n", VaguePartyDescription( - invitee, splitscreen_original_party_size, '\x80') + invitee, G_LocalSplitscreenPartySize(invitee), '\x80') ); buffer[0] = invitee; @@ -2408,7 +2392,7 @@ Command_CancelInvite_f (void) CONS_Printf( "Rescinding invite to %s...\n", VaguePartyDescription( - invitee, splitscreen_original_party_size, '\x80') + invitee, G_LocalSplitscreenPartySize(invitee), '\x80') ); buffer[0] = invitee; diff --git a/src/doomstat.h b/src/doomstat.h index 77c954a25..ff3ef68bb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -195,18 +195,6 @@ extern INT32 displayplayers[MAXSPLITSCREENPLAYERS]; /* g_localplayers[0] = consoleplayer */ extern INT32 g_localplayers[MAXSPLITSCREENPLAYERS]; -/* spitscreen players sync */ -extern INT32 splitscreen_original_party_size[MAXPLAYERS]; -extern INT32 splitscreen_original_party[MAXPLAYERS][MAXSPLITSCREENPLAYERS]; - -/* parties */ -extern INT32 splitscreen_invitations[MAXPLAYERS]; -extern INT32 splitscreen_party_size[MAXPLAYERS]; -extern INT32 splitscreen_party[MAXPLAYERS][MAXSPLITSCREENPLAYERS]; - -/* the only local one */ -extern boolean splitscreen_partied[MAXPLAYERS]; - extern char * titlemap; extern boolean hidetitlepics; extern char * bootmap; //bootmap for loading a map on startup diff --git a/src/g_game.c b/src/g_game.c index c4b9af24d..19117bbb2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -63,6 +63,7 @@ #include "doomstat.h" #include "acs/interface.h" #include "k_director.h" +#include "g_party.h" #ifdef HAVE_DISCORDRPC #include "discord.h" @@ -2936,12 +2937,12 @@ void G_DoReborn(INT32 playernum) void G_AddPlayer(INT32 playernum, INT32 console) { CL_ClearPlayer(playernum); - //G_DestroyParty(playernum); + G_DestroyParty(playernum); playeringame[playernum] = true; playerconsole[playernum] = console; - //G_BuildLocalSplitscreenParty(playernum); + G_BuildLocalSplitscreenParty(playernum); player_t *newplayer = &players[playernum]; diff --git a/src/g_game.h b/src/g_game.h index 005cdb70b..8bcab9b66 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -224,10 +224,6 @@ void G_ResetViews(void); void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive); void G_AdjustView(UINT8 viewnum, INT32 offset, boolean onlyactive); -void G_AddPartyMember (INT32 party_member, INT32 new_party_member); -void G_RemovePartyMember (INT32 party_member); -void G_ResetSplitscreen (INT32 playernum); - void G_AddPlayer(INT32 playernum, INT32 console); void G_SetExitGameFlag(void); diff --git a/src/g_party.cpp b/src/g_party.cpp index 1c82a2d1d..a5dd79270 100644 --- a/src/g_party.cpp +++ b/src/g_party.cpp @@ -1,6 +1,7 @@ // DR. ROBOTNIK'S RING RACERS //----------------------------------------------------------------------------- -// Copyright (C) 2023 by James Robert Roman +// Copyright (C) 2025 by James Robert Roman +// Copyright (C) 2025 by Kart Krew // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -19,7 +20,7 @@ #include "d_clisrv.h" // playerconsole #include "doomdef.h" // MAXPLAYERS #include "doomstat.h" // consoleplayer -#include "g_game.h" // localangle +#include "g_game.h" // G_FixCamera #include "g_party.h" #include "g_state.h" #include "p_local.h" @@ -101,7 +102,7 @@ public: bool local() const { // consoleplayer is not valid yet. - if (!addedtogame) + if (!addedtogame && !demo.playback) { return false; } @@ -128,28 +129,15 @@ public: return; } - // Rendering stuff is not valid outside of levels. - if (!G_GamestateUsesLevel()) - { - return; - } - for (std::size_t i = 0; i < size(); ++i) { - const playernum_t player = at(i); + displayplayers[i] = at(i); - displayplayers[i] = player; - - // The order of displayplayers can change, which - // would make localangle invalid now. - localangle[i] = players[player].angleturn; - - P_ResetCamera(&players[player], &camera[i]); - - // Make sure the viewport doesn't interpolate at - // all into its new position -- just snap - // instantly into place. - R_ResetViewInterpolation(1 + i); + // Camera is not valid outside of levels. + if (G_GamestateUsesLevel()) + { + G_FixCamera(1 + i); + } } r_splitscreen = size() - 1; @@ -186,6 +174,11 @@ public: // consoleplayer. Party& operator [](Party::Console console) { return pool_[console]; } + // Clears a single player's local party. This method + // accesses the playernum directly, instead of the + // consoleplayer. + void reset(playernum_t player) { pool_[player] = {}; } + protected: std::array pool_; } @@ -271,7 +264,7 @@ void G_ObliterateParties(void) void G_DestroyParty(UINT8 player) { - local_party[player] = {}; + local_party.reset(player); final_party[player] = {}; } @@ -324,3 +317,17 @@ UINT8 G_PartyPosition(UINT8 player) return party.find(player) - party.begin(); } + +UINT8 G_LocalSplitscreenPartyPosition(UINT8 player) +{ + const Party& party = local_party[player]; + + return party.find(player) - party.begin(); +} + +UINT8 G_LocalSplitscreenPartyMember(UINT8 player, UINT8 index) +{ + SRB2_ASSERT(index < local_party[player].size()); + + return local_party[player][index]; +} diff --git a/src/g_party.h b/src/g_party.h new file mode 100644 index 000000000..b5fd5c2b0 --- /dev/null +++ b/src/g_party.h @@ -0,0 +1,84 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by James Robert Roman +// Copyright (C) 2025 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#ifndef __G_PARTY_H__ +#define __G_PARTY_H__ + +#include "doomdef.h" // MAXPLAYERS + +#ifdef __cplusplus +extern "C" { +#endif + +// +// Functions +// + +// Frees all party resources. +void G_ObliterateParties(void); + +// Wipes all party data for this player slot. +void G_DestroyParty(UINT8 player); + +// Adds player to their local party. +void G_BuildLocalSplitscreenParty(UINT8 player); + +// Join guest's entire local party to the host. All checks are +// performed, so this is a no-op if the parties are already +// joined, or if either party is too big for the other, etc. +// +// Resets viewports for all players involved. +void G_JoinParty(UINT8 host, UINT8 guest); + +// Removes guest from an online party and restores their +// initial local party. +void G_LeaveParty(UINT8 guest); + +// Size of the player's initial local party. +UINT8 G_LocalSplitscreenPartySize(UINT8 player); + +// Ultimate size of this player's party. Includes any joined +// parties, else the same as G_LocalSplitscreenPartySize. +UINT8 G_PartySize(UINT8 player); + +// True if this player is a member of the consoleplayer's +// party. +boolean G_IsPartyLocal(UINT8 player); + +// Returns the player slot present at a certain position +// within this player's party. Do not call this function with +// an index beyond G_PartySize() - 1. +UINT8 G_PartyMember(UINT8 player, UINT8 index); + +// C array access to the same data as G_PartyMember. +const UINT8 *G_PartyArray(UINT8 player); + +// Suitable index to G_PartyMember and G_PartyArray. +UINT8 G_PartyPosition(UINT8 player); + +// +UINT8 G_LocalSplitscreenPartyPosition(UINT8 player); + +// +UINT8 G_LocalSplitscreenPartyMember(UINT8 player, UINT8 index); + +// +// Globals +// + +// Whether this player has been invited to join anyone's party +// and who invited them. -1 if no invitation. +extern INT32 splitscreen_invitations[MAXPLAYERS]; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __G_PARTY_H__ diff --git a/src/g_splitscreen.c b/src/g_splitscreen.c deleted file mode 100644 index e510a474c..000000000 --- a/src/g_splitscreen.c +++ /dev/null @@ -1,210 +0,0 @@ -// SONIC ROBO BLAST 2 KART -//----------------------------------------------------------------------------- -// Copyright (C) 2020 by James R. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file g_splitscreen.c -/// \brief some splitscreen stuff - -#include "doomdef.h" -#include "g_game.h" -#include "p_local.h" -#include "r_local.h" -#include "doomstat.h" - -INT32 splitscreen_original_party_size[MAXPLAYERS]; -INT32 splitscreen_original_party[MAXPLAYERS][MAXSPLITSCREENPLAYERS]; - -INT32 splitscreen_invitations[MAXPLAYERS]; -INT32 splitscreen_party_size[MAXPLAYERS]; -INT32 splitscreen_party[MAXPLAYERS][MAXSPLITSCREENPLAYERS]; - -boolean splitscreen_partied[MAXPLAYERS]; - -void -G_ResetSplitscreen (INT32 playernum) -{ - INT32 old_displayplayers[MAXSPLITSCREENPLAYERS]; - - INT32 i; - - splitscreen_party_size[playernum] = - splitscreen_original_party_size[playernum]; - - memcpy(splitscreen_party[playernum], splitscreen_original_party[playernum], - sizeof splitscreen_party[playernum]); - - if (playernum == consoleplayer) - { - memset(splitscreen_partied, 0, sizeof splitscreen_partied); - splitscreen_partied[consoleplayer] = true; - - memcpy(old_displayplayers, displayplayers, sizeof old_displayplayers); - - /* easier to just rebuild displayplayers with local players */ - for (i = 0; i <= splitscreen; ++i) - { - displayplayers[i] = g_localplayers[i]; - P_ResetCamera(&players[displayplayers[i]], &camera[i]); - } - - while (i < MAXSPLITSCREENPLAYERS) - { - displayplayers[i] = consoleplayer; - i++; - } - - r_splitscreen = splitscreen; - - R_ExecuteSetViewSize(); - } -} - -void -G_RemovePartyMember (INT32 playernum) -{ - INT32 old_party[MAXSPLITSCREENPLAYERS]; - INT32 new_party[MAXSPLITSCREENPLAYERS]; - - INT32 old_party_size; - INT32 before; - INT32 after; - INT32 views; - - INT32 i; - INT32 n; - - old_party_size = splitscreen_party_size[playernum]; - - for (i = 0; i < old_party_size; ++i) - { - /* exploit that splitscreen players keep order */ - if (splitscreen_party[playernum][i] == playernum) - { - before = i; - - views = splitscreen_original_party_size[playernum]; - after = ( before + views ); - - memcpy(old_party, splitscreen_party[playernum], sizeof old_party); - memcpy(new_party, old_party, before * sizeof *old_party); - - memcpy(&new_party[before], &old_party[after], - ( old_party_size - after ) * sizeof *new_party); - - views = ( old_party_size - views ); - - for (i = 0; i < old_party_size; ++i) - { - n = old_party[i]; - if (n != playernum && playerconsole[n] == n) - { - splitscreen_party_size[n] = views; - memcpy(splitscreen_party[n], new_party, - sizeof splitscreen_party[n]); - } - } - - /* don't want to remove yourself from your own screen! */ - if (playernum != consoleplayer && splitscreen_partied[playernum]) - { - splitscreen_partied[playernum] = false; - - for (i = 0; i < views; ++i) - { - displayplayers[i] = new_party[i]; - P_ResetCamera(&players[displayplayers[i]], &camera[i]); - } - while (i < MAXSPLITSCREENPLAYERS) - { - displayplayers[i] = displayplayers[0]; - - i++; - } - - r_splitscreen = ( views - 1 ); - - R_ExecuteSetViewSize(); - } - - break; - } - } -} - -void -G_AddPartyMember (INT32 invitation, INT32 playernum) -{ - INT32 * party; - INT32 *add_party; - - INT32 old_party_size; - INT32 new_party_size; - - INT32 views; - - INT32 i; - INT32 n; - - views = splitscreen_original_party_size[playernum]; - - old_party_size = splitscreen_party_size[invitation]; - new_party_size = ( old_party_size + views ); - - party = splitscreen_party[invitation]; - add_party = splitscreen_original_party[playernum]; - - for (i = 0; i < old_party_size; ++i) - { - n = party[i]; - if (playerconsole[n] == n) - { - splitscreen_party_size[n] = new_party_size; - memcpy(&splitscreen_party[n][old_party_size], add_party, - views * sizeof *splitscreen_party[n]); - } - } - - splitscreen_party_size[playernum] = new_party_size; - memcpy(splitscreen_party[playernum], party, - sizeof splitscreen_party[playernum]); - - /* in my party or adding me? */ - if (splitscreen_partied[invitation]) - { - splitscreen_partied[playernum] = true; - - for (i = old_party_size; i < new_party_size; ++i) - { - displayplayers[i] = party[i]; - P_ResetCamera(&players[displayplayers[i]], &camera[i]); - } - - r_splitscreen += views; - - R_ExecuteSetViewSize(); - } - else if (playernum == consoleplayer) - { - for (i = 0; i < new_party_size; ++i) - { - splitscreen_partied[playerconsole[party[i]]] = true; - - displayplayers[i] = party[i]; - P_ResetCamera(&players[displayplayers[i]], &camera[i]); - } - while (i < MAXSPLITSCREENPLAYERS) - { - displayplayers[i] = displayplayers[0]; - - i++; - } - - r_splitscreen = ( new_party_size - 1 ); - - R_ExecuteSetViewSize(); - } -} diff --git a/src/k_hud.c b/src/k_hud.c index c6c4641aa..f2ad6f0c3 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -38,6 +38,7 @@ #include "r_things.h" #include "r_fps.h" #include "m_random.h" +#include "g_party.h" #define NUMPOSNUMS 10 #define NUMPOSFRAMES 7 // White, three blues, three reds diff --git a/src/p_saveg.c b/src/p_saveg.c index 582a7a68f..9dbcb6e0a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -42,6 +42,7 @@ #include "k_pwrlv.h" #include "k_terrain.h" #include "acs/interface.h" +#include "g_party.h" #include @@ -51,6 +52,7 @@ savedata_t savedata; // being sent and received #define ARCHIVEBLOCK_MISC 0x7FEEDEED #define ARCHIVEBLOCK_PLAYERS 0x7F448008 +#define ARCHIVEBLOCK_PARTIES 0x7F87AF0C #define ARCHIVEBLOCK_WORLD 0x7F8C08C0 #define ARCHIVEBLOCK_POBJS 0x7F928546 #define ARCHIVEBLOCK_THINKERS 0x7F37037C @@ -121,14 +123,6 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, playerconsole[i]); WRITEINT32(save->p, splitscreen_invitations[i]); - WRITEINT32(save->p, splitscreen_party_size[i]); - WRITEINT32(save->p, splitscreen_original_party_size[i]); - - for (j = 0; j < MAXSPLITSCREENPLAYERS; ++j) - { - WRITEINT32(save->p, splitscreen_party[i][j]); - WRITEINT32(save->p, splitscreen_original_party[i][j]); - } WRITEANGLE(save->p, players[i].angleturn); WRITEANGLE(save->p, players[i].aiming); @@ -440,14 +434,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) playerconsole[i] = READUINT8(save->p); splitscreen_invitations[i] = READINT32(save->p); - splitscreen_party_size[i] = READINT32(save->p); - splitscreen_original_party_size[i] = READINT32(save->p); - - for (j = 0; j < MAXSPLITSCREENPLAYERS; ++j) - { - splitscreen_party[i][j] = READINT32(save->p); - splitscreen_original_party[i][j] = READINT32(save->p); - } players[i].angleturn = READANGLE(save->p); players[i].aiming = READANGLE(save->p); @@ -722,6 +708,59 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) TracyCZoneEnd(__zone); } +static void P_NetArchiveParties(savebuffer_t *save) +{ + INT32 i, k; + UINT8 partySize; + + WRITEUINT32(save->p, ARCHIVEBLOCK_PARTIES); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + partySize = G_PartySize(i); + + WRITEUINT8(save->p, partySize); + + for (k = 0; k < partySize; ++k) + { + WRITEUINT8(save->p, G_PartyMember(i, k)); + } + } +} + +static void P_NetUnArchiveParties(savebuffer_t *save) +{ + INT32 i, k; + UINT8 partySize; + + if (READUINT32(save->p) != ARCHIVEBLOCK_PARTIES) + I_Error("Bad $$$.sav at archive block Parties"); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + G_BuildLocalSplitscreenParty(i); + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + partySize = READUINT8(save->p); + + for (k = 0; k < partySize; ++k) + { + G_JoinParty(i, READUINT8(save->p)); + } + } +} + /// /// Colormaps /// @@ -5404,6 +5443,8 @@ void P_SaveNetGame(savebuffer_t *save, boolean resending) } P_NetArchivePlayers(save); + P_NetArchiveParties(save); + if (gamestate == GS_LEVEL) { P_NetArchiveWorld(save); @@ -5452,6 +5493,8 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading) if (!P_NetUnArchiveMisc(save,reloading)) return false; P_NetUnArchivePlayers(save); + P_NetUnArchiveParties(save); + if (gamestate == GS_LEVEL) { P_NetUnArchiveWorld(save); diff --git a/src/p_user.c b/src/p_user.c index ad2ce9c9d..4bf556f67 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -60,6 +60,7 @@ #include "k_terrain.h" // K_SpawnSplashForMobj #include "k_color.h" #include "k_follower.h" +#include "g_party.h" #include "acs/interface.h" @@ -717,7 +718,7 @@ boolean P_EndingMusic(player_t *player) if (r_splitscreen) { - INT32 *localplayertable = (splitscreen_partied[consoleplayer] ? splitscreen_party[consoleplayer] : g_localplayers); + const UINT8 *localplayertable = G_PartyArray(consoleplayer); if (!((players[localplayertable[0]].exiting || (players[localplayertable[0]].pflags & PF_NOCONTEST)) || (players[localplayertable[1]].exiting || (players[localplayertable[1]].pflags & PF_NOCONTEST)) @@ -816,7 +817,7 @@ void P_RestoreMusic(player_t *player) if (r_splitscreen) { INT32 bestlocaltimer = 1; - INT32 *localplayertable = (splitscreen_partied[consoleplayer] ? splitscreen_party[consoleplayer] : g_localplayers); + const UINT8 *localplayertable = G_PartyArray(consoleplayer); #define setbests(p) \ if (players[p].playerstate == PST_LIVE) \ @@ -1107,8 +1108,6 @@ boolean P_IsMachineLocalPlayer(player_t *player) // boolean P_IsLocalPlayer(player_t *player) { - UINT8 i; - if (player == NULL) { return false; @@ -1118,18 +1117,8 @@ boolean P_IsLocalPlayer(player_t *player) if (demo.playback) return false; - // parties - treat everyone as if it's couch co-op - if (splitscreen_partied[consoleplayer]) - { - for (i = 0; i < splitscreen_party_size[consoleplayer]; i++) - { - if (splitscreen_party[consoleplayer][i] == (player-players)) - return true; - } - return false; - } - - return P_IsMachineLocalPlayer(player); + // handles both online parties and local players (no need to call P_IsMachineLocalPlayer here) + return G_IsPartyLocal(player-players); } // @@ -3548,7 +3537,7 @@ boolean P_SpectatorJoinGame(player_t *player) // Reset away view (some code referenced from Got_Teamchange) { UINT8 i = 0; - INT32 *localplayertable = (splitscreen_partied[consoleplayer] ? splitscreen_party[consoleplayer] : g_localplayers); + const UINT8 *localplayertable = G_PartyArray(consoleplayer); for (i = 0; i < r_splitscreen; i++) {