G_GetNextMap cleanup

- Lost & Found courses are now part of the intended sequence of `advancemap next`
    - Does not include Test Run, that's admin choice only
- Courses with too-small playerLimits will be skipped for both `advancemap random` and `advancemap next`
    - Resolves KartKrew/Kart#1411
This commit is contained in:
toaster 2024-10-05 17:44:55 +01:00
parent 63aaec65b1
commit a8d8a10319

View file

@ -4406,13 +4406,28 @@ void G_GetNextMap(void)
if (setalready == false) if (setalready == false)
{ {
UINT8 numPlayers = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
{
continue;
}
numPlayers++;
}
UINT32 tolflag = G_TOLFlag(gametype); UINT32 tolflag = G_TOLFlag(gametype);
register INT16 cm; register INT16 cm;
if (!(gametyperules & GTR_NOCUPSELECT)) const boolean cupmode = (!(gametyperules & GTR_NOCUPSELECT));
nextmap = NEXTMAP_TITLE;
if (cupmode)
{ {
cupheader_t *cup = mapheaderinfo[gamemap-1]->cup; cupheader_t *cup = mapheaderinfo[prevmap]->cup;
UINT8 gettingresult = 0; boolean gettingresult = false;
while (cup) while (cup)
{ {
@ -4420,7 +4435,7 @@ void G_GetNextMap(void)
if (!marathonmode && M_CupLocked(cup)) if (!marathonmode && M_CupLocked(cup))
{ {
cup = cup->next; cup = cup->next;
gettingresult = 1; gettingresult = true;
continue; continue;
} }
@ -4437,6 +4452,35 @@ void G_GetNextMap(void)
continue; continue;
} }
// If the map is in multiple cups, only consider the first one valid.
if (mapheaderinfo[cm]->cup != cup)
{
continue;
}
if (!gettingresult)
{
// Not the map you're on?
if (cm == prevmap)
{
// Ok, this is the current map, time to get the next valid
gettingresult = true;
}
continue;
}
if ((mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU) == LF2_HIDEINMENU)
{
// Not intended to be accessed in multiplayer.
continue;
}
if (numPlayers > mapheaderinfo[cm]->playerLimit)
{
// Too many players for this map.
continue;
}
// Only care about restrictions if the host is a listen server. // Only care about restrictions if the host is a listen server.
if (!dedicated && !marathonmode) if (!dedicated && !marathonmode)
{ {
@ -4462,32 +4506,13 @@ void G_GetNextMap(void)
continue; continue;
} }
// If the map is in multiple cups, only consider the first one valid.
if (mapheaderinfo[cm]->cup != cup)
{
continue;
}
// Grab the first valid after the map you're on // Grab the first valid after the map you're on
if (gettingresult)
{
nextmap = cm; nextmap = cm;
gettingresult = 2;
break; break;
} }
// Not the map you're on?
if (cm != prevmap)
{
continue;
}
// Ok, this is the current map, time to get the next
gettingresult = 1;
}
// We have a good nextmap? // We have a good nextmap?
if (gettingresult == 2) if (nextmap < NEXTMAP_SPECIAL)
{ {
break; break;
} }
@ -4495,22 +4520,25 @@ void G_GetNextMap(void)
// Ok, iterate to the next // Ok, iterate to the next
cup = cup->next; cup = cup->next;
} }
// Didn't get a nextmap before reaching the end?
if (gettingresult != 2)
{
nextmap = NEXTMAP_CEREMONY; // ceremonymap
} }
// Haven't grabbed a nextmap yet?
if (nextmap >= NEXTMAP_SPECIAL)
{
if (cupmode && mapheaderinfo[prevmap]->cup)
{
// Special case - looking for Lost & Found #1.
// Could be anywhere in mapheaderinfo.
cm = 0;
} }
else else
{ {
cm = prevmap; // All subsequent courses in load order.
cm = prevmap+1;
}
do for (; cm < nummapheaders; cm++)
{ {
if (++cm >= nummapheaders)
cm = 0;
if (!mapheaderinfo[cm] if (!mapheaderinfo[cm]
|| mapheaderinfo[cm]->lumpnum == LUMPERROR || mapheaderinfo[cm]->lumpnum == LUMPERROR
|| !(mapheaderinfo[cm]->typeoflevel & tolflag) || !(mapheaderinfo[cm]->typeoflevel & tolflag)
@ -4519,6 +4547,24 @@ void G_GetNextMap(void)
continue; continue;
} }
if (cupmode && mapheaderinfo[cm]->cup)
{
// Only Lost & Found this loop around.
continue;
}
if ((mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU) == LF2_HIDEINMENU)
{
// Not intended to be accessed in multiplayer.
continue;
}
if (numPlayers > mapheaderinfo[cm]->playerLimit)
{
// Too many players for this map.
continue;
}
// Only care about restrictions if the host is a listen server. // Only care about restrictions if the host is a listen server.
if (!dedicated && !marathonmode) if (!dedicated && !marathonmode)
{ {
@ -4547,10 +4593,9 @@ void G_GetNextMap(void)
continue; continue;
} }
break;
} while (cm != prevmap);
nextmap = cm; nextmap = cm;
break;
}
} }
if (K_CanChangeRules(true)) if (K_CanChangeRules(true))
@ -4563,24 +4608,14 @@ void G_GetNextMap(void)
nextmap = prevmap; nextmap = prevmap;
break; break;
case 3: // Voting screen. case 3: // Voting screen.
{ if (numPlayers != 0)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator)
continue;
break;
}
if (i != MAXPLAYERS)
{ {
nextmap = NEXTMAP_VOTING; nextmap = NEXTMAP_VOTING;
break; break;
} }
}
/* FALLTHRU */ /* FALLTHRU */
case 2: // Go to random map. case 2: // Go to random map.
nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, false, NULL); nextmap = G_RandMapPerPlayerCount(G_TOLFlag(gametype), prevmap, false, false, NULL, numPlayers);
break; break;
default: default:
if (nextmap >= NEXTMAP_SPECIAL) // Loop back around if (nextmap >= NEXTMAP_SPECIAL) // Loop back around