Rework the Level List functions to operate off a provided levelsearch_t pointer.

* Prevents the dependency on a `levellist` global that could be corrupted
* Fixes the issue where cups that were not unlocked would not show up on the cup select (because `M_MapLocked` would make `M_CanShowLevelInList` fail).
* Shows both Race and Battle maps in the cup unlock preview.
This commit is contained in:
toaster 2022-12-19 21:18:36 +00:00
parent 8e88a840bb
commit d0cd059c5e
4 changed files with 125 additions and 104 deletions

View file

@ -3404,23 +3404,27 @@ INT16 G_GetFirstMapOfGametype(UINT8 pgametype)
{ {
UINT8 i = 0; UINT8 i = 0;
INT16 mapnum = NEXTMAP_INVALID; INT16 mapnum = NEXTMAP_INVALID;
UINT32 tol = G_TOLFlag(pgametype); levelsearch_t templevelsearch;
levellist.cupmode = (!(gametypedefaultrules[pgametype] & GTR_NOCUPSELECT)); templevelsearch.cup = NULL;
levellist.timeattack = false; templevelsearch.typeoflevel = G_TOLFlag(pgametype);
templevelsearch.cupmode = (!(gametypedefaultrules[pgametype] & GTR_NOCUPSELECT));
templevelsearch.timeattack = false;
templevelsearch.checklocked = true;
if (levellist.cupmode) if (templevelsearch.cupmode)
{ {
cupheader_t *cup = kartcupheaders; templevelsearch.cup = kartcupheaders;
while (cup && mapnum >= nummapheaders) while (templevelsearch.cup && mapnum >= nummapheaders)
{ {
mapnum = M_GetFirstLevelInList(&i, tol, cup); mapnum = M_GetFirstLevelInList(&i, &templevelsearch);
i = 0; i = 0;
templevelsearch.cup = templevelsearch.cup->next;
} }
} }
else else
{ {
mapnum = M_GetFirstLevelInList(&i, tol, NULL); mapnum = M_GetFirstLevelInList(&i, &templevelsearch);
} }
return mapnum; return mapnum;

View file

@ -695,23 +695,28 @@ extern struct cupgrid_s {
boolean netgame; // Start the game in an actual server boolean netgame; // Start the game in an actual server
} cupgrid; } cupgrid;
typedef struct levelsearch_s {
UINT32 typeoflevel;
cupheader_t *cup;
boolean timeattack;
boolean cupmode;
boolean checklocked;
} levelsearch_t;
extern struct levellist_s { extern struct levellist_s {
SINT8 cursor; SINT8 cursor;
UINT16 y; UINT16 y;
UINT16 dest; UINT16 dest;
cupheader_t *selectedcup;
INT16 choosemap; INT16 choosemap;
UINT8 newgametype; UINT8 newgametype;
UINT32 typeoflevel; levelsearch_t levelsearch;
boolean cupmode;
boolean timeattack; // Setup time attack menu after picking
boolean netgame; // Start the game in an actual server boolean netgame; // Start the game in an actual server
} levellist; } levellist;
boolean M_CanShowLevelInList(INT16 mapnum, UINT32 tol, cupheader_t *cup); boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch);
UINT16 M_CountLevelsToShowInList(UINT32 tol, cupheader_t *cup); UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch);
UINT16 M_GetFirstLevelInList(UINT8 *i, UINT32 tol, cupheader_t *cup); UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch);
UINT16 M_GetNextLevelInList(UINT16 map, UINT8 *i, UINT32 tol, cupheader_t *cup); UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch);
void M_LevelSelectInit(INT32 choice); void M_LevelSelectInit(INT32 choice);
void M_CupSelectHandler(INT32 choice); void M_CupSelectHandler(INT32 choice);

View file

@ -1922,24 +1922,24 @@ void M_DrawRaceDifficulty(void)
// LEVEL SELECT // LEVEL SELECT
static void M_DrawCupPreview(INT16 y, cupheader_t *cup) static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
{ {
UINT8 i = 0; UINT8 i = 0;
INT16 maxlevels = M_CountLevelsToShowInList(levellist.typeoflevel, cup); INT16 maxlevels = M_CountLevelsToShowInList(levelsearch);
INT16 x = -(cupgrid.previewanim % 82); INT16 x = -(cupgrid.previewanim % 82);
INT16 add; INT16 add;
INT16 map, start = M_GetFirstLevelInList(&i, levellist.typeoflevel, cup); INT16 map, start = M_GetFirstLevelInList(&i, levelsearch);
UINT8 starti = i; UINT8 starti = i;
V_DrawFill(0, y, BASEVIDWIDTH, 54, 31); V_DrawFill(0, y, BASEVIDWIDTH, 54, 31);
if (cup && !M_CupLocked(cup)) if (levelsearch->cup && !M_CupLocked(levelsearch->cup))
{ {
add = (cupgrid.previewanim / 82) % maxlevels; add = (cupgrid.previewanim / 82) % maxlevels;
map = start; map = start;
while (add > 0) while (add > 0)
{ {
map = M_GetNextLevelInList(map, &i, levellist.typeoflevel, cup); map = M_GetNextLevelInList(map, &i, levelsearch);
if (map >= nummapheaders) if (map >= nummapheaders)
{ {
@ -1965,7 +1965,7 @@ static void M_DrawCupPreview(INT16 y, cupheader_t *cup)
x += 82; x += 82;
map = M_GetNextLevelInList(map, &i, levellist.typeoflevel, cup); map = M_GetNextLevelInList(map, &i, levelsearch);
} }
} }
else else
@ -2009,7 +2009,8 @@ static void M_DrawCupTitle(INT16 y, cupheader_t *cup)
void M_DrawCupSelect(void) void M_DrawCupSelect(void)
{ {
UINT8 i, j; UINT8 i, j;
cupheader_t *cup = cupgrid.builtgrid[CUPMENU_CURSORID]; levelsearch_t templevelsearch = levellist.levelsearch; // full copy
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
for (i = 0; i < CUPMENU_COLUMNS; i++) for (i = 0; i < CUPMENU_COLUMNS; i++)
{ {
@ -2057,8 +2058,8 @@ void M_DrawCupSelect(void)
0, W_CachePatchName("CUPCURS", PU_CACHE) 0, W_CachePatchName("CUPCURS", PU_CACHE)
); );
M_DrawCupPreview(146 + (24*menutransition.tics), cup); M_DrawCupPreview(146 + (24*menutransition.tics), &templevelsearch);
M_DrawCupTitle(120 - (24*menutransition.tics), cup); M_DrawCupTitle(120 - (24*menutransition.tics), templevelsearch.cup);
} }
static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map) static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
@ -2190,7 +2191,7 @@ void M_DrawLevelSelect(void)
{ {
INT16 i = 0; INT16 i = 0;
UINT8 j = 0; UINT8 j = 0;
INT16 map = M_GetFirstLevelInList(&j, levellist.typeoflevel, levellist.selectedcup); INT16 map = M_GetFirstLevelInList(&j, &levellist.levelsearch);
INT16 t = (64*menutransition.tics), tay = 0; INT16 t = (64*menutransition.tics), tay = 0;
INT16 y = 80 - (12 * levellist.y); INT16 y = 80 - (12 * levellist.y);
boolean tatransition = ((menutransition.startmenu == &PLAY_TimeAttackDef || menutransition.endmenu == &PLAY_TimeAttackDef) && menutransition.tics); boolean tatransition = ((menutransition.startmenu == &PLAY_TimeAttackDef || menutransition.endmenu == &PLAY_TimeAttackDef) && menutransition.tics);
@ -2221,10 +2222,10 @@ void M_DrawLevelSelect(void)
y += 72; y += 72;
i++; i++;
map = M_GetNextLevelInList(map, &j, levellist.typeoflevel, levellist.selectedcup); map = M_GetNextLevelInList(map, &j, &levellist.levelsearch);
} }
M_DrawCupTitle(tay, levellist.selectedcup); M_DrawCupTitle(tay, levellist.levelsearch.cup);
} }
void M_DrawTimeAttack(void) void M_DrawTimeAttack(void)
@ -4638,27 +4639,16 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
} }
case SECRET_CUP: case SECRET_CUP:
{ {
cupheader_t *cup = M_UnlockableCup(ref); levelsearch_t templevelsearch;
#if 0 // First attempt
UINT8 i = cup->numlevels;
x = 4; templevelsearch.cup = M_UnlockableCup(ref);
y = (BASEVIDHEIGHT-4) - 38; templevelsearch.typeoflevel = G_TOLFlag(GT_RACE)|G_TOLFlag(GT_BATTLE);
templevelsearch.cupmode = true;
templevelsearch.timeattack = false;
templevelsearch.checklocked = false;
M_DrawCupPreview(146, &templevelsearch);
while (i > 0)
{
i--;
K_DrawMapThumbnail(
(x+(i*2))<<FRACBITS,
(y-(i*6))<<FRACBITS,
60<<FRACBITS,
0,
cup->cachedlevels[i],
NULL);
}
#else
M_DrawCupPreview(146, cup);
#endif
break; break;
} }
case SECRET_MAP: case SECRET_MAP:

View file

@ -3386,8 +3386,11 @@ void M_SetupDifficultySelect(INT32 choice)
// //
// Determines whether to show a given map in the various level-select lists. // Determines whether to show a given map in the various level-select lists.
// //
boolean M_CanShowLevelInList(INT16 mapnum, UINT32 tol, cupheader_t *cup) boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
{ {
if (!levelsearch)
return false;
if (mapnum >= nummapheaders) if (mapnum >= nummapheaders)
return false; return false;
@ -3403,11 +3406,11 @@ boolean M_CanShowLevelInList(INT16 mapnum, UINT32 tol, cupheader_t *cup)
if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR) if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
return false; return false;
if (M_MapLocked(mapnum+1)) if (levelsearch->checklocked && M_MapLocked(mapnum+1))
return false; // not unlocked return false; // not unlocked
// Check for TOL // Check for TOL
if (!(mapheaderinfo[mapnum]->typeoflevel & tol)) if (!(mapheaderinfo[mapnum]->typeoflevel & levelsearch->typeoflevel))
return false; return false;
// Should the map be hidden? // Should the map be hidden?
@ -3415,26 +3418,31 @@ boolean M_CanShowLevelInList(INT16 mapnum, UINT32 tol, cupheader_t *cup)
return false; return false;
// I don't know why, but some may have exceptions. // I don't know why, but some may have exceptions.
if (levellist.timeattack && (mapheaderinfo[mapnum]->menuflags & LF2_NOTIMEATTACK)) if (levelsearch->timeattack && (mapheaderinfo[mapnum]->menuflags & LF2_NOTIMEATTACK))
return false; return false;
// Don't permit cup when no cup requested (also no dupes in time attack) // Don't permit cup when no cup requested (also no dupes in time attack)
if (levellist.cupmode && (levellist.timeattack || !cup) && mapheaderinfo[mapnum]->cup != cup) if (levelsearch->cupmode
&& (levelsearch->timeattack || !levelsearch->cup)
&& mapheaderinfo[mapnum]->cup != levelsearch->cup)
return false; return false;
// Survived our checks. // Survived our checks.
return true; return true;
} }
UINT16 M_CountLevelsToShowInList(UINT32 tol, cupheader_t *cup) UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
{ {
INT16 i, count = 0; INT16 i, count = 0;
if (cup) if (!levelsearch)
return false;
if (levelsearch->cup)
{ {
for (i = 0; i < CUPCACHE_MAX; i++) for (i = 0; i < CUPCACHE_MAX; i++)
{ {
if (!M_CanShowLevelInList(cup->cachedlevels[i], tol, cup)) if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[i], levelsearch))
continue; continue;
count++; count++;
} }
@ -3443,60 +3451,66 @@ UINT16 M_CountLevelsToShowInList(UINT32 tol, cupheader_t *cup)
} }
for (i = 0; i < nummapheaders; i++) for (i = 0; i < nummapheaders; i++)
if (M_CanShowLevelInList(i, tol, NULL)) if (M_CanShowLevelInList(i, levelsearch))
count++; count++;
return count; return count;
} }
UINT16 M_GetFirstLevelInList(UINT8 *i, UINT32 tol, cupheader_t *cup) UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch)
{ {
INT16 mapnum = NEXTMAP_INVALID; INT16 mapnum = NEXTMAP_INVALID;
if (cup) if (!levelsearch)
return false;
if (levelsearch->cup)
{ {
*i = 0; *i = 0;
mapnum = NEXTMAP_INVALID; mapnum = NEXTMAP_INVALID;
for (; *i < CUPCACHE_MAX; (*i)++) for (; *i < CUPCACHE_MAX; (*i)++)
{ {
if (!M_CanShowLevelInList(cup->cachedlevels[*i], tol, cup)) if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[*i], levelsearch))
continue; continue;
mapnum = cup->cachedlevels[*i]; mapnum = levelsearch->cup->cachedlevels[*i];
break; break;
} }
} }
else else
{ {
for (mapnum = 0; mapnum < nummapheaders; mapnum++) for (mapnum = 0; mapnum < nummapheaders; mapnum++)
if (M_CanShowLevelInList(mapnum, tol, NULL)) if (M_CanShowLevelInList(mapnum, levelsearch))
break; break;
} }
return mapnum; return mapnum;
} }
UINT16 M_GetNextLevelInList(UINT16 map, UINT8 *i, UINT32 tol, cupheader_t *cup) UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch)
{ {
if (cup) if (!levelsearch)
return false;
if (levelsearch->cup)
{ {
map = NEXTMAP_INVALID; mapnum = NEXTMAP_INVALID;
(*i)++; (*i)++;
for (; *i < CUPCACHE_MAX; (*i)++) for (; *i < CUPCACHE_MAX; (*i)++)
{ {
if (!M_CanShowLevelInList(cup->cachedlevels[*i], tol, cup)) if (!M_CanShowLevelInList(levelsearch->cup->cachedlevels[*i], levelsearch))
continue; continue;
map = cup->cachedlevels[*i]; mapnum = levelsearch->cup->cachedlevels[*i];
break; break;
} }
} }
else else
{ {
map++; mapnum++;
while (!M_CanShowLevelInList(map, tol, NULL) && map < nummapheaders) while (!M_CanShowLevelInList(mapnum, levelsearch) && mapnum < nummapheaders)
map++; mapnum++;
} }
return map; return mapnum;
} }
struct cupgrid_s cupgrid; struct cupgrid_s cupgrid;
@ -3504,7 +3518,7 @@ struct levellist_s levellist;
static void M_LevelSelectScrollDest(void) static void M_LevelSelectScrollDest(void)
{ {
UINT16 m = M_CountLevelsToShowInList(levellist.typeoflevel, levellist.selectedcup)-1; UINT16 m = M_CountLevelsToShowInList(&levellist.levelsearch)-1;
levellist.dest = (6*levellist.cursor); levellist.dest = (6*levellist.cursor);
@ -3522,9 +3536,9 @@ static void M_LevelListFromGametype(INT16 gt)
if (first || gt != levellist.newgametype) if (first || gt != levellist.newgametype)
{ {
levellist.newgametype = gt; levellist.newgametype = gt;
levellist.typeoflevel = G_TOLFlag(gt); levellist.levelsearch.typeoflevel = G_TOLFlag(gt);
levellist.cupmode = (!(gametypedefaultrules[gt] & GTR_NOCUPSELECT)); levellist.levelsearch.cupmode = (!(gametypedefaultrules[gt] & GTR_NOCUPSELECT));
levellist.selectedcup = NULL; levellist.levelsearch.cup = NULL;
first = false; first = false;
} }
@ -3533,14 +3547,17 @@ static void M_LevelListFromGametype(INT16 gt)
// Obviously go to Cup Select in gametypes that have cups. // Obviously go to Cup Select in gametypes that have cups.
// Use a really long level select in gametypes that don't use cups. // Use a really long level select in gametypes that don't use cups.
if (levellist.cupmode) if (levellist.levelsearch.cupmode)
{ {
cupheader_t *cup = kartcupheaders; levelsearch_t templevelsearch = levellist.levelsearch; // full copy
size_t currentid = 0, highestunlockedid = 0; size_t currentid = 0, highestunlockedid = 0;
const size_t unitlen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS); const size_t unitlen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
templevelsearch.cup = kartcupheaders;
templevelsearch.checklocked = false;
// Make sure there's valid cups before going to this menu. // Make sure there's valid cups before going to this menu.
if (cup == NULL) if (templevelsearch.cup == NULL)
I_Error("Can you really call this a racing game, I didn't recieve any Cups on my pillow or anything"); I_Error("Can you really call this a racing game, I didn't recieve any Cups on my pillow or anything");
if (!cupgrid.builtgrid) if (!cupgrid.builtgrid)
@ -3558,12 +3575,12 @@ static void M_LevelListFromGametype(INT16 gt)
} }
memset(cupgrid.builtgrid, 0, cupgrid.cappages * unitlen); memset(cupgrid.builtgrid, 0, cupgrid.cappages * unitlen);
while (cup) while (templevelsearch.cup)
{ {
if (!M_CountLevelsToShowInList(levellist.typeoflevel, cup)) if (!M_CountLevelsToShowInList(&templevelsearch))
{ {
// No valid maps, skip. // No valid maps, skip.
cup = cup->next; templevelsearch.cup = templevelsearch.cup->next;
continue; continue;
} }
@ -3584,21 +3601,21 @@ static void M_LevelListFromGametype(INT16 gt)
cupgrid.cappages *= 2; cupgrid.cappages *= 2;
} }
cupgrid.builtgrid[currentid] = cup; cupgrid.builtgrid[currentid] = templevelsearch.cup;
if (!M_CupLocked(cup)) if (!M_CupLocked(templevelsearch.cup))
{ {
highestunlockedid = currentid; highestunlockedid = currentid;
if (Playing() && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == cup) if (Playing() && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
{ {
cupgrid.x = cup->id % CUPMENU_COLUMNS; cupgrid.x = currentid % CUPMENU_COLUMNS;
cupgrid.y = (cup->id / CUPMENU_COLUMNS) % CUPMENU_ROWS; cupgrid.y = (currentid / CUPMENU_COLUMNS) % CUPMENU_ROWS;
cupgrid.pageno = cup->id / (CUPMENU_COLUMNS * CUPMENU_ROWS); cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS);
} }
} }
currentid++; currentid++;
cup = cup->next; templevelsearch.cup = templevelsearch.cup->next;
} }
cupgrid.numpages = (highestunlockedid / (CUPMENU_COLUMNS * CUPMENU_ROWS)) + 1; cupgrid.numpages = (highestunlockedid / (CUPMENU_COLUMNS * CUPMENU_ROWS)) + 1;
@ -3614,10 +3631,10 @@ static void M_LevelListFromGametype(INT16 gt)
} }
// Reset position properly if you go back & forth between gametypes // Reset position properly if you go back & forth between gametypes
if (levellist.selectedcup) if (levellist.levelsearch.cup)
{ {
levellist.cursor = 0; levellist.cursor = 0;
levellist.selectedcup = NULL; levellist.levelsearch.cup = NULL;
} }
M_LevelSelectScrollDest(); M_LevelSelectScrollDest();
@ -3636,22 +3653,24 @@ void M_LevelSelectInit(INT32 choice)
{ {
(void)choice; (void)choice;
levellist.netgame = false; // Make sure this is reset as we'll only be using this function for offline games! // Make sure this is reset as we'll only be using this function for offline games!
cupgrid.netgame = false; // Ditto cupgrid.netgame = false;
levellist.netgame = false;
levellist.levelsearch.checklocked = true;
switch (currentMenu->menuitems[itemOn].mvar1) switch (currentMenu->menuitems[itemOn].mvar1)
{ {
case 0: case 0:
cupgrid.grandprix = false; cupgrid.grandprix = false;
levellist.timeattack = false; levellist.levelsearch.timeattack = false;
break; break;
case 1: case 1:
cupgrid.grandprix = false; cupgrid.grandprix = false;
levellist.timeattack = true; levellist.levelsearch.timeattack = true;
break; break;
case 2: case 2:
cupgrid.grandprix = true; cupgrid.grandprix = true;
levellist.timeattack = false; levellist.levelsearch.timeattack = false;
break; break;
default: default:
CONS_Alert(CONS_WARNING, "Bad level select init\n"); CONS_Alert(CONS_WARNING, "Bad level select init\n");
@ -3787,10 +3806,10 @@ void M_CupSelectHandler(INT32 choice)
else else
{ {
// Keep cursor position if you select the same cup again, reset if it's a different cup // Keep cursor position if you select the same cup again, reset if it's a different cup
if (levellist.selectedcup != newcup) if (levellist.levelsearch.cup != newcup)
{ {
levellist.cursor = 0; levellist.cursor = 0;
levellist.selectedcup = newcup; levellist.levelsearch.cup = newcup;
} }
M_LevelSelectScrollDest(); M_LevelSelectScrollDest();
@ -3818,7 +3837,7 @@ void M_CupSelectTick(void)
void M_LevelSelectHandler(INT32 choice) void M_LevelSelectHandler(INT32 choice)
{ {
INT16 maxlevels = M_CountLevelsToShowInList(levellist.typeoflevel, levellist.selectedcup); INT16 maxlevels = M_CountLevelsToShowInList(&levellist.levelsearch);
const UINT8 pid = 0; const UINT8 pid = 0;
(void)choice; (void)choice;
@ -3850,14 +3869,14 @@ void M_LevelSelectHandler(INT32 choice)
if (M_MenuConfirmPressed(pid) /*|| M_MenuButtonPressed(pid, MBT_START)*/) if (M_MenuConfirmPressed(pid) /*|| M_MenuButtonPressed(pid, MBT_START)*/)
{ {
UINT8 i = 0; UINT8 i = 0;
INT16 map = M_GetFirstLevelInList(&i, levellist.typeoflevel, levellist.selectedcup); INT16 map = M_GetFirstLevelInList(&i, &levellist.levelsearch);
INT16 add = levellist.cursor; INT16 add = levellist.cursor;
M_SetMenuDelay(pid); M_SetMenuDelay(pid);
while (add > 0) while (add > 0)
{ {
map = M_GetNextLevelInList(map, &i, levellist.typeoflevel, levellist.selectedcup); map = M_GetNextLevelInList(map, &i, &levellist.levelsearch);
if (map >= nummapheaders) if (map >= nummapheaders)
{ {
@ -3875,7 +3894,7 @@ void M_LevelSelectHandler(INT32 choice)
levellist.choosemap = map; levellist.choosemap = map;
if (levellist.timeattack) if (levellist.levelsearch.timeattack)
{ {
M_SetupNextMenu(&PLAY_TimeAttackDef, false); M_SetupNextMenu(&PLAY_TimeAttackDef, false);
S_StartSound(NULL, sfx_s3k63); S_StartSound(NULL, sfx_s3k63);
@ -4106,10 +4125,13 @@ void M_MPSetupNetgameMapSelect(INT32 choice)
INT16 gt = GT_RACE; INT16 gt = GT_RACE;
(void)choice; (void)choice;
levellist.netgame = true; // Yep, we'll be starting a netgame. // Yep, we'll be starting a netgame.
cupgrid.netgame = true; // Ditto levellist.netgame = true;
levellist.timeattack = false; // Make sure we reset those cupgrid.netgame = true;
cupgrid.grandprix = false; // Ditto // Make sure we reset those
levellist.levelsearch.timeattack = false;
levellist.levelsearch.checklocked = true;
cupgrid.grandprix = false;
// In case we ever want to add new gamemodes there somehow, have at it! // In case we ever want to add new gamemodes there somehow, have at it!
switch (cv_dummygametype.value) switch (cv_dummygametype.value)