Fix multiplayer ghosts crashing the game sometimes

This commit is contained in:
fickleheart 2019-02-16 21:55:08 -06:00
parent be353c9260
commit 3bd47b3beb
3 changed files with 67 additions and 52 deletions

View File

@ -5196,6 +5196,23 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim)
ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim; ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim;
} }
void G_WriteAllGhostTics(void)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
WRITEUINT8(demo_p, i);
G_WriteGhostTic(players[i].mo, i);
}
WRITEUINT8(demo_p, 0xFF);
}
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
{ {
char ziptic = 0; char ziptic = 0;
@ -5370,6 +5387,17 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
} }
} }
void G_ConsAllGhostTics(void)
{
UINT8 p = READUINT8(demo_p);
while (p != 0xFF)
{
G_ConsGhostTic(p);
p = READUINT8(demo_p);
}
}
// Uses ghost data to do consistency checks on your position. // Uses ghost data to do consistency checks on your position.
// This fixes desynchronising demos when fighting eggman. // This fixes desynchronising demos when fighting eggman.
void G_ConsGhostTic(INT32 playernum) void G_ConsGhostTic(INT32 playernum)
@ -5415,7 +5443,7 @@ void G_ConsGhostTic(INT32 playernum)
if (ziptic & GZT_SPRITE) if (ziptic & GZT_SPRITE)
demo_p++; demo_p++;
if(ziptic & GZT_NIGHTS) { if(ziptic & GZT_NIGHTS) {
if (!testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer) if (!testmo || !testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer)
nightsfail = true; nightsfail = true;
else else
testmo = testmo->tracer; testmo = testmo->tracer;
@ -5480,41 +5508,44 @@ void G_ConsGhostTic(INT32 playernum)
} }
} }
// Re-synchronise if (testmo)
px = testmo->x;
py = testmo->y;
pz = testmo->z;
gx = oldghost[playernum].x;
gy = oldghost[playernum].y;
gz = oldghost[playernum].z;
if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
{ {
if (demosynced) // Re-synchronise
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); px = testmo->x;
demosynced = false; py = testmo->y;
pz = testmo->z;
gx = oldghost[playernum].x;
gy = oldghost[playernum].y;
gz = oldghost[playernum].z;
P_UnsetThingPosition(testmo); if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
testmo->x = oldghost[playernum].x; {
testmo->y = oldghost[playernum].y; if (demosynced)
P_SetThingPosition(testmo); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
testmo->z = oldghost[playernum].z; demosynced = false;
}
if ( P_UnsetThingPosition(testmo);
ghostext[playernum].kartresync && ( testmo->x = oldghost[playernum].x;
players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem || testmo->y = oldghost[playernum].y;
players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount || P_SetThingPosition(testmo);
players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers) testmo->z = oldghost[playernum].z;
) }
{
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
players[playernum].kartstuff[k_itemtype] = ghostext[playernum].kartitem; if (
players[playernum].kartstuff[k_itemamount] = ghostext[playernum].kartamount; ghostext[playernum].kartresync && (
players[playernum].kartstuff[k_bumper] = ghostext[playernum].kartbumpers; players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem ||
players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount ||
players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers)
)
{
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false;
players[playernum].kartstuff[k_itemtype] = ghostext[playernum].kartitem;
players[playernum].kartstuff[k_itemamount] = ghostext[playernum].kartamount;
players[playernum].kartstuff[k_bumper] = ghostext[playernum].kartbumpers;
}
} }
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)

View File

@ -180,7 +180,9 @@ void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
void G_GhostAddFlip(INT32 playernum); void G_GhostAddFlip(INT32 playernum);
void G_GhostAddScale(INT32 playernum, fixed_t scale); void G_GhostAddScale(INT32 playernum, fixed_t scale);
void G_GhostAddHit(INT32 playernum, mobj_t *victim); void G_GhostAddHit(INT32 playernum, mobj_t *victim);
void G_WriteAllGhostTics(void);
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum); void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
void G_ConsAllGhostTics(void);
void G_ConsGhostTic(INT32 playernum); void G_ConsGhostTic(INT32 playernum);
void G_GhostTicker(void); void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal); void G_ReadMetalTic(mobj_t *metal);

View File

@ -728,32 +728,14 @@ void P_Ticker(boolean run)
{ {
if (demorecording) if (demorecording)
{ {
for (i = 0; i < MAXPLAYERS; i++) G_WriteAllGhostTics();
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
G_WriteGhostTic(players[i].mo, i);
}
if (demosavebutton && demosavebutton + 3*TICRATE < leveltime && InputDown(gc_lookback, 1)) if (demosavebutton && demosavebutton + 3*TICRATE < leveltime && InputDown(gc_lookback, 1))
demodefersave = true; demodefersave = true;
} }
if (demoplayback) // Use Ghost data for consistency checks. if (demoplayback) // Use Ghost data for consistency checks.
{ {
for (i = 0; i < MAXPLAYERS; i++) G_ConsAllGhostTics();
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
G_ConsGhostTic(i);
}
} }
} }
else else