mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'replay_fuckery' into 'master'
Replay fuckery (resolves #95) Closes #95 See merge request KartKrew/Kart!338
This commit is contained in:
commit
8861da8108
10 changed files with 145 additions and 132 deletions
|
|
@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = {
|
||||||
|
|
||||||
// player's followers. Also saved.
|
// player's followers. Also saved.
|
||||||
consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = {
|
consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = {
|
||||||
CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
|
CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
|
||||||
CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
|
CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
|
||||||
CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
|
CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
|
||||||
CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
|
CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
|
||||||
};
|
};
|
||||||
|
|
||||||
// player's follower colors... Also saved...
|
// player's follower colors... Also saved...
|
||||||
|
|
@ -2858,13 +2858,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
memset(&luabanks, 0, sizeof(luabanks));
|
memset(&luabanks, 0, sizeof(luabanks));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modeattacking)
|
|
||||||
{
|
|
||||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
|
||||||
players[0].skincolor = skins[players[0].skin].prefcolor;
|
|
||||||
CV_StealthSetValue(&cv_playercolor[0], players[0].skincolor);
|
|
||||||
}
|
|
||||||
|
|
||||||
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
mapnumber = M_MapNumber(mapname[3], mapname[4]);
|
||||||
LUAh_MapChange(mapnumber);
|
LUAh_MapChange(mapnumber);
|
||||||
|
|
||||||
|
|
|
||||||
150
src/g_demo.c
150
src/g_demo.c
|
|
@ -104,7 +104,7 @@ demoghost *ghosts = NULL;
|
||||||
// DEMO RECORDING
|
// DEMO RECORDING
|
||||||
//
|
//
|
||||||
|
|
||||||
#define DEMOVERSION 0x0004
|
#define DEMOVERSION 0x0007
|
||||||
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
||||||
|
|
||||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||||
|
|
@ -112,7 +112,7 @@ demoghost *ghosts = NULL;
|
||||||
#define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time!
|
#define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time!
|
||||||
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
|
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
|
||||||
|
|
||||||
#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability
|
#define DF_LUAVARS 0x20 // this demo contains extra lua vars
|
||||||
|
|
||||||
#define DF_ATTACKSHIFT 1
|
#define DF_ATTACKSHIFT 1
|
||||||
#define DF_ENCORE 0x40
|
#define DF_ENCORE 0x40
|
||||||
|
|
@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void)
|
||||||
{
|
{
|
||||||
// write follower
|
// write follower
|
||||||
memset(name, 0, 16);
|
memset(name, 0, 16);
|
||||||
strncpy(name, followers[players[i].followerskin].skinname, 16);
|
if (players[i].followerskin == -1)
|
||||||
|
strncpy(name, "None", 16);
|
||||||
|
else
|
||||||
|
strncpy(name, followers[players[i].followerskin].skinname, 16);
|
||||||
M_Memcpy(demo_p, name, 16);
|
M_Memcpy(demo_p, name, 16);
|
||||||
demo_p += 16;
|
demo_p += 16;
|
||||||
|
|
||||||
|
|
@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void)
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
|
if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WRITEUINT8(demo_p, i);
|
WRITEUINT8(demo_p, i);
|
||||||
G_WriteGhostTic(players[i].mo, i);
|
G_WriteGhostTic(players[i].mo, i);
|
||||||
}
|
}
|
||||||
WRITEUINT8(demo_p, 0xFF);
|
WRITEUINT8(demo_p, 0xFF);
|
||||||
|
|
||||||
|
// attention here for the ticcmd size!
|
||||||
|
// latest demos with mouse aiming byte in ticcmd
|
||||||
|
if (demo_p >= demoend - (13 + 9 + 9))
|
||||||
|
{
|
||||||
|
G_CheckDemoStatus(); // no more space
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||||
|
|
@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||||
ghostext[playernum].flags |= EZT_SPRITE;
|
ghostext[playernum].flags |= EZT_SPRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ghost->player && (
|
||||||
|
ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] ||
|
||||||
|
ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] ||
|
||||||
|
ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper]
|
||||||
|
))
|
||||||
|
{
|
||||||
|
ghostext[playernum].flags |= EZT_KART;
|
||||||
|
ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype];
|
||||||
|
ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount];
|
||||||
|
ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper];
|
||||||
|
}
|
||||||
|
|
||||||
if (ghostext[playernum].flags)
|
if (ghostext[playernum].flags)
|
||||||
{
|
{
|
||||||
ziptic |= GZT_EXTRA;
|
ziptic |= GZT_EXTRA;
|
||||||
|
|
||||||
if (ghost->player)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] ||
|
|
||||||
ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] ||
|
|
||||||
ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper]
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ghostext[playernum].flags |= EZT_KART;
|
|
||||||
ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype];
|
|
||||||
ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount];
|
|
||||||
ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ghostext[playernum].color == ghostext[playernum].lastcolor)
|
if (ghostext[playernum].color == ghostext[playernum].lastcolor)
|
||||||
ghostext[playernum].flags &= ~EZT_COLOR;
|
ghostext[playernum].flags &= ~EZT_COLOR;
|
||||||
if (ghostext[playernum].scale == ghostext[playernum].lastscale)
|
if (ghostext[playernum].scale == ghostext[playernum].lastscale)
|
||||||
|
|
@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||||
oldghost[playernum].flags2 &= ~MF2_AMBUSH;
|
oldghost[playernum].flags2 &= ~MF2_AMBUSH;
|
||||||
|
|
||||||
*ziptic_p = ziptic;
|
*ziptic_p = ziptic;
|
||||||
|
|
||||||
// attention here for the ticcmd size!
|
|
||||||
// latest demos with mouse aiming byte in ticcmd
|
|
||||||
if (demo_p >= demoend - (13 + 9 + 9))
|
|
||||||
{
|
|
||||||
G_CheckDemoStatus(); // no more space
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_ConsAllGhostTics(void)
|
void G_ConsAllGhostTics(void)
|
||||||
|
|
@ -1067,16 +1066,18 @@ void G_GhostTicker(void)
|
||||||
if (ziptic & DXD_FOLLOWER)
|
if (ziptic & DXD_FOLLOWER)
|
||||||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||||
if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING)
|
if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING)
|
||||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this
|
||||||
}
|
}
|
||||||
else if (ziptic == DW_RNG)
|
else if (ziptic == DW_RNG)
|
||||||
g->p += 4; // RNG seed
|
g->p += 4; // RNG seed
|
||||||
else
|
else
|
||||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
I_Error("Ghost is not a record attack ghost DXD"); //@TODO lmao don't blow up like this
|
||||||
|
|
||||||
ziptic = READUINT8(g->p);
|
ziptic = READUINT8(g->p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ziptic = READUINT8(g->p);
|
||||||
|
|
||||||
if (ziptic & ZT_FWD)
|
if (ziptic & ZT_FWD)
|
||||||
g->p++;
|
g->p++;
|
||||||
if (ziptic & ZT_TURNING)
|
if (ziptic & ZT_TURNING)
|
||||||
|
|
@ -1086,9 +1087,9 @@ void G_GhostTicker(void)
|
||||||
if (ziptic & ZT_AIMING)
|
if (ziptic & ZT_AIMING)
|
||||||
g->p += 2;
|
g->p += 2;
|
||||||
if (ziptic & ZT_LATENCY)
|
if (ziptic & ZT_LATENCY)
|
||||||
g->p += 1;
|
g->p++;
|
||||||
if (ziptic & ZT_FLAGS)
|
if (ziptic & ZT_FLAGS)
|
||||||
g->p += 1;
|
g->p++;
|
||||||
|
|
||||||
// Grab ghost data.
|
// Grab ghost data.
|
||||||
ziptic = READUINT8(g->p);
|
ziptic = READUINT8(g->p);
|
||||||
|
|
@ -1096,7 +1097,7 @@ void G_GhostTicker(void)
|
||||||
if (ziptic == 0xFF)
|
if (ziptic == 0xFF)
|
||||||
goto skippedghosttic; // Didn't write ghost info this frame
|
goto skippedghosttic; // Didn't write ghost info this frame
|
||||||
else if (ziptic != 0)
|
else if (ziptic != 0)
|
||||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this
|
||||||
ziptic = READUINT8(g->p);
|
ziptic = READUINT8(g->p);
|
||||||
|
|
||||||
if (ziptic & GZT_XYZ)
|
if (ziptic & GZT_XYZ)
|
||||||
|
|
@ -1109,17 +1110,17 @@ void G_GhostTicker(void)
|
||||||
{
|
{
|
||||||
if (ziptic & GZT_MOMXY)
|
if (ziptic & GZT_MOMXY)
|
||||||
{
|
{
|
||||||
g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
g->oldmo.momx = READFIXED(g->p);
|
||||||
g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
g->oldmo.momy = READFIXED(g->p);
|
||||||
}
|
}
|
||||||
if (ziptic & GZT_MOMZ)
|
if (ziptic & GZT_MOMZ)
|
||||||
g->oldmo.momz = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
|
g->oldmo.momz = READFIXED(g->p);
|
||||||
g->oldmo.x += g->oldmo.momx;
|
g->oldmo.x += g->oldmo.momx;
|
||||||
g->oldmo.y += g->oldmo.momy;
|
g->oldmo.y += g->oldmo.momy;
|
||||||
g->oldmo.z += g->oldmo.momz;
|
g->oldmo.z += g->oldmo.momz;
|
||||||
}
|
}
|
||||||
if (ziptic & GZT_ANGLE)
|
if (ziptic & GZT_ANGLE)
|
||||||
g->mo->angle = READUINT8(g->p)<<24;
|
g->oldmo.angle = READUINT8(g->p)<<24;
|
||||||
if (ziptic & GZT_FRAME)
|
if (ziptic & GZT_FRAME)
|
||||||
g->oldmo.frame = READUINT8(g->p);
|
g->oldmo.frame = READUINT8(g->p);
|
||||||
if (ziptic & GZT_SPR2)
|
if (ziptic & GZT_SPR2)
|
||||||
|
|
@ -1205,30 +1206,6 @@ void G_GhostTicker(void)
|
||||||
g->p += 12; // kartitem, kartamount, kartbumpers
|
g->p += 12; // kartitem, kartamount, kartbumpers
|
||||||
}
|
}
|
||||||
|
|
||||||
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
|
||||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
|
||||||
|
|
||||||
skippedghosttic:
|
|
||||||
// Tick ghost colors (Super and Mario Invincibility flashing)
|
|
||||||
switch(g->color)
|
|
||||||
{
|
|
||||||
case GHC_SUPER: // Super (P_DoSuperStuff)
|
|
||||||
if (g->mo->skin)
|
|
||||||
{
|
|
||||||
skin_t *skin = (skin_t *)g->mo->skin;
|
|
||||||
g->mo->color = skin->supercolor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g->mo->color = SKINCOLOR_SUPERGOLD1;
|
|
||||||
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
|
|
||||||
break;
|
|
||||||
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
|
|
||||||
g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define follow g->mo->tracer
|
#define follow g->mo->tracer
|
||||||
if (ziptic & GZT_FOLLOW)
|
if (ziptic & GZT_FOLLOW)
|
||||||
{ // Even more...
|
{ // Even more...
|
||||||
|
|
@ -1294,6 +1271,31 @@ skippedghosttic:
|
||||||
P_RemoveMobj(follow);
|
P_RemoveMobj(follow);
|
||||||
P_SetTarget(&follow, NULL);
|
P_SetTarget(&follow, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skippedghosttic:
|
||||||
|
// Tick ghost colors (Super and Mario Invincibility flashing)
|
||||||
|
switch(g->color)
|
||||||
|
{
|
||||||
|
case GHC_SUPER: // Super (P_DoSuperStuff)
|
||||||
|
if (g->mo->skin)
|
||||||
|
{
|
||||||
|
skin_t *skin = (skin_t *)g->mo->skin;
|
||||||
|
g->mo->color = skin->supercolor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g->mo->color = SKINCOLOR_SUPERGOLD1;
|
||||||
|
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
|
||||||
|
break;
|
||||||
|
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
|
||||||
|
g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
||||||
|
I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this
|
||||||
|
|
||||||
// Demo ends after ghost data.
|
// Demo ends after ghost data.
|
||||||
if (*g->p == DEMOMARKER)
|
if (*g->p == DEMOMARKER)
|
||||||
{
|
{
|
||||||
|
|
@ -1314,6 +1316,7 @@ skippedghosttic:
|
||||||
Z_Free(g);
|
Z_Free(g);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = g;
|
p = g;
|
||||||
#undef follow
|
#undef follow
|
||||||
}
|
}
|
||||||
|
|
@ -1436,8 +1439,11 @@ void G_PreviewRewind(tic_t previewtime)
|
||||||
players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue);
|
players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue);
|
||||||
|
|
||||||
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||||
|
players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2;
|
||||||
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
||||||
|
|
||||||
|
players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag;
|
||||||
|
|
||||||
players[i].realtime = info->playerinfo[i].player.realtime;
|
players[i].realtime = info->playerinfo[i].player.realtime;
|
||||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||||
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||||
|
|
@ -1462,7 +1468,7 @@ void G_ConfirmRewind(tic_t rewindtime)
|
||||||
|
|
||||||
if (rewindtime <= starttime)
|
if (rewindtime <= starttime)
|
||||||
{
|
{
|
||||||
demo.rewinding = false;
|
demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again
|
||||||
G_DoPlayDemo(NULL); // Restart the current demo
|
G_DoPlayDemo(NULL); // Restart the current demo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1899,7 +1905,8 @@ void G_BeginRecording(void)
|
||||||
if (encoremode)
|
if (encoremode)
|
||||||
demoflags |= DF_ENCORE;
|
demoflags |= DF_ENCORE;
|
||||||
|
|
||||||
demoflags |= DF_LUAVARS;
|
if (multiplayer)
|
||||||
|
demoflags |= DF_LUAVARS;
|
||||||
|
|
||||||
// Setup header.
|
// Setup header.
|
||||||
M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12;
|
M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12;
|
||||||
|
|
@ -2033,9 +2040,8 @@ 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
|
||||||
|
|
||||||
// player lua vars, always saved even if empty
|
// player lua vars, always saved even if empty
|
||||||
LUA_Archive(&demo_p);
|
if (demoflags & DF_LUAVARS)
|
||||||
|
LUA_Archive(&demo_p);
|
||||||
WRITEUINT32(demo_p,P_GetInitSeed());
|
|
||||||
|
|
||||||
memset(&oldcmd,0,sizeof(oldcmd));
|
memset(&oldcmd,0,sizeof(oldcmd));
|
||||||
memset(&oldghost,0,sizeof(oldghost));
|
memset(&oldghost,0,sizeof(oldghost));
|
||||||
|
|
@ -2712,7 +2718,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
demo.version = READUINT16(demo_p);
|
demo.version = READUINT16(demo_p);
|
||||||
switch(demo.version)
|
switch(demo.version)
|
||||||
{
|
{
|
||||||
case 0x000d:
|
|
||||||
case DEMOVERSION: // latest always supported
|
case DEMOVERSION: // latest always supported
|
||||||
break;
|
break;
|
||||||
// too old, cannot support.
|
// too old, cannot support.
|
||||||
|
|
@ -3101,7 +3106,6 @@ void G_AddGhost(char *defdemoname)
|
||||||
ghostversion = READUINT16(p);
|
ghostversion = READUINT16(p);
|
||||||
switch(ghostversion)
|
switch(ghostversion)
|
||||||
{
|
{
|
||||||
case 0x000d:
|
|
||||||
case DEMOVERSION: // latest always supported
|
case DEMOVERSION: // latest always supported
|
||||||
break;
|
break;
|
||||||
// too old, cannot support.
|
// too old, cannot support.
|
||||||
|
|
@ -3145,6 +3149,14 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & DF_LUAVARS) // can't be arsed to add support for grinding away ported lua material
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Replay data contains luavars, cannot continue.\n"), pdemoname);
|
||||||
|
Z_Free(pdemoname);
|
||||||
|
Z_Free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p++; // gametype
|
p++; // gametype
|
||||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||||
|
|
||||||
|
|
@ -3211,6 +3223,8 @@ void G_AddGhost(char *defdemoname)
|
||||||
kartspeed = READUINT8(p);
|
kartspeed = READUINT8(p);
|
||||||
kartweight = READUINT8(p);
|
kartweight = READUINT8(p);
|
||||||
|
|
||||||
|
p += 4; // followitem (maybe change later)
|
||||||
|
|
||||||
if (READUINT8(p) != 0xFF)
|
if (READUINT8(p) != 0xFF)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||||
|
|
|
||||||
|
|
@ -1252,7 +1252,7 @@ void G_StartTitleCard(void)
|
||||||
{
|
{
|
||||||
// The title card has been disabled for this map.
|
// The title card has been disabled for this map.
|
||||||
// Oh well.
|
// Oh well.
|
||||||
if (!G_IsTitleCardAvailable())
|
if (!G_IsTitleCardAvailable() || demo.rewinding)
|
||||||
{
|
{
|
||||||
WipeStageTitle = false;
|
WipeStageTitle = false;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -3523,7 +3523,7 @@ static void K_drawInput(void)
|
||||||
#define BUTTH 11
|
#define BUTTH 11
|
||||||
|
|
||||||
#define drawbutt(xoffs, butt, symb)\
|
#define drawbutt(xoffs, butt, symb)\
|
||||||
if (stplyr->cmd.buttons & butt)\
|
if (!stplyr->exiting && (cmd->buttons & butt))\
|
||||||
{\
|
{\
|
||||||
offs = 2;\
|
offs = 2;\
|
||||||
col = accent1;\
|
col = accent1;\
|
||||||
|
|
@ -3549,7 +3549,7 @@ static void K_drawInput(void)
|
||||||
|
|
||||||
y -= 1;
|
y -= 1;
|
||||||
|
|
||||||
if (!cmd->turning) // no turn
|
if (stplyr->exiting || !cmd->turning) // no turn
|
||||||
target = 0;
|
target = 0;
|
||||||
else // turning of multiple strengths!
|
else // turning of multiple strengths!
|
||||||
{
|
{
|
||||||
|
|
|
||||||
14
src/m_menu.c
14
src/m_menu.c
|
|
@ -8139,11 +8139,11 @@ static void M_ReplayTimeAttack(INT32 choice)
|
||||||
break;
|
break;
|
||||||
case 3: // guest
|
case 3: // guest
|
||||||
// srb2/replay/main/map01-guest.lmp
|
// srb2/replay/main/map01-guest.lmp
|
||||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// srb2/replay/main/map01-sonic-time-best.lmp
|
// srb2/replay/main/map01-sonic-time-best.lmp
|
||||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which));
|
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which));
|
||||||
}
|
}
|
||||||
/*else if (currentMenu == &SP_NightsReplayDef)
|
/*else if (currentMenu == &SP_NightsReplayDef)
|
||||||
{
|
{
|
||||||
|
|
@ -8165,13 +8165,13 @@ static void M_ReplayTimeAttack(INT32 choice)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// srb2/replay/main/map01-score-best.lmp
|
// srb2/replay/main/map01-score-best.lmp
|
||||||
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which));
|
G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which));
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_EraseGuest(INT32 choice)
|
static void M_EraseGuest(INT32 choice)
|
||||||
{
|
{
|
||||||
const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||||
(void)choice;
|
(void)choice;
|
||||||
if (FIL_FileExists(rguest))
|
if (FIL_FileExists(rguest))
|
||||||
remove(rguest);
|
remove(rguest);
|
||||||
|
|
@ -8186,10 +8186,10 @@ static void M_EraseGuest(INT32 choice)
|
||||||
|
|
||||||
static void M_OverwriteGuest(const char *which)
|
static void M_OverwriteGuest(const char *which)
|
||||||
{
|
{
|
||||||
char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
|
||||||
UINT8 *buf;
|
UINT8 *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf);
|
len = FIL_ReadFile(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -8258,7 +8258,7 @@ static void M_SetGuestReplay(INT32 choice)
|
||||||
M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO);
|
M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))))
|
if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))))
|
||||||
M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO);
|
M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO);
|
||||||
else
|
else
|
||||||
which(0);
|
which(0);
|
||||||
|
|
|
||||||
|
|
@ -3924,40 +3924,40 @@ boolean P_LoadLevel(boolean fromnetsave)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Make sure all sounds are stopped before Z_FreeTags.
|
|
||||||
S_StopSounds();
|
|
||||||
S_ClearSfx();
|
|
||||||
|
|
||||||
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
|
|
||||||
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
|
|
||||||
if (!titlemapinaction)
|
|
||||||
S_FadeMusic(0, FixedMul(
|
|
||||||
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
|
|
||||||
|
|
||||||
// Reset the palette now all fades have been done
|
|
||||||
if (rendermode != render_none)
|
|
||||||
V_SetPaletteLump(GetPalette()); // Set the level palette
|
|
||||||
|
|
||||||
if (!titlemapinaction)
|
|
||||||
{
|
|
||||||
if (ranspecialwipe == 2)
|
|
||||||
{
|
|
||||||
pausedelay = -3; // preticker plus one
|
|
||||||
S_StartSound(NULL, sfx_s3k73);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As oddly named as this is, this handles music only.
|
|
||||||
// We should be fine starting it here.
|
|
||||||
// Don't do this during titlemap, because the menu code handles music by itself.
|
|
||||||
S_Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
levelfadecol = (encoremode ? 0 : 31);
|
|
||||||
|
|
||||||
// Let's fade to white here
|
// Let's fade to white here
|
||||||
// But only if we didn't do the encore startup wipe
|
// But only if we didn't do the encore startup wipe
|
||||||
if (!demo.rewinding)
|
if (!demo.rewinding)
|
||||||
{
|
{
|
||||||
|
// Make sure all sounds are stopped before Z_FreeTags.
|
||||||
|
S_StopSounds();
|
||||||
|
S_ClearSfx();
|
||||||
|
|
||||||
|
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
|
||||||
|
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
|
||||||
|
if (!titlemapinaction)
|
||||||
|
S_FadeMusic(0, FixedMul(
|
||||||
|
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
|
||||||
|
|
||||||
|
// Reset the palette now all fades have been done
|
||||||
|
if (rendermode != render_none)
|
||||||
|
V_SetPaletteLump(GetPalette()); // Set the level palette
|
||||||
|
|
||||||
|
if (!titlemapinaction)
|
||||||
|
{
|
||||||
|
if (ranspecialwipe == 2)
|
||||||
|
{
|
||||||
|
pausedelay = -3; // preticker plus one
|
||||||
|
S_StartSound(NULL, sfx_s3k73);
|
||||||
|
}
|
||||||
|
|
||||||
|
// As oddly named as this is, this handles music only.
|
||||||
|
// We should be fine starting it here.
|
||||||
|
// Don't do this during titlemap, because the menu code handles music by itself.
|
||||||
|
S_Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
levelfadecol = (encoremode ? 0 : 31);
|
||||||
|
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
{
|
{
|
||||||
F_WipeStartScreen();
|
F_WipeStartScreen();
|
||||||
|
|
|
||||||
17
src/p_spec.c
17
src/p_spec.c
|
|
@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
||||||
|
|
||||||
player->karthud[khud_lapanimation] = 80;
|
player->karthud[khud_lapanimation] = 80;
|
||||||
|
|
||||||
|
// save best lap for record attack
|
||||||
|
if (player == &players[consoleplayer])
|
||||||
|
{
|
||||||
|
if (curlap < bestlap || bestlap == 0)
|
||||||
|
bestlap = curlap;
|
||||||
|
curlap = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rainbowstartavailable == true)
|
if (rainbowstartavailable == true)
|
||||||
|
|
@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
||||||
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
||||||
|
|
||||||
// SRB2Kart: save best lap for record attack
|
|
||||||
if (player == &players[consoleplayer])
|
|
||||||
{
|
|
||||||
if (curlap < bestlap || bestlap == 0)
|
|
||||||
bestlap = curlap;
|
|
||||||
curlap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
player->starpostnum = 0;
|
player->starpostnum = 0;
|
||||||
|
|
||||||
if (P_IsDisplayPlayer(player))
|
if (P_IsDisplayPlayer(player))
|
||||||
|
|
@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player)
|
||||||
{
|
{
|
||||||
player->starpostnum = numstarposts;
|
player->starpostnum = numstarposts;
|
||||||
player->laps--;
|
player->laps--;
|
||||||
|
curlap = UINT32_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -516,6 +516,8 @@ void P_Ticker(boolean run)
|
||||||
if (demo.rewinding && leveltime > 0)
|
if (demo.rewinding && leveltime > 0)
|
||||||
{
|
{
|
||||||
leveltime = (leveltime-1) & ~3;
|
leveltime = (leveltime-1) & ~3;
|
||||||
|
if (timeinmap > 0)
|
||||||
|
timeinmap = (timeinmap-1) & ~3;
|
||||||
G_PreviewRewind(leveltime);
|
G_PreviewRewind(leveltime);
|
||||||
}
|
}
|
||||||
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
|
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
|
||||||
|
|
@ -613,9 +615,7 @@ void P_Ticker(boolean run)
|
||||||
if (run)
|
if (run)
|
||||||
leveltime++;
|
leveltime++;
|
||||||
|
|
||||||
// as this is mostly used for HUD stuff, add the record attack specific hack to it as well!
|
timeinmap++;
|
||||||
if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4)
|
|
||||||
timeinmap++;
|
|
||||||
|
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
P_DoTeamStuff();
|
P_DoTeamStuff();
|
||||||
|
|
|
||||||
|
|
@ -2644,7 +2644,7 @@ static void P_DeathThink(player_t *player)
|
||||||
{
|
{
|
||||||
if (player->spectator || !circuitmap)
|
if (player->spectator || !circuitmap)
|
||||||
curlap = 0;
|
curlap = 0;
|
||||||
else
|
else if (curlap != UINT32_MAX)
|
||||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4385,7 +4385,7 @@ void P_PlayerThink(player_t *player)
|
||||||
{
|
{
|
||||||
if (player->spectator || !circuitmap)
|
if (player->spectator || !circuitmap)
|
||||||
curlap = 0;
|
curlap = 0;
|
||||||
else
|
else if (curlap != UINT32_MAX)
|
||||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
player_t *player = &players[playernum];
|
player_t *player = &players[playernum];
|
||||||
|
|
||||||
|
if (stricmp("None", skinname) == 0)
|
||||||
|
{
|
||||||
|
SetFollower(playernum, -1); // reminder that -1 is nothing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (i = 0; i < numfollowers; i++)
|
for (i = 0; i < numfollowers; i++)
|
||||||
{
|
{
|
||||||
// search in the skin list
|
// search in the skin list
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue