Challenges Menu: Chao Medal icon in the top right

Fills up as you complete challenges.
Unlock all Challenges without using Chao Keys on a major tile to get the Beginner Chao Medal.
Do so without using any Chao Keys at all and you get 101%, with the Challenge Chao Medal!
(This can retroactively apply if you complete the relevant tasks legitimately at a later date.)

Also makes CC_s into an enum (now prefixed with CMC_, since CC_MAX exists in a header file already).
This commit is contained in:
toaster 2023-09-28 12:28:14 +01:00
parent bd7be2dd6f
commit cf1367fb8d
3 changed files with 147 additions and 47 deletions

View file

@ -1204,13 +1204,26 @@ void M_DrawAddons(void);
#define RIGHTUNLOCKSCROLL 3
#define LEFTUNLOCKSCROLL (RIGHTUNLOCKSCROLL-1)
#define CC_TOTAL 0
#define CC_UNLOCKED 1
#define CC_PERCENT 2
#define CC_ANIM 3
#define CC_CHAOANIM 4
#define CC_CHAONOPE 5
#define CC_MAX 6
typedef enum
{
CMC_TOTAL = 0,
CMC_UNLOCKED,
CMC_KEYED,
CMC_MAJORSKIPPED,
CMC_PERCENT,
CMC_MEDALID,
CMC_MEDALBLANK,
CMC_MEDALFILLED,
CMC_ANIM,
CMC_CHAOANIM,
CMC_CHAONOPE,
CMC_MAX,
} challengesmenucount_e;
#define TILEFLIP_MAX 16
@ -1251,7 +1264,7 @@ extern struct challengesmenu_s {
boolean requestflip;
UINT16 unlockcount[CC_MAX];
UINT16 unlockcount[CMC_MAX];
UINT8 fade;
} challengesmenu;

View file

@ -5902,7 +5902,7 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
const UINT8 pid = 0;
patch_t *key = W_CachePatchName("UN_CHA00", PU_CACHE);
INT32 offs = challengesmenu.unlockcount[CC_CHAONOPE];
INT32 offs = challengesmenu.unlockcount[CMC_CHAONOPE];
if (offs & 1)
offs = -offs;
offs /= 2;
@ -5935,7 +5935,7 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
// Counter
{
INT32 textx = 4, texty = 20-challengesmenu.unlockcount[CC_CHAOANIM];
INT32 textx = 4, texty = 20-challengesmenu.unlockcount[CMC_CHAOANIM];
UINT8 numbers[4];
numbers[0] = ((gamedata->chaokeys / 100) % 10);
numbers[1] = ((gamedata->chaokeys / 10) % 10);
@ -6201,13 +6201,50 @@ challengedesc:
V_DrawLSTitleLowString(BASEVIDWIDTH/2 - offset, y+6, 0, str);
}
// Tally
// Percentage
{
INT32 textx = BASEVIDWIDTH - 24, texty = 20-challengesmenu.unlockcount[CC_ANIM];
patch_t *medal = W_CachePatchName(
va("UN_MDL%c", '0' + challengesmenu.unlockcount[CMC_MEDALID]),
PU_CACHE
);
fixed_t medalchopy = 1;
for (i = CMC_MEDALBLANK; i <= CMC_MEDALFILLED; i++)
{
if (challengesmenu.unlockcount[i] == 0)
continue;
V_SetClipRect(
0,
medalchopy << FRACBITS,
BASEVIDWIDTH << FRACBITS,
(medalchopy + challengesmenu.unlockcount[CMC_MEDALBLANK]) << FRACBITS,
0
);
UINT8 *medalcolormap = NULL;
if (i == CMC_MEDALBLANK)
{
medalcolormap = R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_MENUCACHE);
}
else if (challengesmenu.unlockcount[CMC_MEDALID] == 0)
{
medalcolormap = R_GetTranslationColormap(TC_DEFAULT, M_GetCvPlayerColor(0), GTC_MENUCACHE);
}
V_DrawFixedPatch((BASEVIDWIDTH - 32)*FRACUNIT, 1*FRACUNIT, FRACUNIT, 0, medal, medalcolormap);
V_ClearClipRect();
medalchopy += challengesmenu.unlockcount[i];
}
INT32 textx = BASEVIDWIDTH - 24, texty = 20-challengesmenu.unlockcount[CMC_ANIM];
UINT8 numbers[3];
numbers[0] = ((challengesmenu.unlockcount[CC_PERCENT] / 100) % 10);
numbers[1] = ((challengesmenu.unlockcount[CC_PERCENT] / 10) % 10);
numbers[2] = (challengesmenu.unlockcount[CC_PERCENT] % 10);
numbers[0] = ((challengesmenu.unlockcount[CMC_PERCENT] / 100) % 10);
numbers[1] = ((challengesmenu.unlockcount[CMC_PERCENT] / 10) % 10);
numbers[2] = (challengesmenu.unlockcount[CMC_PERCENT] % 10);
patch_t *percent = W_CachePatchName("K_SPDML1", PU_CACHE);

View file

@ -56,10 +56,79 @@ struct challengesmenu_s challengesmenu;
static void M_UpdateChallengeGridVisuals(void)
{
// Currently only updates the completion %.
challengesmenu.unlockcount[CC_PERCENT] =
(100 * challengesmenu.unlockcount[CC_UNLOCKED])
/challengesmenu.unlockcount[CC_TOTAL];
UINT16 i;
challengesmenu.unlockcount[CMC_UNLOCKED] = 0;
challengesmenu.unlockcount[CMC_TOTAL] = 0;
for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (!unlockables[i].conditionset)
{
continue;
}
challengesmenu.unlockcount[CMC_TOTAL]++;
if (!gamedata->unlocked[i])
{
continue;
}
challengesmenu.unlockcount[CMC_UNLOCKED]++;
if (M_Achieved(unlockables[i].conditionset - 1) == true)
{
continue;
}
challengesmenu.unlockcount[CMC_KEYED]++;
if (unlockables[i].majorunlock == false)
{
continue;
}
challengesmenu.unlockcount[CMC_MAJORSKIPPED]++;
}
challengesmenu.unlockcount[CMC_PERCENT] =
(100 * challengesmenu.unlockcount[CMC_UNLOCKED])
/challengesmenu.unlockcount[CMC_TOTAL];
#define medalheight (19)
challengesmenu.unlockcount[CMC_MEDALID] = 0;
if (challengesmenu.unlockcount[CMC_PERCENT] == 100)
{
challengesmenu.unlockcount[CMC_MEDALFILLED] = medalheight;
if (challengesmenu.unlockcount[CMC_KEYED] == 0)
{
challengesmenu.unlockcount[CMC_MEDALID] = 2;
challengesmenu.unlockcount[CMC_PERCENT]++; // 101%
}
else if (challengesmenu.unlockcount[CMC_MAJORSKIPPED] == 0)
{
challengesmenu.unlockcount[CMC_MEDALID] = 1;
}
}
else
{
challengesmenu.unlockcount[CMC_MEDALFILLED] =
(medalheight * challengesmenu.unlockcount[CMC_UNLOCKED])
/challengesmenu.unlockcount[CMC_TOTAL];
if (challengesmenu.unlockcount[CMC_MEDALFILLED] == 0 && challengesmenu.unlockcount[CMC_UNLOCKED] != 0)
{
// Cheat to give you a sliver of pixel.
challengesmenu.unlockcount[CMC_MEDALFILLED] = 1;
}
}
challengesmenu.unlockcount[CMC_MEDALBLANK] =
medalheight - challengesmenu.unlockcount[CMC_MEDALFILLED];
}
static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
@ -218,7 +287,7 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
{
UINT16 i, newunlock;
UINT16 newunlock;
if (Playing())
return desiredmenu;
@ -254,22 +323,6 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
memset(setup_explosions, 0, sizeof(setup_explosions));
memset(&challengesmenu.unlockcount, 0, sizeof(challengesmenu.unlockcount));
for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (!unlockables[i].conditionset)
{
continue;
}
challengesmenu.unlockcount[CC_TOTAL]++;
if (!gamedata->unlocked[i])
{
continue;
}
challengesmenu.unlockcount[CC_UNLOCKED]++;
}
M_UpdateChallengeGridVisuals();
@ -322,7 +375,7 @@ static boolean M_CanKeyHiliTile(void)
// Not a hinted tile OR a fresh board.
if (!(challengesmenu.extradata[i].flags & CHE_HINT)
&& (challengesmenu.unlockcount[CC_UNLOCKED] > 0))
&& (challengesmenu.unlockcount[CMC_UNLOCKED] > 0))
return false;
// Marked as major?
@ -353,7 +406,7 @@ void M_ChallengesTick(void)
if (setup_explosions[i].tics > 0)
setup_explosions[i].tics--;
}
for (i = CC_ANIM; i < CC_MAX; i++)
for (i = CMC_ANIM; i < CMC_MAX; i++)
{
if (challengesmenu.unlockcount[i] > 0)
challengesmenu.unlockcount[i]--;
@ -406,7 +459,7 @@ void M_ChallengesTick(void)
? 10 : 1;
#endif
challengesmenu.chaokeyhold = 0;
challengesmenu.unlockcount[CC_CHAOANIM]++;
challengesmenu.unlockcount[CMC_CHAOANIM]++;
S_StartSound(NULL, sfx_chchng);
@ -419,7 +472,7 @@ void M_ChallengesTick(void)
else
{
challengesmenu.chaokeyhold = 0;
challengesmenu.unlockcount[CC_CHAONOPE] = 6;
challengesmenu.unlockcount[CMC_CHAONOPE] = 6;
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2
}
}
@ -479,7 +532,7 @@ void M_ChallengesTick(void)
S_StartSound(NULL, sfx_achiev);
gamedata->keyspending--;
gamedata->chaokeys++;
challengesmenu.unlockcount[CC_CHAOANIM]++;
challengesmenu.unlockcount[CMC_CHAOANIM]++;
if (gamedata->musicstate < GDMUSIC_KEYG)
gamedata->musicstate = GDMUSIC_KEYG;
@ -529,11 +582,9 @@ void M_ChallengesTick(void)
if (challengesmenu.unlockcondition)
Z_Free(challengesmenu.unlockcondition);
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
challengesmenu.unlockcount[CC_UNLOCKED]++;
M_UpdateChallengeGridVisuals();
challengesmenu.unlockcount[CC_ANIM]++;
challengesmenu.unlockcount[CMC_ANIM]++;
if (challengesmenu.extradata)
{
@ -626,7 +677,7 @@ boolean M_ChallengesInputs(INT32 ch)
}
else
{
challengesmenu.unlockcount[CC_CHAONOPE] = 6;
challengesmenu.unlockcount[CMC_CHAONOPE] = 6;
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kb2
#ifdef CHAOKEYDEBUG
@ -634,7 +685,6 @@ boolean M_ChallengesInputs(INT32 ch)
{
gamedata->unlocked[challengesmenu.currentunlock] = gamedata->unlockpending[challengesmenu.currentunlock] = false;
challengesmenu.unlockcount[CC_UNLOCKED]--;
M_UpdateChallengeGridVisuals();
}
#endif
@ -645,7 +695,7 @@ boolean M_ChallengesInputs(INT32 ch)
else if (M_MenuButtonPressed(pid, MBT_Z))
{
gamedata->chaokeys++;
challengesmenu.unlockcount[CC_CHAOANIM]++;
challengesmenu.unlockcount[CMC_CHAOANIM]++;
S_StartSound(NULL, sfx_dbgsal);
return true;
}