[WIP, CRASHES] Save ghost data in netreplays

This commit is contained in:
fickleheart 2019-02-16 12:42:24 -06:00
parent 1fa32a4b9d
commit 78adae109a
6 changed files with 152 additions and 147 deletions

View file

@ -320,7 +320,7 @@ static struct {
// EZT_HIT // EZT_HIT
UINT16 hits; UINT16 hits;
mobj_t **hitlist; mobj_t **hitlist;
} ghostext; } ghostext[MAXPLAYERS];
// Your naming conventions are stupid and useless. // Your naming conventions are stupid and useless.
// There is no conflict here. // There is no conflict here.
@ -4675,7 +4675,7 @@ static ticcmd_t oldcmd[MAXPLAYERS];
#define EZT_HIT 0x20 // Damaged a mobj #define EZT_HIT 0x20 // Damaged a mobj
#define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever) #define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever)
static mobj_t oldmetal, oldghost; static mobj_t oldmetal, oldghost[MAXPLAYERS];
void G_SaveMetal(UINT8 **buffer) void G_SaveMetal(UINT8 **buffer)
{ {
@ -4737,6 +4737,7 @@ void G_ReadDemoExtraData(void)
M_Memcpy(name, demo_p, 16); M_Memcpy(name, demo_p, 16);
demo_p += 16; demo_p += 16;
SetPlayerSkin(p, name); SetPlayerSkin(p, name);
CONS_Printf("new skin %d %d\n", players[p].kartspeed, players[p].kartweight);
} }
if (extradata & DXD_COLOR) if (extradata & DXD_COLOR)
{ {
@ -4761,6 +4762,7 @@ void G_ReadDemoExtraData(void)
if (extradata & DXD_PLAYSTATE) if (extradata & DXD_PLAYSTATE)
{ {
extradata = READUINT8(demo_p); extradata = READUINT8(demo_p);
CONS_Printf("player state %d %d\n", p, extradata);
// @TODO uhhhhh do something here // @TODO uhhhhh do something here
@ -4982,71 +4984,71 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
} }
} }
void G_GhostAddThok(void) void G_GhostAddThok(INT32 playernum)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_THOK; ghostext[playernum].flags = (ghostext[playernum].flags & ~EZT_THOKMASK) | EZT_THOK;
} }
void G_GhostAddSpin(void) void G_GhostAddSpin(INT32 playernum)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_SPIN; ghostext[playernum].flags = (ghostext[playernum].flags & ~EZT_THOKMASK) | EZT_SPIN;
} }
void G_GhostAddRev(void) void G_GhostAddRev(INT32 playernum)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_REV; ghostext[playernum].flags = (ghostext[playernum].flags & ~EZT_THOKMASK) | EZT_REV;
} }
void G_GhostAddFlip(void) void G_GhostAddFlip(INT32 playernum)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
ghostext.flags |= EZT_FLIP; ghostext[playernum].flags |= EZT_FLIP;
} }
void G_GhostAddColor(ghostcolor_t color) void G_GhostAddColor(INT32 playernum, ghostcolor_t color)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
if (ghostext.lastcolor == (UINT8)color) if (ghostext[playernum].lastcolor == (UINT8)color)
{ {
ghostext.flags &= ~EZT_COLOR; ghostext[playernum].flags &= ~EZT_COLOR;
return; return;
} }
ghostext.flags |= EZT_COLOR; ghostext[playernum].flags |= EZT_COLOR;
ghostext.color = (UINT8)color; ghostext[playernum].color = (UINT8)color;
} }
void G_GhostAddScale(fixed_t scale) void G_GhostAddScale(INT32 playernum, fixed_t scale)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
if (ghostext.lastscale == scale) if (ghostext[playernum].lastscale == scale)
{ {
ghostext.flags &= ~EZT_SCALE; ghostext[playernum].flags &= ~EZT_SCALE;
return; return;
} }
ghostext.flags |= EZT_SCALE; ghostext[playernum].flags |= EZT_SCALE;
ghostext.scale = scale; ghostext[playernum].scale = scale;
} }
void G_GhostAddHit(mobj_t *victim) void G_GhostAddHit(INT32 playernum, mobj_t *victim)
{ {
if (!demorecording || !(demoflags & DF_GHOST)) if (!demorecording || !(demoflags & DF_GHOST))
return; return;
ghostext.flags |= EZT_HIT; ghostext[playernum].flags |= EZT_HIT;
ghostext.hits++; ghostext[playernum].hits++;
ghostext.hitlist = Z_Realloc(ghostext.hitlist, ghostext.hits * sizeof(mobj_t *), PU_LEVEL, NULL); ghostext[playernum].hitlist = Z_Realloc(ghostext[playernum].hitlist, ghostext[playernum].hits * sizeof(mobj_t *), PU_LEVEL, NULL);
ghostext.hitlist[ghostext.hits-1] = victim; ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim;
} }
void G_WriteGhostTic(mobj_t *ghost) void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
{ {
char ziptic = 0; char ziptic = 0;
UINT8 *ziptic_p; UINT8 *ziptic_p;
@ -5071,38 +5073,38 @@ void G_WriteGhostTic(mobj_t *ghost)
#define MAXMOM (0xFFFF<<8) #define MAXMOM (0xFFFF<<8)
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
if (abs(ghost->x-oldghost.x) > MAXMOM if (abs(ghost->x-oldghost[playernum].x) > MAXMOM
|| abs(ghost->y-oldghost.y) > MAXMOM || abs(ghost->y-oldghost[playernum].y) > MAXMOM
|| abs(ghost->z-oldghost.z) > MAXMOM || abs(ghost->z-oldghost[playernum].z) > MAXMOM
|| leveltime & 255 == 1) // Hack to enable slightly nicer resyncing || (leveltime & 255) == 1) // Hack to enable slightly nicer resyncing
{ {
oldghost.x = ghost->x; oldghost[playernum].x = ghost->x;
oldghost.y = ghost->y; oldghost[playernum].y = ghost->y;
oldghost.z = ghost->z; oldghost[playernum].z = ghost->z;
ziptic |= GZT_XYZ; ziptic |= GZT_XYZ;
WRITEFIXED(demo_p,oldghost.x); WRITEFIXED(demo_p,oldghost[playernum].x);
WRITEFIXED(demo_p,oldghost.y); WRITEFIXED(demo_p,oldghost[playernum].y);
WRITEFIXED(demo_p,oldghost.z); WRITEFIXED(demo_p,oldghost[playernum].z);
} }
else else
{ {
// For moving normally: // For moving normally:
// Store one full byte of movement, plus one byte of fractional movement. // Store one full byte of movement, plus one byte of fractional movement.
INT16 momx = (INT16)((ghost->x-oldghost.x + (1<<4))>>8); INT16 momx = (INT16)((ghost->x-oldghost[playernum].x + (1<<4))>>8);
INT16 momy = (INT16)((ghost->y-oldghost.y + (1<<4))>>8); INT16 momy = (INT16)((ghost->y-oldghost[playernum].y + (1<<4))>>8);
if (momx != oldghost.momx if (momx != oldghost[playernum].momx
|| momy != oldghost.momy) || momy != oldghost[playernum].momy)
{ {
oldghost.momx = momx; oldghost[playernum].momx = momx;
oldghost.momy = momy; oldghost[playernum].momy = momy;
ziptic |= GZT_MOMXY; ziptic |= GZT_MOMXY;
WRITEINT16(demo_p,momx); WRITEINT16(demo_p,momx);
WRITEINT16(demo_p,momy); WRITEINT16(demo_p,momy);
} }
momx = (INT16)((ghost->z-oldghost.z + (1<<4))>>8); momx = (INT16)((ghost->z-oldghost[playernum].z + (1<<4))>>8);
if (momx != oldghost.momz) if (momx != oldghost[playernum].momz)
{ {
oldghost.momz = momx; oldghost[playernum].momz = momx;
ziptic |= GZT_MOMZ; ziptic |= GZT_MOMZ;
WRITEINT16(demo_p,momx); WRITEINT16(demo_p,momx);
} }
@ -5110,9 +5112,9 @@ void G_WriteGhostTic(mobj_t *ghost)
// This SHOULD set oldghost.x/y/z to match ghost->x/y/z // This SHOULD set oldghost.x/y/z to match ghost->x/y/z
// but it keeps the fractional loss of one byte, // but it keeps the fractional loss of one byte,
// so it will hopefully be made up for in future tics. // so it will hopefully be made up for in future tics.
oldghost.x += oldghost.momx<<8; oldghost[playernum].x += oldghost[playernum].momx<<8;
oldghost.y += oldghost.momy<<8; oldghost[playernum].y += oldghost[playernum].momy<<8;
oldghost.z += oldghost.momz<<8; oldghost[playernum].z += oldghost[playernum].momz<<8;
} }
#undef MAXMOM #undef MAXMOM
@ -5120,56 +5122,56 @@ void G_WriteGhostTic(mobj_t *ghost)
// Only store the 8 most relevant bits of angle // Only store the 8 most relevant bits of angle
// because exact values aren't too easy to discern to begin with when only 8 angles have different sprites // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites
// and it does not affect this mode of movement at all anyway. // and it does not affect this mode of movement at all anyway.
if (ghost->angle>>24 != oldghost.angle) if (ghost->angle>>24 != oldghost[playernum].angle)
{ {
oldghost.angle = ghost->angle>>24; oldghost[playernum].angle = ghost->angle>>24;
ziptic |= GZT_ANGLE; ziptic |= GZT_ANGLE;
WRITEUINT8(demo_p,oldghost.angle); WRITEUINT8(demo_p,oldghost[playernum].angle);
} }
// Store the sprite frame. // Store the sprite frame.
frame = ghost->frame & 0xFF; frame = ghost->frame & 0xFF;
if (frame != oldghost.frame) if (frame != oldghost[playernum].frame)
{ {
oldghost.frame = frame; oldghost[playernum].frame = frame;
ziptic |= GZT_SPRITE; ziptic |= GZT_SPRITE;
WRITEUINT8(demo_p,oldghost.frame); WRITEUINT8(demo_p,oldghost[playernum].frame);
} }
// Check for sprite set changes // Check for sprite set changes
sprite = ghost->sprite; sprite = ghost->sprite;
if (sprite != oldghost.sprite) if (sprite != oldghost[playernum].sprite)
{ {
oldghost.sprite = sprite; oldghost[playernum].sprite = sprite;
ghostext.flags |= EZT_SPRITE; ghostext[playernum].flags |= EZT_SPRITE;
} }
if (ghostext.flags) if (ghostext[playernum].color == ghostext[playernum].lastcolor)
ghostext[playernum].flags &= ~EZT_COLOR;
if (ghostext[playernum].scale == ghostext[playernum].lastscale)
ghostext[playernum].flags &= ~EZT_SCALE;
if (ghostext[playernum].flags)
{ {
ziptic |= GZT_EXTRA; ziptic |= GZT_EXTRA;
WRITEUINT8(demo_p,ghostext[playernum].flags);
if (ghostext.color == ghostext.lastcolor) if (ghostext[playernum].flags & EZT_COLOR)
ghostext.flags &= ~EZT_COLOR;
if (ghostext.scale == ghostext.lastscale)
ghostext.flags &= ~EZT_SCALE;
WRITEUINT8(demo_p,ghostext.flags);
if (ghostext.flags & EZT_COLOR)
{ {
WRITEUINT8(demo_p,ghostext.color); WRITEUINT8(demo_p,ghostext[playernum].color);
ghostext.lastcolor = ghostext.color; ghostext[playernum].lastcolor = ghostext[playernum].color;
} }
if (ghostext.flags & EZT_SCALE) if (ghostext[playernum].flags & EZT_SCALE)
{ {
WRITEFIXED(demo_p,ghostext.scale); WRITEFIXED(demo_p,ghostext[playernum].scale);
ghostext.lastscale = ghostext.scale; ghostext[playernum].lastscale = ghostext[playernum].scale;
} }
if (ghostext.flags & EZT_HIT) if (ghostext[playernum].flags & EZT_HIT)
{ {
WRITEUINT16(demo_p,ghostext.hits); WRITEUINT16(demo_p,ghostext[playernum].hits);
for (i = 0; i < ghostext.hits; i++) for (i = 0; i < ghostext[playernum].hits; i++)
{ {
mobj_t *mo = ghostext.hitlist[i]; mobj_t *mo = ghostext[playernum].hitlist[i];
WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.) WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.)
WRITEUINT32(demo_p,mo->type); WRITEUINT32(demo_p,mo->type);
WRITEUINT16(demo_p,(UINT16)mo->health); WRITEUINT16(demo_p,(UINT16)mo->health);
@ -5178,13 +5180,13 @@ void G_WriteGhostTic(mobj_t *ghost)
WRITEFIXED(demo_p,mo->z); WRITEFIXED(demo_p,mo->z);
WRITEANGLE(demo_p,mo->angle); WRITEANGLE(demo_p,mo->angle);
} }
Z_Free(ghostext.hitlist); Z_Free(ghostext[playernum].hitlist);
ghostext.hits = 0; ghostext[playernum].hits = 0;
ghostext.hitlist = NULL; ghostext[playernum].hitlist = NULL;
} }
if (ghostext.flags & EZT_SPRITE) if (ghostext[playernum].flags & EZT_SPRITE)
WRITEUINT8(demo_p,sprite); WRITEUINT8(demo_p,sprite);
ghostext.flags = 0; ghostext[playernum].flags = 0;
} }
*ziptic_p = ziptic; *ziptic_p = ziptic;
@ -5200,7 +5202,7 @@ void G_WriteGhostTic(mobj_t *ghost)
// 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(void) void G_ConsGhostTic(INT32 playernum)
{ {
UINT8 ziptic; UINT8 ziptic;
UINT32 px,py,pz,gx,gy,gz; UINT32 px,py,pz,gx,gy,gz;
@ -5213,29 +5215,29 @@ void G_ConsGhostTic(void)
if (!(demoflags & DF_GHOST)) if (!(demoflags & DF_GHOST))
return; // No ghost data to use. return; // No ghost data to use.
testmo = players[0].mo; testmo = players[playernum].mo;
// Grab ghost data. // Grab ghost data.
ziptic = READUINT8(demo_p); ziptic = READUINT8(demo_p);
if (ziptic & GZT_XYZ) if (ziptic & GZT_XYZ)
{ {
oldghost.x = READFIXED(demo_p); oldghost[playernum].x = READFIXED(demo_p);
oldghost.y = READFIXED(demo_p); oldghost[playernum].y = READFIXED(demo_p);
oldghost.z = READFIXED(demo_p); oldghost[playernum].z = READFIXED(demo_p);
syncleeway = 0; syncleeway = 0;
} }
else else
{ {
if (ziptic & GZT_MOMXY) if (ziptic & GZT_MOMXY)
{ {
oldghost.momx = READINT16(demo_p)<<8; oldghost[playernum].momx = READINT16(demo_p)<<8;
oldghost.momy = READINT16(demo_p)<<8; oldghost[playernum].momy = READINT16(demo_p)<<8;
} }
if (ziptic & GZT_MOMZ) if (ziptic & GZT_MOMZ)
oldghost.momz = READINT16(demo_p)<<8; oldghost[playernum].momz = READINT16(demo_p)<<8;
oldghost.x += oldghost.momx; oldghost[playernum].x += oldghost[playernum].momx;
oldghost.y += oldghost.momy; oldghost[playernum].y += oldghost[playernum].momy;
oldghost.z += oldghost.momz; oldghost[playernum].z += oldghost[playernum].momz;
syncleeway = FRACUNIT; syncleeway = FRACUNIT;
} }
if (ziptic & GZT_ANGLE) if (ziptic & GZT_ANGLE)
@ -5305,21 +5307,21 @@ void G_ConsGhostTic(void)
px = testmo->x; px = testmo->x;
py = testmo->y; py = testmo->y;
pz = testmo->z; pz = testmo->z;
gx = oldghost.x; gx = oldghost[playernum].x;
gy = oldghost.y; gy = oldghost[playernum].y;
gz = oldghost.z; gz = oldghost[playernum].z;
if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway) if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
{ {
if (demosynced) if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced! %d>%d %d>%d %d>%d\n"), px, gx, py, gy, pz, gz);
demosynced = false; demosynced = false;
P_UnsetThingPosition(testmo); P_UnsetThingPosition(testmo);
testmo->x = oldghost.x; testmo->x = oldghost[playernum].x;
testmo->y = oldghost.y; testmo->y = oldghost[playernum].y;
P_SetThingPosition(testmo); P_SetThingPosition(testmo);
testmo->z = oldghost.z; testmo->z = oldghost[playernum].z;
} }
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)
@ -5775,7 +5777,7 @@ void G_BeginRecording(void)
memset(name,0,sizeof(name)); memset(name,0,sizeof(name));
demo_p = demobuffer; demo_p = demobuffer;
demoflags = multiplayer ? DF_MULTIPLAYER : (DF_GHOST|(modeattacking<<DF_ATTACKSHIFT)); demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<<DF_ATTACKSHIFT));
demoflags |= gametype<<DF_GAMESHIFT; demoflags |= gametype<<DF_GAMESHIFT;
@ -5853,13 +5855,7 @@ void G_BeginRecording(void)
WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing
memset(&oldcmd,0,sizeof(oldcmd)); goto initcmdandghost;
memset(&demo_extradata, 0, sizeof(demo_extradata));
// Lower two lines aren't useful until ghost replays for mp are implemented, but eh
memset(&oldghost,0,sizeof(oldghost));
memset(&ghostext,0,sizeof(ghostext));
return;
} }
// Name // Name
@ -5909,22 +5905,27 @@ void G_BeginRecording(void)
// Save netvar data (SONICCD, etc) // Save netvar data (SONICCD, etc)
CV_SaveNetVars(&demo_p, false); //@TODO can this be true? it's not necessary for now but would be nice for consistency CV_SaveNetVars(&demo_p, false); //@TODO can this be true? it's not necessary for now but would be nice for consistency
initcmdandghost:
memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost)); memset(&oldghost,0,sizeof(oldghost));
memset(&ghostext,0,sizeof(ghostext)); memset(&ghostext,0,sizeof(ghostext));
ghostext.lastcolor = ghostext.color = GHC_NORMAL;
ghostext.lastscale = ghostext.scale = FRACUNIT;
if (player->mo) for (i = 0; i < MAXPLAYERS; i++)
{ {
oldghost.x = player->mo->x; ghostext[i].lastcolor = ghostext[i].color = GHC_NORMAL;
oldghost.y = player->mo->y; ghostext[i].lastscale = ghostext[i].scale = FRACUNIT;
oldghost.z = player->mo->z;
oldghost.angle = player->mo->angle;
// preticker started us gravity flipped if (players[i].mo)
if (player->mo->eflags & MFE_VERTICALFLIP) {
ghostext.flags |= EZT_FLIP; oldghost[i].x = players[i].mo->x;
oldghost[i].y = players[i].mo->y;
oldghost[i].z = players[i].mo->z;
oldghost[i].angle = players[i].mo->angle;
// preticker started us gravity flipped
if (players[i].mo->eflags & MFE_VERTICALFLIP)
ghostext[i].flags |= EZT_FLIP;
}
} }
} }
@ -6409,15 +6410,19 @@ void G_DoPlayDemo(char *defdemoname)
P_SetRandSeed(randseed); P_SetRandSeed(randseed);
G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
for (i = 0; i < MAXPLAYERS; i++)
{
if (players[i].mo)
{
players[i].mo->color = players[i].skincolor;
oldghost[i].x = players[i].mo->x;
oldghost[i].y = players[i].mo->y;
oldghost[i].z = players[i].mo->z;
}
}
if (!multiplayer) { if (!multiplayer) {
//CV_StealthSetValue(&cv_playercolor, players[0].skincolor); -- as far as I can tell this is more trouble than it's worth //CV_StealthSetValue(&cv_playercolor, players[0].skincolor); -- as far as I can tell this is more trouble than it's worth
if (players[0].mo)
{
players[0].mo->color = players[0].skincolor;
oldghost.x = players[0].mo->x;
oldghost.y = players[0].mo->y;
oldghost.z = players[0].mo->z;
}
// Set saved attribute values // Set saved attribute values
// No cheat checking here, because even if they ARE wrong... // No cheat checking here, because even if they ARE wrong...

View file

@ -170,15 +170,15 @@ void G_ReadDemoExtraData(void);
void G_WriteDemoExtraData(void); void G_WriteDemoExtraData(void);
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum); void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum); void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void); void G_GhostAddThok(INT32 playernum);
void G_GhostAddSpin(void); void G_GhostAddSpin(INT32 playernum);
void G_GhostAddRev(void); void G_GhostAddRev(INT32 playernum);
void G_GhostAddColor(ghostcolor_t color); void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
void G_GhostAddFlip(void); void G_GhostAddFlip(INT32 playernum);
void G_GhostAddScale(fixed_t scale); void G_GhostAddScale(INT32 playernum, fixed_t scale);
void G_GhostAddHit(mobj_t *victim); void G_GhostAddHit(INT32 playernum, mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost); void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
void G_ConsGhostTic(void); 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);
void G_WriteMetalTic(mobj_t *metal); void G_WriteMetalTic(mobj_t *metal);

