From 9da5c3afb5e6481788e87fa898278aa7ad861b1d Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 1 Aug 2025 16:26:07 +0100 Subject: [PATCH 1/3] MT_WALLSPIKE, MT_ITEMCAPSULE: Remove time attack compat-intended hacks - You now can't phase through a stationary Prison Egg in any gametype, not just Tutorial - You can now scale Item Capsules in any gametype, not just Special --- src/k_kart.c | 6 ++---- src/p_mobj.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f30e3bbd4..26f365df1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -978,12 +978,9 @@ static boolean K_JustBumpedException(mobj_t *mobj) { case MT_SA2_CRATE: return Obj_SA2CrateIsMetal(mobj); - case MT_WALLSPIKE: - return true; case MT_BATTLECAPSULE: { - if (gametype == GT_TUTORIAL // Remove gametype check whenever it's safe to break compatibility with ghosts in a post-release patch - && mobj->momx == 0 + if (mobj->momx == 0 && mobj->momy == 0 && mobj->momz == 0) { @@ -991,6 +988,7 @@ static boolean K_JustBumpedException(mobj_t *mobj) } break; } + case MT_WALLSPIKE: case MT_STONESHOE: return true; default: diff --git a/src/p_mobj.c b/src/p_mobj.c index 645faf3ac..427bdd985 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14090,9 +14090,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj) mobj->scalespeed <<= 1; } - if (gametype == GT_SPECIAL) { - // TODO: When we invalidate replays, permit manual size changes everywhere + // Now we're invalidating replays, permit manual size changes everywhere mobj->extravalue1 = FixedMul(mthing->scale, mobj->extravalue1); mobj->scalespeed = FixedMul(mthing->scale, mobj->scalespeed); } From 841fc2472cc39769a572c6403e19088d276892e1 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 1 Aug 2025 16:30:22 +0100 Subject: [PATCH 2/3] Remove all replay backwards compat - Cleans up codebase in some high density regions - Prevents crashing on the title screen due to old demos being played before we replace staffghosts - Guarantees nothing we don't want slips in --- src/g_demo.cpp | 108 ++++++++---------------------------------------- src/k_kart.c | 72 +++----------------------------- src/p_polyobj.c | 2 +- src/p_user.c | 5 +-- 4 files changed, 25 insertions(+), 162 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 172309016..0a5bc893f 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -97,9 +97,6 @@ tic_t demostarttime; // for comparative timing purposes static constexpr DemoBufferSizes get_buffer_sizes(UINT16 version) { - if (version < 0x000A) // old staff ghost support - return {16, 16, 16}; - // These sizes are compatible as of version 0x000A static_assert(MAXPLAYERNAME == 21); static_assert(SKINNAMESIZE == 16); @@ -158,7 +155,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -// Also supported: +// Formerly supported: // - 0x0009 (older staff ghosts) // - Player names, skin names and color names were 16 // bytes. See get_buffer_sizes(). @@ -440,15 +437,7 @@ void G_ReadDemoExtraData(void) { case DW_RNG: { - UINT32 num_classes; - if (demo.version <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(demobuf.p); - } + UINT32 num_classes = READUINT32(demobuf.p); for (i = 0; i < (signed)num_classes; i++) { @@ -1334,15 +1323,7 @@ fadeghost: { INT32 i; - UINT32 num_classes = PROLDDEMO; - if (g->version <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(g->p); - } + UINT32 num_classes = READUINT32(g->p); for (i = 0; i < (signed)num_classes; i++) { @@ -1540,11 +1521,11 @@ fadeghost: P_SetScale(follow, follow->destscale); P_UnsetThingPosition(follow); - temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + temp = READFIXED(g->p); follow->x = g->mo->x + temp; - temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + temp = READFIXED(g->p); follow->y = g->mo->y + temp; - temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + temp = READFIXED(g->p); follow->z = g->mo->z + temp; P_SetThingPosition(follow); if (followtic & FZT_SKIN) @@ -2314,10 +2295,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported - case 0x0009: // older staff ghosts - case 0x000A: // 2.0, 2.1 - case 0x000B: // 2.2 indev (staff ghosts) - case 0x000C: // 2.2 break; // too old, cannot support. default: @@ -2430,6 +2407,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) democharlist_t *skinlist = NULL; UINT16 pdemoversion, count; UINT16 legacystandingplayercount; + UINT32 num_classes; char mapname[MAXMAPLUMPNAME],gtname[MAXGAMETYPELENGTH]; INT32 i; @@ -2466,10 +2444,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) switch(pdemoversion) { case DEMOVERSION: // latest always supported - case 0x0009: // older staff ghosts - case 0x000A: // 2.0, 2.1 - case 0x000B: // 2.2 indev (staff ghosts) - case 0x000C: // 2.2 if (P_SaveBufferRemaining(&info) < 64) { goto corrupt; @@ -2552,15 +2526,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) } } - UINT32 num_classes; - if (pdemoversion <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(info.p); - } + num_classes = READUINT32(info.p); for (i = 0; i < (signed)num_classes; i++) { @@ -2743,6 +2709,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) UINT8 availabilities[MAXPLAYERS][MAXAVAILABILITY]; UINT8 version,subversion; UINT32 randseed[PRNUMSYNCED]; + UINT32 num_classes; char msg[1024]; boolean spectator, bot; @@ -2904,10 +2871,6 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) switch(demo.version) { case DEMOVERSION: // latest always supported - case 0x0009: // older staff ghosts - case 0x000A: // 2.0, 2.1 - case 0x000B: // 2.2 indev (staff ghosts) - case 0x000C: // 2.2 break; // too old, cannot support. default: @@ -3045,15 +3008,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) hu_demolap = READUINT32(demobuf.p); // Random seed - UINT32 num_classes; - if (demo.version <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(demobuf.p); - } + num_classes = READUINT32(demobuf.p); for (i = 0; i < PRNUMSYNCED; i++) { @@ -3097,10 +3052,7 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum) grandprixinfo.gamespeed = READUINT8(demobuf.p); grandprixinfo.masterbots = READUINT8(demobuf.p) != 0; grandprixinfo.eventmode = static_cast(READUINT8(demobuf.p)); - if (demo.version >= 0x000D) - { - grandprixinfo.specialDamage = READUINT32(demobuf.p); - } + grandprixinfo.specialDamage = READUINT32(demobuf.p); } // Load unlocks into netUnlocked @@ -3379,6 +3331,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) UINT16 count, ghostversion; skin_t *ghskin = &skins[0]; UINT8 worknumskins; + UINT32 num_classes; democharlist_t *skinlist = NULL; p = buffer->buffer; @@ -3398,10 +3351,6 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) switch(ghostversion) { case DEMOVERSION: // latest always supported - case 0x0009: // older staff ghosts - case 0x000A: // 2.0, 2.1 - case 0x000B: // 2.2 indev (staff ghosts) - case 0x000C: // 2.2 break; // too old, cannot support. default: @@ -3471,15 +3420,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) if (flags & ATTACKING_LAP) p += 4; - UINT32 num_classes; - if (ghostversion <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(p); - } + num_classes = READUINT32(p); for (i = 0; i < (signed)num_classes; i++) { @@ -3499,9 +3440,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname) if ((flags & DF_GRANDPRIX)) { - p += 3; - if (ghostversion >= 0x000D) - p++; + p += 4; } // Skip unlockables @@ -3652,6 +3591,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) UINT8 *p = buffer; UINT16 ghostversion; UINT16 flags; + UINT32 num_classes; INT32 i; staffbrief_t temp = {0}; staffbrief_t *ret = NULL; @@ -3673,10 +3613,6 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) switch(ghostversion) { case DEMOVERSION: // latest always supported - case 0x0009: // older staff ghosts - case 0x000A: // 2.0, 2.1 - case 0x000B: // 2.2 indev (staff ghosts) - case 0x000C: // 2.2 break; // too old, cannot support. @@ -3713,15 +3649,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) if (flags & ATTACKING_LAP) temp.lap = READUINT32(p); - UINT32 num_classes; - if (ghostversion <= 0x000D) - { - num_classes = PROLDDEMO; - } - else - { - num_classes = READUINT32(p); - } + num_classes = READUINT32(p); for (i = 0; i < (signed)num_classes; i++) { @@ -3741,9 +3669,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer) if ((flags & DF_GRANDPRIX)) { - p += 3; - if (ghostversion >= 0x000D) - p++; + p += 4; } // Skip unlockables diff --git a/src/k_kart.c b/src/k_kart.c index 26f365df1..9ee867e08 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3520,7 +3520,6 @@ fixed_t K_GetSpindashChargeSpeed(const player_t *player) fixed_t val = (10*FRACUNIT/277) + (((player->kartspeed + player->kartweight) + 2) * FRACUNIT) / 45; // 2.2 - Improved Spindash - if (!G_CompatLevel(0x000A)) { if (gametyperules & GTR_CIRCUIT) val = 5 * val / 4; @@ -11811,12 +11810,6 @@ static INT16 K_GetKartDriftValue(const player_t *player, fixed_t countersteer) } #endif - // Compat level for 2.0 staff ghosts - if (G_CompatLevel(0x000A)) - { - return basedrift + (FixedMul(driftadjust * FRACUNIT, countersteer) / FRACUNIT); - } - else { return basedrift + FixedMul(driftadjust, countersteer); } @@ -11901,7 +11894,7 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) } // Staff ghosts - direction-only trickpanel behavior - if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player)) + if (K_PlayerUsesBotMovement(player)) { if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) { @@ -11943,12 +11936,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) } else { - if (G_CompatLevel(0x000A)) - { - // Compat level for 2.0 staff ghosts - p_speed = min(currentSpeed, p_maxspeed * 2); - } - else { // Turning dampens as you go faster, but at extremely high speeds, keeping some control is important. // Dampening is applied in two stages, one harsh and one soft. @@ -11989,19 +11976,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) if (player->drift != 0 && P_IsObjectOnGround(player->mo)) { - if (G_CompatLevel(0x000A)) - { - // Compat level for 2.0 staff ghosts - fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN * FRACUNIT); - - if (player->pflags & PF_DRIFTEND) - { - countersteer = FRACUNIT; - } - - return K_GetKartDriftValue(player, countersteer); - } - else { if (player->pflags & PF_DRIFTEND) { @@ -12047,12 +12021,6 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) { fixed_t sliptide_handle; - if (G_CompatLevel(0x000A)) - { - // Compat level for 2.0 staff ghosts - sliptide_handle = 5 * HANDLESCALING / 4; - } - else { sliptide_handle = 3 * HANDLESCALING / 4; } @@ -12083,7 +12051,7 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue) } // 2.2 - Presteering allowed in trickpanels - if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player)) + if (!K_PlayerUsesBotMovement(player)) { if (player->trickpanel == TRICKSTATE_READY || player->trickpanel == TRICKSTATE_FORWARD) { @@ -12286,15 +12254,6 @@ static void K_KartDrift(player_t *player, boolean onground) if (player->trickcharge && dokicker) { - // 2.2 - Egg-friendly trick stuff - if (G_CompatLevel(0x000B)) - { - player->driftboost += 20; - player->wavedashboost += 10; - player->wavedashpower = FRACUNIT; - P_Thrust(player->mo, pushdir, player->speed / 2); - } - else { player->driftboost += TICRATE; player->counterdash += TICRATE/2; @@ -13359,7 +13318,6 @@ static void K_KartSpindash(player_t *player) } // 2.2 - Driftbrake slideoff fastfall prevention - if (!G_CompatLevel(0x000A)) { if (player->drift && onGround && player->cmd.buttons & BT_BRAKE) { @@ -13377,7 +13335,6 @@ static void K_KartSpindash(player_t *player) else { // 2.2 - More responsive ebrake - if (!G_CompatLevel(0x000A)) { if (onGround && player->noEbrakeMagnet == 0 && (FixedHypot(player->mo->momx, player->mo->momy) < 20*player->mo->scale)) { @@ -13486,11 +13443,6 @@ static void K_KartSpindash(player_t *player) // Funky Kong's Ring Racers. // 2.2 - No extended ring debt for recovery spindash - if (G_CompatLevel(0x000A)) - { - P_PlayerRingBurst(player, 1); - } - else { if (player->rings > 0) P_PlayerRingBurst(player, 1); @@ -13611,7 +13563,6 @@ boolean K_FastFallBounce(player_t *player) player->fastfall = 0; // 2.2 - More lenient fastfall - if (!G_CompatLevel(0x000A)) { if (player->curshield != KSHIELD_BUBBLE) { @@ -15323,8 +15274,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->tricktime <= TRICKDELAY) { // 2.3 - Prevent accidental fastfalls during trickdelay - if (!G_CompatLevel(0x000C)) - player->pflags |= PF_NOFASTFALL; + player->pflags |= PF_NOFASTFALL; player->tricktime++; } @@ -15362,8 +15312,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) UINT16 buttons = player->cmd.buttons; INT16 TRICKTHRESHOLD = 2*KART_FULLTURN/3; - // 2.3 - aimingcompare - if (!G_CompatLevel(0x000C)) { TRICKTHRESHOLD = KART_FULLTURN/2; INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning); @@ -15372,14 +15320,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } // 2.2 - Pre-steering trickpanels - if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player)) + if (!K_PlayerUsesBotMovement(player)) { if (!(buttons & BT_ACCELERATE)) { cantrick = false; } // 2.3 - also allow tricking with the Spindash button - else if (!G_CompatLevel(0x000C) && ((buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK)) + else if ((buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK) { player->pflags |= PF_NOFASTFALL; } @@ -15614,7 +15562,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } // 2.2 - Lenient trickpanels - if (G_CompatLevel(0x000A) || K_PlayerUsesBotMovement(player)) + if (K_PlayerUsesBotMovement(player)) { // Wait until we let go off the control stick to remove the delay // buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying. @@ -15625,14 +15573,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else { - if (G_CompatLevel(0x000C)) - { - if ((player->pflags & PF_TRICKDELAY) && !(player->cmd.buttons & BT_ACCELERATE) && (player->tricktime >= TRICKDELAY)) - { - player->pflags &= ~PF_TRICKDELAY; - } - } - else // 2.3 - Spindash to trick { // Ignore pre-existing Accel inputs if not pressing Spindash. Always ignore pre-existing Spindash inputs to prevent accidental tricking. diff --git a/src/p_polyobj.c b/src/p_polyobj.c index b6e15204d..2c819a861 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -201,7 +201,7 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) { if (P_BoxOnLineSide(bbox, po->lines[i]) == 0) return false; - if (g_tm.sweep && !G_CompatLevel(0x000A)) + if (g_tm.sweep) { P_TestLine(po->lines[i]); } diff --git a/src/p_user.c b/src/p_user.c index d542ceaea..583cd34b7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1948,10 +1948,7 @@ static void P_3dMovement(player_t *player) totalthrust.x = totalthrust.y = 0; // I forget if this is needed - if (G_CompatLevel(0x000B)) // Ring Racers 2.1 behavior - totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes - else - totalthrust.z = FixedMul(mapobjectscale, K_GrowShrinkSpeedMul(player))*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes, but scaled for mapobject and player size + totalthrust.z = FixedMul(mapobjectscale, K_GrowShrinkSpeedMul(player))*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes, but scaled for mapobject and player size if (K_SlopeResistance(player) == true) { From c389922f698ef3afbfc76540b19835da9d8d70db Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 3 Aug 2025 20:28:05 +0100 Subject: [PATCH 3/3] Remove legacy non-json Standings handling --- src/g_demo.cpp | 55 +++++++++----------------------------------------- 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 0a5bc893f..c71fd92cc 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -235,8 +235,8 @@ static ticcmd_t oldcmd[MAXPLAYERS]; #define DW_EXTRASTUFF 0xFE // Numbers below this are reserved for writing player slot data // Below consts are only used for demo extrainfo sections -#define DW_STANDING 0x00 -#define DW_STANDING2 0x01 +#define DW_DEPRECATED 0x00 +#define DW_STANDINGS 0x01 // For time attack ghosts #define GZT_XYZ 0x01 @@ -2188,7 +2188,7 @@ void srb2::write_current_demo_standings(const srb2::StandingsJson& standings) Vector ubjson = value.to_ubjson(); uint32_t bytes = ubjson.size(); - WRITEUINT8(demobuf.p, DW_STANDING2); + WRITEUINT8(demobuf.p, DW_STANDINGS); WRITEUINT32(demobuf.p, bytes); WRITEMEM(demobuf.p, (UINT8*)ubjson.data(), bytes); @@ -2402,11 +2402,10 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) { savebuffer_t info = {0}; UINT8 *extrainfo_p; - UINT8 version, subversion, worknumskins, skinid; + UINT8 version, subversion, worknumskins; UINT16 pdemoflags; democharlist_t *skinlist = NULL; UINT16 pdemoversion, count; - UINT16 legacystandingplayercount; UINT32 num_classes; char mapname[MAXMAPLUMPNAME],gtname[MAXGAMETYPELENGTH]; INT32 i; @@ -2574,7 +2573,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) pdemo->gp = true; // Read standings! - legacystandingplayercount = 0; info.p = extrainfo_p; @@ -2584,48 +2582,13 @@ void G_LoadDemoInfo(menudemo_t *pdemo, boolean allownonmultiplayer) switch (extrainfotag) { - case DW_STANDING: + case DW_DEPRECATED: { - // This is the only extrainfo tag that is not length prefixed. All others must be. - constexpr size_t kLegacyStandingSize = 1+16+1+16+4; - if (P_SaveBufferRemaining(&info) < kLegacyStandingSize) - { - goto corrupt; - } - if (legacystandingplayercount >= MAXPLAYERS) - { - info.p += kLegacyStandingSize; - break; // switch - } - char temp[16+1]; - - pdemo->standings[legacystandingplayercount].ranking = READUINT8(info.p); - - // Name - info.p += copy_fixed_buf(pdemo->standings[legacystandingplayercount].name, info.p, 16); - - // Skin - skinid = READUINT8(info.p); - if (skinid > worknumskins) - skinid = 0; - pdemo->standings[legacystandingplayercount].skin = skinlist[skinid].mapping; - - // Color - info.p += copy_fixed_buf(temp, info.p, 16); - for (i = 0; i < numskincolors; i++) - if (!stricmp(skincolors[i].name,temp)) // SRB2kart - { - pdemo->standings[legacystandingplayercount].color = i; - break; - } - - // Score/time/whatever - pdemo->standings[legacystandingplayercount].timeorscore = READUINT32(info.p); - - legacystandingplayercount++; - break; + // Because this isn't historically length-prefixed, + // we can't free this one value up. Sorry! + goto corrupt; } - case DW_STANDING2: + case DW_STANDINGS: { if (P_SaveBufferRemaining(&info) < 4) {