M_SanitiseChallengeGrid

Attempts to recover Challenge Grids that aren't quite appropriate for the current suite of unlocks.
- If there's multiple small tiles pointing to the same unlock, turn the later ones empty.
- If there's a small tile that SHOULD present on the grid and an empty spot, put the needed tile in that spot.
- Otherwise, regenerate the entire grid.
This will permit us to change the number of unlockables without forcing people to run with the command line param `-resetchallengegrid` to see 'em.
This commit is contained in:
toaster 2023-06-06 18:41:43 +01:00
parent 7fd957c929
commit f106d14d69
3 changed files with 85 additions and 0 deletions

View file

@ -4974,6 +4974,8 @@ void G_LoadGameData(void)
gamedata->challengegrid[i] = READUINT16(save.p);
}
}
M_SanitiseChallengeGrid();
}
else
{

View file

@ -312,6 +312,88 @@ quickcheckagain:
}
}
void M_SanitiseChallengeGrid(void)
{
UINT8 seen[MAXUNLOCKABLES];
UINT16 empty[MAXUNLOCKABLES + (CHALLENGEGRIDHEIGHT-1)];
UINT16 i, j, numempty = 0;
if (gamedata->challengegrid == NULL)
return;
memset(seen, 0, sizeof(seen));
// Go through all spots to identify duplicates and absences.
for (j = 0; j < gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT; j++)
{
i = gamedata->challengegrid[j];
if (i >= MAXUNLOCKABLES || !unlockables[i].conditionset)
{
empty[numempty++] = j;
continue;
}
if (seen[i] != 5) // Arbitrary cap greater than 4
{
seen[i]++;
if (seen[i] == 1 || unlockables[i].majorunlock)
{
continue;
}
}
empty[numempty++] = j;
}
// Go through unlockables to identify if any haven't been seen.
for (i = 0; i < MAXUNLOCKABLES; ++i)
{
if (!unlockables[i].conditionset)
{
continue;
}
if (unlockables[i].majorunlock && seen[i] != 4)
{
// Probably not enough spots to retrofit.
goto badgrid;
}
if (seen[i] != 0)
{
// Present on the challenge grid.
continue;
}
if (numempty != 0)
{
// Small ones can be slotted in easy.
j = empty[--numempty];
gamedata->challengegrid[j] = i;
}
// Nothing we can do to recover.
goto badgrid;
}
// Fill the remaining spots with empties.
while (numempty != 0)
{
j = empty[--numempty];
gamedata->challengegrid[j] = MAXUNLOCKABLES;
}
return;
badgrid:
// Just remove everything and let it get regenerated.
Z_Free(gamedata->challengegrid);
gamedata->challengegrid = NULL;
gamedata->challengegridwidth = 0;
}
void M_UpdateChallengeGridExtraData(challengegridextradata_t *extradata)
{
UINT16 i, j, num, id, tempid, work;

View file

@ -302,6 +302,7 @@ void M_NewGameDataStruct(void);
// Challenges menu stuff
void M_PopulateChallengeGrid(void);
void M_SanitiseChallengeGrid(void);
struct challengegridextradata_t
{