mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Minimum viable product of Chao Keys condition bypass
- Start with 3, per Sakurai's prior art.
- Earn them per certain number of rounds
- DEVELOP builds: once every 4 rounds
- Release builds: once every 50 rounds
- Has an internal cap based on the maximum number of unlockables supported.
- Possible future work could adjust this to restrict based on the maximum number of unlockables unlocks.pk3 actually has set.
- Use on the Challenges screen to bust open small tiles with hints (or the very first tile, if you haven't unlocked anything yet).
- Will do a funny shake if you try anything else.
- Interrupts menu flow just like getting an unlock.
- The matches you've played will tick upwards, giving you keys as they loop over.
This commit is contained in:
parent
328ab0059a
commit
8b437d5a32
6 changed files with 237 additions and 78 deletions
20
src/g_game.c
20
src/g_game.c
|
|
@ -4141,6 +4141,7 @@ static void G_DoCompleted(void)
|
||||||
roundtype = GDGT_SPECIAL;
|
roundtype = GDGT_SPECIAL;
|
||||||
|
|
||||||
gamedata->roundsplayed[roundtype]++;
|
gamedata->roundsplayed[roundtype]++;
|
||||||
|
gamedata->pendingkeyrounds++;
|
||||||
|
|
||||||
// Done before forced addition of PF_NOCONTEST to make UCRP_NOCONTEST harder to achieve
|
// Done before forced addition of PF_NOCONTEST to make UCRP_NOCONTEST harder to achieve
|
||||||
M_UpdateUnlockablesAndExtraEmblems(true);
|
M_UpdateUnlockablesAndExtraEmblems(true);
|
||||||
|
|
@ -4562,6 +4563,12 @@ void G_LoadGameData(void)
|
||||||
gamedata->roundsplayed[i] = READUINT32(save.p);
|
gamedata->roundsplayed[i] = READUINT32(save.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gamedata->pendingkeyrounds = READUINT32(save.p);
|
||||||
|
gamedata->pendingkeyroundoffset = READUINT8(save.p);
|
||||||
|
gamedata->keyspending = READUINT8(save.p);
|
||||||
|
gamedata->chaokeys = READUINT8(save.p);
|
||||||
|
gamedata->usedkeys = READUINT8(save.p);
|
||||||
|
|
||||||
gamedata->crashflags = READUINT8(save.p);
|
gamedata->crashflags = READUINT8(save.p);
|
||||||
if (gamedata->crashflags & GDCRASH_LAST)
|
if (gamedata->crashflags & GDCRASH_LAST)
|
||||||
gamedata->crashflags |= GDCRASH_ANY;
|
gamedata->crashflags |= GDCRASH_ANY;
|
||||||
|
|
@ -4740,7 +4747,12 @@ void G_SaveGameData(boolean dirty)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = (4+1+4+4+(4*GDGT_MAX)+1+1+4+(MAXEMBLEMS+(MAXUNLOCKABLES*2)+MAXCONDITIONSETS)+4+4+2);
|
length = (4+1+4+4+
|
||||||
|
(4*GDGT_MAX)+
|
||||||
|
4+1+1+1+1+
|
||||||
|
1+1+4+
|
||||||
|
(MAXEMBLEMS+(MAXUNLOCKABLES*2)+MAXCONDITIONSETS)+
|
||||||
|
4+4+2);
|
||||||
if (gamedata->challengegrid)
|
if (gamedata->challengegrid)
|
||||||
{
|
{
|
||||||
length += gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT;
|
length += gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT;
|
||||||
|
|
@ -4765,6 +4777,12 @@ void G_SaveGameData(boolean dirty)
|
||||||
WRITEUINT32(save.p, gamedata->roundsplayed[i]);
|
WRITEUINT32(save.p, gamedata->roundsplayed[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITEUINT32(save.p, gamedata->pendingkeyrounds); // 4
|
||||||
|
WRITEUINT8(save.p, gamedata->pendingkeyroundoffset); // 1
|
||||||
|
WRITEUINT8(save.p, gamedata->keyspending); // 1
|
||||||
|
WRITEUINT8(save.p, gamedata->chaokeys); // 1
|
||||||
|
WRITEUINT8(save.p, gamedata->usedkeys); // 1
|
||||||
|
|
||||||
{
|
{
|
||||||
UINT8 crashflags = (gamedata->crashflags & GDCRASH_ANY);
|
UINT8 crashflags = (gamedata->crashflags & GDCRASH_ANY);
|
||||||
if (dirty)
|
if (dirty)
|
||||||
|
|
|
||||||
|
|
@ -1144,7 +1144,9 @@ void M_DrawAddons(void);
|
||||||
#define CC_UNLOCKED 1
|
#define CC_UNLOCKED 1
|
||||||
#define CC_TALLY 2
|
#define CC_TALLY 2
|
||||||
#define CC_ANIM 3
|
#define CC_ANIM 3
|
||||||
#define CC_MAX 4
|
#define CC_CHAOANIM 4
|
||||||
|
#define CC_CHAONOPE 5
|
||||||
|
#define CC_MAX 6
|
||||||
|
|
||||||
#define TILEFLIP_MAX 16
|
#define TILEFLIP_MAX 16
|
||||||
|
|
||||||
|
|
@ -1155,7 +1157,6 @@ extern struct timeattackmenu_s {
|
||||||
|
|
||||||
} timeattackmenu;
|
} timeattackmenu;
|
||||||
|
|
||||||
|
|
||||||
// Keep track of some pause menu data for visual goodness.
|
// Keep track of some pause menu data for visual goodness.
|
||||||
extern struct challengesmenu_s {
|
extern struct challengesmenu_s {
|
||||||
|
|
||||||
|
|
@ -1174,6 +1175,7 @@ extern struct challengesmenu_s {
|
||||||
|
|
||||||
boolean pending;
|
boolean pending;
|
||||||
boolean requestnew;
|
boolean requestnew;
|
||||||
|
boolean chaokeyadd;
|
||||||
|
|
||||||
boolean requestflip;
|
boolean requestflip;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5170,6 +5170,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
||||||
|
|
||||||
#define challengetransparentstrength 8
|
#define challengetransparentstrength 8
|
||||||
#define challengesgridstep 22
|
#define challengesgridstep 22
|
||||||
|
#define challengekeybarwidth 50
|
||||||
|
|
||||||
void M_DrawChallenges(void)
|
void M_DrawChallenges(void)
|
||||||
{
|
{
|
||||||
|
|
@ -5293,6 +5294,26 @@ void M_DrawChallenges(void)
|
||||||
|
|
||||||
challengedesc:
|
challengedesc:
|
||||||
|
|
||||||
|
// Chao Keys
|
||||||
|
{
|
||||||
|
patch_t *key = W_CachePatchName("UN_CHA00", PU_CACHE);
|
||||||
|
INT32 offs = challengesmenu.unlockcount[CC_CHAONOPE];
|
||||||
|
if (offs & 1)
|
||||||
|
offs = -offs;
|
||||||
|
offs /= 2;
|
||||||
|
V_DrawFixedPatch((6+offs)*FRACUNIT, 5*FRACUNIT, FRACUNIT, 0, key, NULL);
|
||||||
|
V_DrawKartString((25+offs), 9-challengesmenu.unlockcount[CC_CHAOANIM], 0, va("%u", gamedata->chaokeys));
|
||||||
|
|
||||||
|
offs = challengekeybarwidth;
|
||||||
|
if ((gamedata->chaokeys + gamedata->usedkeys) < GDMAX_CHAOKEYS)
|
||||||
|
offs = ((gamedata->pendingkeyroundoffset * challengekeybarwidth)/GDCONVERT_ROUNDSTOKEY);
|
||||||
|
|
||||||
|
if (offs > 0)
|
||||||
|
V_DrawFill(1, 25, offs, 2, 0);
|
||||||
|
if (offs < challengekeybarwidth)
|
||||||
|
V_DrawFadeFill(1+offs, 25, challengekeybarwidth-offs, 2, 0, 31, challengetransparentstrength);
|
||||||
|
}
|
||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
{
|
{
|
||||||
str = va("%d/%d",
|
str = va("%d/%d",
|
||||||
|
|
@ -5347,6 +5368,7 @@ challengedesc:
|
||||||
|
|
||||||
#undef challengetransparentstrength
|
#undef challengetransparentstrength
|
||||||
#undef challengesgridstep
|
#undef challengesgridstep
|
||||||
|
#undef challengekeybarwidth
|
||||||
|
|
||||||
// Statistics menu
|
// Statistics menu
|
||||||
|
|
||||||
|
|
|
||||||
30
src/m_cond.c
30
src/m_cond.c
|
|
@ -548,6 +548,12 @@ void M_ClearSecrets(void)
|
||||||
Z_Free(gamedata->challengegrid);
|
Z_Free(gamedata->challengegrid);
|
||||||
gamedata->challengegrid = NULL;
|
gamedata->challengegrid = NULL;
|
||||||
gamedata->challengegridwidth = 0;
|
gamedata->challengegridwidth = 0;
|
||||||
|
|
||||||
|
gamedata->pendingkeyrounds = 0;
|
||||||
|
gamedata->pendingkeyroundoffset = 0;
|
||||||
|
gamedata->keyspending = 0;
|
||||||
|
gamedata->chaokeys = 3; // Start with 3 !!
|
||||||
|
gamedata->usedkeys = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
@ -1336,8 +1342,7 @@ static boolean M_CheckUnlockConditions(player_t *player)
|
||||||
|
|
||||||
boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||||
{
|
{
|
||||||
INT32 i;
|
UINT16 i = 0, response = 0, newkeys = 0;
|
||||||
UINT8 response = 0;
|
|
||||||
|
|
||||||
if (!gamedata)
|
if (!gamedata)
|
||||||
{
|
{
|
||||||
|
|
@ -1355,6 +1360,14 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||||
|
|
||||||
response = M_CheckUnlockConditions(NULL);
|
response = M_CheckUnlockConditions(NULL);
|
||||||
|
|
||||||
|
while ((gamedata->keyspending + gamedata->chaokeys + gamedata->usedkeys) < GDMAX_CHAOKEYS
|
||||||
|
&& ((gamedata->pendingkeyrounds + gamedata->pendingkeyroundoffset)/GDCONVERT_ROUNDSTOKEY) > gamedata->keyspending)
|
||||||
|
{
|
||||||
|
gamedata->keyspending++;
|
||||||
|
newkeys++;
|
||||||
|
response |= true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!demo.playback && Playing() && (gamestate == GS_LEVEL))
|
if (!demo.playback && Playing() && (gamestate == GS_LEVEL))
|
||||||
{
|
{
|
||||||
for (i = 0; i <= splitscreen; i++)
|
for (i = 0; i <= splitscreen; i++)
|
||||||
|
|
@ -1367,7 +1380,7 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response && loud)
|
if (loud && response == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1397,8 +1410,10 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||||
response++;
|
response++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response += newkeys;
|
||||||
|
|
||||||
// Announce
|
// Announce
|
||||||
if (response)
|
if (response != 0)
|
||||||
{
|
{
|
||||||
if (loud)
|
if (loud)
|
||||||
{
|
{
|
||||||
|
|
@ -1409,7 +1424,7 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 M_GetNextAchievedUnlock(void)
|
UINT16 M_GetNextAchievedUnlock(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
|
|
@ -1434,6 +1449,11 @@ UINT8 M_GetNextAchievedUnlock(void)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gamedata->keyspending > 0)
|
||||||
|
{
|
||||||
|
return PENDING_CHAOKEYS;
|
||||||
|
}
|
||||||
|
|
||||||
return MAXUNLOCKABLES;
|
return MAXUNLOCKABLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
19
src/m_cond.h
19
src/m_cond.h
|
|
@ -207,6 +207,13 @@ typedef enum
|
||||||
|
|
||||||
// This is the largest number of 9s that will fit in UINT32.
|
// This is the largest number of 9s that will fit in UINT32.
|
||||||
#define GDMAX_RINGS 999999999
|
#define GDMAX_RINGS 999999999
|
||||||
|
#define GDMAX_CHAOKEYS MAXUNLOCKABLES
|
||||||
|
|
||||||
|
#ifdef DEVELOP
|
||||||
|
#define GDCONVERT_ROUNDSTOKEY 4
|
||||||
|
#else
|
||||||
|
#define GDCONVERT_ROUNDSTOKEY 50
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GDGT_RACE,
|
GDGT_RACE,
|
||||||
|
|
@ -247,6 +254,13 @@ struct gamedata_t
|
||||||
UINT32 roundsplayed[GDGT_MAX];
|
UINT32 roundsplayed[GDGT_MAX];
|
||||||
UINT32 totalrings;
|
UINT32 totalrings;
|
||||||
|
|
||||||
|
// Chao Key condition bypass
|
||||||
|
UINT32 pendingkeyrounds;
|
||||||
|
UINT8 pendingkeyroundoffset;
|
||||||
|
UINT8 keyspending;
|
||||||
|
UINT8 chaokeys;
|
||||||
|
UINT8 usedkeys;
|
||||||
|
|
||||||
// SPECIFIC SPECIAL EVENTS
|
// SPECIFIC SPECIAL EVENTS
|
||||||
boolean everloadedaddon;
|
boolean everloadedaddon;
|
||||||
UINT8 crashflags;
|
UINT8 crashflags;
|
||||||
|
|
@ -297,7 +311,10 @@ void M_ClearStats(void);
|
||||||
// Updating conditions and unlockables
|
// Updating conditions and unlockables
|
||||||
boolean M_CheckCondition(condition_t *cn, player_t *player);
|
boolean M_CheckCondition(condition_t *cn, player_t *player);
|
||||||
boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud);
|
boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud);
|
||||||
UINT8 M_GetNextAchievedUnlock(void);
|
|
||||||
|
#define PENDING_CHAOKEYS (UINT16_MAX-1)
|
||||||
|
UINT16 M_GetNextAchievedUnlock(void);
|
||||||
|
|
||||||
UINT8 M_CheckLevelEmblems(void);
|
UINT8 M_CheckLevelEmblems(void);
|
||||||
UINT8 M_CompletionEmblems(void);
|
UINT8 M_CompletionEmblems(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,17 +49,59 @@ menu_t MISC_StatisticsDef = {
|
||||||
|
|
||||||
struct challengesmenu_s challengesmenu;
|
struct challengesmenu_s challengesmenu;
|
||||||
|
|
||||||
static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
|
static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
SINT8 work;
|
SINT8 work;
|
||||||
|
|
||||||
|
if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
|
||||||
|
&& ((gamedata->chaokeys + gamedata->usedkeys) < GDMAX_CHAOKEYS))
|
||||||
|
challengesmenu.chaokeyadd = true;
|
||||||
|
|
||||||
|
if (fresh && unlockid >= MAXUNLOCKABLES)
|
||||||
|
{
|
||||||
|
UINT8 selection[MAXUNLOCKABLES];
|
||||||
|
UINT8 numunlocks = 0;
|
||||||
|
|
||||||
|
// Get a random available unlockable.
|
||||||
|
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||||
|
{
|
||||||
|
if (!unlockables[i].conditionset)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gamedata->unlocked[i])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
selection[numunlocks++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!numunlocks)
|
||||||
|
{
|
||||||
|
// ...OK, get a random unlockable.
|
||||||
|
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||||
|
{
|
||||||
|
if (!unlockables[i].conditionset)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
selection[numunlocks++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unlockid = selection[M_RandomKey(numunlocks)];
|
||||||
|
}
|
||||||
|
|
||||||
if (unlockid >= MAXUNLOCKABLES)
|
if (unlockid >= MAXUNLOCKABLES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
challengesmenu.currentunlock = unlockid;
|
challengesmenu.currentunlock = unlockid;
|
||||||
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
||||||
challengesmenu.unlockanim = 0;
|
challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME);
|
||||||
|
|
||||||
if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL)
|
if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
@ -161,12 +203,13 @@ static void M_ChallengesAutoFocus(UINT8 unlockid, boolean fresh)
|
||||||
|
|
||||||
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT16 i, newunlock;
|
||||||
UINT16 newunlock = M_GetNextAchievedUnlock();
|
|
||||||
|
|
||||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||||
|
|
||||||
if ((challengesmenu.pending = (newunlock < MAXUNLOCKABLES)))
|
newunlock = M_GetNextAchievedUnlock();
|
||||||
|
|
||||||
|
if ((challengesmenu.pending = (newunlock != MAXUNLOCKABLES)))
|
||||||
{
|
{
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
MISC_ChallengesDef.prevMenu = desiredmenu;
|
MISC_ChallengesDef.prevMenu = desiredmenu;
|
||||||
|
|
@ -177,6 +220,7 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||||
challengesmenu.ticker = 0;
|
challengesmenu.ticker = 0;
|
||||||
challengesmenu.requestflip = false;
|
challengesmenu.requestflip = false;
|
||||||
challengesmenu.requestnew = false;
|
challengesmenu.requestnew = false;
|
||||||
|
challengesmenu.chaokeyadd = false;
|
||||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||||
challengesmenu.unlockcondition = NULL;
|
challengesmenu.unlockcondition = NULL;
|
||||||
|
|
||||||
|
|
@ -210,6 +254,9 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||||
|
|
||||||
if (challengesmenu.pending)
|
if (challengesmenu.pending)
|
||||||
M_ChallengesAutoFocus(newunlock, true);
|
M_ChallengesAutoFocus(newunlock, true);
|
||||||
|
else if (newunlock >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
|
||||||
|
&& ((gamedata->chaokeys + gamedata->usedkeys) < GDMAX_CHAOKEYS))
|
||||||
|
challengesmenu.chaokeyadd = true;
|
||||||
|
|
||||||
return &MISC_ChallengesDef;
|
return &MISC_ChallengesDef;
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +266,6 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||||
|
|
||||||
void M_Challenges(INT32 choice)
|
void M_Challenges(INT32 choice)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
||||||
M_InterruptMenuWithChallenges(NULL);
|
M_InterruptMenuWithChallenges(NULL);
|
||||||
|
|
@ -227,40 +273,7 @@ void M_Challenges(INT32 choice)
|
||||||
|
|
||||||
if (gamedata->challengegrid != NULL && !challengesmenu.pending)
|
if (gamedata->challengegrid != NULL && !challengesmenu.pending)
|
||||||
{
|
{
|
||||||
UINT8 selection[MAXUNLOCKABLES];
|
M_ChallengesAutoFocus(UINT16_MAX, true);
|
||||||
UINT8 numunlocks = 0;
|
|
||||||
|
|
||||||
// Get a random available unlockable.
|
|
||||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
|
||||||
{
|
|
||||||
if (!unlockables[i].conditionset)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gamedata->unlocked[i])
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
selection[numunlocks++] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!numunlocks)
|
|
||||||
{
|
|
||||||
// ...OK, get a random unlockable.
|
|
||||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
|
||||||
{
|
|
||||||
if (!unlockables[i].conditionset)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
selection[numunlocks++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
M_ChallengesAutoFocus(selection[M_RandomKey(numunlocks)], true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
M_SetupNextMenu(&MISC_ChallengesDef, false);
|
M_SetupNextMenu(&MISC_ChallengesDef, false);
|
||||||
|
|
@ -270,7 +283,7 @@ void M_ChallengesTick(void)
|
||||||
{
|
{
|
||||||
const UINT8 pid = 0;
|
const UINT8 pid = 0;
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
UINT8 newunlock = MAXUNLOCKABLES;
|
UINT16 newunlock = MAXUNLOCKABLES;
|
||||||
|
|
||||||
// Ticking
|
// Ticking
|
||||||
challengesmenu.ticker++;
|
challengesmenu.ticker++;
|
||||||
|
|
@ -280,8 +293,11 @@ void M_ChallengesTick(void)
|
||||||
if (setup_explosions[i].tics > 0)
|
if (setup_explosions[i].tics > 0)
|
||||||
setup_explosions[i].tics--;
|
setup_explosions[i].tics--;
|
||||||
}
|
}
|
||||||
if (challengesmenu.unlockcount[CC_ANIM] > 0)
|
for (i = CC_ANIM; i < CC_MAX; i++)
|
||||||
challengesmenu.unlockcount[CC_ANIM]--;
|
{
|
||||||
|
if (challengesmenu.unlockcount[i] > 0)
|
||||||
|
challengesmenu.unlockcount[i]--;
|
||||||
|
}
|
||||||
M_CupSelectTick();
|
M_CupSelectTick();
|
||||||
|
|
||||||
// Update tile flip state.
|
// Update tile flip state.
|
||||||
|
|
@ -307,15 +323,46 @@ void M_ChallengesTick(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (challengesmenu.pending)
|
if (challengesmenu.chaokeyadd == true)
|
||||||
{
|
{
|
||||||
// Pending mode.
|
if (challengesmenu.ticker <= 5)
|
||||||
|
; // recreate the slight delay the unlock fades provide
|
||||||
|
else if (gamedata->pendingkeyrounds == 0)
|
||||||
|
{
|
||||||
|
challengesmenu.chaokeyadd = false;
|
||||||
|
challengesmenu.requestnew = true;
|
||||||
|
}
|
||||||
|
else if ((gamedata->chaokeys + gamedata->usedkeys) >= GDMAX_CHAOKEYS)
|
||||||
|
{
|
||||||
|
gamedata->keyspending = 0;
|
||||||
|
gamedata->pendingkeyrounds = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(--gamedata->pendingkeyrounds & 1))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_ptally);
|
||||||
|
}
|
||||||
|
|
||||||
if (challengesmenu.requestnew)
|
if (++gamedata->pendingkeyroundoffset >= GDCONVERT_ROUNDSTOKEY)
|
||||||
|
{
|
||||||
|
gamedata->pendingkeyroundoffset %= GDCONVERT_ROUNDSTOKEY;
|
||||||
|
|
||||||
|
if (gamedata->keyspending > 0)
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_achiev);
|
||||||
|
gamedata->keyspending--;
|
||||||
|
gamedata->chaokeys++;
|
||||||
|
challengesmenu.unlockcount[CC_CHAOANIM]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (challengesmenu.requestnew)
|
||||||
{
|
{
|
||||||
// The menu apparatus is requesting a new unlock.
|
// The menu apparatus is requesting a new unlock.
|
||||||
challengesmenu.requestnew = false;
|
challengesmenu.requestnew = false;
|
||||||
if ((newunlock = M_GetNextAchievedUnlock()) < MAXUNLOCKABLES)
|
if ((newunlock = M_GetNextAchievedUnlock()) != MAXUNLOCKABLES)
|
||||||
{
|
{
|
||||||
// We got one!
|
// We got one!
|
||||||
M_ChallengesAutoFocus(newunlock, false);
|
M_ChallengesAutoFocus(newunlock, false);
|
||||||
|
|
@ -323,11 +370,14 @@ void M_ChallengesTick(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// All done! Let's save the unlocks we've busted open.
|
// All done! Let's save the unlocks we've busted open.
|
||||||
challengesmenu.pending = false;
|
challengesmenu.pending = challengesmenu.chaokeyadd = false;
|
||||||
G_SaveGameData(true);
|
G_SaveGameData(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (challengesmenu.fade < 5)
|
else if (challengesmenu.pending)
|
||||||
|
{
|
||||||
|
// Pending mode.
|
||||||
|
if (challengesmenu.fade < 5)
|
||||||
{
|
{
|
||||||
// Fade increase.
|
// Fade increase.
|
||||||
challengesmenu.fade++;
|
challengesmenu.fade++;
|
||||||
|
|
@ -441,28 +491,58 @@ boolean M_ChallengesInputs(INT32 ch)
|
||||||
const boolean move = (menucmd[pid].dpad_ud != 0 || menucmd[pid].dpad_lr != 0);
|
const boolean move = (menucmd[pid].dpad_ud != 0 || menucmd[pid].dpad_lr != 0);
|
||||||
(void) ch;
|
(void) ch;
|
||||||
|
|
||||||
if (challengesmenu.fade)
|
if (challengesmenu.fade || challengesmenu.chaokeyadd)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
#ifdef DEVELOP
|
else if (M_MenuExtraPressed(pid)
|
||||||
else if (M_MenuExtraPressed(pid) && challengesmenu.extradata) // debugging
|
&& challengesmenu.extradata)
|
||||||
{
|
{
|
||||||
|
i = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
|
||||||
|
|
||||||
|
if (challengesmenu.currentunlock < MAXUNLOCKABLES
|
||||||
|
&& !gamedata->unlocked[challengesmenu.currentunlock]
|
||||||
|
&& !unlockables[challengesmenu.currentunlock].majorunlock
|
||||||
|
&& ((challengesmenu.extradata[i].flags & CHE_HINT)
|
||||||
|
|| (challengesmenu.unlockcount[CC_UNLOCKED] + challengesmenu.unlockcount[CC_TALLY] == 0))
|
||||||
|
&& gamedata->chaokeys > 0)
|
||||||
|
{
|
||||||
|
gamedata->chaokeys--;
|
||||||
|
gamedata->usedkeys++;
|
||||||
|
challengesmenu.unlockcount[CC_CHAOANIM]++;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_chchng);
|
||||||
|
|
||||||
|
challengesmenu.pending = true;
|
||||||
|
M_ChallengesAutoFocus(challengesmenu.currentunlock, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
challengesmenu.unlockcount[CC_CHAONOPE] = 6;
|
||||||
|
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2
|
||||||
|
#if 0 // debugging
|
||||||
if (challengesmenu.currentunlock < MAXUNLOCKABLES)
|
if (challengesmenu.currentunlock < MAXUNLOCKABLES)
|
||||||
{
|
{
|
||||||
|
if (gamedata->unlocked[challengesmenu.currentunlock] && challengesmenu.unlockanim >= UNLOCKTIME)
|
||||||
|
{
|
||||||
|
if (challengesmenu.unlockcount[CC_TALLY] > 0)
|
||||||
|
challengesmenu.unlockcount[CC_TALLY]--;
|
||||||
|
else
|
||||||
|
challengesmenu.unlockcount[CC_UNLOCKED]--;
|
||||||
|
}
|
||||||
|
|
||||||
Z_Free(gamedata->challengegrid);
|
Z_Free(gamedata->challengegrid);
|
||||||
gamedata->challengegrid = NULL;
|
gamedata->challengegrid = NULL;
|
||||||
gamedata->challengegridwidth = 0;
|
gamedata->challengegridwidth = 0;
|
||||||
M_PopulateChallengeGrid();
|
M_PopulateChallengeGrid();
|
||||||
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
|
M_UpdateChallengeGridExtraData(challengesmenu.extradata);
|
||||||
|
|
||||||
M_ChallengesAutoFocus(challengesmenu.currentunlock, true);
|
|
||||||
|
|
||||||
challengesmenu.pending = true;
|
challengesmenu.pending = true;
|
||||||
|
M_ChallengesAutoFocus(challengesmenu.currentunlock, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (M_MenuBackPressed(pid) || start)
|
if (M_MenuBackPressed(pid) || start)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue