Large Challenge Tiles can now be Key'd.

- Must have every challenge surrounding it unlocked. (CHE_ALLCLEAR, see previous commits)
- Takes 10 Chao Keys.
- Has a swag animation.

In addition:
- Replace the DEVELOP-only Z button behaviour with "add a free key", since large tiles are no longer permalocked, only expensive.
This commit is contained in:
toaster 2023-09-24 17:17:05 +01:00
parent 33dfb697bf
commit 1ce41bdfb4
2 changed files with 81 additions and 43 deletions

View file

@ -6080,46 +6080,81 @@ challengedesc:
if (offs < challengekeybarwidth)
V_DrawFadeFill(1+offs, 25, challengekeybarwidth-offs, 2, 0, 31, challengetransparentstrength);
if (challengesmenu.chaokeyhold)
if (challengesmenu.currentunlock < MAXUNLOCKABLES && challengesmenu.chaokeyhold)
{
fixed_t keyholdrotation = 0, radius = challengesgridstep;
fixed_t tilex = selectx, tiley = selecty;
if (challengesmenu.chaokeyhold < CHAOHOLD_BEGIN)
fixed_t baseradius = challengesgridstep;
boolean major = false, ending = false;
if (unlockables[challengesmenu.currentunlock].majorunlock == true)
{
radius = (challengesmenu.chaokeyhold*radius)*(FRACUNIT/CHAOHOLD_BEGIN);
keyx += challengesmenu.chaokeyhold*((selectx*FRACUNIT) - keyx)/CHAOHOLD_BEGIN;
keyy += challengesmenu.chaokeyhold*((selecty*FRACUNIT) - keyy)/CHAOHOLD_BEGIN;
major = true;
tilex += challengesgridstep/2;
tiley += challengesgridstep/2;
baseradius *= 2;
}
else
if (challengesmenu.chaokeyhold >= CHAOHOLD_MAX - CHAOHOLD_END)
{
if (challengesmenu.chaokeyhold < CHAOHOLD_MAX - CHAOHOLD_END)
ending = true;
baseradius = ((CHAOHOLD_MAX - challengesmenu.chaokeyhold)*baseradius)*(FRACUNIT/CHAOHOLD_END);
}
INT16 specifickeyholdtime = challengesmenu.chaokeyhold;
for (i = 0; i < (major ? 10 : 1); i++, specifickeyholdtime -= 4)
{
fixed_t radius = baseradius;
fixed_t thiskeyx, thiskeyy;
fixed_t keyholdrotation = 0;
if (specifickeyholdtime < CHAOHOLD_BEGIN)
{
radius <<= FRACBITS;
if (specifickeyholdtime < 0)
{
// Nothing following will be relevant
break;
}
keyholdrotation = 360 * ((challengesmenu.chaokeyhold - CHAOHOLD_BEGIN))
* (FRACUNIT/(CHAOHOLD_MAX - (CHAOHOLD_BEGIN + CHAOHOLD_END)));
INT32 time = 3 - (keyholdrotation - 1) / (90 * FRACUNIT);
if (time <= 5 && time >= 0)
V_DrawScaledPatch(selectx + 2, selecty - 2, 0, kp_eggnum[time]);
radius = (specifickeyholdtime*radius)*(FRACUNIT/CHAOHOLD_BEGIN);
thiskeyx = keyx + specifickeyholdtime*((tilex*FRACUNIT) - keyx)/CHAOHOLD_BEGIN;
thiskeyy = keyy + specifickeyholdtime*((tiley*FRACUNIT) - keyy)/CHAOHOLD_BEGIN;
}
else
{
radius = ((CHAOHOLD_MAX - challengesmenu.chaokeyhold)*radius)*(FRACUNIT/CHAOHOLD_END);
keyholdrotation = (-36 * i) * FRACUNIT;
if (ending == false)
{
radius <<= FRACBITS;
keyholdrotation += 360 * ((challengesmenu.chaokeyhold - CHAOHOLD_BEGIN))
* (FRACUNIT/(CHAOHOLD_MAX - (CHAOHOLD_BEGIN + CHAOHOLD_END)));
if (i == 0)
{
INT32 time = 3 - (keyholdrotation - 1) / (90 * FRACUNIT);
if (time <= 5 && time >= 0)
V_DrawScaledPatch(tilex + 2, tiley - 2, 0, kp_eggnum[time]);
}
}
thiskeyx = tilex*FRACUNIT;
thiskeyy = tiley*FRACUNIT;
}
keyx = selectx*FRACUNIT;
keyy = selecty*FRACUNIT;
}
if (radius != 0)
{
angle_t ang = (FixedAngle(
keyholdrotation
) >> ANGLETOFINESHIFT) & FINEMASK;
if (radius)
{
angle_t ang = (FixedAngle(
keyholdrotation
) >> ANGLETOFINESHIFT) & FINEMASK;
thiskeyx += FixedMul(radius, FINESINE(ang));
thiskeyy -= FixedMul(radius, FINECOSINE(ang));
}
keyx += FixedMul(radius, FINESINE(ang));
keyy -= FixedMul(radius, FINECOSINE(ang));
V_DrawFixedPatch(thiskeyx, thiskeyy, FRACUNIT, 0, key, NULL);
}
}

