Clear separation between basegame and mods

- Always force a page seperation between the last core files cup and the first modded cup
- Lost and Found sits exactly between them
    - If any cup on the last page of basegame is unlocked, place LnF on the last core page
    - Else, LnF is the first "cup" on the first Modded page
    - It's done this way so no Core material is spoiled if you haven't unlocked it yet. We want people to believe RR contains only 7 cups unless they go above and beyond

Also address Volt's bug report: Prevent the first page of cups from being overridden if everything is locked
This commit is contained in:
toaster 2023-11-21 22:59:12 +00:00
parent b46b61e7a1
commit 21f152989d
5 changed files with 97 additions and 39 deletions

View file

@ -1609,6 +1609,7 @@ void D_SRB2Main(void)
// //
P_InitMapData(); P_InitMapData();
basenummapheaders = nummapheaders; basenummapheaders = nummapheaders;
basenumkartcupheaders = numkartcupheaders;
CON_SetLoadingProgress(LOADED_IWAD); CON_SetLoadingProgress(LOADED_IWAD);

View file

@ -613,6 +613,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (gamedataadded) if (gamedataadded)
{ {
basenummapheaders = nummapheaders; basenummapheaders = nummapheaders;
basenumkartcupheaders = numkartcupheaders;
G_LoadGameData(); G_LoadGameData();
} }

View file

@ -423,7 +423,7 @@ struct cupheader_t
}; };
extern cupheader_t *kartcupheaders; // Start of cup linked list extern cupheader_t *kartcupheaders; // Start of cup linked list
extern UINT16 numkartcupheaders; extern UINT16 numkartcupheaders, basenumkartcupheaders;
struct unloaded_cupheader_t struct unloaded_cupheader_t
{ {

View file

@ -204,6 +204,7 @@ unloaded_mapheader_t *unloadedmapheaders = NULL;
// Kart cup definitions // Kart cup definitions
cupheader_t *kartcupheaders = NULL; cupheader_t *kartcupheaders = NULL;
UINT16 numkartcupheaders = 0; UINT16 numkartcupheaders = 0;
UINT16 basenumkartcupheaders = 0;
unloaded_cupheader_t *unloadedcupheaders = NULL; unloaded_cupheader_t *unloadedcupheaders = NULL;

View file

@ -313,15 +313,14 @@ boolean M_LevelListFromGametype(INT16 gt)
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, foundanythispage = false, currentvalid = false; boolean foundany = false, currentvalid = false;
size_t deltaid = 0;
G_GetBackupCupData( G_GetBackupCupData(
cupgrid.grandprix == true cupgrid.grandprix == true
&& cv_splitplayers.value <= 1 && cv_splitplayers.value <= 1
); );
templevelsearch.cup = kartcupheaders;
#if 0 #if 0
// Make sure there's valid cups before going to this menu. -- rip sweet prince // Make sure there's valid cups before going to this menu. -- rip sweet prince
if (templevelsearch.cup == NULL) if (templevelsearch.cup == NULL)
@ -368,8 +367,89 @@ boolean M_LevelListFromGametype(INT16 gt)
cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS); \ cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS); \
currentvalid = true; 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; templevelsearch.checklocked = false;
if (!M_CountLevelsToShowInList(&templevelsearch)) if (!M_CountLevelsToShowInList(&templevelsearch))
{ {
@ -397,59 +477,34 @@ boolean M_LevelListFromGametype(INT16 gt)
} }
} }
currentid++; templevelsearch.cup = templevelsearch.cup->next;
currentid++;
deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS);
// If the second row is locked and you've reached it, skip onward.
if (secondrowlocked == true) if (secondrowlocked == true)
{ {
size_t deltaid = currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS); // If the second row is locked and you've reached it, skip onward.
if (deltaid >= CUPMENU_COLUMNS) if (deltaid >= CUPMENU_COLUMNS)
{ {
currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid; currentid += (CUPMENU_COLUMNS * CUPMENU_ROWS) - deltaid;
deltaid = 0;
} }
} }
// If you've gone a full page without anything valid, compress it down! if (deltaid == 0)
if ((currentid % (CUPMENU_COLUMNS * CUPMENU_ROWS)) == 0)
{ {
if (foundanythispage == false) if (foundanythispage == false)
{ {
currentid -= (CUPMENU_COLUMNS * CUPMENU_ROWS); GRID_TIDYLOCKED((CUPMENU_COLUMNS * CUPMENU_ROWS));
memset(&cupgrid.builtgrid[currentid], 0, pagelen);
} }
foundanythispage = false; foundanythispage = false;
} }
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;
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
{
foundany = 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++;
}
templevelsearch.cup = NULL;
} }
#undef GRID_INSERTCUP #undef GRID_INSERTCUP
#undef GRID_FOCUSCUP #undef GRID_FOCUSCUP
#undef GRID_TIDYLOCKED
if (foundany == false) if (foundany == false)
{ {