View file

@ -3079,7 +3079,7 @@ void A_Invincibility(mobj_t *actor)
{ {
S_StopMusic(); S_StopMusic();
if (mariomode) if (mariomode)
G_GhostAddColor(GHC_INVINCIBLE); G_GhostAddColor((INT32) (player - players), GHC_INVINCIBLE);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false); S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
} }
} }

View file

@ -1424,7 +1424,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
player->powers[pw_shield] |= SH_FIREFLOWER; player->powers[pw_shield] |= SH_FIREFLOWER;
toucher->color = SKINCOLOR_WHITE; toucher->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER); G_GhostAddColor(player - players, GHC_FIREFLOWER);
break; break;
// *************** // // *************** //
@ -3028,7 +3028,7 @@ void P_RemoveShield(player_t *player)
if (!player->powers[pw_super]) if (!player->powers[pw_super])
{ {
player->mo->color = player->skincolor; player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL); G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
} }
} }
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) // Give them what's coming to them! else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) // Give them what's coming to them!
@ -3459,7 +3459,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
target->health -= damage; target->health -= damage;
if (source && source->player && target) if (source && source->player && target)
G_GhostAddHit(target); G_GhostAddHit((INT32) (source->player - players), target);
if (target->health <= 0) if (target->health <= 0)
{ {

View file

@ -1220,7 +1220,7 @@ static void P_PlayerFlip(mobj_t *mo)
if (!mo->player) if (!mo->player)
return; return;
G_GhostAddFlip(); G_GhostAddFlip((INT32) (mo->player - players));
// Flip aiming to match! // Flip aiming to match!
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam
@ -6010,7 +6010,7 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
if (player) if (player)
{ {
G_GhostAddScale(newscale); G_GhostAddScale((INT32) (player - players), newscale);
player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it! player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it!
player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size
} }

View file

@ -1708,7 +1708,7 @@ void P_SpawnThokMobj(player_t *player)
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
if (demorecording) if (demorecording)
G_GhostAddThok(); G_GhostAddThok((INT32) (player - players));
} }
// //
@ -2416,12 +2416,12 @@ static void P_CheckInvincibilityTimer(player_t *player)
//if (player->powers[pw_shield] & SH_FIREFLOWER) //if (player->powers[pw_shield] & SH_FIREFLOWER)
//{ //{
// player->mo->color = SKINCOLOR_WHITE; // player->mo->color = SKINCOLOR_WHITE;
// G_GhostAddColor(GHC_FIREFLOWER); // G_GhostAddColor((INT32) (player - players), GHC_FIREFLOWER);
//} //}
//else //else
{ {
player->mo->color = player->skincolor; player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL); G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
} }
} }
@ -3673,12 +3673,12 @@ static void P_DoSuperStuff(player_t *player)
if (player->powers[pw_shield] & SH_FIREFLOWER) if (player->powers[pw_shield] & SH_FIREFLOWER)
{ {
player->mo->color = SKINCOLOR_WHITE; player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER); G_GhostAddColor((INT32) (player - players), GHC_FIREFLOWER);
} }
else else
{ {
player->mo->color = player->skincolor; player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL); G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
} }
if (gametype != GT_COOP) if (gametype != GT_COOP)
@ -3714,7 +3714,7 @@ static void P_DoSuperStuff(player_t *player)
P_SetScale(spark, player->mo->scale); P_SetScale(spark, player->mo->scale);
} }
G_GhostAddColor(GHC_SUPER); G_GhostAddColor((INT32) (player - players), GHC_SUPER);
// Ran out of rings while super! // Ran out of rings while super!
if (player->health <= 1 || player->exiting) if (player->health <= 1 || player->exiting)
@ -3728,12 +3728,12 @@ static void P_DoSuperStuff(player_t *player)
if (player->powers[pw_shield] & SH_FIREFLOWER) if (player->powers[pw_shield] & SH_FIREFLOWER)
{ {
player->mo->color = SKINCOLOR_WHITE; player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER); G_GhostAddColor((INT32) (player - players), GHC_FIREFLOWER);
} }
else else
{ {
player->mo->color = player->skincolor; player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL); G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
} }
if (gametype != GT_COOP) if (gametype != GT_COOP)
@ -4035,7 +4035,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // SRB2kart - unused.
// Now spawn the color thok circle. // Now spawn the color thok circle.
P_SpawnSpinMobj(player, player->revitem); P_SpawnSpinMobj(player, player->revitem);
if (demorecording) if (demorecording)
G_GhostAddRev(); G_GhostAddRev((INT32) (player - players));
} }
} }
// If not moving up or down, and travelling faster than a speed of four while not holding // If not moving up or down, and travelling faster than a speed of four while not holding
@ -7017,7 +7017,7 @@ static void P_MovePlayer(player_t *player)
{ {
P_SpawnSpinMobj(player, player->spinitem); P_SpawnSpinMobj(player, player->spinitem);
if (demorecording) if (demorecording)
G_GhostAddSpin(); G_GhostAddSpin((INT32) (player - players));
} }
*/ */