diff --git a/src/command.c b/src/command.c index 305a5eee..54406ade 100644 --- a/src/command.c +++ b/src/command.c @@ -28,6 +28,7 @@ #include "byteptr.h" #include "p_saveg.h" #include "g_game.h" // for player_names +#include "m_cond.h" // for encore mode #include "d_netcmd.h" #include "hu_stuff.h" #include "p_setup.h" @@ -1373,6 +1374,12 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) return; } + if (var == &cv_kartencore && !M_SecretUnlocked(SECRET_ENCORE)) + { + CONS_Printf(M_GetText("You haven't unlocked Encore Mode yet!\n")); + return; + } + // Only add to netcmd buffer if in a netgame, otherwise, just change it. if (netgame || multiplayer) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e1e0a635..a504453e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -352,7 +352,7 @@ static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, N consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; @@ -5249,11 +5249,11 @@ static void KartEncore_OnChange(void) if (G_RaceGametype()) { if ((boolean)cv_kartencore.value != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) - CONS_Printf(M_GetText("Encore tracks will be turned %s next round.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + CONS_Printf(M_GetText("Encore Mode will be turned %s next round.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); else { - CONS_Printf(M_GetText("Encore tracks have been turned %s.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); - encoremode = (boolean)cv_kartencore.value; + CONS_Printf(M_GetText("Encore Mode has been turned %s.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + //encoremode = (boolean)cv_kartencore.value; } } } diff --git a/src/dehacked.c b/src/dehacked.c index 8fcf597d..15586934 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2384,8 +2384,8 @@ static void readunlockable(MYFILE *f, INT32 num) else if (fastcmp(word, "OBJECTIVE")) deh_strlcpy(unlockables[num].objective, word2, sizeof (unlockables[num].objective), va("Unlockable %d: objective", num)); - else if (fastcmp(word, "HEIGHT")) - unlockables[num].height = (UINT16)i; + else if (fastcmp(word, "SHOWCONDITIONSET")) + unlockables[num].showconditionset = (UINT8)i; else if (fastcmp(word, "CONDITIONSET")) unlockables[num].conditionset = (UINT8)i; else if (fastcmp(word, "NOCECHO")) @@ -2416,6 +2416,8 @@ static void readunlockable(MYFILE *f, INT32 num) unlockables[num].type = SECRET_WARP; else if (fastcmp(word2, "SOUNDTEST")) unlockables[num].type = SECRET_SOUNDTEST; + else if (fastcmp(word2, "ENCORE")) + unlockables[num].type = SECRET_ENCORE; else unlockables[num].type = (INT16)i; } diff --git a/src/m_cond.c b/src/m_cond.c index 7d07d00a..63f88cb6 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -96,12 +96,14 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] = // Default Unlockables unlockable_t unlockables[MAXUNLOCKABLES] = { - // Name, Objective, Menu Height, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist - /* 01 */ {"Egg Cup", "", 0, 1, SECRET_NONE, 0, false, false, 0}, - /* 02 */ {"SMK Cup", "", 0, 2, SECRET_NONE, 0, false, false, 0}, - /* 03 */ {"Chao Cup", "", 0, 3, SECRET_NONE, 0, false, false, 0}, + // Name, Objective, Showing Conditionset, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist + /* 01 */ {"Egg Cup", "", -1, 1, SECRET_NONE, 0, false, false, 0}, + /* 02 */ {"SMK Cup", "", -1, 2, SECRET_NONE, 0, false, false, 0}, + /* 03 */ {"Chao Cup", "", -1, 3, SECRET_NONE, 0, false, false, 0}, - /* 04 */ {"Record Attack", "", 0, -1, SECRET_RECORDATTACK, 0, true, true, 0}, + /* 04 */ {"Encore Mode", "", 3, 4, SECRET_ENCORE, 0, false, false, 0}, + + /* 05 */ {"Record Attack", "", -1, -1, SECRET_RECORDATTACK, 0, true, true, 0}, }; // Default number of emblems and extra emblems @@ -125,6 +127,10 @@ void M_SetupDefaultConditionSets(void) M_AddRawCondition(3, 1, UC_TOTALEMBLEMS, 30, 0, 0); M_AddRawCondition(3, 2, UC_MATCHESPLAYED, 50, 0, 0); + // -- 4: Collect 50 emblems OR play 150 matches + M_AddRawCondition(4, 1, UC_TOTALEMBLEMS, 50, 0, 0); + M_AddRawCondition(4, 2, UC_MATCHESPLAYED, 150, 0, 0); + // -- 10: Play 100 matches M_AddRawCondition(10, 1, UC_MATCHESPLAYED, 100, 0, 0); } diff --git a/src/m_cond.h b/src/m_cond.h index 052c31f2..5c8762ad 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -103,7 +103,7 @@ typedef struct { char name[64]; char objective[64]; - UINT16 height; // menu height + UINT8 showconditionset; UINT8 conditionset; INT16 type; INT16 variable; @@ -112,6 +112,7 @@ typedef struct UINT8 unlocked; } unlockable_t; +// I have NO idea why these are going negative, but whatever. #define SECRET_NONE -6 // Does nil. Use with levels locked by UnlockRequired #define SECRET_ITEMFINDER -5 // Enables Item Finder/Emblem Radar #define SECRET_EMBLEMHINTS -4 // Enables Emblem Hints @@ -123,6 +124,7 @@ typedef struct #define SECRET_WARP 2 // Selectable warp #define SECRET_SOUNDTEST 3 // Sound Test #define SECRET_CREDITS 4 // Enables Credits +#define SECRET_ENCORE 5 // Enables Encore mode cvar // If you have more secrets than these variables allow in your game, // you seriously need to get a life. diff --git a/src/m_menu.c b/src/m_menu.c index 3e12c65d..07a2a9c3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1444,7 +1444,7 @@ static menuitem_t OP_GameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Game Speed", &cv_kartspeed, 30}, {IT_STRING | IT_CVAR, NULL, "Frantic Items", &cv_kartfrantic, 40}, - {IT_STRING | IT_CVAR, NULL, "Encore Mode", &cv_kartencore, 50}, + {IT_SECRET, NULL, "Encore Mode", &cv_kartencore, 50}, {IT_STRING | IT_CVAR, NULL, "Number of Laps", &cv_basenumlaps, 70}, {IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", &cv_countdowntime, 80}, @@ -4311,6 +4311,9 @@ static void M_Options(INT32 choice) OP_MainMenu[7].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); OP_MainMenu[8].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); + OP_GameOptionsMenu[3].status = + (M_SecretUnlocked(SECRET_ENCORE)) ? (IT_CVAR|IT_STRING) : IT_SECRET; // cv_kartencore + OP_MainDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_MainDef); } @@ -4463,7 +4466,8 @@ static void M_DrawChecklist(void) for (i = 0; i < MAXUNLOCKABLES; i++) { if (unlockables[i].name[0] == 0 || unlockables[i].nochecklist - || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS) + || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS + || !M_Achieved(unlockables[i].showconditionset - 1)) continue; ++line; diff --git a/src/p_setup.c b/src/p_setup.c index 196eb5c7..39a26260 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -136,6 +136,8 @@ mapthing_t *playerstarts[MAXPLAYERS]; mapthing_t *bluectfstarts[MAXPLAYERS]; mapthing_t *redctfstarts[MAXPLAYERS]; +boolean prevencoremode = false; + /** Logs an error about a map being corrupt, then terminate. * This allows reporting highly technical errors for usefulness, without * confusing a novice map designer who simply needs to run ZenNode. @@ -2245,6 +2247,8 @@ static void P_LevelInitStuff(void) players[i].pflags &= ~PF_TRANSFERTOCLOSEST; } + prevencoremode = ((wipegamestate == GS_TITLESCREEN) ? false : encoremode); + // SRB2Kart: map load variables if (modeattacking) // Just play it safe and set everything { @@ -2647,7 +2651,7 @@ boolean P_SetupLevel(boolean skipprecip) // Encore mode fade to pink to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && encoremode) + if (rendermode != render_none && encoremode && !prevencoremode) { tic_t starttime, endtime, nowtime; @@ -2697,14 +2701,14 @@ boolean P_SetupLevel(boolean skipprecip) S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic(); // Let's fade to white here - // But only if we didn't do the encore wipe + // But only if we didn't do the encore startup wipe if (rendermode != render_none && !ranspecialwipe) { F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (encoremode ? 122 : 120)); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false); + F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); } // Reset the palette now all fades have been done @@ -3045,7 +3049,7 @@ boolean P_SetupLevel(boolean skipprecip) // Remove the loading shit from the screen if (rendermode != render_none) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (encoremode && !ranspecialwipe ? 122 : 120)); if (precache || dedicated) R_PrecacheLevel();