mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
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.)
This commit is contained in:
parent
8a2445820e
commit
11fcb0b9ae
6 changed files with 115 additions and 36 deletions
|
|
@ -1144,11 +1144,29 @@ void M_DrawKartGamemodeMenu(void)
|
||||||
|
|
||||||
void M_DrawHorizontalMenu(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;
|
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;
|
i = itemOn;
|
||||||
|
x = BASEVIDWIDTH/2;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
@ -1161,9 +1179,21 @@ void M_DrawHorizontalMenu(void)
|
||||||
|
|
||||||
while (x < BASEVIDWIDTH + (width/2))
|
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(
|
V_DrawCenteredThinString(
|
||||||
x, y,
|
x, y,
|
||||||
(i == itemOn) ? highlightflags : 0,
|
showflags,
|
||||||
currentMenu->menuitems[i].text
|
currentMenu->menuitems[i].text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1172,30 +1202,13 @@ void M_DrawHorizontalMenu(void)
|
||||||
x += width;
|
x += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
y++; // thin string means better to bottom-align these
|
|
||||||
|
|
||||||
if (itemOn != 0)
|
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
|
'\x1C' | highlightflags, false); // left arrow
|
||||||
|
|
||||||
if (itemOn != currentMenu->numitems-1)
|
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
|
'\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
|
#define MAXMSGLINELEN 256
|
||||||
|
|
|
||||||
|
|
@ -563,6 +563,20 @@ void M_StartControlPanel(void)
|
||||||
|
|
||||||
Music_Stop("title");
|
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)
|
if (M_GameTrulyStarted() == false)
|
||||||
{
|
{
|
||||||
// Are you ready for the First Boot Experience?
|
// Are you ready for the First Boot Experience?
|
||||||
|
|
@ -600,7 +614,7 @@ void M_StartControlPanel(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (restoreMenu == NULL)
|
if (restoreMenu == NULL || restoreMenu == &MAIN_GonerDef)
|
||||||
restoreMenu = &MainDef;
|
restoreMenu = &MainDef;
|
||||||
currentMenu = M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu));
|
currentMenu = M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu));
|
||||||
restoreMenu = NULL;
|
restoreMenu = NULL;
|
||||||
|
|
|
||||||
|
|
@ -3220,10 +3220,13 @@ boolean M_GameTrulyStarted(void)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Okay, we can check to see if this challenge has been achieved.
|
// Okay, we can check to see if this challenge has been achieved.
|
||||||
return (
|
/*return (
|
||||||
gamedata->unlockpending[gamestartchallenge]
|
gamedata->unlockpending[gamestartchallenge]
|
||||||
|| gamedata->unlocked[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)
|
boolean M_CheckNetUnlockByID(UINT16 unlockid)
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,7 @@ typedef enum {
|
||||||
GDGONER_SOUND,
|
GDGONER_SOUND,
|
||||||
GDGONER_PROFILE,
|
GDGONER_PROFILE,
|
||||||
GDGONER_TUTORIAL,
|
GDGONER_TUTORIAL,
|
||||||
|
GDGONER_OUTRO,
|
||||||
GDGONER_DONE,
|
GDGONER_DONE,
|
||||||
} gdgoner_t;
|
} gdgoner_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
|
||||||
|
static void M_GonerDrawer(void);
|
||||||
|
static void M_GonerConclude(INT32 choice);
|
||||||
|
|
||||||
menuitem_t MAIN_Goner[] =
|
menuitem_t MAIN_Goner[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_CALL, NULL, NULL, NULL, {.routine = M_QuitSRB2}, 0, 0}, // will be replaced
|
{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",
|
{IT_STRING | IT_CALL, "BEGIN TUTORIAL",
|
||||||
"PREPARE FOR INTEGRATION.", NULL,
|
"PREPARE FOR INTEGRATION.", NULL,
|
||||||
{.routine = M_GonerTutorial}, 0, 0},
|
{.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 = {
|
menu_t MAIN_GonerDef = {
|
||||||
1, // Intentionally not the sizeof calc
|
1, // Intentionally not the sizeof calc
|
||||||
|
|
@ -305,7 +310,6 @@ void M_AddGonerLines(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GDGONER_TUTORIAL:
|
case GDGONER_TUTORIAL:
|
||||||
case GDGONER_DONE: // maybe we could do something different for this eventually
|
|
||||||
{
|
{
|
||||||
if (!leftoff)
|
if (!leftoff)
|
||||||
{
|
{
|
||||||
|
|
@ -329,6 +333,36 @@ void M_AddGonerLines(void)
|
||||||
|
|
||||||
break;
|
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:
|
default:
|
||||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||||
"I am error");
|
"I am error");
|
||||||
|
|
@ -624,6 +658,15 @@ void M_GonerProfile(INT32 choice)
|
||||||
M_GonerResetLooking(GDGONER_PROFILE);
|
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 M_GonerTutorial(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
@ -646,15 +689,23 @@ void M_GonerTutorial(INT32 choice)
|
||||||
cupgrid.grandprix = false;
|
cupgrid.grandprix = false;
|
||||||
levellist.levelsearch.timeattack = 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.
|
// 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.",
|
"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)
|
void M_GonerGDQ(boolean opinion)
|
||||||
|
|
|
||||||
|
|
@ -744,11 +744,8 @@ void M_LevelSelected(INT16 add)
|
||||||
|
|
||||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||||
|
|
||||||
if (M_GameTrulyStarted() == false)
|
if (!M_GameTrulyStarted() ||
|
||||||
{
|
levellist.levelsearch.tutorial)
|
||||||
// No restoreMenu set.
|
|
||||||
}
|
|
||||||
else if (levellist.levelsearch.tutorial)
|
|
||||||
{
|
{
|
||||||
restoreMenu = currentMenu;
|
restoreMenu = currentMenu;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue