mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'locked-cuprow' into 'master'
Second row of cups is invisible if none of them are unlocked See merge request KartKrew/Kart!1652
This commit is contained in:
commit
25d10e382a
13 changed files with 372 additions and 63 deletions
|
|
@ -1609,6 +1609,7 @@ void D_SRB2Main(void)
|
|||
//
|
||||
P_InitMapData();
|
||||
basenummapheaders = nummapheaders;
|
||||
basenumkartcupheaders = numkartcupheaders;
|
||||
|
||||
CON_SetLoadingProgress(LOADED_IWAD);
|
||||
|
||||
|
|
|
|||
|
|
@ -2464,6 +2464,20 @@ void readunlockable(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
// Todo: Own func
|
||||
static cupheader_t *SOChelper_cupbyname(char *name)
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
UINT32 hash = quickncasehash(name, MAXCUPNAME);
|
||||
while (cup)
|
||||
{
|
||||
if (hash == cup->namehash && !strcmp(cup->name, name))
|
||||
return cup;
|
||||
cup = cup->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This is a home-grown strtok(" ") equivalent so we can isolate the first chunk without destroying the rest of the line.
|
||||
static void conditiongetparam(char **params, UINT8 paramid, char **spos)
|
||||
{
|
||||
|
|
@ -2690,6 +2704,63 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
re = -1;
|
||||
x1 = atoi(params[2]);
|
||||
}
|
||||
else if (fastcmp(params[0], "ALLCUPRECORDS"))
|
||||
{
|
||||
ty = UC_ALLCUPRECORDS;
|
||||
|
||||
re = -1;
|
||||
x1 = 0;
|
||||
x2 = KARTSPEED_EASY;
|
||||
|
||||
if (params[1])
|
||||
{
|
||||
if (!fastcmp(params[1], "ALL"))
|
||||
{
|
||||
cupheader_t *cup = SOChelper_cupbyname(params[1]);
|
||||
|
||||
if (!cup)
|
||||
{
|
||||
deh_warning("Invalid cup %s for condition ID %d", params[1], id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
re = cup->id;
|
||||
}
|
||||
|
||||
if (params[2])
|
||||
{
|
||||
if (!fastcmp(params[1], "ANY"))
|
||||
{
|
||||
if ((offset=0) || fastcmp(params[2], "GOLD")
|
||||
|| (++offset && fastcmp(params[2], "SILVER"))
|
||||
|| (++offset && fastcmp(params[2], "BRONZE")))
|
||||
{
|
||||
x1 = offset + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("placement requirement \"%s\" invalid for condition ID %d", params[2], id+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (params[3])
|
||||
{
|
||||
if (fastcmp(params[3], "NORMAL"))
|
||||
x2 = KARTSPEED_NORMAL;
|
||||
else if (fastcmp(params[3], "HARD"))
|
||||
x2 = KARTSPEED_HARD;
|
||||
else if (fastcmp(params[3], "MASTER"))
|
||||
x2 = KARTGP_MASTER;
|
||||
else
|
||||
{
|
||||
deh_warning("gamespeed requirement \"%s\" invalid for condition ID %d", params[3], id+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "ALLCHAOS")
|
||||
|| (++offset && fastcmp(params[0], "ALLSUPER"))
|
||||
|| (++offset && fastcmp(params[0], "ALLEMERALDS")))
|
||||
|
|
@ -2907,14 +2978,7 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
re = -1;
|
||||
if (!fastcmp(params[1], "ANY"))
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
UINT32 hash = quickncasehash(params[1], MAXCUPNAME);
|
||||
while (cup)
|
||||
{
|
||||
if (hash == cup->namehash && !strcmp(cup->name, params[1]))
|
||||
break;
|
||||
cup = cup->next;
|
||||
}
|
||||
cupheader_t *cup = SOChelper_cupbyname(params[1]);
|
||||
|
||||
if (!cup)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -489,13 +489,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
if (!cup)
|
||||
{
|
||||
cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL);
|
||||
cup->id = numkartcupheaders;
|
||||
cup->monitor = 1;
|
||||
cup->cache_cuplock = MAXUNLOCKABLES;
|
||||
|
||||
deh_strlcpy(cup->name, word2,
|
||||
sizeof(cup->name), va("Cup header %s: name", word2));
|
||||
cup->namehash = hash;
|
||||
|
||||
// Handle some variable init.
|
||||
cup->monitor = 1;
|
||||
cup->id = numkartcupheaders;
|
||||
cup->cache_cuplock = MAXUNLOCKABLES;
|
||||
for (i = 0; i < CUPCACHE_MAX; i++)
|
||||
cup->cachedlevels[i] = NEXTMAP_INVALID;
|
||||
|
||||
char *start = strchr(word2, '_');
|
||||
if (start)
|
||||
start++;
|
||||
|
|
@ -608,6 +613,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
if (gamedataadded)
|
||||
{
|
||||
basenummapheaders = nummapheaders;
|
||||
basenumkartcupheaders = numkartcupheaders;
|
||||
G_LoadGameData();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ extern UINT32 maptol;
|
|||
extern INT32 cursaveslot;
|
||||
extern UINT8 gamecomplete;
|
||||
|
||||
#define CUPMENU_COLUMNS 7
|
||||
#define CUPMENU_ROWS 2
|
||||
|
||||
// Extra abilities/settings for skins (combinable stuff)
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -424,7 +427,7 @@ struct cupheader_t
|
|||
};
|
||||
|
||||
extern cupheader_t *kartcupheaders; // Start of cup linked list
|
||||
extern UINT16 numkartcupheaders;
|
||||
extern UINT16 numkartcupheaders, basenumkartcupheaders;
|
||||
|
||||
struct unloaded_cupheader_t
|
||||
{
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ unloaded_mapheader_t *unloadedmapheaders = NULL;
|
|||
// Kart cup definitions
|
||||
cupheader_t *kartcupheaders = NULL;
|
||||
UINT16 numkartcupheaders = 0;
|
||||
UINT16 basenumkartcupheaders = 0;
|
||||
|
||||
unloaded_cupheader_t *unloadedcupheaders = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -752,8 +752,6 @@ void M_SetupPlayMenu(INT32 choice);
|
|||
void M_SetupGametypeMenu(INT32 choice);
|
||||
void M_SetupRaceMenu(INT32 choice);
|
||||
|
||||
#define CUPMENU_COLUMNS 7
|
||||
#define CUPMENU_ROWS 2
|
||||
#define CUPMENU_CURSORID (cupgrid.x + (cupgrid.y * CUPMENU_COLUMNS) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS)))
|
||||
|
||||
extern struct cupgrid_s {
|
||||
|
|
@ -764,6 +762,7 @@ extern struct cupgrid_s {
|
|||
size_t cappages;
|
||||
tic_t previewanim;
|
||||
boolean grandprix; // Setup grand prix server after picking
|
||||
boolean cache_secondrowlocked;
|
||||
} cupgrid;
|
||||
|
||||
typedef struct levelsearch_s {
|
||||
|
|
@ -1274,6 +1273,8 @@ extern struct challengesmenu_s {
|
|||
UINT16 unlockcount[CMC_MAX];
|
||||
|
||||
UINT8 fade;
|
||||
|
||||
boolean cache_secondrowlocked;
|
||||
} challengesmenu;
|
||||
|
||||
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu);
|
||||
|
|
|
|||
|
|
@ -2712,7 +2712,9 @@ void M_DrawCupSelect(void)
|
|||
|
||||
for (i = 0; i < CUPMENU_COLUMNS; i++)
|
||||
{
|
||||
for (j = 0; j < CUPMENU_ROWS; j++)
|
||||
x = 14 + (i*42);
|
||||
|
||||
for (j = 0; j < (cupgrid.cache_secondrowlocked ? 1 : CUPMENU_ROWS); j++)
|
||||
{
|
||||
size_t id = (i + (j * CUPMENU_COLUMNS)) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||
|
||||
|
|
@ -2721,8 +2723,9 @@ void M_DrawCupSelect(void)
|
|||
|
||||
templevelsearch.cup = cupgrid.builtgrid[id];
|
||||
|
||||
x = 14 + (i*42);
|
||||
y = 20 + (j*44) - (30*menutransition.tics);
|
||||
if (cupgrid.cache_secondrowlocked == true)
|
||||
y += 28;
|
||||
|
||||
const boolean isGP = (cupgrid.grandprix && (cv_dummygpdifficulty.value >= 0 && cv_dummygpdifficulty.value < KARTGP_MAX));
|
||||
if (isGP)
|
||||
|
|
@ -2745,11 +2748,23 @@ void M_DrawCupSelect(void)
|
|||
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP1", PU_CACHE));
|
||||
}
|
||||
|
||||
// used to be 8 + (j*100) - (30*menutransition.tics)
|
||||
// but one-row mode means y has to be changed
|
||||
// this is the difference between y and that
|
||||
if (j == 0)
|
||||
{
|
||||
y -= 12; // (8) - (20)
|
||||
}
|
||||
else
|
||||
{
|
||||
y += 44; //(8 + 100) - (20 + 44)
|
||||
}
|
||||
|
||||
if (windata && windata->best_placement != 0)
|
||||
{
|
||||
M_DrawCupWinData(
|
||||
x,
|
||||
8 + (j*100) - (30*menutransition.tics),
|
||||
y,
|
||||
templevelsearch.cup,
|
||||
cv_dummygpdifficulty.value,
|
||||
(cupgrid.previewanim & 1),
|
||||
|
|
@ -2761,6 +2776,8 @@ void M_DrawCupSelect(void)
|
|||
|
||||
x = 14 + (cupgrid.x*42);
|
||||
y = 20 + (cupgrid.y*44) - (30*menutransition.tics);
|
||||
if (cupgrid.cache_secondrowlocked == true)
|
||||
y += 28;
|
||||
|
||||
V_DrawScaledPatch(x - 4, y - 1, 0, W_CachePatchName("CUPCURS", PU_CACHE));
|
||||
|
||||
|
|
@ -5670,40 +5687,56 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
|
||||
M_DrawCupPreview(146, &templevelsearch);
|
||||
|
||||
maxid = id = (temp->id % 14);
|
||||
maxid = id = (temp->id % (CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||
offset = (temp->id - id) * 2;
|
||||
while (temp && maxid < 14)
|
||||
while (temp && maxid < (CUPMENU_COLUMNS * CUPMENU_ROWS))
|
||||
{
|
||||
maxid++;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
V_DrawFadeFill(4, (BASEVIDHEIGHT-(4+16)), 28 + offset, 16, 0, 31, challengetransparentstrength);
|
||||
y = (BASEVIDHEIGHT-(4+16));
|
||||
if (challengesmenu.cache_secondrowlocked == true)
|
||||
y += 8;
|
||||
|
||||
V_DrawFadeFill(
|
||||
4,
|
||||
y,
|
||||
28 + offset,
|
||||
(challengesmenu.cache_secondrowlocked ? 8 : 16),
|
||||
0,
|
||||
31,
|
||||
challengetransparentstrength
|
||||
);
|
||||
|
||||
for (i = 0; i < offset; i += 4)
|
||||
{
|
||||
V_DrawFill(4+1 + i, (BASEVIDHEIGHT-(4+16))+3, 2, 2, 15);
|
||||
V_DrawFill(4+1 + i, (BASEVIDHEIGHT-(4+16))+8+3, 2, 2, 15);
|
||||
V_DrawFill(4+1 + i, y+3, 2, 2, 15);
|
||||
|
||||
if (challengesmenu.cache_secondrowlocked == false)
|
||||
V_DrawFill(4+1 + i, y+8+3, 2, 2, 15);
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
for (i = 0; i < CUPMENU_COLUMNS; i++)
|
||||
{
|
||||
if (templevelsearch.cup && id == i)
|
||||
{
|
||||
V_DrawFill(offset + 4 + (i*4), (BASEVIDHEIGHT-(4+16)), 4, 8, 0);
|
||||
V_DrawFill(offset + 4 + (i*4), y, 4, 8, 0);
|
||||
}
|
||||
else if (i < maxid)
|
||||
{
|
||||
V_DrawFill(offset + 4+1 + (i*4), (BASEVIDHEIGHT-(4+16))+3, 2, 2, 0);
|
||||
V_DrawFill(offset + 4+1 + (i*4), y+3, 2, 2, 0);
|
||||
}
|
||||
|
||||
if (templevelsearch.cup && (templevelsearch.cup->id % 14) == i+7)
|
||||
if (templevelsearch.cup && id == i+CUPMENU_COLUMNS)
|
||||
{
|
||||
V_DrawFill(offset + 4 + (i*4), (BASEVIDHEIGHT-(4+16))+8, 4, 8, 0);
|
||||
V_DrawFill(offset + 4 + (i*4), y+8, 4, 8, 0);
|
||||
}
|
||||
else if (i+7 < maxid)
|
||||
else if (challengesmenu.cache_secondrowlocked == true)
|
||||
;
|
||||
else if (i+CUPMENU_COLUMNS < maxid)
|
||||
{
|
||||
V_DrawFill(offset + 4+1 + (i*4), (BASEVIDHEIGHT-(4+16))+8+3, 2, 2, 0);
|
||||
V_DrawFill(offset + 4+1 + (i*4), y+8+3, 2, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
116
src/m_cond.c
116
src/m_cond.c
|
|
@ -1388,6 +1388,39 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
|
||||
return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1);
|
||||
|
||||
case UC_ALLCUPRECORDS:
|
||||
{
|
||||
cupheader_t *cup;
|
||||
UINT8 difficulty = cn->extrainfo2;
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
return false; // this one could be laggy with many cups available
|
||||
|
||||
if (difficulty > KARTGP_MASTER)
|
||||
difficulty = KARTGP_MASTER;
|
||||
|
||||
for (cup = kartcupheaders; cup; cup = cup->next)
|
||||
{
|
||||
// Ok, achieved up to the desired cup.
|
||||
if (cn->requirement == cup->id)
|
||||
return true;
|
||||
|
||||
cupwindata_t *windata = &cup->windata[cn->extrainfo2];
|
||||
|
||||
// Did you actually get it?
|
||||
if (windata->best_placement == 0)
|
||||
return false;
|
||||
|
||||
// Sufficient placement?
|
||||
if (cn->extrainfo1 && windata->best_placement > cn->extrainfo1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we ended up here, check we were looking for all cups achieved.
|
||||
return (cn->requirement == -1);
|
||||
}
|
||||
|
||||
|
||||
case UC_ALLCHAOS:
|
||||
case UC_ALLSUPER:
|
||||
case UC_ALLEMERALDS:
|
||||
|
|
@ -2120,6 +2153,50 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
work);
|
||||
}
|
||||
|
||||
case UC_ALLCUPRECORDS:
|
||||
{
|
||||
const char *completetype = "Complete", *orbetter = "", *specialtext = NULL, *speedtext = "";
|
||||
|
||||
if (cn->extrainfo1 == 0)
|
||||
;
|
||||
else if (cn->extrainfo1 == 1)
|
||||
completetype = "get Gold over";
|
||||
else
|
||||
{
|
||||
if (cn->extrainfo1 == 2)
|
||||
completetype = "get Silver";
|
||||
else if (cn->extrainfo1 == 3)
|
||||
completetype = "get Bronze";
|
||||
orbetter = " or better over";
|
||||
}
|
||||
|
||||
if (cn->extrainfo2 == KARTSPEED_NORMAL)
|
||||
{
|
||||
speedtext = " on Normal";
|
||||
}
|
||||
else if (cn->extrainfo2 == KARTSPEED_HARD)
|
||||
{
|
||||
speedtext = " on Hard";
|
||||
}
|
||||
else if (cn->extrainfo2 == KARTGP_MASTER)
|
||||
{
|
||||
if (M_SecretUnlocked(SECRET_MASTERMODE, true))
|
||||
speedtext = " on Master";
|
||||
else
|
||||
speedtext = " on ???";
|
||||
}
|
||||
|
||||
if (cn->requirement == -1)
|
||||
specialtext = "every Cup";
|
||||
else if (M_CupSecondRowLocked() == true && cn->requirement+1 >= CUPMENU_COLUMNS)
|
||||
specialtext = "the first ??? Cups";
|
||||
|
||||
if (specialtext != NULL)
|
||||
return va("GRAND PRIX: %s%s %s%s", completetype, orbetter, specialtext, speedtext);
|
||||
|
||||
return va("GRAND PRIX: %s%s the first %d Cups%s", completetype, orbetter, cn->requirement, speedtext);
|
||||
}
|
||||
|
||||
case UC_ALLCHAOS:
|
||||
case UC_ALLSUPER:
|
||||
case UC_ALLEMERALDS:
|
||||
|
|
@ -2138,17 +2215,17 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
|
||||
/*if (cn->requirement == KARTSPEED_NORMAL) -- Emeralds can not be collected on Easy
|
||||
{
|
||||
speedtext = " on Normal difficulty";
|
||||
speedtext = " on Normal";
|
||||
}
|
||||
else*/
|
||||
if (cn->requirement == KARTSPEED_HARD)
|
||||
{
|
||||
speedtext = " on Hard difficulty";
|
||||
speedtext = " on Hard";
|
||||
}
|
||||
else if (cn->requirement == KARTGP_MASTER)
|
||||
{
|
||||
if (M_SecretUnlocked(SECRET_MASTERMODE, true))
|
||||
speedtext = " on Master difficulty";
|
||||
speedtext = " on Master";
|
||||
else
|
||||
speedtext = " on ???";
|
||||
}
|
||||
|
|
@ -2401,16 +2478,16 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
|
||||
if (cn->requirement == KARTSPEED_NORMAL)
|
||||
{
|
||||
speedtext = "on Normal difficulty";
|
||||
speedtext = "on Normal";
|
||||
}
|
||||
else if (cn->requirement == KARTSPEED_HARD)
|
||||
{
|
||||
speedtext = "on Hard difficulty";
|
||||
speedtext = "on Hard";
|
||||
}
|
||||
else if (cn->requirement == KARTGP_MASTER)
|
||||
{
|
||||
if (M_SecretUnlocked(SECRET_MASTERMODE, true))
|
||||
speedtext = "on Master difficulty";
|
||||
speedtext = "on Master";
|
||||
else
|
||||
speedtext = "on ???";
|
||||
}
|
||||
|
|
@ -3190,6 +3267,33 @@ boolean M_CupLocked(cupheader_t *cup)
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean M_CupSecondRowLocked(void)
|
||||
{
|
||||
// The following was pre-optimised for cached behaviour.
|
||||
// It would need a refactor if the cache system were to
|
||||
// change, maybe to iterate over unlockable_t instead.
|
||||
cupheader_t *cup;
|
||||
for (cup = kartcupheaders; cup; cup = cup->next)
|
||||
{
|
||||
// Only important for the second row.
|
||||
if ((cup->id % (CUPMENU_COLUMNS * CUPMENU_ROWS)) < CUPMENU_COLUMNS)
|
||||
continue;
|
||||
|
||||
// Only important for ones that can be locked.
|
||||
if (cup->cache_cuplock == MAXUNLOCKABLES)
|
||||
continue;
|
||||
|
||||
// If it's NOT unlocked, can't be used as proof of unlock.
|
||||
if (!M_CheckNetUnlockByID(cup->cache_cuplock))
|
||||
continue;
|
||||
|
||||
// Okay, at least one cup on the second row is unlocked!
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean M_MapLocked(UINT16 mapnum)
|
||||
{
|
||||
// Don't lock maps in dedicated servers.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ typedef enum
|
|||
|
||||
UC_CHARACTERWINS, // CHARACTERWINS [character] [x rounds]
|
||||
|
||||
UC_ALLCUPRECORDS, // ALLCUPRECORDS [cup to complete up to] [minimum position] [minimum difficulty]
|
||||
|
||||
UC_ALLCHAOS, // ALLCHAOS [minimum difficulty]
|
||||
UC_ALLSUPER, // ALLSUPER [minimum difficulty]
|
||||
UC_ALLEMERALDS, // ALLEMERALDS [minimum difficulty]
|
||||
|
|
@ -437,6 +439,7 @@ UINT16 M_CompletionEmblems(void);
|
|||
boolean M_CheckNetUnlockByID(UINT16 unlockid);
|
||||
boolean M_SecretUnlocked(INT32 type, boolean local);
|
||||
boolean M_CupLocked(cupheader_t *cup);
|
||||
boolean M_CupSecondRowLocked(void);
|
||||
boolean M_MapLocked(UINT16 mapnum);
|
||||
INT32 M_CountMedals(boolean all, boolean extraonly);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ static void M_UpdateChallengeGridVisuals(void)
|
|||
{
|
||||
UINT16 i;
|
||||
|
||||
challengesmenu.cache_secondrowlocked = M_CupSecondRowLocked();
|
||||
|
||||
challengesmenu.unlockcount[CMC_UNLOCKED] = 0;
|
||||
challengesmenu.unlockcount[CMC_TOTAL] = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ static void M_StatisticsMaps(void)
|
|||
if (M_CupLocked(cup))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < CUPCACHE_MAX; i++)
|
||||
for (i = 0; i < CUPCACHE_PODIUM; i++)
|
||||
{
|
||||
if (cup->cachedlevels[i] >= nummapheaders)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -214,7 +214,9 @@ void M_CupSelectHandler(INT32 choice)
|
|||
M_SetMenuDelay(pid);
|
||||
}
|
||||
|
||||
if (menucmd[pid].dpad_ud > 0)
|
||||
if (cupgrid.cache_secondrowlocked == true)
|
||||
; // No up/down for you!
|
||||
else if (menucmd[pid].dpad_ud > 0)
|
||||
{
|
||||
cupgrid.y++;
|
||||
if (cupgrid.y >= CUPMENU_ROWS)
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
|
|||
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < CUPCACHE_MAX; i++)
|
||||
for (i = 0; i < CUPCACHE_PODIUM; i++)
|
||||
{
|
||||
if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[i], levelsearch))
|
||||
continue;
|
||||
|
|
@ -158,13 +158,13 @@ UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch)
|
|||
{
|
||||
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
||||
{
|
||||
*i = CUPCACHE_MAX;
|
||||
*i = CUPCACHE_PODIUM;
|
||||
return NEXTMAP_INVALID;
|
||||
}
|
||||
|
||||
*i = 0;
|
||||
mapnum = NEXTMAP_INVALID;
|
||||
for (; *i < CUPCACHE_MAX; (*i)++)
|
||||
for (; *i < CUPCACHE_PODIUM; (*i)++)
|
||||
{
|
||||
if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[*i], levelsearch))
|
||||
continue;
|
||||
|
|
@ -194,7 +194,7 @@ UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch)
|
|||
{
|
||||
mapnum = NEXTMAP_INVALID;
|
||||
(*i)++;
|
||||
for (; *i < CUPCACHE_MAX; (*i)++)
|
||||
for (; *i < CUPCACHE_PODIUM; (*i)++)
|
||||
{
|
||||
if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[*i], levelsearch))
|
||||
continue;
|
||||
|
|
@ -299,18 +299,28 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
|
||||
if (levellist.levelsearch.cupmode)
|
||||
{
|
||||
const boolean secondrowlocked = M_CupSecondRowLocked();
|
||||
if (cupgrid.cache_secondrowlocked != secondrowlocked)
|
||||
{
|
||||
cupgrid.cache_secondrowlocked = secondrowlocked;
|
||||
if (cupgrid.y || cupgrid.pageno)
|
||||
{
|
||||
// Prevent softlock, reset to start
|
||||
cupgrid.x = cupgrid.y = cupgrid.pageno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
levelsearch_t templevelsearch = levellist.levelsearch; // full copy
|
||||
size_t currentid = 0, highestunlockedid = 0;
|
||||
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||
boolean foundany = false, currentvalid = false;
|
||||
size_t deltaid = 0;
|
||||
|
||||
G_GetBackupCupData(
|
||||
cupgrid.grandprix == true
|
||||
&& cv_splitplayers.value <= 1
|
||||
);
|
||||
|
||||
templevelsearch.cup = kartcupheaders;
|
||||
|
||||
#if 0
|
||||
// Make sure there's valid cups before going to this menu. -- rip sweet prince
|
||||
if (templevelsearch.cup == NULL)
|
||||
|
|
@ -357,8 +367,89 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS); \
|
||||
currentvalid = true;
|
||||
|
||||
while (templevelsearch.cup)
|
||||
#define GRID_TIDYLOCKED(rewind) \
|
||||
currentid -= rewind; \
|
||||
memset(&cupgrid.builtgrid[currentid], 0, pagelen); \
|
||||
deltaid = 0;
|
||||
|
||||
boolean lostandfoundready = true;
|
||||
// foundanythispage SHOULD start out as false... but if
|
||||
// nothing is unlocked, the first page should never be wiped!
|
||||
boolean foundanythispage = true;
|
||||
|
||||
templevelsearch.cup = kartcupheaders;
|
||||
while (true)
|
||||
{
|
||||
// Handle reaching the end of the base-game cups.
|
||||
if (lostandfoundready == true
|
||||
&& (
|
||||
templevelsearch.cup == NULL
|
||||
|| templevelsearch.cup->id == basenumkartcupheaders
|
||||
)
|
||||
)
|
||||
{
|
||||
lostandfoundready = false;
|
||||
|
||||
if (deltaid != 0 && foundanythispage == false)
|
||||
{
|
||||
GRID_TIDYLOCKED(deltaid);
|
||||
}
|
||||
|
||||
size_t olddelta = deltaid;
|
||||
if (cupgrid.grandprix == false)
|
||||
{
|
||||
cupheader_t *restore = templevelsearch.cup;
|
||||
|
||||
templevelsearch.cup = &dummy_lostandfound;
|
||||
templevelsearch.checklocked = true;
|
||||
|
||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
||||
{
|
||||
foundany = foundanythispage = true;
|
||||
GRID_INSERTCUP;
|
||||
highestunlockedid = currentid;
|
||||
|
||||
if (Playing()
|
||||
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == NULL)
|
||||
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
||||
{
|
||||
GRID_FOCUSCUP;
|
||||
}
|
||||
|
||||
currentid++;
|
||||
deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||
}
|
||||
|
||||
templevelsearch.cup = restore;
|
||||
}
|
||||
|
||||
// Lost and Found marks the transition point between base
|
||||
// and custom cups. Always force a page break between these
|
||||
// (unless LnF is the only "cup" on the page, for sanity).
|
||||
|
||||
if (
|
||||
(deltaid == 0) // a new page already
|
||||
|| (olddelta == 0 && deltaid == 1) // LnF is first and only entry
|
||||
)
|
||||
; // this page layout is fine
|
||||
else
|
||||
{
|
||||
if (foundanythispage == false)
|
||||
{
|
||||
GRID_TIDYLOCKED(deltaid);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid;
|
||||
deltaid = 0;
|
||||
foundanythispage = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (templevelsearch.cup == NULL)
|
||||
break;
|
||||
|
||||
templevelsearch.checklocked = false;
|
||||
if (!M_CountLevelsToShowInList(&templevelsearch))
|
||||
{
|
||||
|
|
@ -374,6 +465,7 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
templevelsearch.checklocked = true;
|
||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
||||
{
|
||||
foundanythispage = true;
|
||||
highestunlockedid = currentid;
|
||||
|
||||
if (Playing()
|
||||
|
|
@ -385,37 +477,34 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
}
|
||||
}
|
||||
|
||||
currentid++;
|
||||
templevelsearch.cup = templevelsearch.cup->next;
|
||||
}
|
||||
|
||||
// Lost and found, a simplified version of the above loop.
|
||||
if (cupgrid.grandprix == false)
|
||||
{
|
||||
templevelsearch.cup = &dummy_lostandfound;
|
||||
templevelsearch.checklocked = true;
|
||||
currentid++;
|
||||
deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||
|
||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
||||
if (secondrowlocked == true)
|
||||
{
|
||||
foundany = true;
|
||||
GRID_INSERTCUP;
|
||||
highestunlockedid = currentid;
|
||||
|
||||
if (Playing()
|
||||
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == NULL)
|
||||
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
||||
// If the second row is locked and you've reached it, skip onward.
|
||||
if (deltaid >= CUPMENU_COLUMNS)
|
||||
{
|
||||
GRID_FOCUSCUP;
|
||||
currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid;
|
||||
deltaid = 0;
|
||||
}
|
||||
|
||||
currentid++;
|
||||
}
|
||||
|
||||
templevelsearch.cup = NULL;
|
||||
if (deltaid == 0)
|
||||
{
|
||||
if (foundanythispage == false)
|
||||
{
|
||||
GRID_TIDYLOCKED((CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||
}
|
||||
foundanythispage = false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef GRID_INSERTCUP
|
||||
#undef GRID_FOCUSCUP
|
||||
#undef GRID_TIDYLOCKED
|
||||
|
||||
if (foundany == false)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue