diff --git a/src/g_game.c b/src/g_game.c index 3474d6ca9..ad519524d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4390,12 +4390,15 @@ void G_LoadGameSettings(void) #define GD_VERSIONCHECK 0xBA5ED123 // Change every major version, as usual #define GD_VERSIONMINOR 7 // Change every format update +// You can't rearrange these without a special format update typedef enum { GDEVER_ADDON = 1, GDEVER_CREDITS = 1<<1, GDEVER_REPLAY = 1<<2, GDEVER_SPECIAL = 1<<3, + GDEVER_KEYTUTORIAL = 1<<4, + GDEVER_KEYMAJORSKIP = 1<<5, } gdeverdone_t; static const char *G_GameDataFolder(void) @@ -4528,6 +4531,8 @@ void G_LoadGameData(void) gamedata->everfinishedcredits = !!(everflags & GDEVER_CREDITS); gamedata->eversavedreplay = !!(everflags & GDEVER_REPLAY); gamedata->everseenspecial = !!(everflags & GDEVER_SPECIAL); + gamedata->chaokeytutorial = !!(everflags & GDEVER_KEYTUTORIAL); + gamedata->majorkeyskipattempted = !!(everflags & GDEVER_KEYMAJORSKIP); } else { @@ -5206,6 +5211,10 @@ void G_SaveGameData(void) everflags |= GDEVER_REPLAY; if (gamedata->everseenspecial) everflags |= GDEVER_SPECIAL; + if (gamedata->chaokeytutorial) + everflags |= GDEVER_KEYTUTORIAL; + if (gamedata->majorkeyskipattempted) + everflags |= GDEVER_KEYMAJORSKIP; WRITEUINT32(save.p, everflags); // 4 } diff --git a/src/k_menu.h b/src/k_menu.h index c6cda78d6..b154332be 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1259,7 +1259,7 @@ extern struct challengesmenu_s { boolean pending; boolean requestnew; - boolean chaokeyadd; + boolean chaokeyadd, keywasadded; UINT8 chaokeyhold; boolean requestflip; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 681be183a..19c0815a3 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -5914,7 +5914,7 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley) 24 << FRACBITS, 16 << FRACBITS, 0, kp_button_c[1], - M_MenuExtraHeld(pid) + menumessage.active == false && M_MenuExtraHeld(pid) == true ); // Metyr of rounds played that contribute to Chao Key generation diff --git a/src/m_cond.c b/src/m_cond.c index 90faf6298..38bebcc28 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -658,6 +658,8 @@ void M_ClearStats(void) gamedata->eversavedreplay = false; gamedata->everseenspecial = false; gamedata->evercrashed = false; + gamedata->chaokeytutorial = false; + gamedata->majorkeyskipattempted = false; gamedata->musicstate = GDMUSIC_NONE; gamedata->importprofilewins = false; diff --git a/src/m_cond.h b/src/m_cond.h index fb4d00195..b34ea5e0f 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -311,6 +311,8 @@ struct gamedata_t boolean eversavedreplay; boolean everseenspecial; boolean evercrashed; + boolean chaokeytutorial; + boolean majorkeyskipattempted; gdmusic_t musicstate; // BACKWARDS COMPAT ASSIST diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index c0cd98b2e..779838056 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -308,6 +308,7 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu) challengesmenu.requestflip = false; challengesmenu.requestnew = false; challengesmenu.chaokeyadd = false; + challengesmenu.keywasadded = false; challengesmenu.chaokeyhold = 0; challengesmenu.currentunlock = MAXUNLOCKABLES; challengesmenu.unlockcondition = NULL; @@ -392,6 +393,55 @@ static boolean M_CanKeyHiliTile(void) return true; } +enum { + CCTUTORIAL_KEYGEN = 0, + CCTUTORIAL_MAJORSKIP, +} cctutorial_e; + +static void M_ChallengesTutorial(UINT8 option) +{ + switch (option) + { + case CCTUTORIAL_KEYGEN: + { + M_StartMessage("Challenges & Chao Keys", + va(M_GetText( + "You just generated a Chao Key!\n" + "\n" + "They can be used to skip your way past\n" + "any Challenges you can see a hint for.\n" + "\n" + "But use them wisely - it'll take\n" + "%u rounds to pick up another.\n" + ), GDCONVERT_ROUNDSTOKEY + ), NULL, MM_NOTHING, NULL, NULL); + gamedata->chaokeytutorial = true; + break; + } + case CCTUTORIAL_MAJORSKIP: + { + M_StartMessage("Major Challenges & Chao Keys", + M_GetText( + "The larger tiles are Major Challenges.\n" + "They are significant tests of skill.\n" + "\n" + "If you're struggling and need to skip one,\n" + "not only will it cost you 10 Chao Keys, but\n" + "every nearby Challenge must be unlocked!\n" + ), NULL, MM_NOTHING, NULL, "Wow, that's a lot"); + gamedata->majorkeyskipattempted = true; + break; + } + default: + { + M_StartMessage("M_ChallengesTutorial ERROR", + "Invalid argument!?\n", + NULL, MM_NOTHING, NULL, NULL); + break; + } + } +} + void M_ChallengesTick(void) { const UINT8 pid = 0; @@ -536,6 +586,8 @@ void M_ChallengesTick(void) if (gamedata->musicstate < GDMUSIC_KEYG) gamedata->musicstate = GDMUSIC_KEYG; + + challengesmenu.keywasadded = true; } } } @@ -652,6 +704,12 @@ void M_ChallengesTick(void) { // Play music the moment control returns. M_PlayMenuJam(); + + if (gamedata->chaokeytutorial == false + && challengesmenu.keywasadded == true) + { + M_ChallengesTutorial(CCTUTORIAL_KEYGEN); + } } } } @@ -671,7 +729,15 @@ boolean M_ChallengesInputs(INT32 ch) } else if (M_MenuExtraPressed(pid)) { - if (M_CanKeyHiliTile()) + if (gamedata->chaokeytutorial == true + && gamedata->majorkeyskipattempted == false + && challengesmenu.currentunlock < MAXUNLOCKABLES + && gamedata->unlocked[challengesmenu.currentunlock] == false + && unlockables[challengesmenu.currentunlock].majorunlock == true) + { + M_ChallengesTutorial(CCTUTORIAL_MAJORSKIP); + } + else if (M_CanKeyHiliTile()) { challengesmenu.chaokeyhold = 1; } @@ -696,6 +762,12 @@ boolean M_ChallengesInputs(INT32 ch) { gamedata->chaokeys++; challengesmenu.unlockcount[CMC_CHAOANIM]++; + + if (gamedata->chaokeytutorial == false) + { + M_ChallengesTutorial(CCTUTORIAL_KEYGEN); + } + S_StartSound(NULL, sfx_dbgsal); return true; }