A whole bunch of cleanup to get most record attack/replay stuff reasonably functional.

* Fix the screen being stuck black at the very start of start record attack.
* Bump up the demoversion to 7, because I want all previous v2 demos to be guaranteed kaput (it was previously 4, but 7 is a nice number).
* Fix a ton MORE shitcausing misalignments in the replay system, this time specifically focused on getting ghosts functional.
* Plug a few holes in the "best lap" record implementation that allowed for stupidly easy records due to the way v2's finish lines work.
* Make a few follower-related things sane, to prevent spurious console prints that were getting in the way of my test prints.
This commit is contained in:
toaster 2020-11-27 20:30:28 +00:00
parent 9c0edb097f
commit f72108c4fa
6 changed files with 85 additions and 87 deletions

View file

@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = {
// player's followers. Also saved.
consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = {
CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange),
CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange),
CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange),
CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange)
};
// player's follower colors... Also saved...
@ -2858,13 +2858,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
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]);
LUAh_MapChange(mapnumber);

View file

@ -104,7 +104,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING
//
#define DEMOVERSION 0x0004
#define DEMOVERSION 0x0007
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
#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_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_ENCORE 0x40
@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void)
{
// write follower
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);
demo_p += 16;
@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void)
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;
WRITEUINT8(demo_p, i);
G_WriteGhostTic(players[i].mo, i);
}
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)
@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
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)
{
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)
ghostext[playernum].flags &= ~EZT_COLOR;
if (ghostext[playernum].scale == ghostext[playernum].lastscale)
@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
oldghost[playernum].flags2 &= ~MF2_AMBUSH;
*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)
@ -1067,16 +1066,18 @@ void G_GhostTicker(void)
if (ziptic & DXD_FOLLOWER)
g->p += 32; // ok (32 because there's both the skin and the colour)
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)
g->p += 4; // RNG seed
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);
if (ziptic & ZT_FWD)
g->p++;
if (ziptic & ZT_TURNING)
@ -1086,9 +1087,9 @@ void G_GhostTicker(void)
if (ziptic & ZT_AIMING)
g->p += 2;
if (ziptic & ZT_LATENCY)
g->p += 1;
g->p++;
if (ziptic & ZT_FLAGS)
g->p += 1;
g->p++;
// Grab ghost data.
ziptic = READUINT8(g->p);
@ -1096,7 +1097,7 @@ void G_GhostTicker(void)
if (ziptic == 0xFF)
goto skippedghosttic; // Didn't write ghost info this frame
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);
if (ziptic & GZT_XYZ)
@ -1109,17 +1110,17 @@ void G_GhostTicker(void)
{
if (ziptic & GZT_MOMXY)
{
g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
g->oldmo.momx = READFIXED(g->p);
g->oldmo.momy = READFIXED(g->p);
}
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.y += g->oldmo.momy;
g->oldmo.z += g->oldmo.momz;
}
if (ziptic & GZT_ANGLE)
g->mo->angle = READUINT8(g->p)<<24;
g->oldmo.angle = READUINT8(g->p)<<24;
if (ziptic & GZT_FRAME)
g->oldmo.frame = READUINT8(g->p);
if (ziptic & GZT_SPR2)
@ -1205,27 +1206,6 @@ void G_GhostTicker(void)
g->p += 12; // kartitem, kartamount, kartbumpers
}
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
if (ziptic & GZT_FOLLOW)
{ // Even more...
@ -1292,6 +1272,30 @@ skippedghosttic:
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.
if (*g->p == DEMOMARKER)
{
@ -1313,9 +1317,6 @@ skippedghosttic:
continue;
}
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
p = g;
#undef follow
}
@ -2714,7 +2715,6 @@ void G_DoPlayDemo(char *defdemoname)
demo.version = READUINT16(demo_p);
switch(demo.version)
{
case 0x000d:
case DEMOVERSION: // latest always supported
break;
// too old, cannot support.
@ -3103,7 +3103,6 @@ void G_AddGhost(char *defdemoname)
ghostversion = READUINT16(p);
switch(ghostversion)
{
case 0x000d:
case DEMOVERSION: // latest always supported
break;
// too old, cannot support.
@ -3221,6 +3220,8 @@ void G_AddGhost(char *defdemoname)
kartspeed = READUINT8(p);
kartweight = READUINT8(p);
p += 4; // followitem (maybe change later)
if (READUINT8(p) != 0xFF)
{
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);

View file

@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player)
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
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)
@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player)
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
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;
if (P_IsDisplayPlayer(player))
@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player)
{
player->starpostnum = numstarposts;
player->laps--;
curlap = UINT32_MAX;
}
}
}

View file

@ -613,9 +613,7 @@ void P_Ticker(boolean run)
if (run)
leveltime++;
// as this is mostly used for HUD stuff, add the record attack specific hack to it as well!
if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4)
timeinmap++;
timeinmap++;
if (G_GametypeHasTeams())
P_DoTeamStuff();

View file

@ -2644,7 +2644,7 @@ static void P_DeathThink(player_t *player)
{
if (player->spectator || !circuitmap)
curlap = 0;
else
else if (curlap != UINT32_MAX)
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)
curlap = 0;
else
else if (curlap != UINT32_MAX)
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
}
}

View file

@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname)
INT32 i;
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++)
{
// search in the skin list