Merge branch 'map-ui-better' into 'master'

Show Medals/Spray Cans/Ancient Shrines more outside of Statistics

See merge request kart-krew-dev/ring-racers-internal!2500
This commit is contained in:
Eidolon 2025-03-16 16:04:53 -05:00
commit 5f4298625c
2 changed files with 236 additions and 15 deletions

View file

@ -3271,11 +3271,169 @@ void M_DrawCupSelect(void)
}
INT16 ty = M_EaseWithTransition(Easing_Linear, 5 * 24);
V_DrawFill(0, 146 + ty, BASEVIDWIDTH, 54, 31);
M_DrawCupPreview(146 + ty, &templevelsearch);
y = 146 + ty;
V_DrawFill(0, y, BASEVIDWIDTH, 54, 31);
M_DrawCupPreview(y, &templevelsearch);
M_DrawCupTitle(120 - ty, &templevelsearch);
if (templevelsearch.grandprix == false && templevelsearch.cup != NULL)
{
if (templevelsearch.cup != &dummy_lostandfound)
{
templevelsearch.checklocked = false;
}
// The following makes a HUGE assumption that we're
// never going to have more than ~9 Race Courses
// (with Medals) in Lost & Found. Which is almost
// certainly true for Krew, but is very likely to
// be violated by the long tail of modding. To those
// finding this eventually: I'M SORRY ~toast 221024
struct work_array_t {
emblem_t *medal;
UINT16 col;
UINT16 dotcol;
} work_array[CUPCACHE_MAX];
boolean incj = false;
i = j = 0;
INT16 map = M_GetFirstLevelInList(&i, &templevelsearch);
emblem_t *emblem = NULL;
while (map < nummapheaders && j < CUPCACHE_MAX)
{
if (map < basenummapheaders)
{
emblem = NULL;
incj = false;
work_array[j].medal = NULL;
work_array[j].col = work_array[j].dotcol = UINT16_MAX;
if (templevelsearch.timeattack)
{
emblem = M_GetLevelEmblems(map+1);
while (emblem)
{
if (emblem->type == ET_TIME)
{
incj = true;
if (gamedata->collected[emblem-emblemlocations])
{
if (!work_array[j].medal
|| (
(work_array[j].medal->type == ET_TIME)
&& (work_array[j].medal->tag < emblem->tag)
)
)
{
work_array[j].medal = emblem;
}
}
}
else if ((emblem->type == ET_MAP)
&& (emblem->flags & ME_SPBATTACK))
{
incj = true;
if (gamedata->collected[emblem-emblemlocations])
{
work_array[j].dotcol = M_GetEmblemColor(emblem);
}
}
emblem = M_GetLevelEmblems(-1);
}
}
else if ((gamedata->gotspraycans > 0) && (mapheaderinfo[map]->typeoflevel & TOL_RACE))
{
incj = true;
if (mapheaderinfo[map]->cache_spraycan < gamedata->numspraycans)
{
work_array[j].col = gamedata->spraycans[mapheaderinfo[map]->cache_spraycan].col;
}
if (mapheaderinfo[map]->records.mapvisited & MV_MYSTICMELODY)
{
work_array[j].dotcol = SKINCOLOR_TURQUOISE;
}
}
if (incj)
j++;
}
map = M_GetNextLevelInList(map, &i, &templevelsearch);
}
if (j)
{
x = (BASEVIDWIDTH - (j*10))/2 + 1;
y += 2;
V_DrawFill(x - 4, y, (j*10) + 6, 3, 31);
for (i = 1; i <= 6; i++)
{
V_DrawFill(x + i - 4, y+2+i, (j*10) + 6 - (i*2), 1, 31);
}
y--;
for (i = 0; i < j; i++)
{
if (templevelsearch.timeattack)
{
if (work_array[i].medal)
{
// Primary Medal
V_DrawMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(work_array[i].medal, false), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(work_array[i].medal), GTC_MENUCACHE));
}
else
{
// Need it!
V_DrawScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
}
}
else
{
if (work_array[i].col < numskincolors)
{
// Spray Can
V_DrawMappedPatch(x, y, 0, W_CachePatchName("GOTCAN", PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, work_array[i].col, GTC_MENUCACHE));
}
else
{
// Need it!
V_DrawFill(x+3, y+3, 2, 2, 6);
}
}
if (work_array[i].dotcol < numskincolors)
{
// Bonus (Secondary Medal or Ancient Shrine)
V_DrawMappedPatch(x+4, y+7, 0, W_CachePatchName("COLORSP1", PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, work_array[i].dotcol, GTC_MENUCACHE));
}
x += 10;
}
}
}
if (cupgrid.numpages > 1)
{
x = 3 - (skullAnimCounter/5);
@ -3393,6 +3551,8 @@ static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
V_DrawLSTitleLowString(x2, y+28, 0, word2);
}
static INT32 M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, boolean allowencore, boolean allowspb, boolean allowbonus, boolean draw);
static void M_DrawLevelSelectBlock(INT16 x, INT16 y, UINT16 map, boolean redblink, boolean greyscale)
{
UINT8 *colormap = NULL;
@ -3426,6 +3586,49 @@ static void M_DrawLevelSelectBlock(INT16 x, INT16 y, UINT16 map, boolean redblin
)
);
}
else if (!levellist.netgame)
{
x += 80+2;
y += 50-1;
const boolean allowencore = (
!levellist.levelsearch.timeattack
&& M_SecretUnlocked(SECRET_ENCORE, true)
);
const boolean allowspb = (
levellist.levelsearch.timeattack
&& M_SecretUnlocked(SECRET_SPBATTACK, true)
);
INT32 width = x - M_DrawMapMedals(map, x, y,
levellist.levelsearch.timeattack,
allowencore,
allowspb,
!levellist.levelsearch.timeattack,
false
);
if (width > 2)
{
width -= 2; // minor poke
V_DrawFill(x + 7 - width, y - 2, width, 9, 31);
UINT8 i;
for (i = 1; i < 7; i++)
{
V_DrawFill(x + 7 - width - i, y + i - 2, 1, 9 - i, 31);
}
M_DrawMapMedals(map, x, y,
levellist.levelsearch.timeattack,
allowencore,
allowspb,
!levellist.levelsearch.timeattack,
true
);
}
}
}
void M_DrawLevelSelect(void)
@ -8028,15 +8231,14 @@ challengedesc:
#define STATSSTEP 10
static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, boolean allowencore, boolean allowspb)
static INT32 M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, boolean allowencore, boolean allowspb, boolean allowbonus, boolean draw)
{
UINT8 lasttype = UINT8_MAX, curtype;
// M_GetLevelEmblems is ONE-indexed, urgh
emblem_t *emblem = M_GetLevelEmblems(mapnum+1);
const boolean hasmedals = (emblem != NULL);
boolean collected = false;
boolean collected = false, hasmedals = false;
while (emblem)
{
@ -8083,11 +8285,19 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, b
}
// Shift over if emblem is of a different discipline
if (lasttype != UINT8_MAX && lasttype != curtype)
x -= 4;
lasttype = curtype;
if (lasttype != curtype)
{
if (lasttype != UINT8_MAX)
x -= 4;
else
hasmedals = true;
if (collected)
lasttype = curtype;
}
if (!draw)
;
else if (collected)
V_DrawMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
else
@ -8097,6 +8307,9 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, b
x -= 8;
}
if (!allowbonus)
return x;
if (hasmedals)
x -= 4;
@ -8104,7 +8317,7 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, b
{
UINT16 col = gamedata->spraycans[mapheaderinfo[mapnum]->cache_spraycan].col;
if (col < numskincolors)
if (draw && col < numskincolors)
{
V_DrawMappedPatch(x, y, 0, W_CachePatchName("GOTCAN", PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE));
@ -8115,9 +8328,13 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y, boolean allowtime, b
if (mapheaderinfo[mapnum]->records.mapvisited & MV_MYSTICMELODY)
{
V_DrawScaledPatch(x, y, 0, W_CachePatchName("GOTMEL", PU_CACHE));
if (draw)
V_DrawScaledPatch(x, y, 0, W_CachePatchName("GOTMEL", PU_CACHE));
x -= 8;
}
return x;
}
static void M_DrawStatsMaps(void)
@ -8284,7 +8501,7 @@ static void M_DrawStatsMaps(void)
);
}
M_DrawMapMedals(mnum, medalspos - 8, y, allowtime, allowencore, allowspb);
M_DrawMapMedals(mnum, medalspos - 8, y, allowtime, allowencore, allowspb, true, true);
if (mapheaderinfo[mnum]->menuttl[0])
{

View file

@ -2442,10 +2442,12 @@ static const char *M_GetConditionString(condition_t *cn)
case UC_EMBLEM: // Requires emblem x to be obtained
{
INT32 checkLevel;
INT32 checkLevel = NEXTMAP_INVALID;
i = cn->requirement-1;
checkLevel = M_EmblemMapNum(&emblemlocations[i]);
if (i >= 0 && i < numemblems)
checkLevel = M_EmblemMapNum(&emblemlocations[i]);
if (checkLevel >= nummapheaders || !mapheaderinfo[checkLevel] || emblemlocations[i].type == ET_NONE)
return va("INVALID MEDAL MAP \"%d:%d\"", cn->requirement, checkLevel);
@ -3869,7 +3871,7 @@ UINT16 M_UnlockableMapNum(unlockable_t *unlock)
UINT16 M_EmblemMapNum(emblem_t *emblem)
{
if (emblem->levelCache == NEXTMAP_INVALID)
if (emblem->levelCache == NEXTMAP_INVALID && emblem->level)
{
UINT16 result = G_MapNumber(emblem->level);
@ -3877,6 +3879,8 @@ UINT16 M_EmblemMapNum(emblem_t *emblem)
return result;
emblem->levelCache = result;
Z_Free(emblem->level);
emblem->level = NULL;
}
return emblem->levelCache;