Adds option to use a rotation of quicksaves instead of having one quicksave slot that needs to be manually created.

This commit is contained in:
Kevin Hutchins 2019-07-13 13:38:44 -07:00
parent 28d4401f4b
commit 5cb59018e0
6 changed files with 58 additions and 9 deletions

View file

@ -95,8 +95,9 @@ void G_DoPlayDemo (void);
void G_DoCompleted (void); void G_DoCompleted (void);
void G_DoVictory (void); void G_DoVictory (void);
void G_DoWorldDone (void); void G_DoWorldDone (void);
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description); void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, const char *description);
void G_DoAutoSave (); void G_DoAutoSave ();
void G_DoQuickSave ();
void STAT_Serialize(FSerializer &file); void STAT_Serialize(FSerializer &file);
bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content); bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content);
@ -1059,7 +1060,7 @@ void G_Ticker ()
G_DoLoadGame (); G_DoLoadGame ();
break; break;
case ga_savegame: case ga_savegame:
G_DoSaveGame (true, savegamefile, savedescription); G_DoSaveGame (true, false, savegamefile, savedescription);
gameaction = ga_nothing; gameaction = ga_nothing;
savegamefile = ""; savegamefile = "";
savedescription = ""; savedescription = "";
@ -2028,6 +2029,14 @@ CUSTOM_CVAR (Int, autosavecount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
if (self < 0) if (self < 0)
self = 0; self = 0;
} }
CVAR (Int, quicksavenum, -1, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
static int lastquicksave = -1;
CVAR (Bool, quicksaverotation, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Int, quicksaverotationcount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
if (self < 1)
self = 1;
}
void G_DoAutoSave () void G_DoAutoSave ()
{ {
@ -2061,7 +2070,35 @@ void G_DoAutoSave ()
readableTime = myasctime (); readableTime = myasctime ();
description.Format("Autosave %s", readableTime); description.Format("Autosave %s", readableTime);
G_DoSaveGame (false, file, description); G_DoSaveGame (false, false, file, description);
}
void G_DoQuickSave ()
{
FString description;
FString file;
// Keeps a rotating set of quicksaves
UCVarValue num;
const char *readableTime;
int count = quicksaverotationcount != 0 ? quicksaverotationcount : 1;
if (quicksavenum < 0)
{
lastquicksave = 0;
}
else
{
lastquicksave = (quicksavenum + 1) % count;
}
num.Int = lastquicksave;
quicksavenum.ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("quick", lastquicksave);
readableTime = myasctime ();
description.Format("Quicksave %s", readableTime);
G_DoSaveGame (true, true, file, description);
} }
@ -2166,7 +2203,7 @@ static void PutSavePic (FileWriter *file, int width, int height)
} }
} }
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description) void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, const char *description)
{ {
TArray<FCompressedBuffer> savegame_content; TArray<FCompressedBuffer> savegame_content;
TArray<FString> savegame_filenames; TArray<FString> savegame_filenames;
@ -2282,7 +2319,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
WriteZip(filename, savegame_filenames, savegame_content); WriteZip(filename, savegame_filenames, savegame_content);
savegameManager.NotifyNewSave (filename, description, okForQuicksave); savegameManager.NotifyNewSave (filename, description, okForQuicksave, forceQuicksave);
// delete the JSON buffers we created just above. Everything else will // delete the JSON buffers we created just above. Everything else will
// either still be needed or taken care of automatically. // either still be needed or taken care of automatically.

View file

@ -82,6 +82,8 @@ void G_DoLoadGame (void);
// Called by M_Responder. // Called by M_Responder.
void G_SaveGame (const char *filename, const char *description); void G_SaveGame (const char *filename, const char *description);
// Called by messagebox
void G_DoQuickSave ();
// Only called by startup code. // Only called by startup code.
void G_RecordDemo (const char* name); void G_RecordDemo (const char* name);

View file

@ -318,7 +318,7 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, ReadSaveStrings)
// //
//============================================================================= //=============================================================================
void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave) void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave, bool forceQuicksave)
{ {
FSaveGameNode *node; FSaveGameNode *node;
@ -342,7 +342,7 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title,
node->bMissingWads = false; node->bMissingWads = false;
if (okForQuicksave) if (okForQuicksave)
{ {
if (quickSaveSlot == nullptr) quickSaveSlot = node; if (quickSaveSlot == nullptr || forceQuicksave) quickSaveSlot = node;
LastAccessed = LastSaved = i; LastAccessed = LastSaved = i;
} }
return; return;
@ -358,7 +358,7 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title,
if (okForQuicksave) if (okForQuicksave)
{ {
if (quickSaveSlot == nullptr) quickSaveSlot = node; if (quickSaveSlot == nullptr || forceQuicksave) quickSaveSlot = node;
LastAccessed = LastSaved = index; LastAccessed = LastSaved = index;
} }
} }

View file

@ -84,7 +84,7 @@ public:
private: private:
int InsertSaveNode(FSaveGameNode *node); int InsertSaveNode(FSaveGameNode *node);
public: public:
void NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave); void NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave, bool forceQuicksave);
void ClearSaveGames(); void ClearSaveGames();
void ReadSaveStrings(); void ReadSaveStrings();

View file

@ -44,6 +44,7 @@
#include "vm.h" #include "vm.h"
EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd]
EXTERN_CVAR (Bool, quicksaverotation)
typedef void(*hfunc)(); typedef void(*hfunc)();
DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler)
@ -175,6 +176,13 @@ CCMD (quicksave)
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
return; return;
// If the quick save rotation is enabled, it handles the save slot.
if (quicksaverotation)
{
G_DoQuickSave();
return;
}
if (savegameManager.quickSaveSlot == NULL) if (savegameManager.quickSaveSlot == NULL)
{ {
S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE);

View file

@ -1182,6 +1182,8 @@ OptionMenu "MiscOptions" protected
Option "$MISCMNU_ENABLEAUTOSAVES", "disableautosave", "Autosave" Option "$MISCMNU_ENABLEAUTOSAVES", "disableautosave", "Autosave"
Option "$MISCMNU_SAVELOADCONFIRMATION", "saveloadconfirmation", "OnOff" Option "$MISCMNU_SAVELOADCONFIRMATION", "saveloadconfirmation", "OnOff"
Slider "$MISCMNU_AUTOSAVECOUNT", "autosavecount", 1, 20, 1, 0 Slider "$MISCMNU_AUTOSAVECOUNT", "autosavecount", 1, 20, 1, 0
Option "$MISCMNU_QUICKSAVEROTATION", "quicksaverotation", "OnOff"
Slider "$MISCMNU_QUICKSAVECOUNT", "quicksaverotationcount", 1, 20, 1, 0
Option "$MISCMNU_DEHLOAD", "dehload", "dehopt" Option "$MISCMNU_DEHLOAD", "dehload", "dehopt"
Option "$MISCMNU_ENABLESCRIPTSCREENSHOTS", "enablescriptscreenshot", "OnOff" Option "$MISCMNU_ENABLESCRIPTSCREENSHOTS", "enablescriptscreenshot", "OnOff"
Option "$MISCMNU_INTERSCROLL", "nointerscrollabort", "OffOn" Option "$MISCMNU_INTERSCROLL", "nointerscrollabort", "OffOn"