From 56e896442734f7e6b2c3cab92c877a0077bf158e Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 19 Mar 2024 16:33:47 +0000 Subject: [PATCH] Challenges Menu: Keep your last focus when returning to it without a new Tile being unlocked - Going back to it on the menus picks up where you left off - Going back to it after earning ONLY a Chao Key(s) Possibly useful for full-game 9-hour speedruns, where unlock tile identification/breakage could genuinely be a part of routing. --- src/menus/extras-challenges.c | 81 ++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index fe9c23e13..75e393b53 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -142,6 +142,7 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) { UINT16 i; INT16 work; + boolean posisvalid = false; if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0 && (gamedata->chaokeys < GDMAX_CHAOKEYS)) @@ -149,28 +150,22 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) if (fresh && unlockid >= MAXUNLOCKABLES) { - UINT16 selection[MAXUNLOCKABLES]; - UINT16 numunlocks = 0; - - // Get a random available unlockable. - for (i = 0; i < MAXUNLOCKABLES; i++) + if (challengesmenu.currentunlock < MAXUNLOCKABLES) { - if (!unlockables[i].conditionset) - { - continue; - } - - if (!gamedata->unlocked[i]) - { - continue; - } - - selection[numunlocks++] = i; + // Use the last selected time. + unlockid = challengesmenu.currentunlock; + posisvalid = true; } - - if (!numunlocks) + else { - // ...OK, get a random unlockable. + UINT16 selection[MAXUNLOCKABLES]; + UINT16 numunlocks = 0; + + boolean triedrandomlevel = 0; + +tryfreshrandom: + + // Get a random available unlockable. for (i = 0; i < MAXUNLOCKABLES; i++) { if (!unlockables[i].conditionset) @@ -178,13 +173,43 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) continue; } + // Otherwise we don't care, just pick any non-blank tile + if (triedrandomlevel < 2) + { + // We try for any unlock second + if (!gamedata->unlocked[i]) + { + continue; + } + + if (triedrandomlevel == 0) + { + // We try for a pending unlock first + if (!gamedata->unlockpending[i]) + { + continue; + } + } + } + selection[numunlocks++] = i; } - } - unlockid = selection[M_RandomKey(numunlocks)]; + if (numunlocks == 0) + { + if (triedrandomlevel == 2) + return; + + triedrandomlevel++; + goto tryfreshrandom; + } + + unlockid = selection[M_RandomKey(numunlocks)]; + } } + challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME); + if (unlockid >= MAXUNLOCKABLES) return; @@ -192,9 +217,8 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh) if (challengesmenu.unlockcondition) Z_Free(challengesmenu.unlockcondition); challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock); - challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME); - if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL) + if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL || posisvalid) return; for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++) @@ -330,6 +354,8 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu) if (challengesmenu.pending || desiredmenu == NULL) { + static boolean firstopen = true; + challengesmenu.ticker = 0; challengesmenu.requestflip = false; challengesmenu.requestnew = false; @@ -337,9 +363,14 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu) challengesmenu.keywasadded = false; challengesmenu.considersealedswapalert = false; challengesmenu.chaokeyhold = 0; - challengesmenu.currentunlock = MAXUNLOCKABLES; challengesmenu.unlockcondition = NULL; + if (firstopen) + { + challengesmenu.currentunlock = MAXUNLOCKABLES; + firstopen = false; + } + M_PopulateChallengeGrid(); if (gamedata->challengegrid) { @@ -860,6 +891,8 @@ boolean M_ChallengesInputs(INT32 ch) Z_Free(challengesmenu.extradata); challengesmenu.extradata = NULL; + if (challengesmenu.unlockcondition) + Z_Free(challengesmenu.unlockcondition); challengesmenu.unlockcondition = NULL; return true;