Make joins/quits/enters/spectates sync in replays

I'm not 100% sure on joins. That P_RandomByte() call
looks ugly. It'll probably be a source of trouble.
This commit is contained in:
fickleheart 2019-02-01 00:44:35 -06:00
parent 6a131f368f
commit e5be5e80ba
4 changed files with 52 additions and 3 deletions

View file

@ -2479,13 +2479,15 @@ void CL_ClearPlayer(INT32 playernum)
// //
// Removes a player from the current game // Removes a player from the current game
// //
static void CL_RemovePlayer(INT32 playernum, INT32 reason) void CL_RemovePlayer(INT32 playernum, INT32 reason)
{ {
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple // Sanity check: exceptional cases (i.e. c-fails) can cause multiple
// kick commands to be issued for the same player. // kick commands to be issued for the same player.
if (!playeringame[playernum]) if (!playeringame[playernum])
return; return;
demo_extradata[playernum] |= DXD_PLAYSTATE;
if (server && !demoplayback) if (server && !demoplayback)
{ {
INT32 node = playernode[playernum]; INT32 node = playernode[playernum];

View file

@ -549,6 +549,7 @@ void CL_AddSplitscreenPlayer(void);
void CL_RemoveSplitscreenPlayer(UINT8 p); void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void); void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum); void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_UpdateServerList(boolean internetsearch, INT32 room); void CL_UpdateServerList(boolean internetsearch, INT32 room);
// Is there a game running // Is there a game running
boolean Playing(void); boolean Playing(void);

View file

@ -3362,6 +3362,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
return; return;
demo_extradata[playernum] |= DXD_PLAYSTATE;
// Clear player score and rings if a spectator. // Clear player score and rings if a spectator.
if (players[playernum].spectator) if (players[playernum].spectator)
{ {

View file

@ -14,6 +14,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "console.h" #include "console.h"
#include "d_main.h" #include "d_main.h"
#include "d_clisrv.h"
#include "d_player.h" #include "d_player.h"
#include "f_finale.h" #include "f_finale.h"
#include "p_setup.h" #include "p_setup.h"
@ -3032,6 +3033,8 @@ void G_AddPlayer(INT32 playernum)
p->jointime = 0; p->jointime = 0;
p->playerstate = PST_REBORN; p->playerstate = PST_REBORN;
demo_extradata[playernum] |= DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN; // Set everything
} }
void G_ExitLevel(void) void G_ExitLevel(void)
@ -3118,7 +3121,7 @@ boolean G_GametypeHasSpectators(void)
#if 0 #if 0
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
#else #else
return (netgame); //true return (netgame || (multiplayer && demoplayback)); //true
#endif #endif
} }
@ -4607,6 +4610,43 @@ void G_ReadDemoExtraData(void)
extradata = READUINT8(demo_p); extradata = READUINT8(demo_p);
// @TODO uhhhhh do something here // @TODO uhhhhh do something here
switch (extradata) {
case DXD_PST_PLAYING:
players[p].pflags |= PF_WANTSTOJOIN; // fuck you
break;
case DXD_PST_SPECTATING:
if (!playeringame[p])
{
CL_ClearPlayer(p);
playeringame[p] = true;
G_AddPlayer(p);
players[p].spectator = true;
P_RandomByte(); // I'm pretty sure this ISN'T right, but it syncs my one test replay.
}
else
{
players[p].spectator = true;
if (players[p].mo)
P_DamageMobj(players[p].mo, NULL, NULL, 10000);
else
players[p].playerstate = PST_REBORN;
}
break;
case DXD_PST_LEFT:
CL_RemovePlayer(p, 0);
break;
}
// maybe these are necessary?
if (G_BattleGametype())
K_CheckBumpers(); // SRB2Kart
else if (G_RaceGametype())
P_CheckRacers(); // also SRB2Kart
CONS_Printf("Change state @ %d\n", leveltime);
} }
@ -4662,7 +4702,10 @@ void G_WriteDemoExtraData(void)
{ {
if (!playeringame[i]) if (!playeringame[i])
WRITEUINT8(demo_p, DXD_PST_LEFT); WRITEUINT8(demo_p, DXD_PST_LEFT);
else if (players[i].spectator) else if (
players[i].spectator &&
!(players[i].pflags & PF_WANTSTOJOIN) // <= fuck you specifically
)
WRITEUINT8(demo_p, DXD_PST_SPECTATING); WRITEUINT8(demo_p, DXD_PST_SPECTATING);
else else
WRITEUINT8(demo_p, DXD_PST_PLAYING); WRITEUINT8(demo_p, DXD_PST_PLAYING);
@ -6173,6 +6216,7 @@ void G_DoPlayDemo(char *defdemoname)
// Look for the next player // Look for the next player
p = READUINT8(demo_p); p = READUINT8(demo_p);
} }
R_ExecuteSetViewSize(); R_ExecuteSetViewSize();
} }