View file

@ -290,10 +290,10 @@ void M_Challenges(INT32 choice)
M_SetupNextMenu(&MISC_ChallengesDef, false);
}
static boolean M_CanKeyHiliTile(boolean devskip)
static boolean M_CanKeyHiliTile(void)
{
// No keys to do it with?
if (gamedata->chaokeys == 0 && !devskip)
if (gamedata->chaokeys == 0)
return false;
// No tile data?
@ -308,18 +308,23 @@ static boolean M_CanKeyHiliTile(boolean devskip)
if (gamedata->unlocked[challengesmenu.currentunlock] == true)
return false;
// Marked as unskippable?
if (unlockables[challengesmenu.currentunlock].majorunlock == true && !devskip)
return false;
UINT16 i = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
// Not a hinted tile OR a fresh board.
if (!(challengesmenu.extradata[i].flags & CHE_HINT)
&& (challengesmenu.unlockcount[CC_UNLOCKED] + challengesmenu.unlockcount[CC_TALLY] > 0)
&& !devskip)
&& (challengesmenu.unlockcount[CC_UNLOCKED] + challengesmenu.unlockcount[CC_TALLY] > 0))
return false;
// Marked as major?
if (unlockables[challengesmenu.currentunlock].majorunlock == true)
{
if (!(challengesmenu.extradata[i].flags & CHE_ALLCLEAR))
return false;
if (gamedata->chaokeys < 10)
return false;
}
// All good!
return true;
}
@ -370,12 +375,7 @@ void M_ChallengesTick(void)
if (challengesmenu.chaokeyhold)
{
boolean devskip = false;
#ifdef DEVELOP
devskip = M_MenuButtonHeld(pid, MBT_Z);
#endif
// A little messy, but don't freak out, this is just so devs don't crash the game on non-tiles
if ((devskip || M_MenuExtraHeld(pid)) && M_CanKeyHiliTile(devskip))
if (M_MenuExtraHeld(pid) && M_CanKeyHiliTile())
{
// Not pressed just this frame?
if (!M_MenuExtraPressed(pid))
@ -385,7 +385,8 @@ void M_ChallengesTick(void)
if (challengesmenu.chaokeyhold > CHAOHOLD_MAX)
{
#ifndef CHAOKEYDEBUG
gamedata->chaokeys--;
gamedata->chaokeys -= (unlockables[challengesmenu.currentunlock].majorunlock == true)
? 10 : 1;
#endif
challengesmenu.chaokeyhold = 0;
challengesmenu.unlockcount[CC_CHAOANIM]++;
@ -616,7 +617,7 @@ boolean M_ChallengesInputs(INT32 ch)
}
else if (M_MenuExtraPressed(pid))
{
if (M_CanKeyHiliTile(false))
if (M_CanKeyHiliTile())
{
challengesmenu.chaokeyhold = 1;
}
@ -642,7 +643,9 @@ boolean M_ChallengesInputs(INT32 ch)
#ifdef DEVELOP
else if (M_MenuButtonPressed(pid, MBT_Z))
{
challengesmenu.chaokeyhold = 1;
gamedata->chaokeys++;
challengesmenu.unlockcount[CC_CHAOANIM]++;
S_StartSound(NULL, sfx_dbgsal);
return true;
}
#endif