mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add Goner Choice
- Selection between Tails' Way (existing Tutorial) and Eggman's Way (Playground)
- Semi-passable UI
- Characterful descriptions
- Add "PlaygroundRoute" condition to Challenges
- Fires if you select Eggman's Way
- 0 Chao Keys unless you go back to Goner for the outro (which Playground skips)
This commit is contained in:
parent
c06fc9cccf
commit
295e8dd0ce
10 changed files with 305 additions and 32 deletions
|
|
@ -2965,7 +2965,8 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
|| (++offset && fastcmp(params[0], "REPLAY"))
|
||||
|| (++offset && fastcmp(params[0], "CRASH"))
|
||||
|| (++offset && fastcmp(params[0], "TUTORIALSKIP"))
|
||||
|| (++offset && fastcmp(params[0], "TUTORIALDONE")))
|
||||
|| (++offset && fastcmp(params[0], "TUTORIALDONE"))
|
||||
|| (++offset && fastcmp(params[0], "PLAYGROUNDROUTE")))
|
||||
{
|
||||
//PARAMCHECK(1);
|
||||
ty = UC_ADDON + offset;
|
||||
|
|
@ -3633,6 +3634,11 @@ void readmaincfg(MYFILE *f, boolean mainfile)
|
|||
titlemap = Z_StrDup(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TUTORIALPLAYGROUNDMAP"))
|
||||
{
|
||||
Z_Free(tutorialplaygroundmap);
|
||||
tutorialplaygroundmap = Z_StrDup(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TUTORIALCHALLENGEMAP"))
|
||||
{
|
||||
Z_Free(tutorialchallengemap);
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ extern boolean looptitle;
|
|||
extern char * bootmap; //bootmap for loading a map on startup
|
||||
extern char * podiummap; // map to load for podium
|
||||
|
||||
extern char * tutorialplaygroundmap; // map to load for playground
|
||||
extern char * tutorialchallengemap; // map to load for tutorial skip
|
||||
extern UINT8 tutorialchallenge;
|
||||
#define TUTORIALSKIP_NONE 0
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ boolean looptitle = true;
|
|||
char * bootmap = NULL; //bootmap for loading a map on startup
|
||||
char * podiummap = NULL; // map to load for podium
|
||||
|
||||
char * tutorialplaygroundmap = NULL; // map to load for playground
|
||||
char * tutorialchallengemap = NULL; // map to load for tutorial skip
|
||||
UINT8 tutorialchallenge = TUTORIALSKIP_NONE;
|
||||
|
||||
|
|
@ -5076,7 +5077,7 @@ void G_EndGame(void)
|
|||
// Only do evaluation and credits in singleplayer contexts
|
||||
if (!netgame)
|
||||
{
|
||||
if (gametype == GT_TUTORIAL)
|
||||
if (gametype == GT_TUTORIAL && gamedata->gonerlevel < GDGONER_DONE)
|
||||
{
|
||||
// Tutorial was finished
|
||||
gamedata->tutorialdone = true;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ void srb2::save_ng_gamedata()
|
|||
ng.milestones.enteredtutorialchallenge = gamedata->enteredtutorialchallenge;
|
||||
ng.milestones.sealedswapalerted = gamedata->sealedswapalerted;
|
||||
ng.milestones.tutorialdone = gamedata->tutorialdone;
|
||||
ng.milestones.playgroundroute = gamedata->playgroundroute;
|
||||
ng.milestones.gonerlevel = gamedata->gonerlevel;
|
||||
ng.prisons.thisprisoneggpickup = gamedata->thisprisoneggpickup;
|
||||
ng.prisons.prisoneggstothispickup = gamedata->prisoneggstothispickup;
|
||||
|
|
@ -471,6 +472,7 @@ void srb2::load_ng_gamedata()
|
|||
gamedata->enteredtutorialchallenge = js.milestones.enteredtutorialchallenge;
|
||||
gamedata->sealedswapalerted = js.milestones.sealedswapalerted;
|
||||
gamedata->tutorialdone = js.milestones.tutorialdone;
|
||||
gamedata->playgroundroute = js.milestones.playgroundroute;
|
||||
gamedata->gonerlevel = js.milestones.gonerlevel;
|
||||
gamedata->thisprisoneggpickup = js.prisons.thisprisoneggpickup;
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ struct GamedataMilestonesJson final
|
|||
bool enteredtutorialchallenge;
|
||||
bool sealedswapalerted;
|
||||
bool tutorialdone;
|
||||
bool playgroundroute;
|
||||
|
||||
SRB2_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
||||
GamedataMilestonesJson,
|
||||
|
|
@ -109,7 +110,8 @@ struct GamedataMilestonesJson final
|
|||
finishedtutorialchallenge,
|
||||
enteredtutorialchallenge,
|
||||
sealedswapalerted,
|
||||
tutorialdone
|
||||
tutorialdone,
|
||||
playgroundroute
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -229,9 +229,12 @@ void M_GonerBGTick(void);
|
|||
void M_GonerBGImplyPassageOfTime(void);
|
||||
void M_DrawGonerBack(void);
|
||||
void M_GonerProfile(INT32 choice);
|
||||
void M_GonerChoice(INT32 choice);
|
||||
void M_GonerTutorial(INT32 choice);
|
||||
void M_GonerPlayground(INT32 choice);
|
||||
void M_GonerResetLooking(int type);
|
||||
void M_GonerCheckLooking(void);
|
||||
void M_GonerResetText(void);
|
||||
void M_GonerGDQ(boolean opinion);
|
||||
boolean M_GonerMusicPlayable(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"podiummap")) {
|
||||
lua_pushstring(L, podiummap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialplaygroundmap")) {
|
||||
lua_pushstring(L, tutorialplaygroundmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialchallengemap")) {
|
||||
lua_pushstring(L, tutorialchallengemap);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -663,6 +663,7 @@ void M_ClearStats(void)
|
|||
gamedata->finishedtutorialchallenge = false;
|
||||
gamedata->sealedswapalerted = false;
|
||||
gamedata->tutorialdone = false;
|
||||
gamedata->playgroundroute = false;
|
||||
gamedata->musicstate = GDMUSIC_NONE;
|
||||
|
||||
gamedata->importprofilewins = false;
|
||||
|
|
@ -1755,6 +1756,8 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
return (gamedata->finishedtutorialchallenge == true);
|
||||
case UC_TUTORIALDONE:
|
||||
return (gamedata->tutorialdone == true);
|
||||
case UC_PLAYGROUND:
|
||||
return (gamedata->playgroundroute == true);
|
||||
case UC_PASSWORD:
|
||||
return (cn->stringvar == NULL);
|
||||
|
||||
|
|
@ -2641,6 +2644,8 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
return "successfully skip the Tutorial";
|
||||
case UC_TUTORIALDONE:
|
||||
return "complete the Tutorial";
|
||||
case UC_PLAYGROUND:
|
||||
return "pick the Playground";
|
||||
case UC_PASSWORD:
|
||||
return "enter a secret password";
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ typedef enum
|
|||
UC_CRASH, // Hee ho !
|
||||
UC_TUTORIALSKIP, // Complete the Tutorial Challenge
|
||||
UC_TUTORIALDONE, // Complete the Tutorial at all
|
||||
UC_PLAYGROUND, // Go to the playground instead..?
|
||||
|
||||
UC_PASSWORD, // Type in something funny
|
||||
|
||||
|
|
@ -301,7 +302,7 @@ typedef enum {
|
|||
|
||||
#define GDCONVERT_ROUNDSTOKEY 5
|
||||
|
||||
#define GDINIT_CHAOKEYS 10 // Start with 10 Chao Keys !!
|
||||
#define GDINIT_CHAOKEYS 0 // Start with ZERO Chao Keys. You get NONE. fizzy lifting dink
|
||||
#define GDINIT_PRISONSTOPRIZE 15 // 15 Prison Eggs to your [Wild Prize] !!
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -395,6 +396,7 @@ struct gamedata_t
|
|||
boolean finishedtutorialchallenge;
|
||||
boolean sealedswapalerted;
|
||||
boolean tutorialdone;
|
||||
boolean playgroundroute;
|
||||
gdmusic_t musicstate;
|
||||
|
||||
UINT8 gonerlevel;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "../core/string.h"
|
||||
|
||||
static void M_GonerDrawer(void);
|
||||
static void M_GonerChoiceDrawer(void);
|
||||
static void M_GonerConclude(INT32 choice);
|
||||
static boolean M_GonerInputs(INT32 ch);
|
||||
|
||||
|
|
@ -55,9 +56,9 @@ menuitem_t MAIN_Goner[] =
|
|||
"ASSIGN VEHICLE INPUTS.", NULL,
|
||||
{.routine = M_GonerProfile}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "BEGIN TUTORIAL",
|
||||
"PREPARE FOR INTEGRATION.", NULL,
|
||||
{.routine = M_GonerTutorial}, 0, 0},
|
||||
{IT_STRING | IT_CALL, "MAKE CHOICE",
|
||||
"PREPARE FOR INTEGRATION?", NULL,
|
||||
{.routine = M_GonerChoice}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "START GAME",
|
||||
"I WILL SUCCEED.", NULL,
|
||||
|
|
@ -82,9 +83,57 @@ menu_t MAIN_GonerDef = {
|
|||
M_GonerInputs,
|
||||
};
|
||||
|
||||
menuitem_t MAIN_GonerChoice[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, "Tails' way",
|
||||
"As a child scientist, Tails has recorded bits\n"
|
||||
"and pieces of an adventure he and Eggman went\n"
|
||||
"on while trying out their new Ring Racers.\n"
|
||||
"\n"
|
||||
"This is a structured, back-to-basics session\n"
|
||||
"that will likely take ""\x88""10-20 minutes""\x80"" of your time.",
|
||||
NULL, {.routine = M_GonerTutorial}, 0, 0},
|
||||
|
||||
//{IT_STRING, NULL, NULL, NULL, {.routine = M_QuitSRB2}, 0, 0}, // will be replaced
|
||||
|
||||
{IT_STRING | IT_CALL, "Eggman's way",
|
||||
"As a childlike scientist, Eggman has turned the\n"
|
||||
"wrecked Egg Carrier into a giant skatepark,\n"
|
||||
"dotted with fun collectables to test drivers.\n"
|
||||
"\n"
|
||||
"You can ""\x88""exit immediately""\x80"" and get to racing...\n"
|
||||
"or spend ""\x88""as long as you want""\x80"" in the playground!",
|
||||
NULL, {.routine = M_GonerPlayground}, 0, 0},
|
||||
};
|
||||
|
||||
menu_t MAIN_GonerChoiceDef = {
|
||||
sizeof (MAIN_GonerChoice) / sizeof (menuitem_t),
|
||||
&MAIN_GonerDef,
|
||||
0,
|
||||
MAIN_GonerChoice,
|
||||
26, 160,
|
||||
0, 0,
|
||||
MBF_UD_LR_FLIPPED,
|
||||
"_GONER",
|
||||
0, 0,
|
||||
M_GonerChoiceDrawer,
|
||||
M_DrawGonerBack,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GONERCHOICE_TAILS = 0,
|
||||
//GONERCHOICE_NONEBINEY,
|
||||
GONERCHOICE_EGGMAN
|
||||
} gonerchoices_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GONERSPEAKER_EGGMAN = 0,
|
||||
|
|
@ -429,16 +478,6 @@ void Miles_Electric_Lower()
|
|||
int goner_levelworking = GDGONER_INIT;
|
||||
bool goner_gdq = false;
|
||||
|
||||
void M_GonerResetText(void)
|
||||
{
|
||||
goner_typewriter.ClearText();
|
||||
LinesToDigest.clear();
|
||||
LinesOutput.clear();
|
||||
|
||||
goner_scroll = 0;
|
||||
goner_scrollend = -1;
|
||||
}
|
||||
|
||||
static void Initial_Control_Info(void)
|
||||
{
|
||||
if (cv_currprofile.value != -1)
|
||||
|
|
@ -669,11 +708,22 @@ void M_AddGonerLines(void)
|
|||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Now, Metal... it's important you pay attention.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"It's time to ""\x87""begin your Tutorial""\x80""!");
|
||||
"We have a ""\x88""choice""\x80"" ready for you.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Remember, MS-1. Even when you move on from this setup, you "\
|
||||
"can always change your ""\x87""Options""\x80"" at any time from the menu.");
|
||||
"You can play back our testing data as a sort of ""\x82""tutorial""\x80"\
|
||||
" and learn the core parts of driving in a safe environment...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"...or if you're too headstrong and want to figure things out"\
|
||||
" for yourself, we can let you loose in our ""\x85""playground""\x80""!");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"If you do run into trouble, the ""\x82""tutorial""\x80"" can"\
|
||||
" always be found in the ""\x87""Extras""\x80"" menu later on.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Either way, MS-1. Even when you move on from this setup,"\
|
||||
" you can always change your ""\x87""Options""\x80"" at any time.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
|
||||
break;
|
||||
|
|
@ -704,8 +754,6 @@ void M_AddGonerLines(void)
|
|||
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,
|
||||
"If you need to learn more, you can always come back to the Tutorial later in the ""\x87""Extras""\x80"" menu.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Now, I'm willing to let bygones be bygones.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
|
|
@ -1218,6 +1266,123 @@ static void M_GonerDrawer(void)
|
|||
M_DrawHorizontalMenu();
|
||||
}
|
||||
|
||||
static void M_GonerChoiceDrawer(void)
|
||||
{
|
||||
srb2::Draw drawer = srb2::Draw();
|
||||
|
||||
const INT32 lex = (24 + BASEVIDWIDTH/2)/2;
|
||||
|
||||
if (itemOn == GONERCHOICE_TAILS)
|
||||
{
|
||||
drawer
|
||||
.size((BASEVIDWIDTH/2) + 25, BASEVIDHEIGHT)
|
||||
.fill(60);
|
||||
|
||||
drawer
|
||||
.xy((BASEVIDWIDTH/2) + 40 + 1, 28+3)
|
||||
.colormap(SKINCOLOR_ORANGE)
|
||||
.flags(V_FLIP)
|
||||
.patch("MENUPLTR");
|
||||
|
||||
drawer
|
||||
.xy(lex, 28)
|
||||
.font(srb2::Draw::Font::kGamemode)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.text(currentMenu->menuitems[itemOn].text);
|
||||
|
||||
drawer
|
||||
.xy(8, 72)
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.align(srb2::Draw::Align::kLeft)
|
||||
.text(currentMenu->menuitems[itemOn].tooltip);
|
||||
|
||||
drawer
|
||||
.xy(lex, 154)
|
||||
.font(srb2::Draw::Font::kFreeplay)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.text("(unlocks 20 )");
|
||||
|
||||
drawer
|
||||
.xy(lex, 154+14)
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.flags(V_TRANSLUCENT)
|
||||
.text("+ more surprises to find");
|
||||
|
||||
drawer
|
||||
.xy(lex + 26, 154-4)
|
||||
.patch("UN_CHA00");
|
||||
}
|
||||
else if (itemOn == GONERCHOICE_EGGMAN)
|
||||
{
|
||||
drawer
|
||||
.x((BASEVIDWIDTH/2) - 24)
|
||||
.size((BASEVIDWIDTH/2) + 24, BASEVIDHEIGHT)
|
||||
.fill(44);
|
||||
|
||||
drawer
|
||||
.xy((BASEVIDWIDTH/2) - 40, 28+3)
|
||||
.colormap(SKINCOLOR_RED)
|
||||
.patch("MENUPLTR");
|
||||
|
||||
drawer
|
||||
.xy(BASEVIDWIDTH - lex, 28)
|
||||
.font(srb2::Draw::Font::kGamemode)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.text(currentMenu->menuitems[itemOn].text);
|
||||
|
||||
drawer
|
||||
.xy(BASEVIDWIDTH - 8, 72)
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.align(srb2::Draw::Align::kRight)
|
||||
.text(currentMenu->menuitems[itemOn].tooltip);
|
||||
|
||||
drawer
|
||||
.xy(BASEVIDWIDTH - lex, 154)
|
||||
.font(srb2::Draw::Font::kFreeplay)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.text("(unlocks Addons/Online)");
|
||||
}
|
||||
|
||||
// Un-highlighteds done this weird way because of GONERCHOICE_NONEBINEY
|
||||
|
||||
if (itemOn != GONERCHOICE_TAILS)
|
||||
{
|
||||
drawer
|
||||
.size(20, BASEVIDHEIGHT)
|
||||
.fill(60);
|
||||
|
||||
drawer
|
||||
.xy(25, 39)
|
||||
.font(srb2::Draw::Font::kFreeplay)
|
||||
.align(srb2::Draw::Align::kLeft)
|
||||
.text(currentMenu->menuitems[GONERCHOICE_TAILS].text);
|
||||
|
||||
drawer
|
||||
.xy(20 - 3 - (skullAnimCounter/5), 39+6)
|
||||
.patch("CUPARROW");
|
||||
}
|
||||
|
||||
if (itemOn != GONERCHOICE_EGGMAN)
|
||||
{
|
||||
drawer
|
||||
.x(BASEVIDWIDTH - 20)
|
||||
.size(20, BASEVIDHEIGHT)
|
||||
.fill(44);
|
||||
|
||||
drawer
|
||||
.xy(BASEVIDWIDTH - 25, 39)
|
||||
.font(srb2::Draw::Font::kFreeplay)
|
||||
.align(srb2::Draw::Align::kRight)
|
||||
.text(currentMenu->menuitems[GONERCHOICE_EGGMAN].text);
|
||||
|
||||
drawer
|
||||
.xy((BASEVIDWIDTH - 20 + 3) + (skullAnimCounter/5), 39+6)
|
||||
.flags(V_FLIP)
|
||||
.patch("CUPARROW");
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
void M_GonerProfile(INT32 choice)
|
||||
|
|
@ -1245,19 +1410,16 @@ void M_GonerProfile(INT32 choice)
|
|||
M_GonerResetLooking(GDGONER_PROFILE);
|
||||
}
|
||||
|
||||
static void M_GonerSurveyResponse(INT32 ch)
|
||||
static void M_GonerTutorialResponse(INT32 ch)
|
||||
{
|
||||
if (ch != MA_YES)
|
||||
return;
|
||||
|
||||
if (gamedata->gonerlevel < GDGONER_OUTRO)
|
||||
gamedata->gonerlevel = GDGONER_OUTRO;
|
||||
M_GonerTutorial(0);
|
||||
}
|
||||
|
||||
void M_GonerTutorial(INT32 choice)
|
||||
void M_GonerChoice(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (cv_currprofile.value == -1)
|
||||
{
|
||||
const INT32 maxp = PR_GetNumProfiles();
|
||||
|
|
@ -1270,6 +1432,43 @@ void M_GonerTutorial(INT32 choice)
|
|||
PR_ApplyProfile(profilen, 0);
|
||||
}
|
||||
|
||||
if (gamedata->gonerlevel >= GDGONER_OUTRO)
|
||||
{
|
||||
M_StartMessage("First Boot Tutorial",
|
||||
"You've already played the Tutorial! Do you want to see it again?",
|
||||
&M_GonerTutorialResponse, MM_YESNO, "I'd love to", "Not right now");
|
||||
return;
|
||||
}
|
||||
|
||||
M_SetupNextMenu(&MAIN_GonerChoiceDef, false);
|
||||
}
|
||||
|
||||
static void M_GonerSurveyResponse(INT32 ch)
|
||||
{
|
||||
if (ch != MA_YES)
|
||||
return;
|
||||
|
||||
if (gamedata->gonerlevel < GDGONER_OUTRO)
|
||||
gamedata->gonerlevel = GDGONER_OUTRO;
|
||||
|
||||
if (currentMenu == &MAIN_GonerChoiceDef)
|
||||
M_GoBack(0);
|
||||
}
|
||||
|
||||
static void M_GonerSurvey(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
// The game is incapable of progression, but I can't bring myself to put an I_Error here.
|
||||
M_StartMessage("First Boot Error",
|
||||
"YOU ACCEPT EVERYTHING THAT\nWILL HAPPEN FROM NOW ON.",
|
||||
&M_GonerSurveyResponse, MM_YESNO, "I agree", "Cancel");
|
||||
}
|
||||
|
||||
void M_GonerTutorial(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
// Please also see M_LevelSelectInit as called in extras-1.c
|
||||
levellist.netgame = false;
|
||||
levellist.canqueue = false;
|
||||
|
|
@ -1279,19 +1478,58 @@ void M_GonerTutorial(INT32 choice)
|
|||
|
||||
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("Agreement",
|
||||
"YOU ACCEPT EVERYTHING THAT WILL HAPPEN FROM NOW ON.",
|
||||
&M_GonerSurveyResponse, MM_YESNO, "I agree", "Cancel");
|
||||
M_GonerSurvey(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void M_GonerPlayground(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
UINT16 playgroundmap = NEXTMAP_INVALID;
|
||||
if (tutorialplaygroundmap)
|
||||
playgroundmap = G_MapNumber(tutorialplaygroundmap);
|
||||
|
||||
if (playgroundmap >= nummapheaders)
|
||||
{
|
||||
M_GonerSurvey(0);
|
||||
return;
|
||||
}
|
||||
|
||||
multiplayer = true;
|
||||
|
||||
M_MenuToLevelPreamble(0, false);
|
||||
|
||||
D_MapChange(
|
||||
playgroundmap+1,
|
||||
GT_TUTORIAL,
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
M_ClearMenus(true);
|
||||
restoreMenu = NULL; // Playground Hack
|
||||
|
||||
// need to do all this here because it will skip returning to goner and there are circumstances (game close) where DoCompleted won't be called
|
||||
M_GonerResetText();
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
gamedata->playgroundroute = true;
|
||||
gamedata->deferredsave = true;
|
||||
}
|
||||
|
||||
static void M_GonerConclude(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
|
||||
if (gamedata->chaokeys < 20)
|
||||
gamedata->chaokeys = 20;
|
||||
|
||||
F_StartIntro();
|
||||
M_ClearMenus(true);
|
||||
M_GonerResetText();
|
||||
|
|
@ -1380,3 +1618,13 @@ static boolean M_GonerInputs(INT32 ch)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void M_GonerResetText(void)
|
||||
{
|
||||
goner_typewriter.ClearText();
|
||||
LinesToDigest.clear();
|
||||
LinesOutput.clear();
|
||||
|
||||
goner_scroll = 0;
|
||||
goner_scrollend = -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue