M_FinaliseGameData

Creates a central landing point where gamedata loads/creates can be finalised properly.

In addition, gamedata wipes caused by data erase or custom SOC gamedata can no longer be saved in a partway corrupted state if they were to crash midway through.
This commit is contained in:
toaster 2023-08-19 12:21:15 +01:00
parent 7f89bee3f2
commit fb8795c8da
6 changed files with 26 additions and 11 deletions

View file

@ -3007,6 +3007,7 @@ void readmaincfg(MYFILE *f, boolean mainfile)
strlwr(gamedatafilename);
savemoddata = true;
majormods = false;
gamedata->loaded = false;
// Also save a time attack folder
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension

View file

@ -607,7 +607,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (gamedataadded)
G_LoadGameData();
if (gamestate == GS_TITLESCREEN)
if (gamestate == GS_MENU || gamestate == GS_TITLESCREEN)
{
if (introchanged)
{

View file

@ -4863,14 +4863,7 @@ void G_LoadGameData(void)
finalisegamedata:
{
// Don't consider loaded until it's a success!
// It used to do this much earlier, but this would cause the gamedata to
// save over itself when it I_Errors from the corruption landing point below,
// which can accidentally delete players' legitimate data if the code ever has any tiny mistakes!
gamedata->loaded = true;
// Silent update unlockables in case they're out of sync with conditions
M_UpdateUnlockablesAndExtraEmblems(false, true);
M_FinaliseGameData();
return;
}

View file

@ -640,6 +640,21 @@ void M_ClearSecrets(void)
gamedata->chaokeys = 3; // Start with 3 !!
}
void M_FinaliseGameData(void)
{
//M_PopulateChallengeGrid(); -- This can be done lazily when we actually need it
// Don't consider loaded until it's a success!
// It used to do this much earlier, but this would cause the gamedata
// to save over itself when it I_Errors from corruption, which can
// accidentally delete players' legitimate data if the code ever has
// any tiny mistakes!
gamedata->loaded = true;
// Silent update unlockables in case they're out of sync with conditions
M_UpdateUnlockablesAndExtraEmblems(false, true);
}
// ----------------------
// Condition set checking
// ----------------------

View file

@ -257,6 +257,8 @@ struct gamedata_t
{
// WHENEVER OR NOT WE'RE READY TO SAVE
boolean loaded;
// DEFERRED EVENTS RELATING TO CHALLENGE PROCESSING
boolean deferredsave;
boolean deferredconditioncheck;
@ -338,10 +340,11 @@ char *M_BuildConditionSetString(UINT16 unlockid);
void M_AddRawCondition(UINT16 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2, char *stringvar);
void M_UpdateConditionSetsPending(void);
// Clearing secrets
// Gamedata clear/init
void M_ClearConditionSet(UINT16 set);
void M_ClearSecrets(void);
void M_ClearStats(void);
void M_FinaliseGameData(void);
boolean M_NotFreePlay(void);
UINT16 M_CheckCupEmeralds(UINT8 difficulty);

View file

@ -60,6 +60,9 @@ static void M_EraseDataResponse(INT32 ch)
// Delete the data
// see also G_LoadGameData
// We do these in backwards order to prevent things from being immediately re-unlocked.
gamedata->loaded = false;
if (optionsmenu.erasecontext & EC_TIMEATTACK)
G_ClearRecords();
if (optionsmenu.erasecontext & EC_STATISTICS)
@ -67,7 +70,7 @@ static void M_EraseDataResponse(INT32 ch)
if (optionsmenu.erasecontext & EC_CHALLENGES)
M_ClearSecrets();
M_UpdateUnlockablesAndExtraEmblems(false, true);
M_FinaliseGameData();
// Don't softlock the Stereo on if you won't be able to access it anymore!?
if (soundtest.playing && M_SecretUnlocked(SECRET_SOUNDTEST, true) == false)