From 11fcb0b9ae7a834cb6d693d83d4c4304598ac0a0 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 7 Dec 2023 23:36:02 +0000 Subject: [PATCH] Goner Setup: Cook 3 - Add "Outro" One last guaranteed visit to the setup, to get a sendoff before the game truly begins. (The "survey program" joke is now themed softlock prevention.) --- src/k_menudraw.c | 55 +++++++++++++++---------- src/k_menufunc.c | 16 +++++++- src/m_cond.c | 7 +++- src/m_cond.h | 1 + src/menus/main-goner.cpp | 65 ++++++++++++++++++++++++++---- src/menus/transient/level-select.c | 7 +--- 6 files changed, 115 insertions(+), 36 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 40a893a2e..70ce57187 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -1144,11 +1144,29 @@ void M_DrawKartGamemodeMenu(void) void M_DrawHorizontalMenu(void) { - INT32 x = BASEVIDWIDTH/2, y = currentMenu->y, i; + INT32 x, y, i, final = currentMenu->extra2-1, showflags; const INT32 width = 80; + y = currentMenu->y; + + x = (BASEVIDWIDTH - 8*final)/2; + for (i = 0; i < currentMenu->extra2; i++, x += 8) + { + if (i == itemOn) + { + V_DrawFill(x-2, y + 16, 4, 4, 0); + } + else + { + V_DrawFill(x-1, y + 17, 2, 2, + (i >= currentMenu->numitems) ? 20 : 10 + ); + } + } + i = itemOn; + x = BASEVIDWIDTH/2; do { @@ -1161,9 +1179,21 @@ void M_DrawHorizontalMenu(void) while (x < BASEVIDWIDTH + (width/2)) { + showflags = 0; + if (i == final) + { + showflags |= V_STRINGDANCE; + if (itemOn == i) + showflags |= V_YELLOWMAP; + } + else if (i == itemOn) + { + showflags |= highlightflags; + } + V_DrawCenteredThinString( x, y, - (i == itemOn) ? highlightflags : 0, + showflags, currentMenu->menuitems[i].text ); @@ -1172,30 +1202,13 @@ void M_DrawHorizontalMenu(void) x += width; } - y++; // thin string means better to bottom-align these - if (itemOn != 0) - V_DrawCharacter((BASEVIDWIDTH - width)/2 + 3 - (skullAnimCounter/5), y, + V_DrawCharacter((BASEVIDWIDTH - width)/2 + 3 - (skullAnimCounter/5), y + 1, '\x1C' | highlightflags, false); // left arrow if (itemOn != currentMenu->numitems-1) - V_DrawCharacter((BASEVIDWIDTH + width)/2 - 10 + (skullAnimCounter/5), y, + V_DrawCharacter((BASEVIDWIDTH + width)/2 - 10 + (skullAnimCounter/5), y + 1, '\x1D' | highlightflags, false); // right arrow - - x = (BASEVIDWIDTH - 8*(currentMenu->extra2-1))/2; - for (i = 0; i < currentMenu->extra2; i++, x += 8) - { - if (i == itemOn) - { - V_DrawFill(x-2, y + 15, 4, 4, 0); - } - else - { - V_DrawFill(x-1, y + 16, 2, 2, - (i >= currentMenu->numitems) ? 20 : 10 - ); - } - } } #define MAXMSGLINELEN 256 diff --git a/src/k_menufunc.c b/src/k_menufunc.c index c6ebeb401..5b5374b23 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -563,6 +563,20 @@ void M_StartControlPanel(void) Music_Stop("title"); + if (gamedata != NULL + && gamedata->gonerlevel < GDGONER_OUTRO + && gamestartchallenge < MAXUNLOCKABLES) + { + // See M_GameTrulyStarted + if ( + gamedata->unlockpending[gamestartchallenge] + || gamedata->unlocked[gamestartchallenge] + ) + { + gamedata->gonerlevel = GDGONER_OUTRO; + } + } + if (M_GameTrulyStarted() == false) { // Are you ready for the First Boot Experience? @@ -600,7 +614,7 @@ void M_StartControlPanel(void) } else { - if (restoreMenu == NULL) + if (restoreMenu == NULL || restoreMenu == &MAIN_GonerDef) restoreMenu = &MainDef; currentMenu = M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu)); restoreMenu = NULL; diff --git a/src/m_cond.c b/src/m_cond.c index 353f19bc0..8fff98d7f 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -3220,10 +3220,13 @@ boolean M_GameTrulyStarted(void) return true; // Okay, we can check to see if this challenge has been achieved. - return ( + /*return ( gamedata->unlockpending[gamestartchallenge] || gamedata->unlocked[gamestartchallenge] - ); + );*/ + // Actually, on second thought, let's let the Goner Setup play one last time + // The above is used in M_StartControlPanel instead + return (gamedata->gonerlevel == GDGONER_DONE); } boolean M_CheckNetUnlockByID(UINT16 unlockid) diff --git a/src/m_cond.h b/src/m_cond.h index 4bccce9b1..551ad7e42 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -296,6 +296,7 @@ typedef enum { GDGONER_SOUND, GDGONER_PROFILE, GDGONER_TUTORIAL, + GDGONER_OUTRO, GDGONER_DONE, } gdgoner_t; diff --git a/src/menus/main-goner.cpp b/src/menus/main-goner.cpp index d3301b130..dccf1ddd7 100644 --- a/src/menus/main-goner.cpp +++ b/src/menus/main-goner.cpp @@ -12,6 +12,9 @@ #include +static void M_GonerDrawer(void); +static void M_GonerConclude(INT32 choice); + menuitem_t MAIN_Goner[] = { {IT_STRING | IT_CALL, NULL, NULL, NULL, {.routine = M_QuitSRB2}, 0, 0}, // will be replaced @@ -31,9 +34,11 @@ menuitem_t MAIN_Goner[] = {IT_STRING | IT_CALL, "BEGIN TUTORIAL", "PREPARE FOR INTEGRATION.", NULL, {.routine = M_GonerTutorial}, 0, 0}, -}; -static void M_GonerDrawer(void); + {IT_STRING | IT_CALL, "START GAME", + "I WILL SUCCEED.", NULL, + {.routine = M_GonerConclude}, 0, 0}, +}; menu_t MAIN_GonerDef = { 1, // Intentionally not the sizeof calc @@ -305,7 +310,6 @@ void M_AddGonerLines(void) break; } case GDGONER_TUTORIAL: - case GDGONER_DONE: // maybe we could do something different for this eventually { if (!leftoff) { @@ -329,6 +333,36 @@ void M_AddGonerLines(void) break; } + case GDGONER_OUTRO: + { + if (!leftoff) + { + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/3, + "And... the training data is completed."); + } + LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2, + "It's kind of funny, actually."); + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/3, + "Oh? Care to elucidate, Prower?"); + LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2, + "No matter how much time we took getting here, a machine like Metal can play it back in minutes."); + LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2, + "It could have been five days or five years of development on our ""\x82""Ring Racers""\x80"", and that barely matters."); + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4, + "Ha! As if. I'd like to think our partnership hasn't felt that long."); + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2, + "But yes. Perhaps now you have a better appreciation of what we're building here, Metal."); + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2, + "Now, I'm willing to let bygones be bygones."); + LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2, + "As long as you keep your violence to the track, I'll be giving you your autonomy back in a moment."); + LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0, + "We've kept the keys from you long enough!"); + break; + } + case GDGONER_DONE: + break; + default: LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0, "I am error"); @@ -624,6 +658,15 @@ void M_GonerProfile(INT32 choice) M_GonerResetLooking(GDGONER_PROFILE); } +static boolean M_GonerSurveyResponse(INT32 ch) +{ + if (ch != CH_YES) + return; + + if (gamedata->gonerlevel < GDGONER_OUTRO) + gamedata->gonerlevel = GDGONER_OUTRO; +} + void M_GonerTutorial(INT32 choice) { (void)choice; @@ -646,15 +689,23 @@ void M_GonerTutorial(INT32 choice) cupgrid.grandprix = false; levellist.levelsearch.timeattack = false; - if (!M_LevelListFromGametype(GT_TUTORIAL)) + if (!M_LevelListFromGametype(GT_TUTORIAL) && gamedata->gonerlevel < GDGONER_OUTRO) { // The game is incapable of progression, but I can't bring myself to put an I_Error here. - M_StartMessage("SURVEY_PROGRAM", + M_StartMessage("Agreement", "YOU ACCEPT EVERYTHING THAT WILL HAPPEN FROM NOW ON.", - &M_QuitResponse, MM_YESNO, "I agree", "Cancel"); + &M_GonerSurveyResponse, MM_YESNO, "I agree", "Cancel"); } +} - goner_levelworking = gamedata->gonerlevel = GDGONER_DONE; +static void M_GonerConclude(INT32 choice) +{ + (void)choice; + + gamedata->gonerlevel = GDGONER_DONE; + + M_ClearMenus(true); + M_GonerResetText(); } void M_GonerGDQ(boolean opinion) diff --git a/src/menus/transient/level-select.c b/src/menus/transient/level-select.c index de121775c..ec0c3034b 100644 --- a/src/menus/transient/level-select.c +++ b/src/menus/transient/level-select.c @@ -744,11 +744,8 @@ void M_LevelSelected(INT16 add) D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false); - if (M_GameTrulyStarted() == false) - { - // No restoreMenu set. - } - else if (levellist.levelsearch.tutorial) + if (!M_GameTrulyStarted() || + levellist.levelsearch.tutorial) { restoreMenu = currentMenu; }