mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'challenge-final' into 'master'
Challenge Final See merge request KartKrew/Kart!2140
This commit is contained in:
commit
bca0b48f45
10 changed files with 291 additions and 47 deletions
|
|
@ -3928,6 +3928,7 @@ void SV_StopServer(void)
|
|||
maketic = gametic+1;
|
||||
neededtic = maketic;
|
||||
serverrunning = false;
|
||||
titlemapinaction = false;
|
||||
}
|
||||
|
||||
// called at singleplayer start and stopdemo
|
||||
|
|
|
|||
|
|
@ -3088,6 +3088,7 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
else if ((offset=0) || fastcmp(params[0], "FINISHCOOL")
|
||||
|| (++offset && fastcmp(params[0], "FINISHPERFECT"))
|
||||
|| (++offset && fastcmp(params[0], "FINISHALLPRISONS"))
|
||||
|| (++offset && fastcmp(params[0], "SURVIVE"))
|
||||
|| (++offset && fastcmp(params[0], "NOCONTEST"))
|
||||
|| (++offset && fastcmp(params[0], "SMASHUFO"))
|
||||
|| (++offset && fastcmp(params[0], "CHASEDBYSPB")))
|
||||
|
|
|
|||
173
src/k_menudraw.c
173
src/k_menudraw.c
|
|
@ -2837,7 +2837,7 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
|
|||
|
||||
if (levelsearch->cup == &dummy_lostandfound)
|
||||
{
|
||||
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, y+6, 0, "Lost and Found");
|
||||
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, y+6, 0, "Lost & Found");
|
||||
}
|
||||
else if (levelsearch->cup)
|
||||
{
|
||||
|
|
@ -6389,7 +6389,7 @@ void M_DrawAddons(void)
|
|||
|
||||
// Challenges Menu
|
||||
|
||||
static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili)
|
||||
static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, UINT8 *flashmap, boolean hili)
|
||||
{
|
||||
#ifdef DEVELOP
|
||||
extern consvar_t cv_debugchallenges;
|
||||
|
|
@ -6710,6 +6710,21 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
|
|||
}
|
||||
|
||||
drawborder:
|
||||
|
||||
if (num < MAXUNLOCKABLES && gamedata->unlockpending[num])
|
||||
{
|
||||
const INT32 area = (ref->majorunlock) ? 42 : 20;
|
||||
INT32 val;
|
||||
for (i = 0; i < area; i++)
|
||||
{
|
||||
val = (x + i + challengesmenu.ticker) % 40;
|
||||
if (val >= 20)
|
||||
val = 40 - val;
|
||||
val = (val + 6)/5;
|
||||
V_DrawFadeFill(x + i, y, 1, area, 0, flashmap[98 + val], 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (hili)
|
||||
{
|
||||
boolean maj = (ref != NULL && ref->majorunlock);
|
||||
|
|
@ -6719,13 +6734,11 @@ drawborder:
|
|||
buffer[7] = (skullAnimCounter/5) ? '2' : '1';
|
||||
pat = W_CachePatchName(buffer, PU_CACHE);
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, M_GetCvPlayerColor(0), GTC_MENUCACHE);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
x*FRACUNIT, y*FRACUNIT,
|
||||
FRACUNIT,
|
||||
0, pat,
|
||||
colormap
|
||||
flashmap
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -7114,6 +7127,32 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
NULL);
|
||||
break;
|
||||
}
|
||||
case SECRET_ADDONS:
|
||||
{
|
||||
V_DrawFixedPatch(28*FRACUNIT, (BASEVIDHEIGHT-28)*FRACUNIT,
|
||||
FRACUNIT,
|
||||
0, W_CachePatchName("M_ICOADD", PU_CACHE),
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
case SECRET_SOUNDTEST:
|
||||
{
|
||||
V_DrawFixedPatch(28*FRACUNIT, (BASEVIDHEIGHT-28)*FRACUNIT,
|
||||
FRACUNIT,
|
||||
0, W_CachePatchName("M_ICOSTM", PU_CACHE),
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
case SECRET_EGGTV:
|
||||
{
|
||||
V_DrawFixedPatch(3*FRACUNIT, (BASEVIDHEIGHT-40)*FRACUNIT,
|
||||
FRACUNIT,
|
||||
0, W_CachePatchName(
|
||||
va("RHTVSQN%c", (challengesmenu.ticker & 2) ? '5' : '6'),
|
||||
PU_CACHE),
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
case SECRET_ALTTITLE:
|
||||
{
|
||||
x = 8;
|
||||
|
|
@ -7282,12 +7321,14 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
|
|||
|
||||
fixed_t keyx = (8+offs)*FRACUNIT, keyy = 0;
|
||||
|
||||
const boolean keybuttonpress = (menumessage.active == false && M_MenuExtraHeld(pid) == true);
|
||||
|
||||
// Button prompt
|
||||
K_drawButton(
|
||||
24 << FRACBITS,
|
||||
16 << FRACBITS,
|
||||
0, kp_button_c[1],
|
||||
menumessage.active == false && M_MenuExtraHeld(pid) == true
|
||||
keybuttonpress
|
||||
);
|
||||
|
||||
// Metyr of rounds played that contribute to Chao Key generation
|
||||
|
|
@ -7334,6 +7375,20 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
|
|||
}
|
||||
}
|
||||
|
||||
// Hand
|
||||
if (challengesmenu.keywasadded == true)
|
||||
{
|
||||
INT32 handx = 32 + 16;
|
||||
if (keybuttonpress == false)
|
||||
{
|
||||
// Only animate if it's the focus
|
||||
handx -= (skullAnimCounter/5);
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(handx, 8, V_FLIP,
|
||||
W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||
}
|
||||
|
||||
UINT8 keysbeingused = 0;
|
||||
|
||||
// The Chao Key swooping animation
|
||||
|
|
@ -7451,6 +7506,103 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_DrawChallengeScrollBar(UINT8 *flashmap)
|
||||
{
|
||||
const INT32 bary = 4, barh = 1, hiliw = 1;
|
||||
|
||||
if (!gamedata->challengegrid || !gamedata->challengegridwidth)
|
||||
return;
|
||||
|
||||
const INT32 barlen = gamedata->challengegridwidth*hiliw;
|
||||
|
||||
INT32 barx = (BASEVIDWIDTH - barlen)/2;
|
||||
if (barlen > 200)
|
||||
{
|
||||
// TODO I DONT KNOW IF THE MATHS IS WRONG BUT WE DON'T HAVE
|
||||
// 200 COLUMNS YET SO KICKING CAN DOWN THE ROAD ~toast 190324
|
||||
INT32 shif = barlen - 200;
|
||||
barx -= (shif/2 + (shif * challengesmenu.col)/barlen);
|
||||
}
|
||||
|
||||
// bg
|
||||
V_DrawFadeFill(barx, bary, barlen, barh, 0, 31, challengetransparentstrength);
|
||||
|
||||
// This was a macro for experimentation
|
||||
#define COLTOPIX(col) (col*hiliw)
|
||||
//((col * barlen)/gamedata->challengegridwidth)
|
||||
|
||||
INT32 hilix, nextstep, i, completionamount, skiplevel;
|
||||
|
||||
// selection
|
||||
hilix = COLTOPIX(challengesmenu.col);
|
||||
V_DrawFill(barx + hilix, bary-1, hiliw, 1, 0);
|
||||
V_DrawFill(barx + hilix, bary+barh, hiliw, 1, 0);
|
||||
|
||||
INT32 mindiscouragement = 2; // skipping major unlocks is just a LITTLE cringe
|
||||
if (challengesmenu.unlockcount[CMC_PERCENT] == 100
|
||||
&& challengesmenu.unlockcount[CMC_MAJORSKIPPED] == 0)
|
||||
mindiscouragement = 1; // so someone looking for 101% isn't hunting forever
|
||||
|
||||
// unbounded so that we can do the last remaining completionamount draw
|
||||
nextstep = completionamount = skiplevel = 0;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
INT32 prevstep = nextstep;
|
||||
nextstep = (i % CHALLENGEGRIDHEIGHT);
|
||||
if (prevstep >= nextstep)
|
||||
{
|
||||
if (completionamount > 0)
|
||||
{
|
||||
if (skiplevel >= mindiscouragement && completionamount == 10)
|
||||
{
|
||||
// awareness
|
||||
completionamount--;
|
||||
}
|
||||
|
||||
V_DrawFadeFill(barx + hilix, bary, hiliw, barh, 0, 1, completionamount);
|
||||
}
|
||||
|
||||
completionamount = skiplevel = 0;
|
||||
hilix = i/CHALLENGEGRIDHEIGHT;
|
||||
hilix = COLTOPIX(hilix);
|
||||
}
|
||||
|
||||
// DO NOT DEREFERENCE gamedata->challengegrid[i] UNTIL AFTER THIS
|
||||
if (i >= gamedata->challengegridwidth*CHALLENGEGRIDHEIGHT)
|
||||
break;
|
||||
|
||||
if (gamedata->challengegrid[i] >= MAXUNLOCKABLES)
|
||||
continue;
|
||||
|
||||
if (gamedata->unlocked[gamedata->challengegrid[i]] && completionamount != -1)
|
||||
{
|
||||
completionamount += (10/CHALLENGEGRIDHEIGHT);
|
||||
|
||||
unlockable_t *ref = &unlockables[gamedata->challengegrid[i]];
|
||||
|
||||
if (skiplevel < 2 && M_Achieved(ref->conditionset - 1) == false)
|
||||
{
|
||||
skiplevel = ref->majorunlock ? 2 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (gamedata->unlockpending[gamedata->challengegrid[i]] == false)
|
||||
continue;
|
||||
|
||||
INT32 val = (hilix + challengesmenu.ticker) % 40;
|
||||
if (val >= 20)
|
||||
val = 40 - val;
|
||||
val = (val + 6)/10;
|
||||
|
||||
V_DrawFill(barx + hilix, bary, hiliw, barh, flashmap[99 + val]);
|
||||
|
||||
// The pending fill overrides everything else.
|
||||
completionamount = -1;
|
||||
}
|
||||
|
||||
#undef COLTOPIX
|
||||
}
|
||||
|
||||
void M_DrawChallenges(void)
|
||||
{
|
||||
INT32 x = currentMenu->x, explodex, selectx = 0, selecty = 0;
|
||||
|
|
@ -7503,6 +7655,8 @@ void M_DrawChallenges(void)
|
|||
goto challengedesc;
|
||||
}
|
||||
|
||||
UINT8 *flashmap = R_GetTranslationColormap(TC_DEFAULT, M_GetCvPlayerColor(0), GTC_MENUCACHE);
|
||||
|
||||
y = currentMenu->y;
|
||||
|
||||
V_DrawFadeFill(0, y-2, BASEVIDWIDTH, (challengesgridstep * CHALLENGEGRIDHEIGHT) + 2, 0, 31, challengetransparentstrength);
|
||||
|
|
@ -7556,7 +7710,7 @@ void M_DrawChallenges(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
M_DrawChallengeTile(i, j, x, y, false);
|
||||
M_DrawChallengeTile(i, j, x, y, flashmap, false);
|
||||
}
|
||||
|
||||
x -= challengesgridstep;
|
||||
|
|
@ -7571,11 +7725,14 @@ void M_DrawChallenges(void)
|
|||
if (challengesmenu.fade)
|
||||
V_DrawFadeScreen(31, challengesmenu.fade);
|
||||
|
||||
M_DrawChallengeScrollBar(flashmap);
|
||||
|
||||
M_DrawChallengeTile(
|
||||
challengesmenu.hilix,
|
||||
challengesmenu.hiliy,
|
||||
selectx,
|
||||
selecty,
|
||||
flashmap,
|
||||
true);
|
||||
M_DrawCharSelectExplosions(false, explodex, currentMenu->y);
|
||||
|
||||
|
|
@ -7881,7 +8038,7 @@ static void M_DrawStatsMaps(void)
|
|||
else if (mapheaderinfo[mnum]->cup)
|
||||
str = va("%s CUP", mapheaderinfo[mnum]->cup->realname);
|
||||
else
|
||||
str = "LOST AND FOUND";
|
||||
str = "LOST & FOUND";
|
||||
|
||||
V_DrawThinString(20, y, highlightflags, str);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -733,6 +733,14 @@ void M_StartControlPanel(void)
|
|||
{
|
||||
if (gamestate != GS_MENU)
|
||||
{
|
||||
if (titlemapinaction)
|
||||
{
|
||||
// We clear a LITTLE bit of state, but not a full D_ClearState.
|
||||
// Just enough to guarantee SV_ResetServer is called before session start.
|
||||
SV_StopServer();
|
||||
SV_ResetServer();
|
||||
}
|
||||
|
||||
G_SetGamestate(GS_MENU);
|
||||
|
||||
gameaction = ga_nothing;
|
||||
|
|
|
|||
31
src/m_cond.c
31
src/m_cond.c
|
|
@ -1125,7 +1125,7 @@ static void M_PrecacheLevelLocks(void)
|
|||
}
|
||||
|
||||
tempstr = va(
|
||||
"Music: %s Cup %c%u %c",
|
||||
"Music: %s CUP %c%u %c",
|
||||
mapheaderinfo[map]->cup->realname,
|
||||
prefix,
|
||||
positionid + 1,
|
||||
|
|
@ -1153,7 +1153,7 @@ static void M_PrecacheLevelLocks(void)
|
|||
|
||||
tempstr = va(
|
||||
"Music: %s #%u %c",
|
||||
(mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) ? "Tutorial" : "Lost and Found",
|
||||
(mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) ? "Tutorial" : "Lost & Found",
|
||||
positionid + 1,
|
||||
'A' + j // :D ?
|
||||
);
|
||||
|
|
@ -1516,8 +1516,10 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
case UC_UNLOCKPERCENT:
|
||||
{
|
||||
// Don't let netgame sessions intefere
|
||||
// (or have this give a performance hit)
|
||||
if (Playing())
|
||||
// or have this give a performance hit
|
||||
// (This is formulated this way to
|
||||
// perfectly eclipse M_CheckNetUnlockByID)
|
||||
if (netgame || demo.playback || Playing())
|
||||
return false;
|
||||
|
||||
UINT16 i, unlocked = cn->extrainfo2, total = 0;
|
||||
|
|
@ -1710,6 +1712,9 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
&& !(player->pflags & PF_NOCONTEST)
|
||||
//&& M_NotFreePlay()
|
||||
&& numtargets >= maptargets);
|
||||
case UCRP_SURVIVE:
|
||||
return (player->exiting
|
||||
&& !(player->pflags & PF_NOCONTEST));
|
||||
case UCRP_NOCONTEST:
|
||||
return (player->pflags & PF_NOCONTEST);
|
||||
|
||||
|
|
@ -2114,7 +2119,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
switch (cn->type)
|
||||
{
|
||||
case UC_PLAYTIME: // Requires total playing time >= x
|
||||
return va("play for %i:%02i:%02i",
|
||||
return va("play the game for %i:%02i:%02i",
|
||||
G_TicsToHours(cn->requirement),
|
||||
G_TicsToMinutes(cn->requirement, false),
|
||||
G_TicsToSeconds(cn->requirement));
|
||||
|
|
@ -2165,7 +2170,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
|
||||
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||
if (cn->requirement > 1)
|
||||
return va("beat game %d times", cn->requirement);
|
||||
return va("beat the game %d times", cn->requirement);
|
||||
else
|
||||
return va("beat the game");
|
||||
|
||||
|
|
@ -2316,7 +2321,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
}
|
||||
|
||||
case UC_TOTALMEDALS: // Requires number of emblems >= x
|
||||
return va("get %d medals", cn->requirement);
|
||||
return va("get %d Medals", cn->requirement);
|
||||
|
||||
case UC_EMBLEM: // Requires emblem x to be obtained
|
||||
{
|
||||
|
|
@ -2461,14 +2466,14 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
case UC_ADDON:
|
||||
if (!M_SecretUnlocked(SECRET_ADDONS, true))
|
||||
return NULL;
|
||||
return "load a custom addon into \"Dr. Robotnik's Ring Racers\"";
|
||||
return "load a custom addon";
|
||||
case UC_CREDITS:
|
||||
return "watch the developer credits all the way from start to finish";
|
||||
case UC_REPLAY:
|
||||
return "save a replay after finishing a round";
|
||||
case UC_CRASH:
|
||||
if (gamedata->evercrashed)
|
||||
return "launch \"Dr. Robotnik's Ring Racers\" again after a game crash";
|
||||
return "re-launch the game after a crash";
|
||||
return NULL;
|
||||
case UC_TUTORIALSKIP:
|
||||
return "successfully skip the Tutorial";
|
||||
|
|
@ -2626,7 +2631,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
{
|
||||
if (cup->id != cn->requirement)
|
||||
continue;
|
||||
return va("%s%s %s Cup",
|
||||
return va("%s%s %s CUP",
|
||||
completetype, orbetter,
|
||||
(M_CupLocked(cup) ? "???" : cup->realname)
|
||||
);
|
||||
|
|
@ -2650,6 +2655,8 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
return "finish a perfect round";
|
||||
case UCRP_FINISHALLPRISONS:
|
||||
return "break every Prison Egg";
|
||||
case UCRP_SURVIVE:
|
||||
return "survive";
|
||||
case UCRP_NOCONTEST:
|
||||
return "NO CONTEST";
|
||||
|
||||
|
|
@ -2875,8 +2882,8 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
{
|
||||
if (lastID != cn->id)
|
||||
{
|
||||
worklen = 4;
|
||||
strncat(message, "\nOR ", len);
|
||||
worklen = 6;
|
||||
strncat(message, " - OR ", len);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ typedef enum
|
|||
UCRP_FINISHCOOL, // Finish in good standing
|
||||
UCRP_FINISHPERFECT, // Finish a perfect race
|
||||
UCRP_FINISHALLPRISONS, // Break all prisons
|
||||
UCRP_SURVIVE, // Survive
|
||||
UCRP_NOCONTEST, // No Contest
|
||||
|
||||
UCRP_SMASHUFO, // Smash the UFO Catcher
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
|||
{
|
||||
UINT16 i;
|
||||
INT16 work;
|
||||
boolean posisvalid = false;
|
||||
|
||||
if (unlockid >= MAXUNLOCKABLES && gamedata->pendingkeyrounds > 0
|
||||
&& (gamedata->chaokeys < GDMAX_CHAOKEYS))
|
||||
|
|
@ -149,28 +150,22 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
|||
|
||||
if (fresh && unlockid >= MAXUNLOCKABLES)
|
||||
{
|
||||
UINT16 selection[MAXUNLOCKABLES];
|
||||
UINT16 numunlocks = 0;
|
||||
|
||||
// Get a random available unlockable.
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
if (challengesmenu.currentunlock < MAXUNLOCKABLES)
|
||||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!gamedata->unlocked[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
selection[numunlocks++] = i;
|
||||
// Use the last selected time.
|
||||
unlockid = challengesmenu.currentunlock;
|
||||
posisvalid = true;
|
||||
}
|
||||
|
||||
if (!numunlocks)
|
||||
else
|
||||
{
|
||||
// ...OK, get a random unlockable.
|
||||
UINT16 selection[MAXUNLOCKABLES];
|
||||
UINT16 numunlocks = 0;
|
||||
|
||||
boolean triedrandomlevel = 0;
|
||||
|
||||
tryfreshrandom:
|
||||
|
||||
// Get a random available unlockable.
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
|
|
@ -178,13 +173,43 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Otherwise we don't care, just pick any non-blank tile
|
||||
if (triedrandomlevel < 2)
|
||||
{
|
||||
// We try for any unlock second
|
||||
if (!gamedata->unlocked[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (triedrandomlevel == 0)
|
||||
{
|
||||
// We try for a pending unlock first
|
||||
if (!gamedata->unlockpending[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selection[numunlocks++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
unlockid = selection[M_RandomKey(numunlocks)];
|
||||
if (numunlocks == 0)
|
||||
{
|
||||
if (triedrandomlevel == 2)
|
||||
return;
|
||||
|
||||
triedrandomlevel++;
|
||||
goto tryfreshrandom;
|
||||
}
|
||||
|
||||
unlockid = selection[M_RandomKey(numunlocks)];
|
||||
}
|
||||
}
|
||||
|
||||
challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME);
|
||||
|
||||
if (unlockid >= MAXUNLOCKABLES)
|
||||
return;
|
||||
|
||||
|
|
@ -192,9 +217,8 @@ static void M_ChallengesAutoFocus(UINT16 unlockid, boolean fresh)
|
|||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
challengesmenu.unlockcondition = M_BuildConditionSetString(challengesmenu.currentunlock);
|
||||
challengesmenu.unlockanim = (challengesmenu.pending && !challengesmenu.chaokeyadd ? 0 : MAXUNLOCKTIME);
|
||||
|
||||
if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL)
|
||||
if (gamedata->challengegrid == NULL || challengesmenu.extradata == NULL || posisvalid)
|
||||
return;
|
||||
|
||||
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
|
||||
|
|
@ -330,6 +354,8 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
|||
|
||||
if (challengesmenu.pending || desiredmenu == NULL)
|
||||
{
|
||||
static boolean firstopen = true;
|
||||
|
||||
challengesmenu.ticker = 0;
|
||||
challengesmenu.requestflip = false;
|
||||
challengesmenu.requestnew = false;
|
||||
|
|
@ -337,9 +363,14 @@ menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
|||
challengesmenu.keywasadded = false;
|
||||
challengesmenu.considersealedswapalert = false;
|
||||
challengesmenu.chaokeyhold = 0;
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
challengesmenu.unlockcondition = NULL;
|
||||
|
||||
if (firstopen)
|
||||
{
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
firstopen = false;
|
||||
}
|
||||
|
||||
M_PopulateChallengeGrid();
|
||||
if (gamedata->challengegrid)
|
||||
{
|
||||
|
|
@ -548,6 +579,7 @@ void M_ChallengesTick(void)
|
|||
|
||||
challengesmenu.chaokeyhold = 0;
|
||||
challengesmenu.unlockcount[CMC_CHAOANIM]++;
|
||||
challengesmenu.keywasadded = false; // disappearify the Hand
|
||||
|
||||
S_StartSound(NULL, sfx_chchng);
|
||||
|
||||
|
|
@ -765,6 +797,21 @@ void M_ChallengesTick(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (challengesmenu.currentunlock < MAXUNLOCKABLES
|
||||
&& gamedata->unlockpending[challengesmenu.currentunlock] == true)
|
||||
{
|
||||
UINT16 id = (challengesmenu.hilix * CHALLENGEGRIDHEIGHT) + challengesmenu.hiliy;
|
||||
if (challengesmenu.extradata
|
||||
&& challengesmenu.extradata[id].flip != (TILEFLIP_MAX/2))
|
||||
{
|
||||
// Only mark visited once flipped
|
||||
}
|
||||
else
|
||||
{
|
||||
gamedata->unlockpending[challengesmenu.currentunlock] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -844,6 +891,8 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
Z_Free(challengesmenu.extradata);
|
||||
challengesmenu.extradata = NULL;
|
||||
|
||||
if (challengesmenu.unlockcondition)
|
||||
Z_Free(challengesmenu.unlockcondition);
|
||||
challengesmenu.unlockcondition = NULL;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ void M_EndModeAttackRun(void)
|
|||
"Secret Exit",
|
||||
va(
|
||||
"No finish time was recorded.\n"
|
||||
"Secrets don't work in Record modes!\n"
|
||||
"Secrets don't work in Attack modes!\n"
|
||||
"Try again in %s.\n",
|
||||
(gametype == GT_RACE)
|
||||
? "Grand Prix or Match Race"
|
||||
|
|
|
|||
21
src/p_mobj.c
21
src/p_mobj.c
|
|
@ -7007,6 +7007,23 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
{
|
||||
trans = tr_trans50;
|
||||
}
|
||||
// Non-RNG-advancing equivalent of Obj_SpawnEmeraldSparks
|
||||
else if (leveltime % 3 == 0)
|
||||
{
|
||||
mobj_t *sparkle = P_SpawnMobjFromMobj(
|
||||
mobj,
|
||||
M_RandomRange(-mobj->radius/FRACUNIT, mobj->radius/FRACUNIT) * FRACUNIT,
|
||||
M_RandomRange(-mobj->radius/FRACUNIT, mobj->radius/FRACUNIT) * FRACUNIT,
|
||||
M_RandomRange(0, mobj->height/FRACUNIT) * FRACUNIT,
|
||||
MT_SPARK
|
||||
);
|
||||
P_SetMobjStateNF(sparkle, mobjinfo[MT_EMERALDSPARK].spawnstate);
|
||||
|
||||
sparkle->color = mobj->color;
|
||||
sparkle->momz += 6 * mapobjectscale * P_MobjFlip(mobj);
|
||||
P_SetScale(sparkle, 2);
|
||||
sparkle->destscale = mapobjectscale;
|
||||
}
|
||||
|
||||
if (mobj->reactiontime > 0
|
||||
&& leveltime > starttime)
|
||||
|
|
@ -13083,7 +13100,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
|
|||
}
|
||||
case MT_SPRAYCAN:
|
||||
{
|
||||
if (nummapspraycans == UINT8_MAX || tutorialchallenge == TUTORIALSKIP_INPROGRESS)
|
||||
if (nummapspraycans == UINT8_MAX
|
||||
|| modeattacking != ATTACKING_NONE
|
||||
|| tutorialchallenge == TUTORIALSKIP_INPROGRESS)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -880,7 +880,8 @@ static void P_SpawnMapThings(boolean spawnemblems)
|
|||
Z_Free(loopends);
|
||||
|
||||
if (spawnemblems
|
||||
&& gametype != GT_TUTORIAL)
|
||||
&& gametype != GT_TUTORIAL
|
||||
&& !modeattacking)
|
||||
{
|
||||
const UINT8 recommendedcans =
|
||||
#ifdef DEVELOP
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue