mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-08 04:06:25 +00:00
Goner Setup: Cook 2
- More dialogue
- Restrict access to your choices based on your progress through the Goner Setup.
- Save progress through the setup to gamedata
- Resets to beginning when Challenges is cleared
- Passwords
- Only permit the password entry in like the first two seconds
- Preemptively disarms potentially annoying people in stream chats
- Make wrongwarp also quit the game on exit instead of returning to the title screen
- Add GDQ cheats
- `savetheanimals`
- `savetheframes`
- Both do practically the same thing, with slightly modified dialogue.
- Skips all of the normal dialogue.
- Performing a social experiment on anyone who might stream this game at a charity event. :)
This commit is contained in:
parent
f5566ff8c4
commit
e91115a8fa
9 changed files with 423 additions and 76 deletions
|
|
@ -4553,6 +4553,8 @@ typedef enum
|
|||
GDEVER_KEYMAJORSKIP = 1<<5,
|
||||
GDEVER_TUTORIALSKIP = 1<<6,
|
||||
GDEVER_ENTERTUTSKIP = 1<<7,
|
||||
// --- Free up to 1<<23 --- //
|
||||
GDEVER_GONERSHIFT = 24, // nothing above this
|
||||
} gdeverdone_t;
|
||||
|
||||
static const char *G_GameDataFolder(void)
|
||||
|
|
@ -4694,6 +4696,8 @@ void G_LoadGameData(void)
|
|||
gamedata->majorkeyskipattempted = !!(everflags & GDEVER_KEYMAJORSKIP);
|
||||
gamedata->finishedtutorialchallenge = !!(everflags & GDEVER_TUTORIALSKIP);
|
||||
gamedata->enteredtutorialchallenge = !!(everflags & GDEVER_ENTERTUTSKIP);
|
||||
|
||||
gamedata->gonerlevel = everflags>>GDEVER_GONERSHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5371,7 +5375,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT16(save.p, gamedata->chaokeys); // 2
|
||||
|
||||
{
|
||||
UINT32 everflags = 0;
|
||||
UINT32 everflags = (gamedata->gonerlevel<<GDEVER_GONERSHIFT);
|
||||
|
||||
if (gamedata->everloadedaddon)
|
||||
everflags |= GDEVER_ADDON;
|
||||
|
|
|
|||
|
|
@ -206,6 +206,9 @@ extern menu_t MAIN_GonerDef;
|
|||
void M_GonerTick(void);
|
||||
void M_GonerProfile(INT32 choice);
|
||||
void M_GonerTutorial(INT32 choice);
|
||||
void M_GonerResetLooking(int type);
|
||||
void M_GonerCheckLooking(void);
|
||||
void M_GonerGDQ(boolean opinion);
|
||||
|
||||
extern menuitem_t PLAY_CharSelect[];
|
||||
extern menu_t PLAY_CharSelectDef;
|
||||
|
|
|
|||
|
|
@ -1156,8 +1156,8 @@ void M_DrawHorizontalMenu(void)
|
|||
V_DrawCharacter((BASEVIDWIDTH + width)/2 - 10 + (skullAnimCounter/5), y,
|
||||
'\x1D' | highlightflags, false); // right arrow
|
||||
|
||||
x = (BASEVIDWIDTH - 8*(currentMenu->numitems-1))/2;
|
||||
for (i = 0; i < currentMenu->numitems; i++, x += 8)
|
||||
x = (BASEVIDWIDTH - 8*(currentMenu->extra2-1))/2;
|
||||
for (i = 0; i < currentMenu->extra2; i++, x += 8)
|
||||
{
|
||||
if (i == itemOn)
|
||||
{
|
||||
|
|
@ -1165,7 +1165,9 @@ void M_DrawHorizontalMenu(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
V_DrawFill(x-1, y + 16, 2, 2, 16);
|
||||
V_DrawFill(x-1, y + 16, 2, 2,
|
||||
(i >= currentMenu->numitems) ? 20 : 10
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -741,8 +741,10 @@ void M_GoBack(INT32 choice)
|
|||
|
||||
M_SetupNextMenu(currentMenu->prevMenu, false);
|
||||
}
|
||||
else
|
||||
else if (M_GameTrulyStarted())
|
||||
M_ClearMenus(true);
|
||||
else // No returning to the title screen.
|
||||
M_QuitSRB2(-1);
|
||||
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,20 @@ static UINT8 cheatf_wrongwarp(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static UINT8 cheatf_savetheanimals(void)
|
||||
{
|
||||
M_GonerGDQ(true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static UINT8 cheatf_savetheframes(void)
|
||||
{
|
||||
M_GonerGDQ(false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEVELOP
|
||||
static UINT8 cheatf_devmode(void)
|
||||
{
|
||||
|
|
@ -179,6 +193,16 @@ static cheatseq_t cheat_wrongwarp = {
|
|||
(UINT8[]){ SCRAMBLE('b'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), 0xff }
|
||||
};
|
||||
|
||||
static cheatseq_t cheat_savetheanimals = {
|
||||
NULL, cheatf_savetheanimals,
|
||||
(UINT8[]){ SCRAMBLE('s'), SCRAMBLE('a'), SCRAMBLE('v'), SCRAMBLE('e'), SCRAMBLE('t'), SCRAMBLE('h'), SCRAMBLE('e'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('i'), SCRAMBLE('m'), SCRAMBLE('a'), SCRAMBLE('l'), SCRAMBLE('s'), 0xff }
|
||||
};
|
||||
|
||||
static cheatseq_t cheat_savetheframes = {
|
||||
NULL, cheatf_savetheframes,
|
||||
(UINT8[]){ SCRAMBLE('s'), SCRAMBLE('a'), SCRAMBLE('v'), SCRAMBLE('e'), SCRAMBLE('t'), SCRAMBLE('h'), SCRAMBLE('e'), SCRAMBLE('f'), SCRAMBLE('r'), SCRAMBLE('a'), SCRAMBLE('m'), SCRAMBLE('e'), SCRAMBLE('s'), 0xff }
|
||||
};
|
||||
|
||||
#ifdef DEVELOP
|
||||
static cheatseq_t cheat_devmode = {
|
||||
NULL, cheatf_devmode,
|
||||
|
|
@ -190,6 +214,8 @@ cheatseq_t *cheatseqlist[] =
|
|||
{
|
||||
&cheat_warp,
|
||||
&cheat_wrongwarp,
|
||||
&cheat_savetheanimals,
|
||||
&cheat_savetheframes,
|
||||
#ifdef DEVELOP
|
||||
&cheat_devmode,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -730,6 +730,8 @@ void M_ClearSecrets(void)
|
|||
|
||||
gamedata->chaokeys = GDINIT_CHAOKEYS;
|
||||
gamedata->prisoneggstothispickup = GDINIT_PRISONSTOPRIZE;
|
||||
|
||||
gamedata->gonerlevel = GDGONER_INIT;
|
||||
}
|
||||
|
||||
// For lack of a better idea on where to put this
|
||||
|
|
|
|||
12
src/m_cond.h
12
src/m_cond.h
|
|
@ -289,6 +289,16 @@ typedef enum {
|
|||
#define GDINIT_CHAOKEYS 3 // Start with 3 Chao Keys !!
|
||||
#define GDINIT_PRISONSTOPRIZE 30 // 30 Prison Eggs to your [Wild Prize] !!
|
||||
|
||||
typedef enum {
|
||||
GDGONER_INIT = 0,
|
||||
GDGONER_INTRO,
|
||||
GDGONER_VIDEO,
|
||||
GDGONER_SOUND,
|
||||
GDGONER_PROFILE,
|
||||
GDGONER_TUTORIAL,
|
||||
GDGONER_DONE,
|
||||
} gdgoner_t;
|
||||
|
||||
typedef enum {
|
||||
GDGT_RACE,
|
||||
GDGT_BATTLE,
|
||||
|
|
@ -370,6 +380,8 @@ struct gamedata_t
|
|||
boolean finishedtutorialchallenge;
|
||||
gdmusic_t musicstate;
|
||||
|
||||
UINT8 gonerlevel;
|
||||
|
||||
// BACKWARDS COMPAT ASSIST
|
||||
boolean importprofilewins;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
/// \brief The Goner Setup.
|
||||
|
||||
#include "../k_menu.h"
|
||||
#include "../m_cond.h"
|
||||
#include "../r_skins.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../p_local.h" // P_AutoPause
|
||||
#include "../st_stuff.h" // faceprefix
|
||||
#include "../v_draw.hpp"
|
||||
#include "../k_dialogue.hpp"
|
||||
|
|
@ -11,41 +14,36 @@
|
|||
|
||||
menuitem_t MAIN_Goner[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, "Password",
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, ". . .",
|
||||
"ATTEMPT ADMINISTRATOR ACCESS.", NULL,
|
||||
{.cvar = &cv_dummyextraspassword}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Quit",
|
||||
"CONCLUDE OBSERVATIONS NOW.", NULL,
|
||||
{.routine = M_QuitSRB2}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Video Options",
|
||||
{IT_STRING | IT_CALL, "VIDEO OPTIONS",
|
||||
"CONFIGURE OCULAR PATHWAYS.", NULL,
|
||||
{.routine = M_VideoOptions}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Sound Options",
|
||||
{IT_STRING | IT_CALL, "SOUND OPTIONS",
|
||||
"CALIBRATE AURAL DATASTREAM.", NULL,
|
||||
{.routine = M_SoundOptions}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Profile Setup",
|
||||
{IT_STRING | IT_CALL, "PROFILE SETUP",
|
||||
"ASSIGN VEHICLE INPUTS.", NULL,
|
||||
{.routine = M_GonerProfile}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Begin Tutorial",
|
||||
{IT_STRING | IT_CALL, "BEGIN TUTORIAL",
|
||||
"PREPARE FOR INTEGRATION.", NULL,
|
||||
{.routine = M_GonerTutorial}, 0, 0},
|
||||
};
|
||||
|
||||
static boolean M_GonerInputs(INT32 ch);
|
||||
static void M_GonerDrawer(void);
|
||||
|
||||
menu_t MAIN_GonerDef = {
|
||||
sizeof (MAIN_Goner) / sizeof (menuitem_t),
|
||||
1, // Intentionally not the sizeof calc
|
||||
NULL,
|
||||
0,
|
||||
MAIN_Goner,
|
||||
32, 160,
|
||||
0, 0,
|
||||
26, 160,
|
||||
0, sizeof (MAIN_Goner) / sizeof (menuitem_t), // extra2 is final width
|
||||
MBF_UD_LR_FLIPPED,
|
||||
"_GONER",
|
||||
0, 0,
|
||||
|
|
@ -53,7 +51,7 @@ menu_t MAIN_GonerDef = {
|
|||
M_GonerTick,
|
||||
NULL,
|
||||
NULL,
|
||||
M_GonerInputs,
|
||||
NULL,
|
||||
};
|
||||
|
||||
namespace
|
||||
|
|
@ -154,63 +152,310 @@ public:
|
|||
std::forward_list<GonerChatLine> LinesToDigest;
|
||||
std::forward_list<GonerChatLine> LinesOutput;
|
||||
|
||||
int goner_levelworking = GDGONER_INIT;
|
||||
bool goner_nicetry = false;
|
||||
bool goner_gdq = false;
|
||||
|
||||
void M_AddGonerLines(void)
|
||||
{
|
||||
SRB2_ASSERT(LinesToDigest.empty());
|
||||
|
||||
auto _ = srb2::finally([]() { LinesToDigest.reverse(); });
|
||||
|
||||
static bool leftoff = false;
|
||||
|
||||
goner_delay = TICRATE;
|
||||
|
||||
// This one always plays, so it checks the levelworking instead of gamedata.
|
||||
if (goner_levelworking == GDGONER_INTRO)
|
||||
{
|
||||
if (!goner_nicetry)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Metal Sonic. Are you online?");
|
||||
}
|
||||
|
||||
leftoff = (goner_levelworking < gamedata->gonerlevel-1);
|
||||
|
||||
if (leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"It must have run into some sort of error...");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Don't worry, your settings so far are saved. "\
|
||||
"Let's pick up where we left off.");
|
||||
|
||||
// the -1 guarantees that one will be (re)played
|
||||
goner_levelworking = gamedata->gonerlevel-1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (gamedata->gonerlevel)
|
||||
{
|
||||
case GDGONER_VIDEO:
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Take a close look, Miles. Moments ago he was at my throat! "\
|
||||
"Now he's docile as can be on that operating table.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"I don't feel very safe!");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/4,
|
||||
"But its programming is definitely locked down...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"You've given me quite the headache, Metal. "\
|
||||
"Thankfully, Tails caught you in the act.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/5,
|
||||
"Wait, I'm getting weird readings over the network.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Metal Sonic is the unit labeled \"MS-1\", right?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
"The ""\x87""viewport""\x80"" and ""\x87""audio""\x80"" "\
|
||||
"config looks like it got messed up.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"So you're right. I wonder if it has anything to do with that outburst.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Alright, Metal! I don't remember your specifications offhand. "\
|
||||
"First things first, go ahead and set up your "\
|
||||
"\x87""Video Options""\x80"" yourself.");
|
||||
break;
|
||||
}
|
||||
case GDGONER_SOUND:
|
||||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Ah, you can see us now. Good.");
|
||||
}
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Now, calibrate your ""\x87""Sound Options""\x80"".");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"You always make your stuff so loud by default, Eggman. It might need a moment.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Not Metal! He always needed to be stealthy. But go on, set your sliders.");
|
||||
break;
|
||||
}
|
||||
case GDGONER_PROFILE:
|
||||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"Oh! Let's tell Metal about our project!");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Of course. I and my lab assista-");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Lab PARTNER.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Irrelevant!");
|
||||
}
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
"We made a machine together, Tails and I. "\
|
||||
"It's called a \"""\x82""Ring Racer""\x80""\".");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"At its core, it is designed to utilise the boundless potential "\
|
||||
"of the ""\x83""High Voltage Ring""\x80"".");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
"We made this special Ring by combining the power of tens of "\
|
||||
"thousands of ordinary ""\x82""Rings""\x80"".");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"We recorded some of our testing for you, MS-1. Maybe your neural "\
|
||||
"network could train on some less violent data for once.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
"While that's uploading, why don't you set up your ""\x87""Profile Card""\x80""?");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Yes! That's one of my contributions.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"(I'm too used to my systems being designed for me alone...)");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Every racer carries one, to contain their personal settings.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"It helps get your ""\x87""controls""\x80"" set up nice and quickly, "\
|
||||
"when starting your vehicle.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"And it helps track your wins, too.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Bragging rights. My idea!");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"You can make the name on there anything you want.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"Mine says \"Nine Tails\". That's the name of my original character! "\
|
||||
"He's like me if I never met my ""\x84""brother""\x80"". He'd have to become stronger "\
|
||||
"with robotics, and kind of mean and cool to protect himself...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Mine says \"Robotnik\". You can't beat a classic.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Go on, do your ""\x87""Profile Setup""\x80""!");
|
||||
break;
|
||||
}
|
||||
case GDGONER_TUTORIAL:
|
||||
case GDGONER_DONE: // maybe we could do something different for this eventually
|
||||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"...right, now that that's sorted. How's the upload going?");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Just finished.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Perfect.");
|
||||
}
|
||||
|
||||
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""!");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"That's a lot to get through. Good luck, MS-1!");
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"I am error");
|
||||
}
|
||||
|
||||
leftoff = false;
|
||||
}
|
||||
|
||||
gdgoner_t goner_lasttypelooking = GDGONER_INIT;
|
||||
tic_t goner_youactuallylooked = 0;
|
||||
|
||||
void M_GonerRailroad(bool set)
|
||||
{
|
||||
INT16 destsize = std::min(
|
||||
static_cast<INT16>(
|
||||
(set ? 2 : 1) // Quit + options + maybe 1 for extra access
|
||||
+ std::max(0, gamedata->gonerlevel - GDGONER_VIDEO)
|
||||
),
|
||||
currentMenu->extra2);
|
||||
currentMenu->numitems = destsize;
|
||||
|
||||
if (!set)
|
||||
return;
|
||||
|
||||
itemOn = destsize-1;
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
}
|
||||
|
||||
void M_GonerHidePassword(void)
|
||||
{
|
||||
if (currentMenu->menuitems[0].mvar2)
|
||||
return;
|
||||
|
||||
currentMenu->menuitems[0] =
|
||||
{IT_STRING | IT_CALL, "EXIT PROGRAM",
|
||||
"CONCLUDE OBSERVATIONS NOW.", NULL,
|
||||
{.routine = M_QuitSRB2}, 0, 1};
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
void M_GonerResetLooking(int type)
|
||||
{
|
||||
if (goner_youactuallylooked > 2*TICRATE
|
||||
&& goner_lasttypelooking == gamedata->gonerlevel)
|
||||
{
|
||||
if (goner_levelworking > gamedata->gonerlevel)
|
||||
goner_levelworking--;
|
||||
gamedata->gonerlevel++;
|
||||
LinesToDigest.clear();
|
||||
}
|
||||
|
||||
goner_lasttypelooking = static_cast<gdgoner_t>(type);
|
||||
goner_youactuallylooked = 0;
|
||||
}
|
||||
|
||||
void M_GonerCheckLooking(void)
|
||||
{
|
||||
if (goner_lasttypelooking != gamedata->gonerlevel)
|
||||
return;
|
||||
goner_youactuallylooked++;
|
||||
}
|
||||
|
||||
void M_GonerTick(void)
|
||||
{
|
||||
static bool speakersinit = false;
|
||||
if (!speakersinit)
|
||||
{
|
||||
goner_delay = TICRATE;
|
||||
static bool first = true;
|
||||
|
||||
if (goner_levelworking == GDGONER_INIT)
|
||||
{
|
||||
first = true;
|
||||
|
||||
// Init.
|
||||
goner_speakers[GONERSPEAKER_EGGMAN] = GonerSpeaker("eggman", 0);
|
||||
goner_speakers[GONERSPEAKER_TAILS] = GonerSpeaker("tails", 12);
|
||||
}
|
||||
else if (gamedata->gonerlevel == GDGONER_INIT)
|
||||
{
|
||||
first = true; // a lie, but only slightly...
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE,
|
||||
"Metal Sonic. Are you online?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Take a close look, Miles. Moments ago he was at my throat!\
|
||||
Now he's docile as can be on that operating table.");
|
||||
// Handle rewinding if you clear your gamedata.
|
||||
goner_typewriter.ClearText();
|
||||
LinesToDigest.clear();
|
||||
LinesOutput.clear();
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"I don't feel very safe!");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/4,
|
||||
"But its programming is definitely locked down...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"You've given me quite the headache, Metal.\
|
||||
Thankfully, Tails caught you in the act.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/5,
|
||||
"Wait, I'm getting weird readings over the network.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Metal Sonic is the unit labeled \"MS1\", right?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
"The ""\x87""viewport""\x80"" and ""\x87""audio""\x80"" config looks like it got messed up.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"So you're right. I wonder if it has anything to do with that outburst.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Alright, Metal! I don't remember your specifications offhand. First things first, go ahead and set up your ""\x87""Video Options""\x80"" yourself.");
|
||||
|
||||
LinesToDigest.reverse();
|
||||
|
||||
speakersinit = true;
|
||||
goner_levelworking = GDGONER_INIT;
|
||||
}
|
||||
|
||||
if (menutyping.active == false && cv_dummyextraspassword.string[0] != '\0')
|
||||
{
|
||||
// Challenges are not interpreted at this stage.
|
||||
// See M_ExtraTick for the full behaviour.
|
||||
M_GonerResetLooking(GDGONER_INIT);
|
||||
|
||||
cht_Interpret(cv_dummyextraspassword.string);
|
||||
CV_StealthSet(&cv_dummyextraspassword, "");
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
|
||||
if (gamedata->gonerlevel < GDGONER_INTRO)
|
||||
gamedata->gonerlevel = GDGONER_INTRO;
|
||||
|
||||
M_GonerRailroad(false);
|
||||
}
|
||||
|
||||
goner_typewriter.WriteText();
|
||||
|
||||
if (menutyping.active || menumessage.active || P_AutoPause())
|
||||
return;
|
||||
|
||||
if (cv_dummyextraspassword.string[0] != '\0')
|
||||
{
|
||||
// Challenges are not interpreted at this stage.
|
||||
// See M_ExtraTick for the full behaviour.
|
||||
|
||||
if (!cht_Interpret(cv_dummyextraspassword.string))
|
||||
{
|
||||
goner_delay = 0;
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE,
|
||||
"Aha! Nice try. You're tricky enough WITHOUT admin access, thank you.");
|
||||
M_GonerHidePassword();
|
||||
goner_nicetry = true;
|
||||
}
|
||||
|
||||
CV_StealthSet(&cv_dummyextraspassword, "");
|
||||
}
|
||||
|
||||
if (goner_typewriter.textDone)
|
||||
{
|
||||
if (!LinesOutput.empty())
|
||||
M_GonerHidePassword();
|
||||
if (goner_delay > 0)
|
||||
goner_delay--;
|
||||
else if (!LinesToDigest.empty())
|
||||
|
|
@ -223,6 +468,21 @@ void M_GonerTick(void)
|
|||
LinesOutput.push_front(line);
|
||||
LinesToDigest.pop_front();
|
||||
}
|
||||
else if (goner_levelworking <= gamedata->gonerlevel)
|
||||
{
|
||||
if (goner_levelworking == GDGONER_INTRO && gamedata->gonerlevel < GDGONER_VIDEO)
|
||||
gamedata->gonerlevel = GDGONER_VIDEO;
|
||||
|
||||
if (++goner_levelworking > gamedata->gonerlevel)
|
||||
{
|
||||
// We've reached the end of the goner text for now.
|
||||
M_GonerRailroad(true);
|
||||
}
|
||||
else if (!goner_gdq)
|
||||
{
|
||||
M_AddGonerLines();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,10 +500,15 @@ static void M_GonerDrawer(void)
|
|||
float newy = BASEVIDHEIGHT/2 + (3*12);
|
||||
boolean first = true;
|
||||
|
||||
int lastspeaker = MAXGONERSPEAKERS;
|
||||
|
||||
for (auto & element : LinesOutput)
|
||||
{
|
||||
INT32 flags = V_TRANSLUCENT;
|
||||
std::string text;
|
||||
|
||||
if (newy < 0) break;
|
||||
|
||||
if (first)
|
||||
{
|
||||
text = goner_typewriter.text;
|
||||
|
|
@ -255,9 +520,12 @@ static void M_GonerDrawer(void)
|
|||
{
|
||||
text = element.dialogue;
|
||||
newy -= element.value*12;
|
||||
|
||||
if (lastspeaker != element.speaker)
|
||||
newy -= 2;
|
||||
}
|
||||
|
||||
if (newy < 0) break;
|
||||
lastspeaker = element.speaker;
|
||||
|
||||
//if (newy > BASEVIDHEIGHT) continue; -- not needed yet
|
||||
|
||||
|
|
@ -267,18 +535,21 @@ static void M_GonerDrawer(void)
|
|||
.xy(speaker.offset, newy)
|
||||
.flags(flags);
|
||||
|
||||
int skinID = speaker.GetSkinID();
|
||||
if (skinID != -1)
|
||||
{
|
||||
line
|
||||
.xy(-16, -2)
|
||||
.colormap(skinID, static_cast<skincolornum_t>(skins[skinID].prefcolor))
|
||||
.patch(faceprefix[skinID][FACE_MINIMAP]);
|
||||
}
|
||||
|
||||
line
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.text( text.c_str() );
|
||||
|
||||
int skinID = speaker.GetSkinID();
|
||||
if (skinID != -1)
|
||||
{
|
||||
line = line
|
||||
.xy(-16, -2)
|
||||
.colormap(skinID, static_cast<skincolornum_t>(skins[skinID].prefcolor));
|
||||
if (gamedata->gonerlevel > GDGONER_VIDEO)
|
||||
line.patch(faceprefix[skinID][FACE_MINIMAP]);
|
||||
else
|
||||
line.patch("HUHMAP");
|
||||
}
|
||||
}
|
||||
|
||||
M_DrawHorizontalMenu();
|
||||
|
|
@ -307,6 +578,8 @@ void M_GonerProfile(INT32 choice)
|
|||
// This will create a new profile if necessary.
|
||||
M_StartEditProfile(MA_YES);
|
||||
PR_ApplyProfilePretend(optionsmenu.profilen, 0);
|
||||
|
||||
M_GonerResetLooking(GDGONER_PROFILE);
|
||||
}
|
||||
|
||||
void M_GonerTutorial(INT32 choice)
|
||||
|
|
@ -338,19 +611,38 @@ void M_GonerTutorial(INT32 choice)
|
|||
"YOU ACCEPT EVERYTHING THAT WILL HAPPEN FROM NOW ON.",
|
||||
&M_QuitResponse, MM_YESNO, "I agree", "Cancel");
|
||||
}
|
||||
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
}
|
||||
|
||||
static boolean M_GonerInputs(INT32 ch)
|
||||
void M_GonerGDQ(boolean opinion)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
(void)ch;
|
||||
if (currentMenu != &MAIN_GonerDef)
|
||||
return;
|
||||
|
||||
if (M_MenuBackPressed(pid))
|
||||
LinesToDigest.clear();
|
||||
goner_delay = TICRATE/2;
|
||||
goner_gdq = true;
|
||||
|
||||
// The mapping of true/false to each opinion is completely
|
||||
// arbitrary, and is not a comment on the nature of the Metroid run.
|
||||
|
||||
if (opinion) // Save The Animals
|
||||
{
|
||||
// No returning to the title screen.
|
||||
M_QuitSRB2(-1);
|
||||
return true;
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Why wouldn't you save the frames..?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Don't mind him. Good luck on the run!");
|
||||
}
|
||||
else // Save The Frames
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"But what about all the little animals...");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"It's just logical. I know you'll conquer this run.");
|
||||
}
|
||||
LinesToDigest.reverse();
|
||||
|
||||
return false;
|
||||
goner_levelworking = GDGONER_TUTORIAL;
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,6 +197,8 @@ void M_OptionsTick(void)
|
|||
optionsmenu.fade--;
|
||||
if (optionsmenu.currcolour != currentMenu->extra1)
|
||||
M_OptionsChangeBGColour(currentMenu->extra1);
|
||||
|
||||
M_GonerCheckLooking();
|
||||
}
|
||||
|
||||
// And one last giggle...
|
||||
|
|
@ -213,12 +215,14 @@ void M_VideoOptions(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
M_OptionsMenuGoto(&OPTIONS_VideoDef);
|
||||
M_GonerResetLooking(GDGONER_VIDEO);
|
||||
}
|
||||
|
||||
void M_SoundOptions(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
M_OptionsMenuGoto(&OPTIONS_SoundDef);
|
||||
M_GonerResetLooking(GDGONER_SOUND);
|
||||
}
|
||||
|
||||
boolean M_OptionsInputs(INT32 ch)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue