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.
This commit is contained in:
toaster 2024-03-19 16:33:47 +00:00
parent 9fd44f21da
commit 56e8964427

View file

@ -142,6 +142,7 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
{ {
UINT16 i; UINT16 i;
INT16 work; INT16 work;
boolean posisvalid = false;
if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0 if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
&& (gamedata->chaokeys < GDMAX_CHAOKEYS)) && (gamedata->chaokeys < GDMAX_CHAOKEYS))
@ -149,28 +150,22 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
if (fresh && unlockid >= MAXUNLOCKABLES) if (fresh && unlockid >= MAXUNLOCKABLES)
{ {
UINT16 selection[MAXUNLOCKABLES]; if (challengesmenu.currentunlock < MAXUNLOCKABLES)
UINT16 numunlocks = 0;
// Get a random available unlockable.
for (i = 0; i < MAXUNLOCKABLES; i++)
{ {
if (!unlockables[i].conditionset) // Use the last selected time.
{ unlockid = challengesmenu.currentunlock;
continue; posisvalid = true;
}
if (!gamedata->unlocked[i])
{
continue;
}
selection[numunlocks++] = i;
} }
else
if (!numunlocks)
{ {
// ...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++) for (i = 0; i < MAXUNLOCKABLES; i++)
{ {
if (!unlockables[i].conditionset) if (!unlockables[i].conditionset)
@ -178,13 +173,43 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
continue; 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; 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) if (unlockid >= MAXUNLOCKABLES)
return; return;
@ -192,9 +217,8 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
if (challengesmenu.unlockcondition) if (challengesmenu.unlockcondition)
Z_Free(challengesmenu.unlockcondition); Z_Free(challengesmenu.unlockcondition);
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock); 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; return;
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++) for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
@ -330,6 +354,8 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
if (challengesmenu.pending || desiredmenu == NULL) if (challengesmenu.pending || desiredmenu == NULL)
{ {
static boolean firstopen = true;
challengesmenu.ticker = 0; challengesmenu.ticker = 0;
challengesmenu.requestflip = false; challengesmenu.requestflip = false;
challengesmenu.requestnew = false; challengesmenu.requestnew = false;
@ -337,9 +363,14 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
challengesmenu.keywasadded = false; challengesmenu.keywasadded = false;
challengesmenu.considersealedswapalert = false; challengesmenu.considersealedswapalert = false;
challengesmenu.chaokeyhold = 0; challengesmenu.chaokeyhold = 0;
challengesmenu.currentunlock = MAXUNLOCKABLES;
challengesmenu.unlockcondition = NULL; challengesmenu.unlockcondition = NULL;
if (firstopen)
{
challengesmenu.currentunlock = MAXUNLOCKABLES;
firstopen = false;
}
M_PopulateChallengeGrid(); M_PopulateChallengeGrid();
if (gamedata->challengegrid) if (gamedata->challengegrid)
{ {
@ -860,6 +891,8 @@ boolean M_ChallengesInputs(INT32 ch)
Z_Free(challengesmenu.extradata); Z_Free(challengesmenu.extradata);
challengesmenu.extradata = NULL; challengesmenu.extradata = NULL;
if (challengesmenu.unlockcondition)
Z_Free(challengesmenu.unlockcondition);
challengesmenu.unlockcondition = NULL; challengesmenu.unlockcondition = NULL;
return true; return true;