From fbfb8a507d609bd71cf9352af426beb091f00d1f Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 26 Mar 2023 22:40:27 +0100 Subject: [PATCH] Extras menu: Add GT_TUTORIAL selection screen - Disabled if no maps available/unlocked - Has another exception for showing TEST RUN under all gametypes - Splitplayers is forbidden --- src/g_game.c | 1 + src/k_menu.h | 1 + src/k_menudraw.c | 7 +++++++ src/menus/extras-1.c | 22 ++++++++++++++++++++++ src/menus/play-online-host.c | 1 + src/menus/transient/level-select.c | 11 ++++++++--- 6 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 5cb9d13f0..526bf621f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3638,6 +3638,7 @@ INT16 G_GetFirstMapOfGametype(UINT8 pgametype) templevelsearch.typeoflevel = G_TOLFlag(pgametype); templevelsearch.cupmode = (!(gametypes[pgametype]->rules & GTR_NOCUPSELECT)); templevelsearch.timeattack = false; + templevelsearch.tutorial = false; templevelsearch.checklocked = true; if (templevelsearch.cupmode) diff --git a/src/k_menu.h b/src/k_menu.h index cd7bbbe68..2018e842a 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -733,6 +733,7 @@ typedef struct levelsearch_s { UINT32 typeoflevel; cupheader_t *cup; boolean timeattack; + boolean tutorial; boolean cupmode; boolean checklocked; } levelsearch_t; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 3ef4eeefd..27cf20c00 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2411,6 +2411,12 @@ void M_DrawLevelSelect(void) INT16 y = 80 - (12 * levellist.y); boolean tatransition = ((menutransition.startmenu == &PLAY_TimeAttackDef || menutransition.endmenu == &PLAY_TimeAttackDef) && menutransition.tics); + if (levellist.levelsearch.tutorial) + { + patch_t *bg = W_CachePatchName("M_XTRABG", PU_CACHE); + V_DrawFixedPatch(0, 0, FRACUNIT, 0, bg, NULL); + } + if (tatransition) { t = -t; @@ -5183,6 +5189,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) templevelsearch.typeoflevel = G_TOLFlag(GT_RACE)|G_TOLFlag(GT_BATTLE); templevelsearch.cupmode = true; templevelsearch.timeattack = false; + templevelsearch.tutorial = false; templevelsearch.checklocked = false; M_DrawCupPreview(146, &templevelsearch); diff --git a/src/menus/extras-1.c b/src/menus/extras-1.c index 771f70036..eb2de1711 100644 --- a/src/menus/extras-1.c +++ b/src/menus/extras-1.c @@ -17,6 +17,9 @@ menuitem_t EXTRAS_Main[] = {IT_STRING | IT_CALL, "Challenges", "View the requirements for some of the secret content you can unlock!", NULL, {.routine = M_Challenges}, 0, 0}, + {IT_STRING | IT_CALL, "Tutorial", "Help Dr. Eggman and Tails test out their new Ring Racers.", + NULL, {.routine = M_LevelSelectInit}, 0, GT_TUTORIAL}, + {IT_STRING | IT_CALL, "Statistics", "Look back on some of your greatest achievements such as your playtime and wins!", NULL, {.routine = M_Statistics}, 0, 0}, @@ -79,6 +82,25 @@ void M_InitExtras(INT32 choice) } } + // Tutorial + { + levelsearch_t templevelsearch; + UINT8 i = 0; + INT16 map; + + templevelsearch.cup = NULL; + templevelsearch.typeoflevel = G_TOLFlag(GT_TUTORIAL); + templevelsearch.cupmode = false; + templevelsearch.timeattack = false; + templevelsearch.tutorial = true; + templevelsearch.checklocked = true; + + map = M_GetFirstLevelInList(&i, &templevelsearch); + + EXTRAS_Main[extras_tutorial].status = (IT_STRING | + ((map == NEXTMAP_INVALID) ? IT_TRANSTEXT : IT_CALL)); + } + // Egg TV if (M_SecretUnlocked(SECRET_EGGTV, true)) { diff --git a/src/menus/play-online-host.c b/src/menus/play-online-host.c index 95ce0660e..9610154ef 100644 --- a/src/menus/play-online-host.c +++ b/src/menus/play-online-host.c @@ -100,6 +100,7 @@ void M_MPSetupNetgameMapSelect(INT32 choice) levellist.netgame = true; // Make sure we reset those levellist.levelsearch.timeattack = false; + levellist.levelsearch.tutorial = false; levellist.levelsearch.checklocked = true; cupgrid.grandprix = false; diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index 234d6d539..4de5b0668 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -61,7 +61,7 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch) return false; // Check for TOL (permits TEST RUN outside of time attack) - if ((levelsearch->timeattack || mapheaderinfo[mapnum]->typeoflevel) + if ((levelsearch->timeattack || levelsearch->tutorial || mapheaderinfo[mapnum]->typeoflevel) && !(mapheaderinfo[mapnum]->typeoflevel & levelsearch->typeoflevel)) return false; @@ -427,6 +427,7 @@ void M_LevelSelectInit(INT32 choice) // Make sure this is reset as we'll only be using this function for offline games! levellist.netgame = false; levellist.levelsearch.checklocked = true; + levellist.levelsearch.tutorial = (gt == GT_TUTORIAL); switch (currentMenu->menuitems[itemOn].mvar1) { @@ -498,7 +499,7 @@ void M_LevelSelected(INT16 add) { if (gamestate == GS_MENU) { - UINT8 ssplayers = cv_splitplayers.value-1; + UINT8 ssplayers = levellist.levelsearch.tutorial ? 0 : cv_splitplayers.value-1; netgame = false; multiplayer = true; @@ -543,7 +544,11 @@ void M_LevelSelected(INT16 add) D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false); - if (levellist.netgame == true) + if (levellist.levelsearch.tutorial) + { + restoreMenu = currentMenu; + } + else if (levellist.netgame == true) { restoreMenu = &PLAY_MP_OptSelectDef; }