mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'seal-a-carte' into 'master'
Sealed Star re-ordering (resolves #606) Closes #606 See merge request KartKrew/Kart!1980
This commit is contained in:
commit
b136df4d41
14 changed files with 336 additions and 43 deletions
69
src/g_game.c
69
src/g_game.c
|
|
@ -3933,15 +3933,68 @@ void G_GPCupIntoRoundQueue(cupheader_t *cup, UINT8 setgametype, boolean setencor
|
|||
// At the end of the Cup is a Rank-restricted treat.
|
||||
// So we append it to the end of the roundqueue.
|
||||
// (as long as it exists, of course!)
|
||||
cupLevelNum = cup->cachedlevels[CUPCACHE_SPECIAL];
|
||||
if (cupLevelNum < nummapheaders)
|
||||
{
|
||||
G_MapIntoRoundQueue(
|
||||
cupLevelNum,
|
||||
G_GuessGametypeByTOL(mapheaderinfo[cupLevelNum]->typeoflevel),
|
||||
setencore, // if this isn't correct, Got_Mapcmd will fix it
|
||||
true // Rank-restricted!
|
||||
);
|
||||
// Of course, this last minute game design tweak
|
||||
// has to make things a little complicated. We
|
||||
// basically just make sure they're dispensed
|
||||
// at the intended difficulty sequence until
|
||||
// you've got them all, at which point they
|
||||
// become their intended order permanently.
|
||||
// ~toast 010324
|
||||
cupheader_t *emeraldcup = NULL;
|
||||
|
||||
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|
||||
|| cup->id >= basenumkartcupheaders // custom content
|
||||
|| M_SecretUnlocked(SECRET_SPECIALATTACK, false)) // true order
|
||||
{
|
||||
// Standard order.
|
||||
emeraldcup = cup;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine order from sealedswaps.
|
||||
for (i = 0; (i < GDMAX_SEALEDSWAPS && gamedata->sealedswaps[i]); i++)
|
||||
{
|
||||
if (gamedata->sealedswaps[i] != grandprixinfo.cup)
|
||||
continue;
|
||||
|
||||
// Repeat visit, grab the same ID.
|
||||
break;
|
||||
}
|
||||
|
||||
// If there's pending stars, get them from the associated cup order.
|
||||
if (i < GDMAX_SEALEDSWAPS)
|
||||
{
|
||||
emeraldcup = kartcupheaders;
|
||||
while (emeraldcup)
|
||||
{
|
||||
if (emeraldcup->id >= basenumkartcupheaders)
|
||||
{
|
||||
emeraldcup = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (emeraldcup->emeraldnum == i+1)
|
||||
break;
|
||||
|
||||
emeraldcup = emeraldcup->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emeraldcup)
|
||||
{
|
||||
cupLevelNum = emeraldcup->cachedlevels[CUPCACHE_SPECIAL];
|
||||
if (cupLevelNum < nummapheaders)
|
||||
{
|
||||
G_MapIntoRoundQueue(
|
||||
cupLevelNum,
|
||||
G_GuessGametypeByTOL(mapheaderinfo[cupLevelNum]->typeoflevel),
|
||||
setencore, // if this isn't correct, Got_Mapcmd will fix it
|
||||
true // Rank-restricted!
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (roundqueue.size == 0)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ void srb2::save_ng_gamedata()
|
|||
ng.milestones.majorkeyskipattempted = gamedata->majorkeyskipattempted;
|
||||
ng.milestones.finishedtutorialchallenge = gamedata->finishedtutorialchallenge;
|
||||
ng.milestones.enteredtutorialchallenge = gamedata->enteredtutorialchallenge;
|
||||
ng.milestones.sealedswapalerted = gamedata->sealedswapalerted;
|
||||
ng.milestones.gonerlevel = gamedata->gonerlevel;
|
||||
ng.prisons.thisprisoneggpickup = gamedata->thisprisoneggpickup;
|
||||
ng.prisons.prisoneggstothispickup = gamedata->prisoneggstothispickup;
|
||||
|
|
@ -176,7 +177,7 @@ void srb2::save_ng_gamedata()
|
|||
}
|
||||
for (auto cup = kartcupheaders; cup; cup = cup->next)
|
||||
{
|
||||
if (cup->windata[0].best_placement == 0)
|
||||
if (cup->windata[0].best_placement == 0 && cup->windata[1].got_emerald == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -229,6 +230,17 @@ void srb2::save_ng_gamedata()
|
|||
ng.cups[cupdata.name] = std::move(cupdata);
|
||||
}
|
||||
|
||||
for (int i = 0; (i < GDMAX_SEALEDSWAPS && gamedata->sealedswaps[i]); i++)
|
||||
{
|
||||
srb2::GamedataSealedSwapJson sealedswap {};
|
||||
|
||||
cupheader_t* cup = gamedata->sealedswaps[i];
|
||||
|
||||
sealedswap.name = std::string(cup->name);
|
||||
|
||||
ng.sealedswaps.emplace_back(std::move(sealedswap));
|
||||
}
|
||||
|
||||
std::string gamedataname_s {gamedatafilename};
|
||||
fs::path savepath {fmt::format("{}/{}", srb2home, gamedataname_s)};
|
||||
fs::path tmpsavepath {fmt::format("{}/{}.tmp", srb2home, gamedataname_s)};
|
||||
|
|
@ -418,6 +430,7 @@ void srb2::load_ng_gamedata()
|
|||
gamedata->majorkeyskipattempted = js.milestones.majorkeyskipattempted;
|
||||
gamedata->finishedtutorialchallenge = js.milestones.finishedtutorialchallenge;
|
||||
gamedata->enteredtutorialchallenge = js.milestones.enteredtutorialchallenge;
|
||||
gamedata->sealedswapalerted = js.milestones.sealedswapalerted;
|
||||
gamedata->gonerlevel = js.milestones.gonerlevel;
|
||||
gamedata->thisprisoneggpickup = js.prisons.thisprisoneggpickup;
|
||||
gamedata->prisoneggstothispickup = js.prisons.prisoneggstothispickup;
|
||||
|
|
@ -720,6 +733,33 @@ void srb2::load_ng_gamedata()
|
|||
}
|
||||
}
|
||||
|
||||
size_t sealedswaps_size = js.sealedswaps.size();
|
||||
for (size_t i = 0; i < std::min((size_t)GDMAX_SEALEDSWAPS, sealedswaps_size); i++)
|
||||
{
|
||||
cupheader_t* cup = nullptr;
|
||||
|
||||
// Find BASE cups only
|
||||
for (cup = kartcupheaders; cup; cup = cup->next)
|
||||
{
|
||||
if (cup->id >= basenumkartcupheaders)
|
||||
{
|
||||
cup = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
std::string cupname = std::string(cup->name);
|
||||
if (cupname == js.sealedswaps[i].name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cup)
|
||||
{
|
||||
gamedata->sealedswaps[i] = cup;
|
||||
}
|
||||
}
|
||||
|
||||
M_FinaliseGameData();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ struct GamedataMilestonesJson final
|
|||
bool majorkeyskipattempted;
|
||||
bool finishedtutorialchallenge;
|
||||
bool enteredtutorialchallenge;
|
||||
bool sealedswapalerted;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
||||
GamedataMilestonesJson,
|
||||
|
|
@ -81,7 +82,8 @@ struct GamedataMilestonesJson final
|
|||
chaokeytutorial,
|
||||
majorkeyskipattempted,
|
||||
finishedtutorialchallenge,
|
||||
enteredtutorialchallenge
|
||||
enteredtutorialchallenge,
|
||||
sealedswapalerted
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -184,6 +186,13 @@ struct GamedataCupJson final
|
|||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(GamedataCupJson, name, records)
|
||||
};
|
||||
|
||||
struct GamedataSealedSwapJson final
|
||||
{
|
||||
std::string name;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(GamedataSealedSwapJson, name)
|
||||
};
|
||||
|
||||
struct GamedataJson final
|
||||
{
|
||||
GamedataPlaytimeJson playtime;
|
||||
|
|
@ -203,6 +212,7 @@ struct GamedataJson final
|
|||
std::unordered_map<std::string, GamedataMapJson> maps;
|
||||
std::vector<GamedataSprayCanJson> spraycans;
|
||||
std::unordered_map<std::string, GamedataCupJson> cups;
|
||||
std::vector<GamedataSealedSwapJson> sealedswaps;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
||||
GamedataJson,
|
||||
|
|
@ -222,7 +232,8 @@ struct GamedataJson final
|
|||
skins,
|
||||
maps,
|
||||
spraycans,
|
||||
cups
|
||||
cups,
|
||||
sealedswaps
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -680,6 +680,8 @@ void M_Init(void);
|
|||
|
||||
void M_PlayMenuJam(void);
|
||||
|
||||
boolean M_ConsiderSealedSwapAlert(void);
|
||||
|
||||
void M_OpenVirtualKeyboard(boolean gamepad);
|
||||
void M_MenuTypingInput(INT32 key);
|
||||
|
||||
|
|
@ -1347,6 +1349,8 @@ extern struct challengesmenu_s {
|
|||
boolean chaokeyadd, keywasadded;
|
||||
UINT8 chaokeyhold;
|
||||
|
||||
boolean considersealedswapalert;
|
||||
|
||||
boolean requestflip;
|
||||
|
||||
UINT16 unlockcount[CMC_MAX];
|
||||
|
|
|
|||
|
|
@ -2823,6 +2823,57 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
|
|||
rankx += 19 - (rankw / 2);
|
||||
|
||||
cupwindata_t *windata = &(cup->windata[difficulty]);
|
||||
UINT8 emeraldnum = UINT8_MAX;
|
||||
|
||||
if (!noemerald)
|
||||
{
|
||||
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|
||||
|| cup->id >= basenumkartcupheaders // custom content
|
||||
|| M_SecretUnlocked(SECRET_SPECIALATTACK, true)) // true order
|
||||
{
|
||||
// Standard order.
|
||||
if (windata->got_emerald == true)
|
||||
{
|
||||
emeraldnum = cup->emeraldnum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine order from sealedswaps.
|
||||
UINT8 i;
|
||||
for (i = 0; (i < GDMAX_SEALEDSWAPS && gamedata->sealedswaps[i]); i++)
|
||||
{
|
||||
if (gamedata->sealedswaps[i] != cup)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// If there's pending stars, get them from the associated cup order.
|
||||
if (i < GDMAX_SEALEDSWAPS)
|
||||
{
|
||||
cupheader_t *emeraldcup = kartcupheaders;
|
||||
while (emeraldcup)
|
||||
{
|
||||
if (emeraldcup->id >= basenumkartcupheaders)
|
||||
{
|
||||
emeraldcup = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (emeraldcup->emeraldnum == i+1)
|
||||
{
|
||||
if (emeraldcup->windata[difficulty].got_emerald == true)
|
||||
emeraldnum = i+1;
|
||||
break;
|
||||
}
|
||||
|
||||
emeraldcup = emeraldcup->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (windata->best_placement == 0)
|
||||
{
|
||||
if (statsmode)
|
||||
|
|
@ -2832,14 +2883,13 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
|
|||
V_DrawCharacter((14-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
|
||||
rankx += 14 + 1;
|
||||
V_DrawCharacter((12-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
|
||||
|
||||
if (!noemerald)
|
||||
{
|
||||
rankx += 12 + 1;
|
||||
V_DrawCharacter((12-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
|
||||
}
|
||||
}
|
||||
return rankw;
|
||||
else
|
||||
{
|
||||
rankx += 14 + 1;
|
||||
}
|
||||
|
||||
goto windataemeraldmaybe;
|
||||
}
|
||||
|
||||
UINT8 *colormap = NULL;
|
||||
|
|
@ -2934,13 +2984,15 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
|
|||
if (charPat)
|
||||
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, charPat, colormap);
|
||||
|
||||
windataemeraldmaybe:
|
||||
|
||||
rankx += 12 + 1;
|
||||
|
||||
if (noemerald)
|
||||
;
|
||||
else if (windata->got_emerald == true)
|
||||
else if (emeraldnum != UINT8_MAX)
|
||||
{
|
||||
if (cup->emeraldnum == 0)
|
||||
if (emeraldnum == 0)
|
||||
V_DrawCharacter(rankx+2, ranky+2, '+', false);
|
||||
else
|
||||
{
|
||||
|
|
@ -2948,14 +3000,14 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
|
|||
|
||||
if (!flash)
|
||||
{
|
||||
UINT16 col = SKINCOLOR_CHAOSEMERALD1 + (cup->emeraldnum-1) % 7;
|
||||
UINT16 col = SKINCOLOR_CHAOSEMERALD1 + (emeraldnum-1) % 7;
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
}
|
||||
|
||||
const char *emname = va(
|
||||
"%sMAP%c",
|
||||
(cup->emeraldnum > 7) ? "SUP" : "EME",
|
||||
(emeraldnum > 7) ? "SUP" : "EME",
|
||||
colormap ? '\0' : 'B'
|
||||
);
|
||||
|
||||
|
|
@ -3116,7 +3168,7 @@ void M_DrawCupSelect(void)
|
|||
y += 44; //(8 + 100) - (20 + 44)
|
||||
}
|
||||
|
||||
if (windata && windata->best_placement != 0)
|
||||
if (windata)
|
||||
{
|
||||
M_DrawCupWinData(
|
||||
x,
|
||||
|
|
|
|||
|
|
@ -560,6 +560,35 @@ void M_PlayMenuJam(void)
|
|||
|
||||
#undef IsCurrentlyPlaying
|
||||
|
||||
boolean M_ConsiderSealedSwapAlert(void)
|
||||
{
|
||||
if (gamedata->sealedswapalerted == true)
|
||||
return false;
|
||||
|
||||
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|
||||
|| M_SecretUnlocked(SECRET_SPECIALATTACK, true)) // true order
|
||||
{
|
||||
gamedata->sealedswapalerted = true;
|
||||
|
||||
// Don't make a message if no Sealed Stars have yet been found.
|
||||
if (gamedata->everseenspecial == false)
|
||||
return false;
|
||||
|
||||
M_StartMessage(
|
||||
"Message from the Stars",
|
||||
"As if called by fate, the Emeralds you've\n"
|
||||
"collected return to their rightful places...\n"
|
||||
"\n"
|
||||
"The Sealed Stars are now ordered via Cups!\n",
|
||||
NULL, MM_NOTHING, NULL, NULL
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void M_ValidateRestoreMenu(void)
|
||||
{
|
||||
if (restoreMenu == NULL || restoreMenu == &MAIN_GonerDef)
|
||||
|
|
@ -629,6 +658,11 @@ menu_t *M_SpecificMenuRestore(menu_t *torestore)
|
|||
M_SetupPlayMenu(-1);
|
||||
PLAY_CharSelectDef.prevMenu = &MainDef;
|
||||
|
||||
if (torestore != &MISC_ChallengesDef)
|
||||
{
|
||||
M_ConsiderSealedSwapAlert();
|
||||
}
|
||||
|
||||
return torestore;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ static struct podiumData_s
|
|||
sfxenum_t gradeVoice;
|
||||
|
||||
cupheader_t *cup;
|
||||
UINT8 emeraldnum;
|
||||
|
||||
boolean fastForward;
|
||||
|
||||
|
|
@ -102,6 +103,7 @@ void podiumData_s::Init(void)
|
|||
{
|
||||
rank = grandprixinfo.rank;
|
||||
cup = grandprixinfo.cup;
|
||||
emeraldnum = cup->emeraldnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -119,6 +121,7 @@ void podiumData_s::Init(void)
|
|||
|
||||
cup = cup->next;
|
||||
}
|
||||
emeraldnum = 0;
|
||||
|
||||
memset(&rank, 0, sizeof(gpRank_t));
|
||||
rank.skin = players[consoleplayer].skin;
|
||||
|
|
@ -628,12 +631,7 @@ void podiumData_s::Draw(void)
|
|||
case GPEVENT_SPECIAL:
|
||||
{
|
||||
srb2::Draw drawer_emerald = drawer_gametype;
|
||||
UINT8 emeraldNum = 0;
|
||||
|
||||
if (cup != nullptr)
|
||||
{
|
||||
emeraldNum = cup->emeraldnum;
|
||||
}
|
||||
UINT8 emeraldNum = g_podiumData.emeraldnum;
|
||||
|
||||
boolean useWhiteFrame = ((leveltime & 1) || !dta->gotSpecialPrize);
|
||||
patch_t *emeraldPatch = nullptr;
|
||||
|
|
@ -844,12 +842,7 @@ void podiumData_s::Draw(void)
|
|||
|
||||
if (rank.specialWon == true)
|
||||
{
|
||||
UINT8 emeraldNum = 0;
|
||||
|
||||
if (cup != nullptr)
|
||||
{
|
||||
emeraldNum = cup->emeraldnum;
|
||||
}
|
||||
UINT8 emeraldNum = g_podiumData.emeraldnum;
|
||||
|
||||
const boolean emeraldBlink = (leveltime & 1);
|
||||
patch_t *emeraldOverlay = nullptr;
|
||||
|
|
@ -1263,6 +1256,60 @@ void K_ResetCeremony(void)
|
|||
return;
|
||||
}
|
||||
|
||||
cupheader_t *emeraldcup = NULL;
|
||||
|
||||
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|
||||
|| grandprixinfo.cup->id >= basenumkartcupheaders // custom content
|
||||
|| M_SecretUnlocked(SECRET_SPECIALATTACK, false)) // true order
|
||||
{
|
||||
// Standard order.
|
||||
emeraldcup = grandprixinfo.cup;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine order from sealedswaps.
|
||||
for (i = 0; i < GDMAX_SEALEDSWAPS; i++)
|
||||
{
|
||||
if (gamedata->sealedswaps[i] == NULL)
|
||||
{
|
||||
if (g_podiumData.rank.specialWon == true)
|
||||
{
|
||||
// First visit! Mark it off.
|
||||
gamedata->sealedswaps[i] = grandprixinfo.cup;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (gamedata->sealedswaps[i] != grandprixinfo.cup)
|
||||
continue;
|
||||
|
||||
// Repeat visit, grab the same ID.
|
||||
break;
|
||||
}
|
||||
|
||||
// If there's pending stars, apply them to the new cup order.
|
||||
if (i < GDMAX_SEALEDSWAPS)
|
||||
{
|
||||
emeraldcup = kartcupheaders;
|
||||
while (emeraldcup)
|
||||
{
|
||||
if (emeraldcup->id >= basenumkartcupheaders)
|
||||
{
|
||||
emeraldcup = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (emeraldcup->emeraldnum == i+1)
|
||||
break;
|
||||
|
||||
emeraldcup = emeraldcup->next;
|
||||
}
|
||||
|
||||
g_podiumData.emeraldnum = i+1;
|
||||
}
|
||||
}
|
||||
|
||||
// Write grade, position, and emerald-having-ness for later sessions!
|
||||
i = (grandprixinfo.masterbots) ? KARTGP_MASTER : grandprixinfo.gamespeed;
|
||||
|
||||
|
|
@ -1292,9 +1339,9 @@ void K_ResetCeremony(void)
|
|||
anymerit = true;
|
||||
}
|
||||
|
||||
if (g_podiumData.rank.specialWon == true)
|
||||
if (g_podiumData.rank.specialWon == true && emeraldcup)
|
||||
{
|
||||
grandprixinfo.cup->windata[i].got_emerald = true;
|
||||
emeraldcup->windata[i].got_emerald = true;
|
||||
anymerit = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ static UINT8 cheatf_warp(void)
|
|||
if (success)
|
||||
{
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
gamedata->sealedswapalerted = true;
|
||||
G_SetUsedCheats();
|
||||
}
|
||||
|
||||
|
|
@ -231,6 +232,7 @@ static UINT8 cheatf_devmode(void)
|
|||
}
|
||||
|
||||
gamedata->gonerlevel = GDGONER_DONE;
|
||||
gamedata->sealedswapalerted = true;
|
||||
|
||||
M_ClearMenus(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -666,6 +666,7 @@ void M_ClearStats(void)
|
|||
gamedata->majorkeyskipattempted = false;
|
||||
gamedata->enteredtutorialchallenge = false;
|
||||
gamedata->finishedtutorialchallenge = false;
|
||||
gamedata->sealedswapalerted = false;
|
||||
gamedata->musicstate = GDMUSIC_NONE;
|
||||
|
||||
gamedata->importprofilewins = false;
|
||||
|
|
@ -720,6 +721,8 @@ void M_ClearSecrets(void)
|
|||
skincolors[i].cache_spraycan = UINT16_MAX;
|
||||
}
|
||||
|
||||
memset(gamedata->sealedswaps, 0, sizeof(gamedata->sealedswaps));
|
||||
|
||||
Z_Free(gamedata->challengegrid);
|
||||
gamedata->challengegrid = NULL;
|
||||
gamedata->challengegridwidth = 0;
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ typedef enum {
|
|||
// This is the largest number of 9s that will fit in UINT32 and UINT16 respectively.
|
||||
#define GDMAX_RINGS 999999999
|
||||
#define GDMAX_CHAOKEYS 9999
|
||||
#define GDMAX_SEALEDSWAPS 7
|
||||
|
||||
#define GDCONVERT_ROUNDSTOKEY 14
|
||||
|
||||
|
|
@ -371,12 +372,15 @@ struct gamedata_t
|
|||
UINT32 totalrings;
|
||||
UINT32 totaltumbletime;
|
||||
|
||||
// Chao Key condition bypass
|
||||
// CHAO KEYS AND THEIR GENERATION
|
||||
UINT32 pendingkeyrounds;
|
||||
UINT8 pendingkeyroundoffset;
|
||||
UINT16 keyspending;
|
||||
UINT16 chaokeys;
|
||||
|
||||
// EMERALD REMAPPING
|
||||
cupheader_t *sealedswaps[GDMAX_SEALEDSWAPS];
|
||||
|
||||
// SPECIFIC SPECIAL EVENTS
|
||||
boolean everloadedaddon;
|
||||
boolean everfinishedcredits;
|
||||
|
|
@ -387,6 +391,7 @@ struct gamedata_t
|
|||
boolean majorkeyskipattempted;
|
||||
boolean enteredtutorialchallenge;
|
||||
boolean finishedtutorialchallenge;
|
||||
boolean sealedswapalerted;
|
||||
gdmusic_t musicstate;
|
||||
|
||||
UINT8 gonerlevel;
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
|||
challengesmenu.requestnew = false;
|
||||
challengesmenu.chaokeyadd = false;
|
||||
challengesmenu.keywasadded = false;
|
||||
challengesmenu.considersealedswapalert = false;
|
||||
challengesmenu.chaokeyhold = 0;
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
challengesmenu.unlockcondition = NULL;
|
||||
|
|
@ -668,10 +669,15 @@ void M_ChallengesTick(void)
|
|||
if (challengesmenu.currentunlock < MAXUNLOCKABLES
|
||||
&& challengesmenu.unlockanim == UNLOCKTIME)
|
||||
{
|
||||
unlockable_t *ref = &unlockables[challengesmenu.currentunlock];
|
||||
|
||||
// Unlock animation... also tied directly to the actual unlock!
|
||||
gamedata->unlocked[challengesmenu.currentunlock] = true;
|
||||
M_UpdateUnlockablesAndExtraEmblems(true, true);
|
||||
|
||||
if (ref->type == SECRET_SPECIALATTACK)
|
||||
challengesmenu.considersealedswapalert = true;
|
||||
|
||||
// Update shown description just in case..?
|
||||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
|
|
@ -682,12 +688,10 @@ void M_ChallengesTick(void)
|
|||
|
||||
if (challengesmenu.extradata)
|
||||
{
|
||||
unlockable_t *ref;
|
||||
UINT16 bombcolor;
|
||||
|
||||
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
|
||||
|
||||
ref = &unlockables[challengesmenu.currentunlock];
|
||||
bombcolor = SKINCOLOR_NONE;
|
||||
|
||||
if (ref->color != SKINCOLOR_NONE && ref->color < numskincolors)
|
||||
|
|
@ -747,7 +751,14 @@ void M_ChallengesTick(void)
|
|||
// Play music the moment control returns.
|
||||
M_PlayMenuJam();
|
||||
|
||||
if (gamedata->chaokeytutorial == false
|
||||
if (challengesmenu.considersealedswapalert == true
|
||||
&& M_ConsiderSealedSwapAlert() == true)
|
||||
{
|
||||
// No keygen tutorial in this case...
|
||||
// not ideal but at least unlikely to
|
||||
// get at same time?? :V
|
||||
}
|
||||
else if (gamedata->chaokeytutorial == false
|
||||
&& challengesmenu.keywasadded == true)
|
||||
{
|
||||
M_ChallengesTutorial(CCTUTORIAL_KEYGEN);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ void M_StopMessage(INT32 choice)
|
|||
|
||||
boolean M_MenuMessageTick(void)
|
||||
{
|
||||
if (menuwipe)
|
||||
return false;
|
||||
|
||||
if (menumessage.closing)
|
||||
{
|
||||
if (menumessage.closing > MENUMESSAGECLOSE)
|
||||
|
|
|
|||
|
|
@ -6284,6 +6284,14 @@ static boolean P_UnArchiveSPGame(savebuffer_t *save)
|
|||
{
|
||||
UINT32 val = READUINT32(save->p);
|
||||
|
||||
if (roundqueue.entries[i].rankrestricted && roundqueue.position != i+1)
|
||||
{
|
||||
// If this is a Sealed Star that hasn't yet been
|
||||
// reached, don't be picky about divergance. Just
|
||||
// use the base game without question. ~toast 010324
|
||||
continue;
|
||||
}
|
||||
|
||||
mapnum = roundqueue.entries[i].mapnum;
|
||||
if (mapnum < nummapheaders && mapheaderinfo[mapnum] != NULL)
|
||||
{
|
||||
|
|
|
|||
24
src/p_user.c
24
src/p_user.c
|
|
@ -296,9 +296,29 @@ UINT8 P_GetNextEmerald(void)
|
|||
{
|
||||
cupheader_t *cup = NULL;
|
||||
|
||||
if (grandprixinfo.gp == true)
|
||||
if (grandprixinfo.gp == true && grandprixinfo.cup)
|
||||
{
|
||||
cup = grandprixinfo.cup;
|
||||
if (gamedata->sealedswaps[GDMAX_SEALEDSWAPS-1] != NULL // all found
|
||||
|| grandprixinfo.cup->id >= basenumkartcupheaders // custom content
|
||||
|| M_SecretUnlocked(SECRET_SPECIALATTACK, false)) // true order
|
||||
{
|
||||
cup = grandprixinfo.cup;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine order from sealedswaps.
|
||||
UINT8 i;
|
||||
for (i = 0; (i < GDMAX_SEALEDSWAPS && gamedata->sealedswaps[i]); i++)
|
||||
{
|
||||
if (gamedata->sealedswaps[i] != grandprixinfo.cup)
|
||||
continue;
|
||||
|
||||
// Repeat visit, grab the same ID.
|
||||
break;
|
||||
}
|
||||
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cup == NULL)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue