Have a Cup visibly locked if no levels are accessible by the current rules of menusearch_t

- Solved by leveraging M_GetFirstLevelInList alongside existing M_CountLevelsInList calls
- Also optimises the above calls in the M_CupLocked case, since that's no longer being directly used otherwise
This commit is contained in:
toaster 2022-12-31 17:50:49 +00:00
parent 2db7562c24
commit 36b1f5f488
2 changed files with 47 additions and 31 deletions

View file

@ -1933,7 +1933,7 @@ static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
V_DrawFill(0, y, BASEVIDWIDTH, 54, 31);
if (levelsearch->cup && !M_CupLocked(levelsearch->cup) && maxlevels > 0)
if (levelsearch->cup && maxlevels > 0)
{
add = (cupgrid.previewanim / 82) % maxlevels;
map = start;
@ -1979,16 +1979,18 @@ static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
}
}
static void M_DrawCupTitle(INT16 y, cupheader_t *cup)
static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
{
UINT8 temp = 0;
V_DrawScaledPatch(0, y, 0, W_CachePatchName("MENUHINT", PU_CACHE));
if (cup)
if (levelsearch->cup)
{
boolean unlocked = !M_CupLocked(cup);
boolean unlocked = (M_GetFirstLevelInList(&temp, levelsearch) != NEXTMAP_INVALID);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
patch_t *icon = W_CachePatchName(cup->icon, PU_CACHE);
const char *str = (unlocked ? va("%s Cup", cup->name) : "???");
patch_t *icon = W_CachePatchName(levelsearch->cup->icon, PU_CACHE);
const char *str = (unlocked ? va("%s Cup", levelsearch->cup->name) : "???");
INT16 offset = V_LSTitleLowStringWidth(str, 0) / 2;
V_DrawLSTitleLowString(BASEVIDWIDTH/2 - offset, y+6, 0, str);
@ -2011,26 +2013,26 @@ static void M_DrawCupTitle(INT16 y, cupheader_t *cup)
void M_DrawCupSelect(void)
{
UINT8 i, j;
UINT8 i, j, temp = 0;
levelsearch_t templevelsearch = levellist.levelsearch; // full copy
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
for (i = 0; i < CUPMENU_COLUMNS; i++)
{
for (j = 0; j < CUPMENU_ROWS; j++)
{
size_t id = (i + (j * CUPMENU_COLUMNS)) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS));
cupheader_t *iconcup = cupgrid.builtgrid[id];
patch_t *patch = NULL;
INT16 x, y;
INT16 icony = 7;
if (!iconcup)
if (!cupgrid.builtgrid[id])
break;
/*if (iconcup->emeraldnum == 0)
templevelsearch.cup = cupgrid.builtgrid[id];
/*if (templevelsearch.cup->emeraldnum == 0)
patch = W_CachePatchName("CUPMON3A", PU_CACHE);
else*/ if (iconcup->emeraldnum > 7)
else*/ if (templevelsearch.cup->emeraldnum > 7)
{
patch = W_CachePatchName("CUPMON2A", PU_CACHE);
icony = 5;
@ -2043,14 +2045,14 @@ void M_DrawCupSelect(void)
V_DrawScaledPatch(x, y, 0, patch);
if (M_CupLocked(iconcup))
if (M_GetFirstLevelInList(&temp, &templevelsearch) == NEXTMAP_INVALID)
{
patch_t *st = W_CachePatchName(va("ICONST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
V_DrawScaledPatch(x + 8, y + icony, 0, st);
}
else
{
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName(iconcup->icon, PU_CACHE));
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName(templevelsearch.cup->icon, PU_CACHE));
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName("CUPBOX", PU_CACHE));
}
}
@ -2061,8 +2063,10 @@ void M_DrawCupSelect(void)
0, W_CachePatchName("CUPCURS", PU_CACHE)
);
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
M_DrawCupPreview(146 + (24*menutransition.tics), &templevelsearch);
M_DrawCupTitle(120 - (24*menutransition.tics), templevelsearch.cup);
M_DrawCupTitle(120 - (24*menutransition.tics), &templevelsearch);
}
static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
@ -2228,7 +2232,7 @@ void M_DrawLevelSelect(void)
map = M_GetNextLevelInList(map, &j, &levellist.levelsearch);
}
M_DrawCupTitle(tay, levellist.levelsearch.cup);
M_DrawCupTitle(tay, &levellist.levelsearch);
}
void M_DrawTimeAttack(void)

View file

@ -3418,19 +3418,6 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
return false;
// Does the map have lock conditions?
if (levelsearch->checklocked)
{
// Check for completion
if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
&& !(mapheaderinfo[mapnum]->mapvisited & MV_BEATEN))
return false;
// Check for unlock
if (M_MapLocked(mapnum+1))
return false;
}
// Check for TOL
if (!(mapheaderinfo[mapnum]->typeoflevel & levelsearch->typeoflevel))
return false;
@ -3449,6 +3436,19 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
&& mapheaderinfo[mapnum]->cup != levelsearch->cup)
return false;
// Finally, the most complex check: does the map have lock conditions?
if (levelsearch->checklocked)
{
// Check for completion
if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
&& !(mapheaderinfo[mapnum]->mapvisited & MV_BEATEN))
return false;
// Check for unlock
if (M_MapLocked(mapnum+1))
return false;
}
// Survived our checks.
return true;
}
@ -3462,6 +3462,9 @@ UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
if (levelsearch->cup)
{
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
return 0;
for (i = 0; i < CUPCACHE_MAX; i++)
{
if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[i], levelsearch))
@ -3488,6 +3491,12 @@ UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch)
if (levelsearch->cup)
{
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
{
*i = CUPCACHE_MAX;
return NEXTMAP_INVALID;
}
*i = 0;
mapnum = NEXTMAP_INVALID;
for (; *i < CUPCACHE_MAX; (*i)++)
@ -3555,6 +3564,8 @@ static void M_LevelSelectScrollDest(void)
static void M_LevelListFromGametype(INT16 gt)
{
static boolean first = true;
UINT8 temp = 0;
if (first || gt != levellist.newgametype || levellist.guessgt != MAXGAMETYPES)
{
levellist.newgametype = gt;
@ -3589,7 +3600,6 @@ static void M_LevelListFromGametype(INT16 gt)
const size_t unitlen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
templevelsearch.cup = kartcupheaders;
templevelsearch.checklocked = false;
// Make sure there's valid cups before going to this menu.
if (templevelsearch.cup == NULL)
@ -3612,6 +3622,7 @@ static void M_LevelListFromGametype(INT16 gt)
while (templevelsearch.cup)
{
templevelsearch.checklocked = false;
if (!M_CountLevelsToShowInList(&templevelsearch))
{
// No valid maps, skip.
@ -3638,7 +3649,8 @@ static void M_LevelListFromGametype(INT16 gt)
cupgrid.builtgrid[currentid] = templevelsearch.cup;
if (!M_CupLocked(templevelsearch.cup))
templevelsearch.checklocked = true;
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
{
highestunlockedid = currentid;
if (Playing() && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)