diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a87d04cb5..46ecc1b97 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); diff --git a/src/g_demo.c b/src/g_demo.c index 9b5687750..69c8fb760 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -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); diff --git a/src/p_spec.c b/src/p_spec.c index 3d0eddd2e..519f21cd4 100644 --- a/src/p_spec.c +++ b/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_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; } } } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..9d7a6ac5c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -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(); diff --git a/src/p_user.c b/src/p_user.c index f03c63464..10b2c9a97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -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 } } diff --git a/src/r_skins.c b/src/r_skins.c index 951eeaad6..135221ea6 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -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