diff --git a/src/fios.cpp b/src/fios.cpp index 05a87e8b04..7692a30723 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -787,7 +787,16 @@ FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(p */ std::string FiosNumberedSaveName::Filename() { - if (++this->number >= _settings_client.gui.max_num_autosaves) this->number = 0; + return this->FilenameUsingMaxSaves(_settings_client.gui.max_num_autosaves); +} + +/** + * Generate a savegame name and number according to max_saves. + * @return A filename in format ".sav". +*/ +std::string FiosNumberedSaveName::FilenameUsingMaxSaves(int max_saves) +{ + if (++this->number >= max_saves) this->number = 0; return this->FilenameUsingNumber(this->number, ""); } diff --git a/src/fios.h b/src/fios.h index efb61888bf..c387ef6d3d 100644 --- a/src/fios.h +++ b/src/fios.h @@ -75,6 +75,7 @@ const char *FindScenario(const ContentInfo *ci, bool md5sum); struct FiosNumberedSaveName { FiosNumberedSaveName(const std::string &prefix); std::string Filename(); + std::string FilenameUsingMaxSaves(int max_saves); std::string FilenameUsingNumber(int num, const char *suffix) const; std::string Extension(); int GetLastNumber() const { return this->number; } diff --git a/src/openttd.cpp b/src/openttd.cpp index 613d7cc9b7..4dcad739d6 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -2143,13 +2143,23 @@ FiosNumberedSaveName &GetAutoSaveFiosNumberedSaveName() return _autosave_ctr; } +FiosNumberedSaveName &GetLongTermAutoSaveFiosNumberedSaveName() +{ + static FiosNumberedSaveName _autosave_lt_ctr("ltautosave"); + return _autosave_lt_ctr; +} + /** * Create an autosave. The default name is "autosave#.sav". However with * the setting 'keep_all_autosave' the name defaults to company-name + date */ static void DoAutosave() { - DoAutoOrNetsave(GetAutoSaveFiosNumberedSaveName(), true); + FiosNumberedSaveName *lt_counter = nullptr; + if (_settings_client.gui.max_num_autosaves > 0) { + lt_counter = &GetLongTermAutoSaveFiosNumberedSaveName(); + } + DoAutoOrNetsave(GetAutoSaveFiosNumberedSaveName(), true, lt_counter); } /** diff --git a/src/settings_type.h b/src/settings_type.h index f6a6ae455e..9abac748d5 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -178,6 +178,7 @@ struct GUISettings : public TimeSettings { bool autosave_on_network_disconnect; ///< save an autosave when you get disconnected from a network game with an error? uint8 date_format_in_default_names; ///< should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) or ISO dates (2008-12-31) byte max_num_autosaves; ///< controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num_autosaves - 1) + byte max_num_lt_autosaves; ///< controls how many long-term autosavegames are made before the game starts to overwrite (names them 0 to max_num_lt_autosaves - 1) uint8 savegame_overwrite_confirm; ///< Mode for when to warn about overwriting an existing savegame bool population_in_label; ///< show the population of a town in its label? uint8 right_mouse_btn_emulation; ///< should we emulate right mouse clicking? diff --git a/src/sl/saveload.cpp b/src/sl/saveload.cpp index 300f015d88..ddd674ac05 100644 --- a/src/sl/saveload.cpp +++ b/src/sl/saveload.cpp @@ -3722,7 +3722,7 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, * @param counter A reference to the counter variable to be used for rotating the file name. * @param netsave Indicates if this is a regular autosave or a netsave. */ -void DoAutoOrNetsave(FiosNumberedSaveName &counter, bool threaded) +void DoAutoOrNetsave(FiosNumberedSaveName &counter, bool threaded, FiosNumberedSaveName *lt_counter) { char buf[MAX_PATH]; @@ -3731,6 +3731,12 @@ void DoAutoOrNetsave(FiosNumberedSaveName &counter, bool threaded) strecat(buf, counter.Extension().c_str(), lastof(buf)); } else { strecpy(buf, counter.Filename().c_str(), lastof(buf)); + if (lt_counter != nullptr && counter.GetLastNumber() == 0) { + std::string lt_path = lt_counter->FilenameUsingMaxSaves(_settings_client.gui.max_num_lt_autosaves); + DEBUG(sl, 2, "Renaming autosave '%s' to long-term file '%s'", buf, lt_path.c_str()); + std::string dir = FioFindDirectory(AUTOSAVE_DIR); + rename((dir + buf).c_str(), (dir + lt_path).c_str()); + } } DEBUG(sl, 2, "Autosaving to '%s'", buf); diff --git a/src/sl/saveload.h b/src/sl/saveload.h index dc17a68964..f4da1c19bf 100644 --- a/src/sl/saveload.h +++ b/src/sl/saveload.h @@ -68,7 +68,7 @@ void WaitTillSaved(); void ProcessAsyncSaveFinish(); void DoExitSave(); -void DoAutoOrNetsave(FiosNumberedSaveName &counter, bool threaded); +void DoAutoOrNetsave(FiosNumberedSaveName &counter, bool threaded, FiosNumberedSaveName *lt_counter = nullptr); SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded, SaveModeFlags flags); SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader); diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 617b9a5a40..0a19e972e3 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -5487,6 +5487,14 @@ def = 16 min = 0 max = 255 +[SDTC_VAR] +var = gui.max_num_lt_autosaves +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 8 +min = 0 +max = 255 + [SDTC_OMANY] var = gui.savegame_overwrite_confirm type = SLE_UINT8