Various fixes from RR

This commit is contained in:
NepDisk 2025-03-24 10:24:26 -04:00
parent af09ba91ec
commit 37c960a14a
6 changed files with 136 additions and 86 deletions

View file

@ -2269,13 +2269,6 @@ static void Command_SetViews_f(void)
UINT8 splits;
UINT8 newsplits;
if (!( demo.playback && multiplayer ))
{
CONS_Alert(CONS_NOTICE,
"You must be viewing a multiplayer replay to use this.\n");
return;
}
if (COM_Argc() != 2)
{
CONS_Printf("setviews <views>: set the number of split screens\n");
@ -2286,12 +2279,33 @@ static void Command_SetViews_f(void)
newsplits = atoi(COM_Argv(1));
newsplits = min(max(newsplits, 1), 4);
if (newsplits > splits)
if (newsplits > splits && demo.playback && multiplayer)
{
G_AdjustView(newsplits, 0, true);
}
else
{
r_splitscreen = newsplits-1;
R_ExecuteSetViewSize();
// Even if the splits go beyond the real number of
// splitscreen players, displayplayers was filled
// with duplicates of P1 (see Got_AddPlayer).
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.
UINT8 i;
for (i = splits + 1; i <= newsplits; ++i)
{
G_FixCamera(i);
}
}
}
@ -2308,7 +2322,7 @@ Command_Invite_f (void)
return;
}
if (r_splitscreen >= MAXSPLITSCREENPLAYERS)
if (G_PartySize(consoleplayer) >= MAXSPLITSCREENPLAYERS)
{
CONS_Alert(CONS_WARNING, "Your party is full!\n");
return;
@ -2327,9 +2341,9 @@ Command_Invite_f (void)
return;
}
if (invitee == consoleplayer)
if (G_IsPartyLocal(invitee))
{
CONS_Alert(CONS_WARNING, "You cannot invite yourself! Bruh!\n");
CONS_Alert(CONS_WARNING, "That player is already a member of your party.\n");
return;
}
@ -2337,6 +2351,7 @@ Command_Invite_f (void)
{
CONS_Alert(CONS_WARNING,
"That player has already been invited to join another party.\n");
return;
}
if ((G_PartySize(consoleplayer) + G_LocalSplitscreenPartySize(invitee)) > MAXSPLITSCREENPLAYERS)
@ -2344,6 +2359,7 @@ Command_Invite_f (void)
CONS_Alert(CONS_WARNING,
"That player joined with too many "
"splitscreen players for your party.\n");
return;
}
CONS_Printf(
@ -2387,6 +2403,7 @@ Command_CancelInvite_f (void)
{
CONS_Alert(CONS_WARNING,
"You have not invited this player!\n");
return;
}
CONS_Printf(
@ -2432,7 +2449,7 @@ Command_RejectInvite_f (void)
static void
Command_LeaveParty_f (void)
{
if (r_splitscreen > splitscreen)
if (G_PartySize(consoleplayer) > G_LocalSplitscreenPartySize(consoleplayer))
{
CONS_Printf("\x85Leaving party...\n");
@ -3647,24 +3664,6 @@ void P_SetPlayerSpectator(INT32 playernum)
players[playernum].pflags &= ~PF_WANTSTOJOIN;
players[playernum].playerstate = PST_REBORN;
/*if (cv_spectatormusic.value && (players[displayplayers[0]].spectator == true) && !r_splitscreen)
{
if (P_UseContinuousLevelMusic())
{
if (!stricmp(Music_Song("level_nosync"), cv_spectatormusiclump.string))
{
// Do not reset music if it is the same
Music_BatchExempt("level_nosync");
}
Music_Remap("level_nosync", cv_spectatormusiclump.string);
}
else
{
Music_Remap("level", cv_spectatormusiclump.string);
}
}*/
}
//todo: This and the other teamchange functions are getting too long and messy. Needs cleaning.
@ -3742,24 +3741,19 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
//Safety first!
// (not respawning spectators here...)
if (!players[playernum].spectator)
wasspectator = (players[playernum].spectator == true);
if (!wasspectator)
{
if (players[playernum].mo)
if (gamestate == GS_LEVEL && players[playernum].mo)
{
P_DamageMobj(players[playernum].mo, NULL, NULL, 1,
(NetPacket.packet.newteam ? DMG_INSTAKILL : DMG_SPECTATOR));
}
//else
if (!NetPacket.packet.newteam)
{
players[playernum].playerstate = PST_REBORN;
// The following will call P_SetPlayerSpectator if successful
P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_SPECTATOR);
}
//...but because the above could return early under some contexts, we try again here
P_SetPlayerSpectator(playernum);
}
else
wasspectator = true;
players[playernum].pflags &= ~PF_WANTSTOJOIN;
//Now that we've done our error checking and killed the player
//if necessary, put the player on the correct team/status.
@ -3809,22 +3803,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
else if (NetPacket.packet.newteam == 0 && !wasspectator)
HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); // "entered the game" text was moved to P_SpectatorJoinGame
// 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;
}
}
}
/*if (G_GametypeHasTeams())
{
if (NetPacket.packet.newteam)

View file

@ -53,6 +53,7 @@
#include "k_color.h"
#include "k_follower.h"
#include "k_grandprix.h"
#include "g_party.h"
static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}};
consvar_t cv_recordmultiplayerdemos = CVAR_INIT ("netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL);
@ -4186,3 +4187,33 @@ boolean G_DemoTitleResponder(event_t *ev)
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();
}

View file

@ -123,6 +123,9 @@ extern UINT8 demo_writerng;
#define DXD_COLOR 0x10 // color changed
#define DXD_FOLLOWER 0x20 // follower was changed
#define DXD_RESPAWN 0x40 // "respawn" command in console
#define DXD_ADDPLAYER (DXD_JOINDATA|DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER)
#define DXD_WEAPONPREF 0x80 // netsynced playsim settings were changed
#define DXD_PST_PLAYING 0x01
@ -197,6 +200,8 @@ void G_SaveDemo(void);
boolean G_DemoTitleResponder(event_t *ev);
void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1805,19 +1805,12 @@ INT32 G_CountPlayersPotentiallyViewable(boolean active)
return total;
}
//
// G_ResetView
// Correct a viewpoint to playernum or the next available, wraps forward.
// Also promotes splitscreen up to available viewable players.
// An out of range playernum is corrected.
//
void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
{
UINT8 splits;
UINT8 viewd;
INT32 *displayplayerp;
camera_t *camerap;
INT32 olddisplayplayer;
INT32 playersviewable;
@ -1843,33 +1836,70 @@ 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;
{
if (G_PartySize(consoleplayer) < viewnum)
{
return;
}
/* Fall back on true self */
playernum = G_PartyMember(consoleplayer, 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;
if ((*displayplayerp) != olddisplayplayer)
{
camerap = &camera[viewnum-1];
P_ResetCamera(&players[(*displayplayerp)], camerap);
R_ResetViewInterpolation(viewnum);
}
/* If a viewpoint changes, reset the camera to clear uninitialized memory. */
if (viewnum > splits)
{
for (viewd = splits+1; viewd < viewnum; ++viewd)
for (viewd = splits+1; viewd <= viewnum; ++viewd)
{
displayplayerp = (&displayplayers[viewd-1]);
camerap = &camera[viewd];
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
P_ResetCamera(&players[(*displayplayerp)], camerap);
G_FixCamera(viewd);
}
}
else
{
if ((*displayplayerp) != olddisplayplayer)
{
G_FixCamera(viewnum);
}
}
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)
ST_changeDemoView();
}
//
// G_FixCamera
// Reset camera position, angle and interpolation on a view
// after changing state.
//
void G_FixCamera(UINT8 view)
{
player_t *player = &players[displayplayers[view - 1]];
// The order of displayplayers can change, which would
// invalidate localangle.
localangle[view - 1] = player->angleturn;
P_ResetCamera(player, &camera[view - 1]);
// Make sure the viewport doesn't interpolate at all into
// its new position -- just snap instantly into place.
R_ResetViewInterpolation(view);
}
//
@ -2949,7 +2979,7 @@ void G_AddPlayer(INT32 playernum, INT32 console)
newplayer->playerstate = PST_REBORN;
newplayer->jointime = 0;
demo_extradata[playernum] |= DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER; // Set everything
demo_extradata[playernum] |= DXD_ADDPLAYER; // Set everything
}
void G_BeginLevelExit(void)

View file

@ -220,6 +220,7 @@ boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive);
INT32 G_FindView(INT32 startview, UINT8 viewnum, boolean onlyactive, boolean reverse);
INT32 G_CountPlayersPotentiallyViewable(boolean active);
void G_FixCamera(UINT8 view);
void G_ResetViews(void);
void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive);
void G_AdjustView(UINT8 viewnum, INT32 offset, boolean onlyactive);

View file

@ -1981,6 +1981,11 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
(void)source;
(void)inflictor;
if (type == DMG_SPECTATOR && (G_GametypeHasTeams() || G_GametypeHasSpectators()))
{
P_SetPlayerSpectator(player-players);
}
if (player->exiting)
{
player->mo->destscale = 1;