mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-05-10 10:51:42 +00:00
Second row of cups is invisible if none of them are unlocked
- Controlled by M_CupSecondRowLocked
- Looks for any Cup with associated unlockable that's on the second row
- Cached on load for both relevant menus - Cupgrid and Challenges
- Custom cups will be stretched out onto more pages
- Side incentive of unlocking more material: Less annoying interactions with custom material
- Pages with nothing unlocked are completely skipped over
Also moves a bunch of minor things which previously used magic numbers to the CUPMENU_COLUMNS/CUPMENU_ROWS defines, for sanity
This commit is contained in:
parent
b8c18ce39f
commit
382119b8fb
8 changed files with 122 additions and 19 deletions
|
|
@ -53,6 +53,9 @@ extern UINT32 maptol;
|
||||||
extern INT32 cursaveslot;
|
extern INT32 cursaveslot;
|
||||||
extern UINT8 gamecomplete;
|
extern UINT8 gamecomplete;
|
||||||
|
|
||||||
|
#define CUPMENU_COLUMNS 7
|
||||||
|
#define CUPMENU_ROWS 2
|
||||||
|
|
||||||
// Extra abilities/settings for skins (combinable stuff)
|
// Extra abilities/settings for skins (combinable stuff)
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -752,8 +752,6 @@ void M_SetupPlayMenu(INT32 choice);
|
||||||
void M_SetupGametypeMenu(INT32 choice);
|
void M_SetupGametypeMenu(INT32 choice);
|
||||||
void M_SetupRaceMenu(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)))
|
#define CUPMENU_CURSORID (cupgrid.x + (cupgrid.y * CUPMENU_COLUMNS) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS)))
|
||||||
|
|
||||||
extern struct cupgrid_s {
|
extern struct cupgrid_s {
|
||||||
|
|
@ -764,6 +762,7 @@ extern struct cupgrid_s {
|
||||||
size_t cappages;
|
size_t cappages;
|
||||||
tic_t previewanim;
|
tic_t previewanim;
|
||||||
boolean grandprix; // Setup grand prix server after picking
|
boolean grandprix; // Setup grand prix server after picking
|
||||||
|
boolean cache_secondrowlocked;
|
||||||
} cupgrid;
|
} cupgrid;
|
||||||
|
|
||||||
typedef struct levelsearch_s {
|
typedef struct levelsearch_s {
|
||||||
|
|
@ -1274,6 +1273,8 @@ extern struct challengesmenu_s {
|
||||||
UINT16 unlockcount[CMC_MAX];
|
UINT16 unlockcount[CMC_MAX];
|
||||||
|
|
||||||
UINT8 fade;
|
UINT8 fade;
|
||||||
|
|
||||||
|
boolean cache_secondrowlocked;
|
||||||
} challengesmenu;
|
} challengesmenu;
|
||||||
|
|
||||||
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu);
|
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu);
|
||||||
|
|
|
||||||
|
|
@ -2712,7 +2712,9 @@ void M_DrawCupSelect(void)
|
||||||
|
|
||||||
for (i = 0; i < CUPMENU_COLUMNS; i++)
|
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));
|
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];
|
templevelsearch.cup = cupgrid.builtgrid[id];
|
||||||
|
|
||||||
x = 14 + (i*42);
|
|
||||||
y = 20 + (j*44) - (30*menutransition.tics);
|
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));
|
const boolean isGP = (cupgrid.grandprix && (cv_dummygpdifficulty.value >= 0 && cv_dummygpdifficulty.value < KARTGP_MAX));
|
||||||
if (isGP)
|
if (isGP)
|
||||||
|
|
@ -2745,11 +2748,23 @@ void M_DrawCupSelect(void)
|
||||||
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP1", PU_CACHE));
|
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)
|
if (windata && windata->best_placement != 0)
|
||||||
{
|
{
|
||||||
M_DrawCupWinData(
|
M_DrawCupWinData(
|
||||||
x,
|
x,
|
||||||
8 + (j*100) - (30*menutransition.tics),
|
y,
|
||||||
templevelsearch.cup,
|
templevelsearch.cup,
|
||||||
cv_dummygpdifficulty.value,
|
cv_dummygpdifficulty.value,
|
||||||
(cupgrid.previewanim & 1),
|
(cupgrid.previewanim & 1),
|
||||||
|
|
@ -2761,6 +2776,8 @@ void M_DrawCupSelect(void)
|
||||||
|
|
||||||
x = 14 + (cupgrid.x*42);
|
x = 14 + (cupgrid.x*42);
|
||||||
y = 20 + (cupgrid.y*44) - (30*menutransition.tics);
|
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));
|
V_DrawScaledPatch(x - 4, y - 1, 0, W_CachePatchName("CUPCURS", PU_CACHE));
|
||||||
|
|
||||||
|
|
@ -5686,40 +5703,56 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
||||||
|
|
||||||
M_DrawCupPreview(146, &templevelsearch);
|
M_DrawCupPreview(146, &templevelsearch);
|
||||||
|
|
||||||
maxid = id = (temp->id % 14);
|
maxid = id = (temp->id % (CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||||
offset = (temp->id - id) * 2;
|
offset = (temp->id - id) * 2;
|
||||||
while (temp && maxid < 14)
|
while (temp && maxid < (CUPMENU_COLUMNS * CUPMENU_ROWS))
|
||||||
{
|
{
|
||||||
maxid++;
|
maxid++;
|
||||||
temp = temp->next;
|
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)
|
for (i = 0; i < offset; i += 4)
|
||||||
{
|
{
|
||||||
V_DrawFill(4+1 + i, (BASEVIDHEIGHT-(4+16))+3, 2, 2, 15);
|
V_DrawFill(4+1 + i, y+3, 2, 2, 15);
|
||||||
V_DrawFill(4+1 + i, (BASEVIDHEIGHT-(4+16))+8+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)
|
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)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
27
src/m_cond.c
27
src/m_cond.c
|
|
@ -3190,6 +3190,33 @@ boolean M_CupLocked(cupheader_t *cup)
|
||||||
return false;
|
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)
|
boolean M_MapLocked(UINT16 mapnum)
|
||||||
{
|
{
|
||||||
// Don't lock maps in dedicated servers.
|
// Don't lock maps in dedicated servers.
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,7 @@ UINT16 M_CompletionEmblems(void);
|
||||||
boolean M_CheckNetUnlockByID(UINT16 unlockid);
|
boolean M_CheckNetUnlockByID(UINT16 unlockid);
|
||||||
boolean M_SecretUnlocked(INT32 type, boolean local);
|
boolean M_SecretUnlocked(INT32 type, boolean local);
|
||||||
boolean M_CupLocked(cupheader_t *cup);
|
boolean M_CupLocked(cupheader_t *cup);
|
||||||
|
boolean M_CupSecondRowLocked(void);
|
||||||
boolean M_MapLocked(UINT16 mapnum);
|
boolean M_MapLocked(UINT16 mapnum);
|
||||||
INT32 M_CountMedals(boolean all, boolean extraonly);
|
INT32 M_CountMedals(boolean all, boolean extraonly);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,8 @@ static void M_UpdateChallengeGridVisuals(void)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
|
|
||||||
|
challengesmenu.cache_secondrowlocked = M_CupSecondRowLocked();
|
||||||
|
|
||||||
challengesmenu.unlockcount[CMC_UNLOCKED] = 0;
|
challengesmenu.unlockcount[CMC_UNLOCKED] = 0;
|
||||||
challengesmenu.unlockcount[CMC_TOTAL] = 0;
|
challengesmenu.unlockcount[CMC_TOTAL] = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,9 @@ void M_CupSelectHandler(INT32 choice)
|
||||||
M_SetMenuDelay(pid);
|
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++;
|
cupgrid.y++;
|
||||||
if (cupgrid.y >= CUPMENU_ROWS)
|
if (cupgrid.y >= CUPMENU_ROWS)
|
||||||
|
|
|
||||||
|
|
@ -299,10 +299,21 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
|
|
||||||
if (levellist.levelsearch.cupmode)
|
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
|
levelsearch_t templevelsearch = levellist.levelsearch; // full copy
|
||||||
size_t currentid = 0, highestunlockedid = 0;
|
size_t currentid = 0, highestunlockedid = 0;
|
||||||
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||||
boolean foundany = false, currentvalid = false;
|
boolean foundany = false, foundanythispage = false, currentvalid = false;
|
||||||
|
|
||||||
G_GetBackupCupData(
|
G_GetBackupCupData(
|
||||||
cupgrid.grandprix == true
|
cupgrid.grandprix == true
|
||||||
|
|
@ -374,6 +385,7 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
templevelsearch.checklocked = true;
|
templevelsearch.checklocked = true;
|
||||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
||||||
{
|
{
|
||||||
|
foundanythispage = true;
|
||||||
highestunlockedid = currentid;
|
highestunlockedid = currentid;
|
||||||
|
|
||||||
if (Playing()
|
if (Playing()
|
||||||
|
|
@ -386,6 +398,28 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentid++;
|
currentid++;
|
||||||
|
|
||||||
|
// If the second row is locked and you've reached it, skip onward.
|
||||||
|
if (secondrowlocked == true)
|
||||||
|
{
|
||||||
|
size_t deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||||
|
if (deltaid >= CUPMENU_COLUMNS)
|
||||||
|
{
|
||||||
|
currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you've gone a full page without anything valid, compress it down!
|
||||||
|
if ((currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS)) == 0)
|
||||||
|
{
|
||||||
|
if (foundanythispage == false)
|
||||||
|
{
|
||||||
|
currentid -= (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||||
|
memset(&cupgrid.builtgrid[currentid], 0, pagelen);
|
||||||
|
}
|
||||||
|
foundanythispage = false;
|
||||||
|
}
|
||||||
|
|
||||||
templevelsearch.cup = templevelsearch.cup->next;
|
templevelsearch.cup = templevelsearch.cup->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue