Add the ability to play Tutorial courses from the Challenges menu

- Only works in parties of 1
- Currently intentionally disabled for other types of Match Race, as they tend to have too many options and I don't want to risk infinite menu loops
This commit is contained in:
toaster 2025-08-13 21:48:34 +01:00
parent 248541833a
commit 9074eaf3c8
2 changed files with 75 additions and 17 deletions

View file

@ -7346,6 +7346,8 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
const char *gtname = "Find your prize...";
UINT16 mapnum = M_UnlockableMapNum(ref);
y = BASEVIDHEIGHT-(9+3);
if (mapnum >= nummapheaders
|| mapheaderinfo[mapnum] == NULL
|| mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
@ -7389,7 +7391,17 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
guessgt = GT_SPECIAL;
}
if (guessgt == GT_SPECIAL && !M_SecretUnlocked(SECRET_SPECIALATTACK, true))
if (setup_numplayers <= 1 && guessgt == GT_TUTORIAL)
{
// Only for 1p
K_DrawGameControl(
1, y, 0,
"<a_animated> <orange>Play Tutorial",
0, TINY_FONT, 0
);
gtname = NULL;
}
else if (guessgt == GT_SPECIAL && !M_SecretUnlocked(SECRET_SPECIALATTACK, true))
{
gtname = "???";
}
@ -7409,7 +7421,10 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
NULL);
}
V_DrawThinString(1, BASEVIDHEIGHT-(9+3), 0, gtname);
if (gtname)
{
V_DrawThinString(1, y, 0, gtname);
}
break;
}
@ -7589,13 +7604,13 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
pushed = strcmp(song, mapheaderinfo[map]->encoremusname[musicid]) == 0;
}
if (!pushed)
K_DrawGameControl(x, y, 0, "<l> <sky>E Side", 0, TINY_FONT, 0);
else
K_DrawGameControl(x, y, 0, "<l_pressed> <gray>E Side", 0, TINY_FONT, 0);
// K_drawButton(x&FRACUNIT, y*FRACUNIT, 0, kp_button_l, pushed);
// x += SHORT(kp_button_l[0]->width);
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "E Side");
K_DrawGameControl(
x, y, 0,
(!pushed)
? "<l> <magenta>E Side"
: "<l_pressed> <gray>E Side",
0, TINY_FONT, 0
);
x = 8;
y -= 10;
@ -7614,13 +7629,13 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
pushed = strcmp(song, mapheaderinfo[map]->musname[musicid]) == 0;
}
if (!pushed)
K_DrawGameControl(x, y, 0, "<a> <sky>Play CD", 0, TINY_FONT, 0);
else
K_DrawGameControl(x, y, 0, "<a_pressed> <gray>Play CD", 0, TINY_FONT, 0);
// K_drawButton(x*FRACUNIT, y*FRACUNIT, 0, kp_button_a[1], pushed);
// x += SHORT(kp_button_a[1][0]->width);
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "Play CD");
K_DrawGameControl(
x, y, 0,
(!pushed)
? "<a> <sky>Play CD"
: "<a_pressed> <gray>Play CD",
0, TINY_FONT, 0
);
}
}
default:

View file

@ -1155,8 +1155,51 @@ boolean M_ChallengesInputs(INT32 ch)
if (challengesmenu.currentunlock < MAXUNLOCKABLES
&& gamedata->unlocked[challengesmenu.currentunlock])
{
unlockable_t *ref = &unlockables[challengesmenu.currentunlock];
switch (unlockables[challengesmenu.currentunlock].type)
{
case SECRET_MAP:
{
// Only for 1p
if (setup_numplayers <= 1 && M_MenuConfirmPressed(pid))
{
// Map exists...
UINT16 mapnum = M_UnlockableMapNum(ref);
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
{
// is tutorial...
INT32 guessgt = G_GuessGametypeByTOL(mapheaderinfo[mapnum]->typeoflevel);
if (guessgt == GT_TUTORIAL)
{
M_SetMenuDelay(pid);
multiplayer = true;
restoreMenu = currentMenu;
restorelevellist = levellist;
// mild hack
levellist.newgametype = guessgt;
levellist.netgame = false;
M_MenuToLevelPreamble(0, false);
D_MapChange(
mapnum+1,
guessgt,
false,
true,
1,
false,
false
);
M_CloseChallenges();
M_ClearMenus(true);
}
}
}
break;
}
case SECRET_ALTTITLE:
{
if (M_MenuConfirmPressed(pid))
@ -1185,7 +1228,7 @@ boolean M_ChallengesInputs(INT32 ch)
{
const char *trymusname = NULL;
UINT16 map = M_UnlockableMapNum(&unlockables[challengesmenu.currentunlock]);
UINT16 map = M_UnlockableMapNum(ref);
if (map >= nummapheaders
|| !mapheaderinfo[map])
{