diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 2f1a10d91..b4ee6f974 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -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); } } diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index 4ca2363e2..df428634e 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -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