mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into recorrect-ringbox-buff-mistake
This commit is contained in:
commit
9726c999ce
18 changed files with 614 additions and 171 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
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ static void F_IntroDrawScene(void)
|
|||
}
|
||||
|
||||
// Joyeaux Anniversaire
|
||||
V_DrawCenteredMenuString(BASEVIDWIDTH/2, 174 - (textoffs/FRACUNIT), (trans<<V_ALPHASHIFT)|V_SUBTRACT, "2013 - 11 years - 2024");
|
||||
V_DrawCenteredMenuString(BASEVIDWIDTH/2, 174 - (textoffs/FRACUNIT), (trans<<V_ALPHASHIFT)|V_SUBTRACT, "2013 - 12 years - 2025");
|
||||
|
||||
// Joyeaux Adressaire
|
||||
V_DrawCenteredMenuString(BASEVIDWIDTH/2, 184 - (textoffs/FRACUNIT), (trans<<V_ALPHASHIFT)|V_SUBTRACT, "kartkrew.org");
|
||||
|
|
|
|||
10
src/g_game.c
10
src/g_game.c
|
|
@ -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;
|
||||
|
|
@ -5129,6 +5130,13 @@ void G_EndGame(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (gametype == GT_TUTORIAL && M_GameAboutToStart() && restoreMenu == NULL)
|
||||
{
|
||||
// Playground Hack
|
||||
F_StartIntro();
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to return to the menu.
|
||||
Command_ExitGame_f();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14125,8 +14125,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
{
|
||||
// Set up bail charge, provided we have something to bail with (any rings or item resource).
|
||||
boolean grounded = P_IsObjectOnGround(player->mo);
|
||||
onground && player->tumbleBounces == 0 ? player->bailcharge += 2 : player->bailcharge++; // charge twice as fast on the ground
|
||||
if ((P_PlayerInPain(player) && player->bailcharge == 1) || (grounded && P_PlayerInPain(player) && player->bailcharge == 2)) // this is brittle ..
|
||||
// onground && player->tumbleBounces == 0 ? player->bailcharge += 2 : player->bailcharge++; // charge twice as fast on the ground
|
||||
player->bailcharge += 2;
|
||||
// if ((P_PlayerInPain(player) && player->bailcharge == 1) || (grounded && P_PlayerInPain(player) && player->bailcharge == 2)) // this is brittle ..
|
||||
if (player->bailcharge == 2)
|
||||
{
|
||||
mobj_t *bail = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_BAILCHARGE);
|
||||
S_StartSound(bail, sfx_gshb9); // I tried to use info.c, but you can't play sounds on mobjspawn via A_PlaySound
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ typedef enum
|
|||
MBF_SOUNDLESS = 1<<1, // do not play base menu sounds
|
||||
MBF_NOLOOPENTRIES = 1<<2, // do not loop M_NextOpt/M_PrevOpt
|
||||
MBF_DRAWBGWHILEPLAYING = 1<<3, // run backroutine() outside of GS_MENU
|
||||
MBF_CANTRESTORE = 1<<4, // Do not use in restoreMenu
|
||||
} menubehaviourflags_t;
|
||||
|
||||
struct menuitem_t
|
||||
|
|
@ -221,7 +222,7 @@ typedef enum
|
|||
quitkart
|
||||
} main_e;
|
||||
|
||||
extern menuitem_t MAIN_Goner[];
|
||||
extern menu_t MAIN_GonerAccessibilityDef;
|
||||
extern menu_t MAIN_GonerDef;
|
||||
|
||||
void M_GonerTick(void);
|
||||
|
|
@ -229,9 +230,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(boolean completely);
|
||||
void M_GonerGDQ(boolean opinion);
|
||||
boolean M_GonerMusicPlayable(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -662,7 +662,7 @@ boolean M_ConsiderSealedSwapAlert(void)
|
|||
|
||||
void M_ValidateRestoreMenu(void)
|
||||
{
|
||||
if (restoreMenu == NULL || restoreMenu == &MAIN_GonerDef)
|
||||
if (restoreMenu == NULL || (restoreMenu->behaviourflags & MBF_CANTRESTORE))
|
||||
restoreMenu = &MainDef;
|
||||
}
|
||||
|
||||
|
|
@ -829,17 +829,10 @@ void M_StartControlPanel(void)
|
|||
|
||||
if (gamedata != NULL
|
||||
&& gamedata->gonerlevel < GDGONER_OUTRO
|
||||
&& gamestartchallenge < MAXUNLOCKABLES)
|
||||
&& M_GameAboutToStart())
|
||||
{
|
||||
// See M_GameTrulyStarted
|
||||
if (
|
||||
gamedata->unlockpending[gamestartchallenge]
|
||||
|| gamedata->unlocked[gamestartchallenge]
|
||||
)
|
||||
{
|
||||
gamedata->gonerlevel = GDGONER_OUTRO;
|
||||
M_GonerBGImplyPassageOfTime();
|
||||
}
|
||||
gamedata->gonerlevel = GDGONER_OUTRO;
|
||||
M_GonerBGImplyPassageOfTime();
|
||||
}
|
||||
|
||||
if (M_GameTrulyStarted() == false)
|
||||
|
|
@ -847,7 +840,7 @@ void M_StartControlPanel(void)
|
|||
// Are you ready for the First Boot Experience?
|
||||
M_ResetOptions();
|
||||
|
||||
currentMenu = &MAIN_GonerDef;
|
||||
currentMenu = &MAIN_GonerAccessibilityDef;
|
||||
restoreMenu = NULL;
|
||||
|
||||
M_PlayMenuJam();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
31
src/m_cond.c
31
src/m_cond.c
|
|
@ -660,9 +660,7 @@ void M_ClearStats(void)
|
|||
gamedata->chaokeytutorial = false;
|
||||
gamedata->majorkeyskipattempted = false;
|
||||
gamedata->enteredtutorialchallenge = false;
|
||||
gamedata->finishedtutorialchallenge = false;
|
||||
gamedata->sealedswapalerted = false;
|
||||
gamedata->tutorialdone = false;
|
||||
gamedata->musicstate = GDMUSIC_NONE;
|
||||
|
||||
gamedata->importprofilewins = false;
|
||||
|
|
@ -777,6 +775,10 @@ void M_ClearSecrets(void)
|
|||
gamedata->chaokeys = GDINIT_CHAOKEYS;
|
||||
gamedata->prisoneggstothispickup = GDINIT_PRISONSTOPRIZE;
|
||||
|
||||
gamedata->tutorialdone = false;
|
||||
gamedata->playgroundroute = false;
|
||||
gamedata->finishedtutorialchallenge = false;
|
||||
|
||||
gamedata->gonerlevel = GDGONER_INIT;
|
||||
}
|
||||
|
||||
|
|
@ -1755,6 +1757,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 +2645,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";
|
||||
|
||||
|
|
@ -3470,6 +3476,27 @@ boolean M_GameTrulyStarted(void)
|
|||
return (gamedata->gonerlevel == GDGONER_DONE);
|
||||
}
|
||||
|
||||
boolean M_GameAboutToStart(void)
|
||||
{
|
||||
// Fail safe
|
||||
if (gamedata == NULL)
|
||||
return false;
|
||||
|
||||
// Not set
|
||||
if (gamestartchallenge >= MAXUNLOCKABLES)
|
||||
return true;
|
||||
|
||||
// An unfortunate sidestep, but sync is important.
|
||||
if (netgame)
|
||||
return true;
|
||||
|
||||
// Pending unlocked, but not unlocked
|
||||
return (
|
||||
gamedata->unlockpending[gamestartchallenge]
|
||||
&& !gamedata->unlocked[gamestartchallenge]
|
||||
);
|
||||
}
|
||||
|
||||
boolean M_CheckNetUnlockByID(UINT16 unlockid)
|
||||
{
|
||||
if (unlockid >= MAXUNLOCKABLES
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -470,6 +472,7 @@ extern UINT16 gamestartchallenge;
|
|||
boolean M_CheckNetUnlockByID(UINT16 unlockid);
|
||||
boolean M_SecretUnlocked(INT32 type, boolean local);
|
||||
boolean M_GameTrulyStarted(void);
|
||||
boolean M_GameAboutToStart(void);
|
||||
boolean M_CupLocked(cupheader_t *cup);
|
||||
boolean M_CupSecondRowLocked(void);
|
||||
boolean M_MapLocked(UINT16 mapnum);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomtype.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "k_menu.h"
|
||||
#include "m_cheat.h"
|
||||
|
|
@ -613,6 +614,7 @@ void f_devmode()
|
|||
|
||||
void f_proceed()
|
||||
{
|
||||
#if 0
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
gamedata->finishedtutorialchallenge = true;
|
||||
M_UpdateUnlockablesAndExtraEmblems(true, true);
|
||||
|
|
@ -621,6 +623,11 @@ void f_proceed()
|
|||
S_StartSound(0, sfx_kc42);
|
||||
|
||||
G_SaveGameData();
|
||||
#else
|
||||
F_StartIntro();
|
||||
M_ClearMenus(true);
|
||||
M_GonerResetText(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ void M_QuitSRB2(INT32 choice)
|
|||
|
||||
(void)choice;
|
||||
|
||||
if (M_GameTrulyStarted())
|
||||
if (!M_GameAboutToStart() && M_GameTrulyStarted())
|
||||
{
|
||||
INT32 mrand = M_RandomKey(sizeof(quitsounds) / sizeof(INT32));
|
||||
if (quitsounds[mrand])
|
||||
|
|
|
|||
|
|
@ -27,17 +27,109 @@
|
|||
#include "../m_pw.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#include <forward_list>
|
||||
#include <deque>
|
||||
|
||||
#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);
|
||||
|
||||
menuitem_t MAIN_Goner[] =
|
||||
static menuitem_t MAIN_GonerAccessibility[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, NULL, NULL, NULL, {.routine = M_QuitSRB2}, 0, 0}, // will be replaced
|
||||
{IT_NOTHING, NULL, NULL, NULL, {NULL}, 0, 0},
|
||||
};
|
||||
|
||||
static UINT32 goneraccessibilitytick = 0;
|
||||
|
||||
//#define HANDSTRAIN
|
||||
|
||||
#ifdef HANDSTRAIN
|
||||
static void M_GonerHandStrain(INT32 ch)
|
||||
{
|
||||
if (ch != MA_YES)
|
||||
return;
|
||||
|
||||
CV_StealthSet(&cv_kickstartaccel[0], "On");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void M_GonerPhotosensitivity(INT32 ch)
|
||||
{
|
||||
if (ch == MA_YES)
|
||||
{
|
||||
CV_StealthSet(&cv_reducevfx, "Yes");
|
||||
CV_StealthSet(&cv_screenshake, "Off");
|
||||
CV_StealthSet(&cv_tilting, "Off");
|
||||
}
|
||||
|
||||
#ifdef HANDSTRAIN
|
||||
M_StartMessage("Hand strain warning",
|
||||
"You may be required to press many buttons\n"
|
||||
"at once in order to control your Ring Racer.\n"
|
||||
"\n"
|
||||
"There is an option for your Accel input\n"
|
||||
"to \"lock\" on after being held for 1 second.\n"
|
||||
"Would you like to turn it on?\n"
|
||||
, &M_GonerHandStrain, MM_YESNO, "Yes, I want Accel to \"lock\"", "No thanks");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void M_GonerAccessibilityTick(void)
|
||||
{
|
||||
if (goneraccessibilitytick)
|
||||
{
|
||||
if (!menumessage.active && !menutransition.dest)
|
||||
{
|
||||
M_SetupNextMenu(&MAIN_GonerDef, true);
|
||||
M_GonerTick(); // tick once, for safety
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
goneraccessibilitytick++;
|
||||
|
||||
M_StartMessage("Photosensitivity warning",
|
||||
"This game has ""\x87""flashing lights and high-contrast\n"
|
||||
"patterns.""\x80"" Listen to your body, and\n"
|
||||
"stop playing if you feel unwell.\n"
|
||||
"\n"
|
||||
"There is a ""\x88""special mode""\x80"" to reduce some\n"
|
||||
"visual effects. Would you like to turn it on?\n"
|
||||
, &M_GonerPhotosensitivity, MM_YESNO, "Yes, reduce effects", "No thanks");
|
||||
return;
|
||||
}
|
||||
|
||||
static void M_GonerAccessibilityDrawer(void)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
}
|
||||
|
||||
menu_t MAIN_GonerAccessibilityDef = {
|
||||
sizeof (MAIN_GonerAccessibility) / sizeof (menuitem_t),
|
||||
NULL,
|
||||
0,
|
||||
MAIN_GonerAccessibility,
|
||||
26, 160,
|
||||
0, 0,
|
||||
MBF_CANTRESTORE,
|
||||
"_GONER",
|
||||
0, 0,
|
||||
M_GonerAccessibilityDrawer,
|
||||
NULL,
|
||||
M_GonerAccessibilityTick,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static menuitem_t MAIN_Goner[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, "PASSWORD",
|
||||
"ATTEMPT ADMINISTRATOR ACCESS.", NULL,
|
||||
{.cvar = &cv_dummyextraspassword}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "EXIT PROGRAM",
|
||||
"CONCLUDE OBSERVATIONS NOW.", NULL,
|
||||
|
|
@ -55,9 +147,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,
|
||||
|
|
@ -71,7 +163,7 @@ menu_t MAIN_GonerDef = {
|
|||
MAIN_Goner,
|
||||
26, 160,
|
||||
0, sizeof (MAIN_Goner) / sizeof (menuitem_t), // extra2 is final width
|
||||
MBF_UD_LR_FLIPPED,
|
||||
MBF_CANTRESTORE|MBF_UD_LR_FLIPPED,
|
||||
"_GONER",
|
||||
0, 0,
|
||||
M_GonerDrawer,
|
||||
|
|
@ -82,9 +174,57 @@ menu_t MAIN_GonerDef = {
|
|||
M_GonerInputs,
|
||||
};
|
||||
|
||||
static 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 tutorial\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},
|
||||
};
|
||||
|
||||
static menu_t MAIN_GonerChoiceDef = {
|
||||
sizeof (MAIN_GonerChoice) / sizeof (menuitem_t),
|
||||
&MAIN_GonerDef,
|
||||
0,
|
||||
MAIN_GonerChoice,
|
||||
26, 160,
|
||||
0, 0,
|
||||
MBF_CANTRESTORE|MBF_UD_LR_FLIPPED|MBF_NOLOOPENTRIES,
|
||||
"_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,
|
||||
|
|
@ -200,8 +340,8 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
std::forward_list<GonerChatLine> LinesToDigest;
|
||||
std::forward_list<GonerChatLine> LinesOutput;
|
||||
std::deque<GonerChatLine> LinesToDigest;
|
||||
std::deque<GonerChatLine> LinesOutput;
|
||||
|
||||
class GonerBGData
|
||||
{
|
||||
|
|
@ -429,16 +569,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)
|
||||
|
|
@ -453,24 +583,13 @@ static void Initial_Control_Info(void)
|
|||
)
|
||||
);
|
||||
|
||||
if (LinesToDigest.empty())
|
||||
{
|
||||
LinesToDigest.emplace_front(line);
|
||||
return;
|
||||
}
|
||||
|
||||
LinesToDigest.emplace_after(
|
||||
LinesToDigest.begin(),
|
||||
line
|
||||
);
|
||||
LinesToDigest.push_back(line);
|
||||
}
|
||||
|
||||
void M_AddGonerLines(void)
|
||||
{
|
||||
SRB2_ASSERT(LinesToDigest.empty());
|
||||
|
||||
auto _ = srb2::finally([]() { LinesToDigest.reverse(); });
|
||||
|
||||
static bool leftoff = false;
|
||||
|
||||
goner_delay = TICRATE;
|
||||
|
|
@ -480,7 +599,7 @@ void M_AddGonerLines(void)
|
|||
{
|
||||
if (!MAIN_Goner[0].mvar2)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Metal Sonic. Are you online?");
|
||||
}
|
||||
|
||||
|
|
@ -488,10 +607,10 @@ void M_AddGonerLines(void)
|
|||
|
||||
if (leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"It must have run into some sort of error...");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Don't worry, your settings so far are saved. "\
|
||||
"Let's pick up where we left off.");
|
||||
|
||||
|
|
@ -506,40 +625,40 @@ void M_AddGonerLines(void)
|
|||
{
|
||||
case GDGONER_VIDEO:
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
LinesToDigest.emplace_back(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(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"I don't feel very safe!");
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/4,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/4,
|
||||
"But its programming is definitely locked down...");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(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,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/5,
|
||||
"Wait, I'm getting weird readings over the network.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Metal Sonic is the unit labeled \"MS-1\", right?");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE,
|
||||
"The ""\x87""viewport""\x80"" and ""\x87""audio""\x80"" "\
|
||||
"config looks like it got messed up.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"So you're right. I wonder if it has anything to do with that outburst.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(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.emplace_front(0, Initial_Control_Info);
|
||||
LinesToDigest.emplace_back(0, Initial_Control_Info);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -547,101 +666,101 @@ void M_AddGonerLines(void)
|
|||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Ah, you can see us now. Good.");
|
||||
}
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Now, calibrate your ""\x87""Sound Options""\x80"".");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"You always make your stuff so loud by default, Eggman. It might need a moment.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Not Metal! He always needed to be stealthy. But go on, set your sliders.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
break;
|
||||
}
|
||||
case GDGONER_PROFILE:
|
||||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"Oh! Let's tell Metal about our project!");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Of course. I and my lab assista-");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Lab PARTNER.");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Irrelevant!");
|
||||
}
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
LinesToDigest.emplace_back(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,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE,
|
||||
"At its core, it is designed to utilise the boundless potential "\
|
||||
"of the ""\x83""High Voltage Ring""\x80"".");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE,
|
||||
"We made this special ""\x83""Ring""\x80"" by combining the power of tens of "\
|
||||
"thousands of ordinary ""\x82""Rings""\x80"".");
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(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(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
"While that's uploading, why don't you set up your ""\x87""Profile Card""\x80""?");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Yes! That's one of my contributions.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"(I'm too used to my systems being designed for me alone...)");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Every racer carries one, to contain their personal settings.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"It helps get your ""\x87""controls""\x80"" set up nice and quickly, "\
|
||||
"when starting your vehicle and navigating the menu.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"And it helps track your wins, too.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Bragging rights. My idea!");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"You can make the ID and player tag on there anything you want.");
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(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 use cool "\
|
||||
"robotics, but be kind of mean to protect himself...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Mine says \"Robotnik\". You can't beat a classic.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"And I'm not sure if you'll need it, but we always tell new drivers to "\
|
||||
"look at the ""\x87""Accessibility""\x80"" settings. Often there's some "\
|
||||
"feature they're not expecting. Maybe you'd be surprised too?");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"So go on, do your ""\x87""Profile Setup""\x80""!");
|
||||
|
||||
break;
|
||||
|
|
@ -650,31 +769,42 @@ void M_AddGonerLines(void)
|
|||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Now that that's been set up, you can use your ""\x87""Profile controls""\x80"" on menus from here on out, too.");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Miles. How's the upload going?");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Just finished.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"Perfect.");
|
||||
}
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(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_back(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"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.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"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_back(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_back(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_back(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_back(0, Miles_Look_Electric);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -682,37 +812,35 @@ void M_AddGonerLines(void)
|
|||
{
|
||||
if (!leftoff)
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/3,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/3,
|
||||
"And... the training data is completed.");
|
||||
}
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"It's kind of funny, actually.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/3,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/3,
|
||||
"Oh? Care to elucidate, Prower?");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(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(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"It could have been five days or five years of development on "\
|
||||
"our ""\x82""Ring Racers""\x80"", and that would barely matter to it.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/4,
|
||||
"Ha! As if. I'd like to think our partnership hasn't felt "\
|
||||
"particularly protracted.");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(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,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/5,
|
||||
"Now, I'm willing to let bygones be bygones.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
LinesToDigest.emplace_back(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(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"We've kept the keys from you long enough!");
|
||||
break;
|
||||
}
|
||||
|
|
@ -720,7 +848,7 @@ void M_AddGonerLines(void)
|
|||
break;
|
||||
|
||||
default:
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"I am error");
|
||||
}
|
||||
|
||||
|
|
@ -839,22 +967,25 @@ void M_GonerTick(void)
|
|||
first = true; // a lie, but only slightly...
|
||||
|
||||
// Handle rewinding if you clear your gamedata.
|
||||
M_GonerResetText();
|
||||
goner_background = GonerBGData();
|
||||
|
||||
goner_levelworking = GDGONER_INIT;
|
||||
M_GonerResetText(true);
|
||||
}
|
||||
|
||||
M_GonerResetLooking(GDGONER_INIT);
|
||||
|
||||
if (first)
|
||||
{
|
||||
goner_background = GonerBGData();
|
||||
|
||||
first = goner_gdq = false;
|
||||
|
||||
#if 0
|
||||
MAIN_Goner[0] =
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, "PASSWORD",
|
||||
"ATTEMPT ADMINISTRATOR ACCESS.", NULL,
|
||||
{.cvar = &cv_dummyextraspassword}, 0, 0};
|
||||
#endif
|
||||
|
||||
MAIN_Goner[0].mvar2 = 0;
|
||||
|
||||
if (gamedata->gonerlevel < GDGONER_INTRO)
|
||||
gamedata->gonerlevel = GDGONER_INTRO;
|
||||
|
|
@ -1218,6 +1349,130 @@ 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)");
|
||||
|
||||
drawer
|
||||
.xy(BASEVIDWIDTH - lex, 154+14)
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.flags(V_TRANSLUCENT)
|
||||
.text("the other way has these too, just later");
|
||||
}
|
||||
|
||||
// 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 +1500,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 +1522,57 @@ 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!\n"
|
||||
"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)
|
||||
{
|
||||
if (itemOn == GONERCHOICE_EGGMAN)
|
||||
{
|
||||
gamedata->playgroundroute = true;
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
|
||||
F_StartIntro();
|
||||
M_ClearMenus(true);
|
||||
M_GonerResetText(false);
|
||||
return;
|
||||
}
|
||||
|
||||
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,22 +1582,61 @@ 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
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
gamedata->playgroundroute = true;
|
||||
gamedata->deferredsave = true;
|
||||
M_GonerResetText(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();
|
||||
M_GonerResetText(true);
|
||||
}
|
||||
|
||||
void M_GonerGDQ(boolean opinion)
|
||||
|
|
@ -1311,24 +1653,23 @@ void M_GonerGDQ(boolean opinion)
|
|||
|
||||
if (opinion) // Save The Animals
|
||||
{
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Why wouldn't you save the frames..?");
|
||||
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Camera);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, 0,
|
||||
"Don't mind him. Good luck on the run!");
|
||||
LinesToDigest.emplace_front(0, Miles_Look_Electric);
|
||||
LinesToDigest.emplace_back(0, Miles_Look_Electric);
|
||||
}
|
||||
else // Save The Frames
|
||||
{
|
||||
LinesToDigest.emplace_front(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
LinesToDigest.emplace_back(0, Miles_Electric_Lower);
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_TAILS, TICRATE/2,
|
||||
"But what about all the little animals...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
LinesToDigest.emplace_back(GONERSPEAKER_EGGMAN, 0,
|
||||
"It's just logical. I know you'll conquer this run.");
|
||||
}
|
||||
LinesToDigest.reverse();
|
||||
|
||||
if (gamedata->gonerlevel <= GDGONER_TUTORIAL)
|
||||
{
|
||||
|
|
@ -1380,3 +1721,18 @@ static boolean M_GonerInputs(INT32 ch)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void M_GonerResetText(boolean completely)
|
||||
{
|
||||
goner_typewriter.ClearText();
|
||||
LinesToDigest.clear();
|
||||
LinesOutput.clear();
|
||||
|
||||
goner_scroll = 0;
|
||||
goner_scrollend = -1;
|
||||
|
||||
if (!completely)
|
||||
return;
|
||||
|
||||
goner_levelworking = GDGONER_INIT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,12 @@ void M_StartEditProfile(INT32 c)
|
|||
PR_InitNewProfile(); // initialize the new profile.
|
||||
|
||||
optionsmenu.profile = PR_GetProfile(optionsmenu.profilen);
|
||||
if (cv_kickstartaccel[0].value)
|
||||
{
|
||||
// Primarily for Goner but should help with standard set-up too
|
||||
optionsmenu.profile->kickstartaccel = true;
|
||||
}
|
||||
|
||||
// copy this profile's controls into optionsmenu so that we can edit controls without changing them directly.
|
||||
// we do this so that we don't edit a profile's controls in real-time and end up doing really weird shit.
|
||||
memcpy(&optionsmenu.tempcontrols, optionsmenu.profile->controls, sizeof(gamecontroldefault));
|
||||
|
|
|
|||
|
|
@ -561,7 +561,8 @@ void M_EndGame(INT32 choice)
|
|||
if (!Playing())
|
||||
return;
|
||||
|
||||
if (M_GameTrulyStarted() == false)
|
||||
if (M_GameTrulyStarted() == false
|
||||
|| M_GameAboutToStart() == true) // Playground Hack
|
||||
{
|
||||
// No returning to the title screen.
|
||||
M_QuitSRB2(-1);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@
|
|||
#include "k_credits.h"
|
||||
#include "k_objects.h"
|
||||
#include "p_deepcopy.h"
|
||||
#include "k_color.h" // K_ColorUsable
|
||||
|
||||
// Replay names have time
|
||||
#if !defined (UNDER_CE)
|
||||
|
|
@ -8046,7 +8047,7 @@ static void P_ShuffleTeams(void)
|
|||
|
||||
static void P_InitPlayers(void)
|
||||
{
|
||||
INT32 i, skin = -1, follower = -1;
|
||||
INT32 i, skin = -1, follower = -1, col = SKINCOLOR_NONE;
|
||||
|
||||
// Make sure objectplace is OFF when you first start the level!
|
||||
OP_ResetObjectplace();
|
||||
|
|
@ -8060,7 +8061,28 @@ static void P_InitPlayers(void)
|
|||
// Get skin from name.
|
||||
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->relevantskin[0])
|
||||
{
|
||||
skin = R_SkinAvailable(mapheaderinfo[gamemap-1]->relevantskin);
|
||||
if (strcmp(mapheaderinfo[gamemap-1]->relevantskin, "_PROFILE") == 0)
|
||||
{
|
||||
profile_t *p = PR_GetProfile(cv_ttlprofilen.value);
|
||||
if (p && !netgame)
|
||||
{
|
||||
skin = R_SkinAvailable(p->skinname);
|
||||
|
||||
if (!R_SkinUsable(g_localplayers[0], skin, false))
|
||||
{
|
||||
skin = GetSkinNumClosestToStats(skins[skin].kartspeed, skins[skin].kartweight, skins[skin].flags, false);
|
||||
}
|
||||
|
||||
if (K_ColorUsable(static_cast<skincolornum_t>(p->color), false, true) == true)
|
||||
{
|
||||
col = p->color;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skin = R_SkinAvailable(mapheaderinfo[gamemap-1]->relevantskin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -8097,7 +8119,7 @@ static void P_InitPlayers(void)
|
|||
if (skin != -1)
|
||||
{
|
||||
SetPlayerSkinByNum(i, skin);
|
||||
players[i].skincolor = skins[skin].prefcolor;
|
||||
players[i].skincolor = (col != SKINCOLOR_NONE) ? col : skins[skin].prefcolor;
|
||||
|
||||
players[i].followerskin = follower;
|
||||
if (follower != -1)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue