From 8d25820c9165a576360429590d76202fe467e66c Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Mar 2023 11:24:57 -0800 Subject: [PATCH 01/12] Move screenshot pass out of basic_rendering, into normal_rendering This fixes a bug with avrecorder capturing a mostly white frame at the beginning of a wipe. This was because wipe_capture_start_rendering depends on basic_rendering and a wipe could occur before any 2d elements are batched for the current frame, thus producing a white frame when basic_rendering is passed. It only lasted for one frame because the PREVIOUS frame is used for the wipe itself. This is also why the white frame was not visible on screen. --- src/i_video_common.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/i_video_common.cpp b/src/i_video_common.cpp index ef76d1e58..e12cb712a 100644 --- a/src/i_video_common.cpp +++ b/src/i_video_common.cpp @@ -193,14 +193,16 @@ static InternalPassData build_pass_manager() ); basic_rendering->insert("pp_final_simple_blit", pp_simple_blit_pass); - basic_rendering->insert( + auto screenshot_rendering = std::make_shared(); + + screenshot_rendering->insert( "screenshot_prepare", [screenshot_pass, framebuffer_manager](PassManager&, Rhi&) { screenshot_pass->set_source(framebuffer_manager->current_post_color(), vid.width, vid.height); } ); - basic_rendering->insert("screenshot", screenshot_pass); + screenshot_rendering->insert("screenshot", screenshot_pass); // Composite-present takes the current postprocess result and outputs it to the default framebuffer. // It also renders imgui and presents the screen. @@ -233,6 +235,7 @@ static InternalPassData build_pass_manager() normal_rendering->insert("resource_manager", resource_manager); normal_rendering->insert("basic_rendering", basic_rendering); + normal_rendering->insert("screenshot_rendering", screenshot_rendering); normal_rendering->insert("composite_present_rendering", composite_present_rendering); // Wipe Start Screen Capture rendering @@ -305,14 +308,7 @@ static InternalPassData build_pass_manager() } ); wipe_rendering->insert("pp_final_wipe", pp_wipe_pass); - wipe_rendering->insert( - "screenshot_prepare", - [screenshot_pass, framebuffer_manager](PassManager&, Rhi&) - { - screenshot_pass->set_source(framebuffer_manager->current_post_color(), vid.width, vid.height); - } - ); - wipe_rendering->insert("screenshot", screenshot_pass); + wipe_rendering->insert("screenshot_rendering", screenshot_rendering); wipe_rendering->insert("composite_present_rendering", composite_present_rendering); InternalPassData ret; From 79d8e4e109085a36e542eeb3122011754b4e82b6 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Mon, 27 Feb 2023 22:56:35 -0700 Subject: [PATCH 02/12] WIP: SPB Attack - temp menu draws OOB, no unlocks --- src/d_player.h | 2 ++ src/doomstat.h | 1 + src/g_demo.c | 2 +- src/k_hud.c | 17 +++++++++++++++++ src/k_kart.c | 7 +++++++ src/k_menu.h | 3 +++ src/k_menufunc.c | 2 ++ src/k_roulette.c | 12 ++++++++++++ src/menus/play-local-race-time-attack.c | 9 +++++++++ src/objects/spb.c | 5 +++++ src/p_inter.c | 2 +- src/p_mobj.c | 3 +++ src/p_spec.c | 7 +++++++ 13 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 298c65485..98dee8e9a 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -671,6 +671,8 @@ struct player_t UINT8 eggmanTransferDelay; + fixed_t SPBdistance; + UINT8 tripwireReboundDelay; // When failing Tripwire, brieftly lock out speed-based tripwire pass (anti-cheese) mobj_t *stumbleIndicator; diff --git a/src/doomstat.h b/src/doomstat.h index b0375ffa2..871c25b62 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -139,6 +139,7 @@ extern boolean metalrecording; #define ATTACKING_NONE 0 #define ATTACKING_TIME 1 #define ATTACKING_LAP (1<<1) +#define ATTACKING_SPB (1<<2) extern UINT8 modeattacking; // menu demo things diff --git a/src/g_demo.c b/src/g_demo.c index 174511e4d..617dc386b 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -119,7 +119,7 @@ demoghost *ghosts = NULL; #define DEMOVERSION 0x0007 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" -#define DF_ATTACKMASK (ATTACKING_TIME|ATTACKING_LAP) // This demo contains time/lap data +#define DF_ATTACKMASK (ATTACKING_TIME|ATTACKING_LAP|ATTACKING_SPB) // This demo contains time/lap data #define DF_GHOST 0x08 // This demo contains ghost data too! diff --git a/src/k_hud.c b/src/k_hud.c index 8fd7607ec..a3accce03 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1654,6 +1654,23 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U workx += 6; } } + + if (modeattacking & ATTACKING_SPB && stplyr->SPBdistance > 0) + { + UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); + int ybar = 180; + int widthbar = 120; + + V_DrawFill(160 - widthbar / 2, ybar, widthbar, 1, 6); + V_DrawMappedPatch(160 + widthbar/2 - 7, ybar - 7, FRACUNIT, faceprefix[stplyr->skin][FACE_MINIMAP], colormap); + + // vibes-based math + int bombxoff = (stplyr->SPBdistance/mapobjectscale - mobjinfo[MT_SPB].radius/FRACUNIT - mobjinfo[MT_PLAYER].radius/FRACUNIT) * 8; + bombxoff = sqrt(bombxoff) - 5; + bombxoff = max(0, min(bombxoff, widthbar)); + V_DrawScaledPatch(160 + widthbar/2 - bombxoff, ybar - 7, FRACUNIT, W_CachePatchName("SPBMMAP", PU_CACHE)); + + } } static fixed_t K_DrawKartPositionNumPatch(UINT8 num, UINT8 *color, fixed_t x, fixed_t y, fixed_t scale, INT32 flags) diff --git a/src/k_kart.c b/src/k_kart.c index ce2827cf7..5e9982648 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4095,6 +4095,13 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A { if (inflictor->type == MT_SPBEXPLOSION && inflictor->movefactor) { + if (modeattacking & ATTACKING_SPB) + { + P_DamageMobj(player->mo, inflictor, source, 1, DMG_INSTAKILL); + player->SPBdistance = 0; + S_StopMusic(); + } + spbMultiplier = inflictor->movefactor; if (spbMultiplier <= 0) diff --git a/src/k_menu.h b/src/k_menu.h index 3adbf25de..4bbd752c4 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -232,6 +232,7 @@ typedef enum ta_replay = 0, ta_guest, ta_ghosts, + ta_spb, ta_spacer, ta_start, } ta_e; @@ -761,6 +762,8 @@ extern consvar_t cv_dummykartspeed; extern consvar_t cv_dummygpencore; extern consvar_t cv_dummymatchbots; +extern consvar_t cv_dummyspbattack; + void M_SetupDifficultyOptions(INT32 choice); void M_SetupDifficultySelect(INT32 choice); void M_DifficultySelectInputs(INT32 choice); diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 8898bee71..ce9b07e2f 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -1138,6 +1138,8 @@ void M_Init(void) CV_RegisterVar(&cv_dummygpencore); CV_RegisterVar(&cv_dummymatchbots); + CV_RegisterVar(&cv_dummyspbattack); + CV_RegisterVar(&cv_dummyaddonsearch); M_UpdateMenuBGImage(true); diff --git a/src/k_roulette.c b/src/k_roulette.c index 0d70b9e87..53bb753db 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -189,6 +189,13 @@ static kartitems_t K_KartItemReelTimeAttack[] = KITEM_NONE }; +static kartitems_t K_KartItemReelSPBAttack[] = +{ + KITEM_GACHABOM, + KITEM_SUPERRING, + KITEM_NONE +}; + static kartitems_t K_KartItemReelBreakTheCapsules[] = { KITEM_GACHABOM, @@ -1238,6 +1245,11 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet presetlist = K_KartItemReelBreakTheCapsules; } + if (modeattacking & ATTACKING_SPB) + { + presetlist = K_KartItemReelSPBAttack; + } + for (i = 0; presetlist[i] != KITEM_NONE; i++) { K_PushToRouletteItemList(roulette, presetlist[i]); diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index d41f29dca..687c282a6 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -10,12 +10,16 @@ #include "../m_misc.h" // M_MkdirEach #include "../z_zone.h" // Z_StrDup/Z_Free +consvar_t cv_dummyspbattack = CVAR_INIT ("dummyspbattack", "Off", CV_HIDDEN, CV_OnOff, NULL); + // see ta_e menuitem_t PLAY_TimeAttack[] = { {IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0}, {IT_STRING | IT_SUBMENU, "Guest...", NULL, NULL, {.submenu = &PLAY_TAReplayGuestDef}, 0, 0}, {IT_STRING | IT_SUBMENU, "Ghosts...", NULL, NULL, {.submenu = &PLAY_TAGhostsDef}, 0, 0}, + {IT_STRING | IT_CVAR, "SPB Attack", NULL, + NULL, {.cvar = &cv_dummyspbattack}, 0, 0}, {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, {IT_STRING | IT_CALL, "Start", NULL, NULL, {.routine = M_StartTimeAttack}, 0, 0}, }; @@ -426,6 +430,11 @@ void M_StartTimeAttack(INT32 choice) modeattacking |= ATTACKING_LAP; } + if (cv_dummyspbattack.value) + { + modeattacking |= ATTACKING_SPB; + } + // Still need to reset devmode cht_debug = 0; emeralds = 0; diff --git a/src/objects/spb.c b/src/objects/spb.c index af1041049..261245e79 100644 --- a/src/objects/spb.c +++ b/src/objects/spb.c @@ -83,6 +83,9 @@ static void SPBMantaRings(mobj_t *spb) const fixed_t floatHeight = 24 * spb->scale; fixed_t floorDist = INT32_MAX; + if (modeattacking & ATTACKING_SPB) + return; // no one else to use 'em + if (leveltime % SPB_MANTA_VRATE == 0) { spb_manta_vscale(spb) = max(spb_manta_vscale(spb) - 1, SPB_MANTA_VMAX); @@ -730,6 +733,8 @@ static void SPBChase(mobj_t *spb, mobj_t *bestMobj) dist = P_AproxDistance(P_AproxDistance(spb->x - chase->x, spb->y - chase->y), spb->z - chase->z); + chasePlayer->SPBdistance = dist; + desiredSpeed = FixedMul(baseSpeed, FRACUNIT + FixedDiv(dist - range, range)); if (desiredSpeed < baseSpeed) diff --git a/src/p_inter.c b/src/p_inter.c index 3d69eec25..f4ce507ac 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1921,7 +1921,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } - if (!player->exiting && specialstageinfo.valid == true) + if (!player->exiting && (specialstageinfo.valid == true || modeattacking & ATTACKING_SPB)) { player->pflags |= PF_NOCONTEST; P_DoPlayerExit(player); diff --git a/src/p_mobj.c b/src/p_mobj.c index 3f0481a94..e939478a6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12225,6 +12225,9 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) if ((i == MT_RANDOMITEM) && (gametyperules & (GTR_PAPERITEMS|GTR_CIRCUIT)) == (GTR_PAPERITEMS|GTR_CIRCUIT)) return MT_PAPERITEMSPOT; + if ((i == MT_RING) && (modeattacking & ATTACKING_SPB)) + return MT_THOK; + return i; } diff --git a/src/p_spec.c b/src/p_spec.c index 5d52da0fb..c881200dd 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1973,6 +1973,13 @@ static void K_HandleLapIncrement(player_t *player) rainbowstartavailable = false; } + if (player->laps == 1 && modeattacking & ATTACKING_SPB) + { + P_SpawnMobj(player->mo->x - FixedMul(8000*mapobjectscale, cos(player->mo->angle)), + player->mo->y - FixedMul(8000*mapobjectscale, sin(player->mo->angle)), + player->mo->z, MT_SPB); + } + if (netgame && player->laps > numlaps) CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players])); From 6173ca47aae9604a588aa02c4afb864327a02aed Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Tue, 28 Feb 2023 06:12:01 -0700 Subject: [PATCH 03/12] SPB Attack: emblems/medals preliminary --- src/deh_tables.c | 1 + src/doomstat.h | 11 ++++++----- src/g_game.c | 11 +++++++++++ src/m_cond.c | 3 +++ src/m_cond.h | 1 + src/p_mobj.c | 2 +- src/p_spec.c | 2 +- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index ab5e7959c..de88639e8 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6402,6 +6402,7 @@ struct int_const_s const INT_CONST[] = { // Map emblem var flags {"ME_ENCORE",ME_ENCORE}, + {"ME_SPBATTACK",ME_SPBATTACK}, // p_local.h constants {"FLOATSPEED",FLOATSPEED}, diff --git a/src/doomstat.h b/src/doomstat.h index 871c25b62..e9a3442ac 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -121,11 +121,12 @@ struct recorddata_t }; // mapvisited is now a set of flags that says what we've done in the map. -#define MV_VISITED (1) -#define MV_BEATEN (1<<1) -#define MV_ENCORE (1<<2) -#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE) -#define MV_MP ((MV_MAX+1)<<1) +#define MV_VISITED (1) +#define MV_BEATEN (1<<1) +#define MV_ENCORE (1<<2) +#define MV_SPBATTACK (1<<3) +#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE) +#define MV_MP ((MV_MAX+1)<<1) // Set if homebrew PWAD stuff has been added. extern boolean modifiedgame; diff --git a/src/g_game.c b/src/g_game.c index b7fce9a96..59ce1c743 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -512,6 +512,12 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord) { break; } + case ET_MAP: + { + if (emblem->flags & ME_SPBATTACK) + break; + goto bademblem; + } default: goto bademblem; } @@ -3697,6 +3703,11 @@ static void G_UpdateVisited(void) mapheaderinfo[prevmap]->mapvisited |= MV_ENCORE; } + if (modeattacking & ATTACKING_SPB) + { + mapheaderinfo[prevmap]->mapvisited |= MV_SPBATTACK; + } + if (modeattacking) G_UpdateRecordReplays(); diff --git a/src/m_cond.c b/src/m_cond.c index 070c5b9ea..8ff27ba24 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1029,6 +1029,9 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa if (embtype & ME_ENCORE) flags |= MV_ENCORE; + if (embtype & ME_SPBATTACK) + flags |= MV_SPBATTACK; + res = ((mapheaderinfo[levelnum]->mapvisited & flags) == flags); gamedata->collected[i] = res; diff --git a/src/m_cond.h b/src/m_cond.h index 367f3d720..c279572f7 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -74,6 +74,7 @@ struct conditionset_t // Map emblem flags #define ME_ENCORE 1 // Achieve in Encore +#define ME_SPBATTACK 2 // Achieve in SPB Attack struct emblem_t { diff --git a/src/p_mobj.c b/src/p_mobj.c index e939478a6..45fa389d2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12175,7 +12175,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) boolean isRingCapsule = (mthing->args[0] < 1 || mthing->args[0] == KITEM_SUPERRING || mthing->args[0] >= NUMKARTITEMS); // don't spawn ring capsules in GTR_SPHERES gametypes - if (isRingCapsule && (gametyperules & GTR_SPHERES)) + if (isRingCapsule && ((gametyperules & GTR_SPHERES) || (modeattacking & ATTACKING_SPB))) return false; // in record attack, only spawn ring capsules diff --git a/src/p_spec.c b/src/p_spec.c index c881200dd..4044cca8a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1973,7 +1973,7 @@ static void K_HandleLapIncrement(player_t *player) rainbowstartavailable = false; } - if (player->laps == 1 && modeattacking & ATTACKING_SPB) + if (player->laps == 1 && modeattacking & ATTACKING_SPB && false) { P_SpawnMobj(player->mo->x - FixedMul(8000*mapobjectscale, cos(player->mo->angle)), player->mo->y - FixedMul(8000*mapobjectscale, sin(player->mo->angle)), From f3f4ac16de9cc6dbf05abcbe07ed1df16536b0a1 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 1 Mar 2023 05:18:01 -0700 Subject: [PATCH 04/12] SPB Attack: medals, emblems, and fixes --- src/console.c | 2 ++ src/g_game.c | 5 ++++- src/k_hud.c | 1 - src/menus/play-local-race-time-attack.c | 7 ++++++- src/p_spec.c | 6 +++--- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/console.c b/src/console.c index 04a9fdce4..a86db72f2 100644 --- a/src/console.c +++ b/src/console.c @@ -923,8 +923,10 @@ boolean CON_Responder(event_t *ev) // check for console toggle key if (ev->type != ev_console) { + #ifndef DEVELOP // I have driven this course 45 times and I just want to give myself rocketsneakers if (modeattacking || metalrecording || marathonmode) return false; + #endif if (ev->data1 >= NUMKEYS) // See also: HUD_Responder { diff --git a/src/g_game.c b/src/g_game.c index 59ce1c743..8b4af1536 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -514,7 +514,7 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord) } case ET_MAP: { - if (emblem->flags & ME_SPBATTACK) + if (emblem->flags & ME_SPBATTACK && cv_dummyspbattack.value) break; goto bademblem; } @@ -522,6 +522,9 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord) goto bademblem; } + if (cv_dummyspbattack.value && !(emblem->flags & ME_SPBATTACK)) + return; + if (!gamedata->collected[(emblem-emblemlocations)] && gonnadrawtime) break; diff --git a/src/k_hud.c b/src/k_hud.c index a3accce03..45037d1d0 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1669,7 +1669,6 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U bombxoff = sqrt(bombxoff) - 5; bombxoff = max(0, min(bombxoff, widthbar)); V_DrawScaledPatch(160 + widthbar/2 - bombxoff, ybar - 7, FRACUNIT, W_CachePatchName("SPBMMAP", PU_CACHE)); - } } diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index 687c282a6..406e4aef8 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -10,7 +10,12 @@ #include "../m_misc.h" // M_MkdirEach #include "../z_zone.h" // Z_StrDup/Z_Free -consvar_t cv_dummyspbattack = CVAR_INIT ("dummyspbattack", "Off", CV_HIDDEN, CV_OnOff, NULL); +static void CV_SPBAttackChanged(void) +{ + G_UpdateTimeStickerMedals(levellist.choosemap, false); +} + +consvar_t cv_dummyspbattack = CVAR_INIT ("dummyspbattack", "Off", CV_HIDDEN|CV_CALL, CV_OnOff, CV_SPBAttackChanged); // see ta_e menuitem_t PLAY_TimeAttack[] = diff --git a/src/p_spec.c b/src/p_spec.c index 4044cca8a..aa480024e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1973,10 +1973,10 @@ static void K_HandleLapIncrement(player_t *player) rainbowstartavailable = false; } - if (player->laps == 1 && modeattacking & ATTACKING_SPB && false) + if (player->laps == 1 && modeattacking & ATTACKING_SPB) { - P_SpawnMobj(player->mo->x - FixedMul(8000*mapobjectscale, cos(player->mo->angle)), - player->mo->y - FixedMul(8000*mapobjectscale, sin(player->mo->angle)), + P_SpawnMobj(player->mo->x - FixedMul(1000*mapobjectscale, FINECOSINE(player->mo->angle >> ANGLETOFINESHIFT)), + player->mo->y - FixedMul(1000*mapobjectscale, FINESINE(player->mo->angle >> ANGLETOFINESHIFT)), player->mo->z, MT_SPB); } From 211206ba6f7b6fd94f6d075c3a8be0adc34670da Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 1 Mar 2023 21:44:20 -0700 Subject: [PATCH 05/12] Fix menus, fix failure condition --- src/g_game.c | 2 ++ src/k_menu.h | 9 +++++++ src/k_menudraw.c | 20 ++++++++++++++ src/menus/play-local-race-time-attack.c | 36 ++++++++++++++++++++++--- src/p_inter.c | 2 +- 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 8b4af1536..cf32b67ea 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2452,6 +2452,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) growshrinktimer = 0; bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); + if (modeattacking & ATTACKING_SPB) + rings = 20; spheres = 0; kickstartaccel = 0; khudfault = 0; diff --git a/src/k_menu.h b/src/k_menu.h index 4bbd752c4..06753e754 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -799,6 +799,7 @@ void M_StartTimeAttack(INT32 choice); void M_ReplayTimeAttack(INT32 choice); void M_HandleStaffReplay(INT32 choice); void M_SetGuestReplay(INT32 choice); +boolean M_TimeAttackInputs (INT32 choice); // MP selection void M_MPOptSelect(INT32 choice); @@ -1143,6 +1144,14 @@ void M_DrawAddons(void); #define TILEFLIP_MAX 16 +extern struct timeattackmenu_s { + + tic_t ticker; // How long the menu's been open for + tic_t spbflicker; // used for SPB flicker-in + +} timeattackmenu; + + // Keep track of some pause menu data for visual goodness. extern struct challengesmenu_s { diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 9c3fe3233..6957e4e35 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2371,6 +2371,26 @@ void M_DrawTimeAttack(void) V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:"); K_drawKartTimestamp(timerec, 162+t, timeheight+6, 0, 1); + + + + const UINT8 anim_duration = 16; + const UINT8 anim = (timeattackmenu.ticker % (anim_duration * 2)) < anim_duration; + + INT32 buttonx = 162 + t; + INT32 buttony = timeheight; + + if (anim) + V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_I", PU_CACHE)); + else + V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_IB", PU_CACHE)); + + if (timeattackmenu.ticker > (timeattackmenu.spbflicker + TICRATE/6) || timeattackmenu.ticker % 2) + { + if (cv_dummyspbattack.value) + V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_STKARM", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE)); + } + } else opty = 80; diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index 406e4aef8..fedb71b35 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -17,14 +17,44 @@ static void CV_SPBAttackChanged(void) consvar_t cv_dummyspbattack = CVAR_INIT ("dummyspbattack", "Off", CV_HIDDEN|CV_CALL, CV_OnOff, CV_SPBAttackChanged); +struct timeattackmenu_s timeattackmenu; + +boolean M_TimeAttackInputs(INT32 ch) +{ + const UINT8 pid = 0; + const boolean buttonR = M_MenuButtonPressed(pid, MBT_R); + (void) ch; + + timeattackmenu.ticker++; + + if (buttonR) + { + cv_dummyspbattack.value = !(cv_dummyspbattack.value); + CV_SPBAttackChanged(); + timeattackmenu.spbflicker = timeattackmenu.ticker; + if (cv_dummyspbattack.value) + { + S_StartSound(NULL, sfx_s3k9f); + S_StopSoundByID(NULL, sfx_s3k92); + } + else + { + S_StartSound(NULL, sfx_s3k92); + S_StopSoundByID(NULL, sfx_s3k9f); + } + + return true; + } + + return false; +} + // see ta_e menuitem_t PLAY_TimeAttack[] = { {IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0}, {IT_STRING | IT_SUBMENU, "Guest...", NULL, NULL, {.submenu = &PLAY_TAReplayGuestDef}, 0, 0}, {IT_STRING | IT_SUBMENU, "Ghosts...", NULL, NULL, {.submenu = &PLAY_TAGhostsDef}, 0, 0}, - {IT_STRING | IT_CVAR, "SPB Attack", NULL, - NULL, {.cvar = &cv_dummyspbattack}, 0, 0}, {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, {IT_STRING | IT_CALL, "Start", NULL, NULL, {.routine = M_StartTimeAttack}, 0, 0}, }; @@ -42,7 +72,7 @@ menu_t PLAY_TimeAttackDef = { NULL, NULL, NULL, - NULL + M_TimeAttackInputs }; diff --git a/src/p_inter.c b/src/p_inter.c index f4ce507ac..09036f117 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1921,7 +1921,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } - if (!player->exiting && (specialstageinfo.valid == true || modeattacking & ATTACKING_SPB)) + if ((!player->exiting && specialstageinfo.valid == true) || (modeattacking & ATTACKING_SPB)) { player->pflags |= PF_NOCONTEST; P_DoPlayerExit(player); From 8739d3076a8e90a065935a3fe8286a58f93cfc56 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 1 Mar 2023 21:52:45 -0700 Subject: [PATCH 06/12] Use more fitting name for SPB Attack menu patch --- src/k_menudraw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 6957e4e35..1a4a465e1 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2388,7 +2388,7 @@ void M_DrawTimeAttack(void) if (timeattackmenu.ticker > (timeattackmenu.spbflicker + TICRATE/6) || timeattackmenu.ticker % 2) { if (cv_dummyspbattack.value) - V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_STKARM", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE)); + V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_SPBATK", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE)); } } From c1baff583c5949948472284aea142de9f7f813ae Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Wed, 1 Mar 2023 22:18:47 -0700 Subject: [PATCH 07/12] Don't abort SPB Attack on postrace death, idiot --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 09036f117..f4ce507ac 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1921,7 +1921,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } - if ((!player->exiting && specialstageinfo.valid == true) || (modeattacking & ATTACKING_SPB)) + if (!player->exiting && (specialstageinfo.valid == true || modeattacking & ATTACKING_SPB)) { player->pflags |= PF_NOCONTEST; P_DoPlayerExit(player); From 31e2c1567eb821755ce50dcaa877d22cc4cf4270 Mon Sep 17 00:00:00 2001 From: SteelT Date: Fri, 3 Mar 2023 23:19:46 -0500 Subject: [PATCH 08/12] Update replay save prompts to use the new button graphics - A K_drawButtonAnim function is also provided for convince, since I figured it would have more future uses - This also makes all of the button patches global, in addition --- src/k_hud.c | 39 +++++++++++++++++++++------------------ src/k_hud.h | 15 +++++++++++++++ src/st_stuff.c | 17 +++++++++++++---- src/y_inter.c | 21 ++++++++++++++++----- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 8fd7607ec..883534094 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -180,19 +180,19 @@ patch_t *kp_capsuletarget_far[2]; patch_t *kp_capsuletarget_far_text[2]; patch_t *kp_capsuletarget_near[8]; -static patch_t *kp_button_a[2][2]; -static patch_t *kp_button_b[2][2]; -static patch_t *kp_button_c[2][2]; -static patch_t *kp_button_x[2][2]; -static patch_t *kp_button_y[2][2]; -static patch_t *kp_button_z[2][2]; -static patch_t *kp_button_start[2]; -static patch_t *kp_button_l[2]; -static patch_t *kp_button_r[2]; -static patch_t *kp_button_up[2]; -static patch_t *kp_button_down[2]; -static patch_t *kp_button_right[2]; -static patch_t *kp_button_left[2]; +patch_t *kp_button_a[2][2]; +patch_t *kp_button_b[2][2]; +patch_t *kp_button_c[2][2]; +patch_t *kp_button_x[2][2]; +patch_t *kp_button_y[2][2]; +patch_t *kp_button_z[2][2]; +patch_t *kp_button_start[2]; +patch_t *kp_button_l[2]; +patch_t *kp_button_r[2]; +patch_t *kp_button_up[2]; +patch_t *kp_button_down[2]; +patch_t *kp_button_right[2]; +patch_t *kp_button_left[2]; static void K_LoadButtonGraphics(patch_t *kp[2], int letter) { @@ -4639,13 +4639,16 @@ K_drawMiniPing (void) } } +void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic) +{ + const UINT8 anim_duration = 16; + const UINT8 anim = (animtic % (anim_duration * 2)) < anim_duration; + V_DrawScaledPatch(x, y, flags, button[anim]); +} + static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2], INT32 textflags) { INT32 flags = V_SNAPTORIGHT | V_SLIDEIN | V_SPLITSCREEN; - - const UINT8 anim_duration = 16; - const UINT8 anim = (leveltime % (anim_duration * 2)) < anim_duration; - INT32 x = (BASEVIDWIDTH/2) - 10; INT32 y = (idx * 16); @@ -4660,7 +4663,7 @@ static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2], I textflags |= (flags | V_6WIDTHSPACE | V_ALLOWLOWERCASE); - V_DrawScaledPatch(x, y - 4, flags, kp[anim]); + K_drawButtonAnim(x, y - 4, flags, kp, leveltime); V_DrawRightAlignedThinString(x - 2, y, textflags, label); } diff --git a/src/k_hud.h b/src/k_hud.h index e9b0603f2..ba50049f5 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -45,6 +45,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap); void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap); void K_drawTargetHUD(const vector3_t *origin, player_t *player); +void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic); extern patch_t *kp_capsuletarget_arrow[2][2]; extern patch_t *kp_capsuletarget_icon[2]; @@ -52,6 +53,20 @@ extern patch_t *kp_capsuletarget_far[2]; extern patch_t *kp_capsuletarget_far_text[2]; extern patch_t *kp_capsuletarget_near[8]; +extern patch_t *kp_button_a[2][2]; +extern patch_t *kp_button_b[2][2]; +extern patch_t *kp_button_c[2][2]; +extern patch_t *kp_button_x[2][2]; +extern patch_t *kp_button_y[2][2]; +extern patch_t *kp_button_z[2][2]; +extern patch_t *kp_button_start[2]; +extern patch_t *kp_button_l[2]; +extern patch_t *kp_button_r[2]; +extern patch_t *kp_button_up[2]; +extern patch_t *kp_button_down[2]; +extern patch_t *kp_button_right[2]; +extern patch_t *kp_button_left[2]; + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/st_stuff.c b/src/st_stuff.c index 24aa174ee..bb7a6f50d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1324,13 +1324,22 @@ void ST_Drawer(void) switch (demo.savemode) { case DSM_NOTSAVING: - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "(B) or (X): Save replay"); - break; + { + INT32 buttonx = BASEVIDWIDTH; + INT32 buttony = 2; + V_DrawRightAlignedThinString(buttonx - 64, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "or"); + K_drawButtonAnim(buttonx - 65, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], leveltime); + V_DrawRightAlignedThinString(buttonx - 2, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Save replay"); + break; + } case DSM_WILLAUTOSAVE: - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Replay will be saved. (Look Backward: Change title)"); + { + V_DrawRightAlignedThinString(BASEVIDWIDTH - 66, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Replay will be saved."); + K_drawButtonAnim(BASEVIDWIDTH - 68, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); + V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Change title"); break; - + } case DSM_WILLSAVE: V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Replay will be saved."); break; diff --git a/src/y_inter.c b/src/y_inter.c index 04b251ec5..e6864e2a3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -96,6 +96,7 @@ static INT32 powertype = PWRLV_DISABLED; static INT32 intertic; static INT32 endtic = -1; static INT32 sorttic = -1; +static INT32 replayprompttic; intertype_t intertype = int_none; @@ -599,10 +600,17 @@ skiptallydrawer: { switch (demo.savemode) { - case DSM_NOTSAVING: - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "(B) or (X): Save replay"); - break; - + case DSM_NOTSAVING: + { + INT32 buttonx = BASEVIDWIDTH; + INT32 buttony = 2; + + K_drawButtonAnim(buttonx - 87, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], replayprompttic); + V_DrawRightAlignedThinString(buttonx - 64, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "or"); + K_drawButtonAnim(buttonx - 65, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], replayprompttic); + V_DrawRightAlignedThinString(buttonx - 2, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Save replay"); + break; + } case DSM_SAVED: V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Replay saved!"); break; @@ -633,8 +641,11 @@ void Y_Ticker(void) if (demo.recording) { if (demo.savemode == DSM_NOTSAVING) + { + replayprompttic++; G_CheckDemoTitleEntry(); - + } + if (demo.savemode == DSM_WILLSAVE || demo.savemode == DSM_WILLAUTOSAVE) G_SaveDemo(); } From e8d6d7f6328132537873209527e30c395cdd2bff Mon Sep 17 00:00:00 2001 From: SteelT Date: Fri, 3 Mar 2023 23:43:06 -0500 Subject: [PATCH 09/12] Fix missing draw call for DSM_NOTSAVING --- src/st_stuff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/st_stuff.c b/src/st_stuff.c index bb7a6f50d..a06f1770c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1328,6 +1328,7 @@ void ST_Drawer(void) INT32 buttonx = BASEVIDWIDTH; INT32 buttony = 2; + K_drawButtonAnim(buttonx - 87, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); V_DrawRightAlignedThinString(buttonx - 64, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "or"); K_drawButtonAnim(buttonx - 65, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], leveltime); V_DrawRightAlignedThinString(buttonx - 2, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Save replay"); From 65e8315bd98400234479cfca05ec6f167f5c7652 Mon Sep 17 00:00:00 2001 From: SteelT Date: Sat, 4 Mar 2023 01:02:21 -0500 Subject: [PATCH 10/12] Update thin strings to use V_6WIDTHSPACE --- src/st_stuff.c | 16 ++++++++-------- src/y_inter.c | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index a06f1770c..9b06af3b6 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1328,21 +1328,21 @@ void ST_Drawer(void) INT32 buttonx = BASEVIDWIDTH; INT32 buttony = 2; - K_drawButtonAnim(buttonx - 87, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); - V_DrawRightAlignedThinString(buttonx - 64, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "or"); - K_drawButtonAnim(buttonx - 65, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], leveltime); - V_DrawRightAlignedThinString(buttonx - 2, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Save replay"); + K_drawButtonAnim(buttonx - 76, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); + V_DrawRightAlignedThinString(buttonx - 55, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, "or"); + K_drawButtonAnim(buttonx - 55, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], leveltime); + V_DrawRightAlignedThinString(buttonx - 2, buttony, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, "Save replay"); break; } case DSM_WILLAUTOSAVE: { - V_DrawRightAlignedThinString(BASEVIDWIDTH - 66, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Replay will be saved."); - K_drawButtonAnim(BASEVIDWIDTH - 68, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Change title"); + V_DrawRightAlignedThinString(BASEVIDWIDTH - 55, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, "Replay will be saved."); + K_drawButtonAnim(BASEVIDWIDTH - 56, 0, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], leveltime); + V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, "Change title"); break; } case DSM_WILLSAVE: - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_YELLOWMAP, "Replay will be saved."); + V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_YELLOWMAP, "Replay will be saved."); break; case DSM_TITLEENTRY: diff --git a/src/y_inter.c b/src/y_inter.c index e6864e2a3..5687602b4 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -605,14 +605,14 @@ skiptallydrawer: INT32 buttonx = BASEVIDWIDTH; INT32 buttony = 2; - K_drawButtonAnim(buttonx - 87, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], replayprompttic); - V_DrawRightAlignedThinString(buttonx - 64, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "or"); - K_drawButtonAnim(buttonx - 65, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], replayprompttic); - V_DrawRightAlignedThinString(buttonx - 2, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Save replay"); + K_drawButtonAnim(buttonx - 76, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_b[1], replayprompttic); + V_DrawRightAlignedThinString(buttonx - 55, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|hilicol, "or"); + K_drawButtonAnim(buttonx - 55, buttony, V_SNAPTOTOP|V_SNAPTORIGHT, kp_button_x[1], replayprompttic); + V_DrawRightAlignedThinString(buttonx - 2, buttony, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|hilicol, "Save replay"); break; } case DSM_SAVED: - V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|hilicol, "Replay saved!"); + V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|V_6WIDTHSPACE|hilicol, "Replay saved!"); break; case DSM_TITLEENTRY: From 320685cf97d27d918c2d21d8a910d4f7474a1651 Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sat, 4 Mar 2023 06:41:44 -0700 Subject: [PATCH 11/12] SPB Attack: review fixup omnibus --- src/doomstat.h | 2 +- src/g_game.c | 13 ++++++++-- src/k_menu.h | 1 + src/k_menudraw.c | 34 +++++++++++++------------ src/k_roulette.c | 3 +-- src/menus/play-local-race-time-attack.c | 13 ++++++---- src/menus/transient/level-select.c | 3 +++ src/p_mobj.c | 9 ++++--- 8 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index e9a3442ac..88e9bd66d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -125,7 +125,7 @@ struct recorddata_t #define MV_BEATEN (1<<1) #define MV_ENCORE (1<<2) #define MV_SPBATTACK (1<<3) -#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE) +#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE|MV_SPBATTACK) #define MV_MP ((MV_MAX+1)<<1) // Set if homebrew PWAD stuff has been added. diff --git a/src/g_game.c b/src/g_game.c index cf32b67ea..a0d187790 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2451,9 +2451,18 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) itemamount = 0; growshrinktimer = 0; bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); - rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); - if (modeattacking & ATTACKING_SPB) + if (gametyperules & GTR_SPHERES) + { + rings = 0; + } + else if (modeattacking & ATTACKING_SPB) + { rings = 20; + } + else + { + rings = 5; + } spheres = 0; kickstartaccel = 0; khudfault = 0; diff --git a/src/k_menu.h b/src/k_menu.h index 06753e754..fb41a64a2 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -799,6 +799,7 @@ void M_StartTimeAttack(INT32 choice); void M_ReplayTimeAttack(INT32 choice); void M_HandleStaffReplay(INT32 choice); void M_SetGuestReplay(INT32 choice); +void M_TimeAttackTick(void); boolean M_TimeAttackInputs (INT32 choice); // MP selection diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 1a4a465e1..547da7ed6 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2372,23 +2372,25 @@ void M_DrawTimeAttack(void) V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:"); K_drawKartTimestamp(timerec, 162+t, timeheight+6, 0, 1); - - - const UINT8 anim_duration = 16; - const UINT8 anim = (timeattackmenu.ticker % (anim_duration * 2)) < anim_duration; - - INT32 buttonx = 162 + t; - INT32 buttony = timeheight; - - if (anim) - V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_I", PU_CACHE)); - else - V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_IB", PU_CACHE)); - - if (timeattackmenu.ticker > (timeattackmenu.spbflicker + TICRATE/6) || timeattackmenu.ticker % 2) + // SPB Attack control hint + menu overlay + if (levellist.newgametype == GT_RACE && levellist.levelsearch.timeattack == true) { - if (cv_dummyspbattack.value) - V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_SPBATK", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE)); + const UINT8 anim_duration = 16; + const UINT8 anim = (timeattackmenu.ticker % (anim_duration * 2)) < anim_duration; + + INT32 buttonx = 162 + t; + INT32 buttony = timeheight; + + if (anim) + V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_I", PU_CACHE)); + else + V_DrawScaledPatch(buttonx + 35, buttony - 3, V_SNAPTOLEFT, W_CachePatchName("TLB_IB", PU_CACHE)); + + if (timeattackmenu.ticker > (timeattackmenu.spbflicker + TICRATE/6) || timeattackmenu.ticker % 2) + { + if (cv_dummyspbattack.value) + V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_SPBATK", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE)); + } } } diff --git a/src/k_roulette.c b/src/k_roulette.c index 53bb753db..57f948880 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -1244,8 +1244,7 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet { presetlist = K_KartItemReelBreakTheCapsules; } - - if (modeattacking & ATTACKING_SPB) + else if (modeattacking & ATTACKING_SPB) { presetlist = K_KartItemReelSPBAttack; } diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index fedb71b35..f96b7b6b5 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -19,17 +19,20 @@ consvar_t cv_dummyspbattack = CVAR_INIT ("dummyspbattack", "Off", CV_HIDDEN|CV_C struct timeattackmenu_s timeattackmenu; +void M_TimeAttackTick(void) +{ + timeattackmenu.ticker++; +} + boolean M_TimeAttackInputs(INT32 ch) { const UINT8 pid = 0; const boolean buttonR = M_MenuButtonPressed(pid, MBT_R); (void) ch; - timeattackmenu.ticker++; - - if (buttonR) + if (buttonR && levellist.newgametype == GT_RACE) { - cv_dummyspbattack.value = !(cv_dummyspbattack.value); + CV_AddValue(&cv_dummyspbattack, 1); CV_SPBAttackChanged(); timeattackmenu.spbflicker = timeattackmenu.ticker; if (cv_dummyspbattack.value) @@ -69,7 +72,7 @@ menu_t PLAY_TimeAttackDef = { NULL, 2, 5, M_DrawTimeAttack, - NULL, + M_TimeAttackTick, NULL, NULL, M_TimeAttackInputs diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index 461473bd9..20442ceb6 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -230,6 +230,9 @@ boolean M_LevelListFromGametype(INT16 gt) first = false; } + if (levellist.levelsearch.timeattack == false || levellist.newgametype != GT_RACE) + CV_SetValue(&cv_dummyspbattack, 0); + // Obviously go to Cup Select in gametypes that have cups. // Use a really long level select in gametypes that don't use cups. diff --git a/src/p_mobj.c b/src/p_mobj.c index 45fa389d2..8fe24ffed 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12185,6 +12185,10 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return false; } break; + case MT_RING: + if (modeattacking & ATTACKING_SPB) + return false; + break; default: break; } @@ -12224,10 +12228,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) if ((i == MT_RANDOMITEM) && (gametyperules & (GTR_PAPERITEMS|GTR_CIRCUIT)) == (GTR_PAPERITEMS|GTR_CIRCUIT)) return MT_PAPERITEMSPOT; - - if ((i == MT_RING) && (modeattacking & ATTACKING_SPB)) - return MT_THOK; - + return i; } From 4121b4c385593e5e72c3dc52b98be729d2bdf5fd Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Sat, 4 Mar 2023 06:43:52 -0700 Subject: [PATCH 12/12] SPB Attack: fix double cvar callback --- src/menus/play-local-race-time-attack.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index f96b7b6b5..abdff5762 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -33,7 +33,6 @@ boolean M_TimeAttackInputs(INT32 ch) if (buttonR && levellist.newgametype == GT_RACE) { CV_AddValue(&cv_dummyspbattack, 1); - CV_SPBAttackChanged(); timeattackmenu.spbflicker = timeattackmenu.ticker; if (cv_dummyspbattack.value) {