From 756b5600a087380fc67197c49afe0333912c6477 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 13:24:36 +0100 Subject: [PATCH 01/15] V_DrawFill: Fix with color profile settings (also the DrawDiag func we don't use anywhere right now) --- src/v_video.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 3255544bd..d47125972 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1070,7 +1070,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) c &= 255; - RGBA_t color = pMasterPalette[c]; + RGBA_t color = pLocalPalette[c]; UINT8 r = (color.rgba & 0xFF); UINT8 g = (color.rgba & 0xFF00) >> 8; UINT8 b = (color.rgba & 0xFF0000) >> 16; @@ -1262,7 +1262,7 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c) { auto builder = g_2d.begin_verts(); - const RGBA_t color = pMasterPalette[c]; + const RGBA_t color = pLocalPalette[c]; const float r = ((color.rgba & 0xFF000000) >> 24) / 255.f; const float g = ((color.rgba & 0xFF0000) >> 16) / 255.f; const float b = ((color.rgba & 0xFF00) >> 8) / 255.f; From 2f623e060cec2086144e01d45100ea7fab7c6bcb Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 13:26:13 +0100 Subject: [PATCH 02/15] Fix checkpoints in Tutorial Mode --- src/objects/checkpoint.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/objects/checkpoint.cpp b/src/objects/checkpoint.cpp index 81b93feb0..195e1436a 100644 --- a/src/objects/checkpoint.cpp +++ b/src/objects/checkpoint.cpp @@ -584,7 +584,11 @@ void Obj_CheckpointThink(mobj_t* end) void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y) { - if (player->exiting || player->laps == 0) // can't cross checkpoints when exiting, or before the first lap starts + if (player->exiting + || ( + (gametyperules & GTR_CIRCUIT) + && (player->laps == 0) + )) { return; } From 94fe67e87b7392d3e6d6ca668e5fe45c418137c1 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 13:33:11 +0100 Subject: [PATCH 03/15] Don't allow devmode arrow-key skips if you haven't gotten all the way through Goner --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index ac6312e7f..65ff28412 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1118,7 +1118,7 @@ boolean F_IntroResponder(event_t *event) } // Quick skips for development/testing. See F_IntroTicker. - if (!demo.playback) + if (!demo.playback && skippableallowed) { switch(key) { From a6f71215ec27afd2b1acf8ebb205879a4500d68a Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 13:35:41 +0100 Subject: [PATCH 04/15] Fix bail-induced follower horn sound playing for everyone --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 1fe6f4c3c..d21e15cdc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10578,7 +10578,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->follower && fls >= 0 && fls < numfollowers) { const follower_t *fl = &followers[fls]; - S_StartSound(NULL, fl->hornsound); + S_StartSound(player->follower, fl->hornsound); } S_StartSound(player->mo, sfx_kc33); From 69241774f8c16bc251d50faf08252bebe9d4804b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 14:29:15 +0100 Subject: [PATCH 05/15] M_DrawPause: Adjust names of Tutorial Mode gamecontrol hints - No more "Respawn" - shows "Bail / Burst" instead - Added spaces to "Spin Dash" and "Item / Rings" for consistency --- src/k_menudraw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index af9187074..31e76aa86 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -6424,11 +6424,11 @@ void M_DrawPause(void) K_DrawGameControl(4, 184 - 60 + offset/2, 0, " Steering", 0, TINY_FONT, 0); K_DrawGameControl(4, 184 - 45 + offset/2, 0, " Accelerate", 0, TINY_FONT, 0); K_DrawGameControl(4, 184 - 30 + offset/2, 0, " Look Back", 0, TINY_FONT, 0); - K_DrawGameControl(4, 184 - 15 + offset/2, 0, " Spindash", 0, TINY_FONT, 0); - K_DrawGameControl(4, 184 - 0 + offset/2, 0, " Item/Rings", 0, TINY_FONT, 0); + K_DrawGameControl(4, 184 - 15 + offset/2, 0, " Spin Dash", 0, TINY_FONT, 0); + K_DrawGameControl(4, 184 - 0 + offset/2, 0, " Item / Rings", 0, TINY_FONT, 0); K_DrawGameControl(90, 184 - 45 + offset/2, 0, " Brake", 0, TINY_FONT, 0); - K_DrawGameControl(90, 184 - 30 + offset/2, 0, " Respawn", 0, TINY_FONT, 0); + K_DrawGameControl(90, 184 - 30 + offset/2, 0, " Bail / Burst", 0, TINY_FONT, 0); K_DrawGameControl(90, 184 - 15 + offset/2, 0, " Dialogue / Action", 0, TINY_FONT, 0); K_DrawGameControl(90, 184 - 0 + offset/2, 0, " Drift", 0, TINY_FONT, 0); } From 026831d9c8a75bf454bc65155d0fbe4e0f5f30c4 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 15:29:40 +0100 Subject: [PATCH 06/15] Statistics Map screen: If Sealed Stars have been visited but you haven't unlocked Special Mode, show them under Lost & Found instead of revealing the true cup order early --- src/menus/extras-statistics.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/menus/extras-statistics.cpp b/src/menus/extras-statistics.cpp index d5bdf990c..6d2b54d0e 100644 --- a/src/menus/extras-statistics.cpp +++ b/src/menus/extras-statistics.cpp @@ -26,7 +26,20 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere if (!mapheaderinfo[map]) return false; - if (mapheaderinfo[map]->cup != cup) + if (mapheaderinfo[map]->typeoflevel & TOL_SPECIAL) + { + if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found + || (mapheaderinfo[map]->cup + && mapheaderinfo[map]->cup->id >= basenumkartcupheaders) // custom content + || M_SecretUnlocked(SECRET_SPECIALATTACK, true)) // true order + { + if (mapheaderinfo[map]->cup != cup) + return false; + } + else if (cup) // Appear under Lost & Found until you've ordered them. + return false; + } + else if (mapheaderinfo[map]->cup != cup) return false; if (((mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL) != tutorial) From 57c5fa3cd77aa62484331466855daec9ac051b61 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 15:01:54 +0100 Subject: [PATCH 07/15] Replace new gametype-specific checks with gametyperule checks - K_PlayerTripwireSpeedThreshold, K_CheckpointCrossAward - repaced with "GTR_CIRCUIT and not K_Cooperative" - excludes Sealed Stars as before, but includes custom Race-based gametypes - UFO Spawner tracking on minimap - GTR_PAPERITEMS, per how UFOs are handled in k_battle.c - G_RandMapPerPlayerCount: Check for the absence of GT_SPECIAL when excluding LF_SECTIONRACE, not the presence of GT_RACE - Little bit of a hack, but right now there's no way to do custom cooperative gametypes, we don't have proper access to gametyperules in this function, and Battle courses aren't going to have this flag anyways --- src/g_game.c | 6 +++++- src/k_hud.cpp | 2 +- src/k_kart.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 31cd80b9a..204d6ed84 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3932,7 +3932,11 @@ tryAgain: continue; } - if (numPlayers == 2 && gametype == GT_RACE && ((mapheaderinfo[i]->levelflags & LF_SECTIONRACE) == LF_SECTIONRACE)) + // TODO - We don't have guaranteed access to gametype/rules of TOL. + // If revising in future and willing to break this function open, + // this should be checking for GTR_CIRCUIT and not cooperative + // (but K_Cooperative also won't be correct inside this func). + if (numPlayers == 2 && gametype != GT_SPECIAL && ((mapheaderinfo[i]->levelflags & LF_SECTIONRACE) == LF_SECTIONRACE)) { // Duel doesn't support sprints. continue; diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 9734d8cdc..4f91c412f 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -6448,7 +6448,7 @@ static void K_drawKartMinimap(void) } } - if (gametype == GT_BATTLE && Obj_GetNextUFOSpawner() != NULL) + if ((gametyperules & GTR_PAPERITEMS) && Obj_GetNextUFOSpawner() != NULL) { const INT32 prevsplitflags = splitflags; mobj_t *spawner = Obj_GetNextUFOSpawner(); diff --git a/src/k_kart.c b/src/k_kart.c index d21e15cdc..589d0ecf7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3119,7 +3119,7 @@ fixed_t K_PlayerTripwireSpeedThreshold(const player_t *player) UINT32 distance = K_GetItemRouletteDistance(player, 8); - if (gametype == GT_RACE && M_NotFreePlay() && !modeattacking) + if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative() && M_NotFreePlay() && !modeattacking) { if (distance < SCAMDIST) // Players near 1st need more speed! { @@ -4618,7 +4618,7 @@ static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint) void K_CheckpointCrossAward(player_t *player) { - if (gametype != GT_RACE) + if (!(gametyperules & GTR_CIRCUIT) || K_Cooperative()) return; if (!demo.playback && G_TimeAttackStart()) From ae21a8266d2a15e859ca0f5ef50d3b98f0fe4bf6 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 14:03:39 +0100 Subject: [PATCH 08/15] Disable Demo title entry inputs in GS_LEVEL freecam Also disables input when Director is enabled --- src/g_demo.cpp | 17 ++++++++++++++++- src/st_stuff.c | 28 ++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 0098c58b2..4001d8906 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -49,6 +49,7 @@ #include "md5.h" // demo checksums #include "p_saveg.h" // savebuffer_t #include "g_party.h" +#include "k_director.h" // K_DirectorIsEnabled #include "core/json.hpp" // SRB2Kart @@ -4315,9 +4316,23 @@ boolean G_CheckDemoTitleEntry(void) if (menuactive || chat_on) return false; - if (!G_PlayerInputDown(0, gc_b, 0) && !G_PlayerInputDown(0, gc_x, 0)) + // Input conflict for both and + if (gamestate == GS_LEVEL && camera[0].freecam) return false; + if (!G_PlayerInputDown(0, gc_b, 0)) + { + // Input conflict for + if (gamestate == GS_LEVEL + && playeringame[consoleplayer] + && players[consoleplayer].spectator + && K_DirectorIsEnabled(0)) + return false; + + if (!G_PlayerInputDown(0, gc_x, 0)) + return false; + } + demo.willsave = true; M_OpenVirtualKeyboard( sizeof demo.titlename, diff --git a/src/st_stuff.c b/src/st_stuff.c index 5263c71d8..128ff58b9 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -34,7 +34,7 @@ #include "p_setup.h" // NiGHTS grading #include "r_fps.h" #include "m_random.h" // random index -#include "m_cond.h" // item finder +#include "k_director.h" // K_DirectorIsEnabled #ifdef HWRENDER #include "hardware/hw_main.h" @@ -1498,11 +1498,27 @@ void ST_DrawServerSplash(boolean timelimited) void ST_DrawSaveReplayHint(INT32 flags) { - K_DrawGameControl( - BASEVIDWIDTH - 2, 2, 0, - (demo.willsave && demo.titlename[0]) ? "Replay will be saved. Change title" : " or Save replay", - 2, TINY_FONT, flags|V_YELLOWMAP - ); + const char *text; + if (gamestate == GS_LEVEL && camera[0].freecam) + { + text = va( + " Disable Freecam to %s replay", + (demo.willsave && demo.titlename[0]) + ? "rename" + : "save" + ); + } + else if (demo.willsave && demo.titlename[0]) + text = "Replay will be saved. Change title"; + else if (gamestate == GS_LEVEL + && playeringame[consoleplayer] + && players[consoleplayer].spectator + && K_DirectorIsEnabled(0)) + text = " Save replay"; + else + text = " or Save replay"; + + K_DrawGameControl(BASEVIDWIDTH - 2, 2, 0, text, 2, TINY_FONT, flags|V_YELLOWMAP); } static fixed_t ST_CalculateFadeIn(player_t *player) From daf32c5eab6d6cc8dda89ddc76b39692ee2ea286 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 16:46:42 +0100 Subject: [PATCH 09/15] Use "tiny timer" font if you have >=1000 wins on a Profile --- src/k_menudraw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 31e76aa86..7503b6af9 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2383,7 +2383,9 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p) if (p != NULL) { V_DrawFixedPatch((x+30)*FRACUNIT, (y+84)*FRACUNIT, FRACUNIT, 0, pwrlv, colormap); - V_DrawCenteredTimerString(x+30, y+87, 0, va("%d", p->wins)); + K_DrawGameControl(x+30, y+87, 0, va("%d", p->wins), 1, + (p->wins >= 1000 ? TINYTIMER_FONT : TIMER_FONT), + 0); } From 73c381750a7da105c5723f6e3dfd197ede8001fa Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 19:30:48 +0100 Subject: [PATCH 10/15] Instead of trying to carve out an exception for the brief window of time after winning but before director begins, just remove the input for starting demo title entry --- src/g_demo.cpp | 14 ++------------ src/st_stuff.c | 7 +------ 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 4001d8906..16d6eabdc 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -4316,22 +4316,12 @@ boolean G_CheckDemoTitleEntry(void) if (menuactive || chat_on) return false; - // Input conflict for both and + // Input conflict if (gamestate == GS_LEVEL && camera[0].freecam) return false; if (!G_PlayerInputDown(0, gc_b, 0)) - { - // Input conflict for - if (gamestate == GS_LEVEL - && playeringame[consoleplayer] - && players[consoleplayer].spectator - && K_DirectorIsEnabled(0)) - return false; - - if (!G_PlayerInputDown(0, gc_x, 0)) - return false; - } + return false; demo.willsave = true; M_OpenVirtualKeyboard( diff --git a/src/st_stuff.c b/src/st_stuff.c index 128ff58b9..07f17cb3d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1510,13 +1510,8 @@ void ST_DrawSaveReplayHint(INT32 flags) } else if (demo.willsave && demo.titlename[0]) text = "Replay will be saved. Change title"; - else if (gamestate == GS_LEVEL - && playeringame[consoleplayer] - && players[consoleplayer].spectator - && K_DirectorIsEnabled(0)) - text = " Save replay"; else - text = " or Save replay"; + text = " Save replay"; K_DrawGameControl(BASEVIDWIDTH - 2, 2, 0, text, 2, TINY_FONT, flags|V_YELLOWMAP); } From 06390642acf0a166295468068264a86ee4303276 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 19:41:03 +0100 Subject: [PATCH 11/15] Sliptide makes waterrun particles only show on the outside of your turn --- src/k_kart.c | 102 +++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 589d0ecf7..5c39a687f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3401,58 +3401,64 @@ void K_SpawnWaterRunParticles(mobj_t *mobj) y2 = y2 + P_ReturnThrustY(mobj, forwardangle, playerVisualRadius); // Left - // underlay - water = P_SpawnMobj(x1, y1, - ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); - water->angle = forwardangle - ANGLE_180 - ANGLE_22h; - water->destscale = trailScale; - water->momx = mobj->momx; - water->momy = mobj->momy; - water->momz = mobj->momz; - P_SetScale(water, trailScale); - P_SetMobjState(water, curUnderlayFrame); - P_SetTarget(&water->owner, mobj); - water->renderflags |= RF_REDUCEVFX; + if (!mobj->player || mobj->player->aizdriftstrat <= 0) + { + // underlay + water = P_SpawnMobj(x1, y1, + ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; + water->destscale = trailScale; + water->momx = mobj->momx; + water->momy = mobj->momy; + water->momz = mobj->momz; + P_SetScale(water, trailScale); + P_SetMobjState(water, curUnderlayFrame); + P_SetTarget(&water->owner, mobj); + water->renderflags |= RF_REDUCEVFX; - // overlay - water = P_SpawnMobj(x1, y1, - ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); - water->angle = forwardangle - ANGLE_180 - ANGLE_22h; - water->destscale = trailScale; - water->momx = mobj->momx; - water->momy = mobj->momy; - water->momz = mobj->momz; - P_SetScale(water, trailScale); - P_SetMobjState(water, curOverlayFrame); - P_SetTarget(&water->owner, mobj); - water->renderflags |= RF_REDUCEVFX; + // overlay + water = P_SpawnMobj(x1, y1, + ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); + water->angle = forwardangle - ANGLE_180 - ANGLE_22h; + water->destscale = trailScale; + water->momx = mobj->momx; + water->momy = mobj->momy; + water->momz = mobj->momz; + P_SetScale(water, trailScale); + P_SetMobjState(water, curOverlayFrame); + P_SetTarget(&water->owner, mobj); + water->renderflags |= RF_REDUCEVFX; + } // Right - // Underlay - water = P_SpawnMobj(x2, y2, - ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); - water->angle = forwardangle - ANGLE_180 + ANGLE_22h; - water->destscale = trailScale; - water->momx = mobj->momx; - water->momy = mobj->momy; - water->momz = mobj->momz; - P_SetScale(water, trailScale); - P_SetMobjState(water, curUnderlayFrame); - P_SetTarget(&water->owner, mobj); - water->renderflags |= RF_REDUCEVFX; + if (!mobj->player || mobj->player->aizdriftstrat >= 0) + { + // Underlay + water = P_SpawnMobj(x2, y2, + ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; + water->destscale = trailScale; + water->momx = mobj->momx; + water->momy = mobj->momy; + water->momz = mobj->momz; + P_SetScale(water, trailScale); + P_SetMobjState(water, curUnderlayFrame); + P_SetTarget(&water->owner, mobj); + water->renderflags |= RF_REDUCEVFX; - // Overlay - water = P_SpawnMobj(x2, y2, - ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); - water->angle = forwardangle - ANGLE_180 + ANGLE_22h; - water->destscale = trailScale; - water->momx = mobj->momx; - water->momy = mobj->momy; - water->momz = mobj->momz; - P_SetScale(water, trailScale); - P_SetMobjState(water, curOverlayFrame); - P_SetTarget(&water->owner, mobj); - water->renderflags |= RF_REDUCEVFX; + // Overlay + water = P_SpawnMobj(x2, y2, + ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL); + water->angle = forwardangle - ANGLE_180 + ANGLE_22h; + water->destscale = trailScale; + water->momx = mobj->momx; + water->momy = mobj->momy; + water->momz = mobj->momz; + P_SetScale(water, trailScale); + P_SetMobjState(water, curOverlayFrame); + P_SetTarget(&water->owner, mobj); + water->renderflags |= RF_REDUCEVFX; + } if (!S_SoundPlaying(mobj, sfx_s3kdbs)) { From 8ccf5f3b891d8555de3d7f3225696a89d3fb9499 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 20:10:07 +0100 Subject: [PATCH 12/15] Shuffle some of player death handling in p_inter.c around Permits a dying player to have its wavedash indicator actually removed (was made very obvious by the new sliptide segment in Drifting) --- src/p_inter.c | 88 ++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 549e61d66..f8d3f162a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1922,6 +1922,44 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } + if (target->player->spectator == false) + { + UINT32 skinflags = (demo.playback) + ? demo.skinlist[demo.currentskinid[(target->player-players)]].flags + : skins[target->player->skin]->flags; + + if (skinflags & SF_IRONMAN) + { + target->skin = skins[target->player->skin]; + target->player->charflags = skinflags; + K_SpawnMagicianParticles(target, 5); + S_StartSound(target, sfx_slip); + } + + target->renderflags &= ~RF_DONTDRAW; + } + + K_DropEmeraldsFromPlayer(target->player, target->player->emeralds); + + target->player->carry = CR_NONE; + + K_KartResetPlayerColor(target->player); + + P_ResetPlayer(target->player); + +#define PlayerPointerRemove(field) \ + if (P_MobjWasRemoved(field) == false) \ + { \ + P_RemoveMobj(field); \ + P_SetTarget(&field, NULL); \ + } + + PlayerPointerRemove(target->player->stumbleIndicator); + PlayerPointerRemove(target->player->wavedashIndicator); + PlayerPointerRemove(target->player->trickIndicator); + +#undef PlayerPointerRemove + if (gametyperules & GTR_BUMPERS) { if (battleovertime.enabled >= 10*TICRATE) // Overtime Barrier is armed @@ -2684,7 +2722,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, if (modeattacking & ATTACKING_SPB) { - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); return true; } @@ -2700,6 +2737,9 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, // disappearifies, but still gotta put items back in play break; + case DMG_TIMEOVER: + player->pflags |= PF_ELIMINATED; + //FALLTHRU default: // Everything else REALLY kills if (leveltime < starttime) @@ -2709,52 +2749,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, break; } - if (player->spectator == false) - { - UINT32 skinflags = (demo.playback) - ? demo.skinlist[demo.currentskinid[(player-players)]].flags - : skins[player->skin]->flags; - - if (skinflags & SF_IRONMAN) - { - player->mo->skin = skins[player->skin]; - player->charflags = skinflags; - K_SpawnMagicianParticles(player->mo, 5); - S_StartSound(player->mo, sfx_slip); - } - - player->mo->renderflags &= ~RF_DONTDRAW; - } - - K_DropEmeraldsFromPlayer(player, player->emeralds); - //K_SetHitLagForObjects(player->mo, inflictor, source, MAXHITLAGTICS, true); - - player->carry = CR_NONE; - - K_KartResetPlayerColor(player); - - P_ResetPlayer(player); - - P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - -#define PlayerPointerRemove(field) \ - if (P_MobjWasRemoved(field) == false) \ - { \ - P_RemoveMobj(field); \ - P_SetTarget(&field, NULL); \ - } - - PlayerPointerRemove(player->stumbleIndicator); - PlayerPointerRemove(player->wavedashIndicator); - PlayerPointerRemove(player->trickIndicator); - -#undef PlayerPointerRemove - - if (type == DMG_TIMEOVER) - { - player->pflags |= PF_ELIMINATED; - } - return true; } From b5b26522553a410b1cd8f1ae5cc64017690157ec Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 20:21:59 +0100 Subject: [PATCH 13/15] Fix off-by-one error in down-down-down input --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 65ff28412..a6c2c1f00 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -910,7 +910,7 @@ void F_IntroTicker(void) ResetSkipSequences(); CV_StealthSetValue(&cv_kartbot, 9); CV_StealthSetValue(&cv_maxplayers, 8); - D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL), GT_RACE, (cv_kartencore.value == 1), true, 0, false, false); + D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL)+1, GT_RACE, (cv_kartencore.value == 1), true, 0, false, false); return; } From 72d9728c937361fbe0da580b6d8d0224f50a14f6 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 20:51:22 +0100 Subject: [PATCH 14/15] Eggman's Way should never be a netgame --- src/menus/main-goner.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/menus/main-goner.cpp b/src/menus/main-goner.cpp index cea76976c..8074bc8a2 100644 --- a/src/menus/main-goner.cpp +++ b/src/menus/main-goner.cpp @@ -1603,6 +1603,8 @@ void M_GonerPlayground(INT32 choice) multiplayer = true; + levellist.newgametype = GT_TUTORIAL; + levellist.netgame = false; M_MenuToLevelPreamble(0, false); D_MapChange( From cf65205ec46fd66e10465fb5290d72bf19cc12f2 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 28 Aug 2025 21:26:34 +0100 Subject: [PATCH 15/15] Fix "LOST & FOUND" header for only one L&F map available being a de-cupped Sealed Star --- src/k_menudraw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 7503b6af9..a82aaebd7 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -8765,6 +8765,7 @@ static void M_DrawStatsMaps(void) i = -1; + const boolean allowsealed = M_SecretUnlocked(SECRET_SPECIALATTACK, true); const boolean allowencore = M_SecretUnlocked(SECRET_ENCORE, true); const boolean allowspb = M_SecretUnlocked(SECRET_SPBATTACK, true); boolean allowtime = false; @@ -8792,7 +8793,11 @@ static void M_DrawStatsMaps(void) if (mapheaderinfo[mnum]->typeoflevel & TOL_TUTORIAL) str = "TUTORIAL MODE"; - else if (mapheaderinfo[mnum]->cup) + else if (mapheaderinfo[mnum]->cup + && (!(mapheaderinfo[mnum]->typeoflevel & TOL_SPECIAL) // not special + || gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found + || mapheaderinfo[mnum]->cup->id >= basenumkartcupheaders // custom content + || allowsealed)) // true order str = va("%s CUP", mapheaderinfo[mnum]->cup->realname); else str = "LOST & FOUND";