Save override for level header

Kind of like 2.2's, but with backwards-compatability with 2.1
This commit is contained in:
TehRealSalt 2018-12-16 20:09:59 -05:00
parent d85c9b5abc
commit 9e596d15af
4 changed files with 50 additions and 4 deletions

View file

@ -1248,6 +1248,18 @@ static void readlevelheader(MYFILE *f, INT32 num)
deh_warning("Level header %d: invalid bonus type number %d", num, i);
}
else if (fastcmp(word, "SAVEOVERRIDE"))
{
if (fastcmp(word2, "DEFAULT")) i = SAVE_DEFAULT;
else if (fastcmp(word2, "ALWAYS")) i = SAVE_ALWAYS;
else if (fastcmp(word2, "NEVER")) i = SAVE_NEVER;
if (i >= SAVE_NEVER && i <= SAVE_ALWAYS)
mapheaderinfo[num-1]->saveoverride = (SINT8)i;
else
deh_warning("Level header %d: invalid save override number %d", num, i);
}
else if (fastcmp(word, "LEVELFLAGS"))
mapheaderinfo[num-1]->levelflags = (UINT8)i;
else if (fastcmp(word, "MENUFLAGS"))
@ -7074,6 +7086,11 @@ struct {
{"LF2_NIGHTSATTACK",LF2_NIGHTSATTACK},
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
// Save override
{"SAVE_NEVER",SAVE_NEVER},
{"SAVE_DEFAULT",SAVE_DEFAULT},
{"SAVE_ALWAYS",SAVE_ALWAYS},
// NiGHTS grades
{"GRADE_F",GRADE_F},
{"GRADE_E",GRADE_E},

View file

@ -234,6 +234,7 @@ typedef struct
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
SINT8 saveoverride; ///< Set how the game is allowed to save (1 for always, -1 for never, 0 is 2.1 default)
UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
@ -261,6 +262,11 @@ typedef struct
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
// Save override
#define SAVE_NEVER -1
#define SAVE_DEFAULT 0
#define SAVE_ALWAYS 1
extern mapheader_t* mapheaderinfo[NUMMAPS];
enum TypeOfLevel

View file

@ -1504,6 +1504,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelselect);
else if (fastcmp(field,"bonustype"))
lua_pushinteger(L, header->bonustype);
else if (fastcmp(field,"saveoverride"))
lua_pushinteger(L, header->saveoverride);
else if (fastcmp(field,"levelflags"))
lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"menuflags"))

View file

@ -219,6 +219,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->levelselect = 0;
DEH_WriteUndoline("BONUSTYPE", va("%d", mapheaderinfo[num]->bonustype), UNDO_NONE);
mapheaderinfo[num]->bonustype = 0;
DEH_WriteUndoline("SAVEOVERRIDE", va("%d", mapheaderinfo[num]->saveoverride), UNDO_NONE);
mapheaderinfo[num]->saveoverride = SAVE_DEFAULT;
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
mapheaderinfo[num]->levelflags = 0;
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
@ -2626,6 +2628,28 @@ static void P_SetupCamera(void)
}
}
static boolean P_CanSave(void)
{
// Saving is completely ignored under these conditions:
if ((cursaveslot < 0) // Playing without saving
|| (!modifiedgame || savemoddata) // Game is modified
|| (netgame || multiplayer) // Not in single-player
|| (demoplayback || demorecording || metalrecording) // Currently in demo
|| (players[consoleplayer].lives <= 0) // Completely dead
|| (modeattacking || ultimatemode || G_IsSpecialStage(gamemap))) // Specialized instances
return false;
if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_ALWAYS)
return true; // Saving should ALWAYS happen!
else if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_NEVER)
return false; // Saving should NEVER happen!
// Default condition: In a non-hidden map, at the beginning of a zone or on a completed save-file, and not on save reload.
return (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
&& (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete)
&& (gamemap != lastmapsaved));
}
/** Loads a level from a lump or external wad.
*
* \param skipprecip If true, don't spawn precipitation.
@ -3103,10 +3127,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_RunCachedActions();
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
&& (!modifiedgame || savemoddata) && cursaveslot >= 0 && !ultimatemode
&& !(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
&& (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete))
if (P_CanSave())
G_SaveGame((UINT32)cursaveslot);
if (savedata.lives > 0)