From 583663bca101de9fab81f1fdf6f42696f447cc5d Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 14 Dec 2021 18:08:06 +0000 Subject: [PATCH] Allow setting autosave interval to a custom number of days --- src/date.cpp | 8 +++- src/lang/english.txt | 8 ++++ src/settings.cpp | 4 ++ src/settings_gui.cpp | 53 +++++++++++++++++++++++-- src/settings_type.h | 1 + src/table/settings/gameopt_settings.ini | 2 +- src/table/settings/settings.ini | 17 +++++++- 7 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/date.cpp b/src/date.cpp index 9e00334ee7..7a5d99bd19 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -249,7 +249,7 @@ static void OnNewYear() */ static void OnNewMonth() { - if (_settings_client.gui.autosave != 0 && (_cur_date_ymd.month % _autosave_months[_settings_client.gui.autosave]) == 0) { + if (_settings_client.gui.autosave != 0 && _settings_client.gui.autosave < 5 && (_cur_date_ymd.month % _autosave_months[_settings_client.gui.autosave]) == 0) { _do_autosave = true; _check_special_modes = true; SetWindowDirty(WC_STATUS_BAR, 0); @@ -271,6 +271,12 @@ static void OnNewMonth() */ static void OnNewDay() { + if (_settings_client.gui.autosave == 5 && (_date % _settings_client.gui.autosave_custom_days) == 0) { + _do_autosave = true; + _check_special_modes = true; + SetWindowDirty(WC_STATUS_BAR, 0); + } + if (!_newgrf_profilers.empty() && _newgrf_profile_end_date <= _date) { NewGRFProfiler::FinishAll(); } diff --git a/src/lang/english.txt b/src/lang/english.txt index e71f18442f..fb74d3389d 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1036,6 +1036,11 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_1_MONTH :Every month STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_3_MONTHS :Every 3 months STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_6_MONTHS :Every 6 months STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :Every 12 months +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM_LABEL :Custom interval (days) +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM :Every {COMMA}{NBSP}days +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM_SINGULAR :Every day + +STR_GAME_OPTIONS_AUTOSAVE_QUERY_CAPT :{WHITE}Autosave interval in days STR_GAME_OPTIONS_LANGUAGE :{BLACK}Language STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Select the interface language to use @@ -1788,6 +1793,9 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Closes a window STR_CONFIG_SETTING_AUTOSAVE :Autosave: {STRING2} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Select interval between automatic game saves +STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_DAYS :Custom autosave interval in days: {STRING2} +STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_DAYS_HELPTEXT :Set custom days interval between automatic game saves + STR_CONFIG_SETTING_AUTOSAVE_ON_NETWORK_DISCONNECT :Autosave on network disconnection: {STRING2} STR_CONFIG_SETTING_AUTOSAVE_ON_NETWORK_DISCONNECT_HELPTEXT :When enabled, multiplayer clients automatically save the game when disconnected from the server diff --git a/src/settings.cpp b/src/settings.cpp index 22269dfe8b..97adbf7723 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1406,6 +1406,10 @@ static void TrainSpeedAdaptationChanged(int32 new_value) { } } +static void AutosaveModeChanged(int32 new_value) { + InvalidateWindowClassesData(WC_GAME_OPTIONS); +} + /** Checks if any settings are set to incorrect values, and sets them to correct values in that case. */ static void ValidateSettings() { diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index d83f862e27..298b70dc7c 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -39,6 +39,7 @@ #include "rev.h" #include "video/video_driver.hpp" #include "music/music_driver.hpp" +#include "scope.h" #include #include @@ -60,6 +61,7 @@ static const StringID _autosave_dropdown[] = { STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_3_MONTHS, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_6_MONTHS, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS, + STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM_LABEL, INVALID_STRING_ID, }; @@ -168,6 +170,12 @@ struct GameOptionsWindow : Window { GameSettings *opt; bool reload; + enum class QueryTextItem { + None, + AutosaveCustomDays, + }; + QueryTextItem current_query_text_item = QueryTextItem::None; + GameOptionsWindow(WindowDesc *desc) : Window(desc) { this->opt = &GetGameSettings(); @@ -307,7 +315,15 @@ struct GameOptionsWindow : Window { { switch (widget) { case WID_GO_CURRENCY_DROPDOWN: SetDParam(0, _currency_specs[this->opt->locale.currency].name); break; - case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; + case WID_GO_AUTOSAVE_DROPDOWN: { + if (_settings_client.gui.autosave == 5) { + SetDParam(0, _settings_client.gui.autosave_custom_days == 1 ? STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM_SINGULAR : STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_DAYS_CUSTOM); + SetDParam(1, _settings_client.gui.autosave_custom_days); + } else { + SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); + } + break; + } case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; @@ -534,8 +550,14 @@ struct GameOptionsWindow : Window { break; case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options - _settings_client.gui.autosave = index; - this->SetDirty(); + if (index == 5) { + this->current_query_text_item = QueryTextItem::AutosaveCustomDays; + SetDParam(0, _settings_client.gui.autosave_custom_days); + ShowQueryString(STR_JUST_INT, STR_GAME_OPTIONS_AUTOSAVE_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); + } else { + _settings_client.gui.autosave = index; + this->SetDirty(); + } break; case WID_GO_LANG_DROPDOWN: // Change interface language @@ -608,6 +630,30 @@ struct GameOptionsWindow : Window { } } + void OnQueryTextFinished(char *str) override + { + auto guard = scope_guard([this]() { + this->current_query_text_item = QueryTextItem::None; + }); + + /* Was 'cancel' pressed? */ + if (str == nullptr) return; + + if (!StrEmpty(str)) { + int value = atoi(str); + switch (this->current_query_text_item) { + case QueryTextItem::None: + break; + + case QueryTextItem::AutosaveCustomDays: + _settings_client.gui.autosave = 5; + _settings_client.gui.autosave_custom_days = Clamp(value, 1, 4000); + this->SetDirty(); + break; + } + } + } + /** * Some data on this window has become invalid. * @param data Information about the changed data. @see GameOptionsInvalidationData @@ -1836,6 +1882,7 @@ static SettingsContainer &GetSettingsTree() interface->Add(new SettingEntry("gui.fast_forward_speed_limit")); interface->Add(new SettingEntry("gui.autosave")); + interface->Add(new ConditionallyHiddenSettingEntry("gui.autosave_custom_days", []() -> bool { return _settings_client.gui.autosave != 5; })); interface->Add(new SettingEntry("gui.autosave_on_network_disconnect")); interface->Add(new SettingEntry("gui.savegame_overwrite_confirm")); interface->Add(new SettingEntry("gui.toolbar_pos")); diff --git a/src/settings_type.h b/src/settings_type.h index 27a1fba236..dcdeecd350 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -147,6 +147,7 @@ struct GUISettings : public TimeSettings { ZoomLevel zoom_max; ///< maximum zoom out level ZoomLevel sprite_zoom_min; ///< maximum zoom level at which higher-resolution alternative sprites will be used (if available) instead of scaling a lower resolution sprite byte autosave; ///< how often should we do autosaves? + uint16 autosave_custom_days; ///< custom autosave interval in days bool threaded_saves; ///< should we do threaded saves? bool keep_all_autosave; ///< name the autosave in a different way bool autosave_on_exit; ///< save an autosave when you quit the game, but do not ask "Do you really want to quit?" diff --git a/src/table/settings/gameopt_settings.ini b/src/table/settings/gameopt_settings.ini index 931c3addc3..2df5c7a976 100644 --- a/src/table/settings/gameopt_settings.ini +++ b/src/table/settings/gameopt_settings.ini @@ -27,7 +27,7 @@ static_assert(_locale_currencies.size() == CURRENCY_END); static constexpr std::initializer_list _locale_units{"imperial", "metric", "si", "gameunits"}; static constexpr std::initializer_list _town_names{"english", "french", "german", "american", "latin", "silly", "swedish", "dutch", "finnish", "polish", "slovak", "norwegian", "hungarian", "austrian", "romanian", "czech", "swiss", "danish", "turkish", "italian", "catalan"}; static constexpr std::initializer_list _climates{"temperate", "arctic", "tropic", "toyland"}; -static constexpr std::initializer_list _autosave_interval{"off", "monthly", "quarterly", "half year", "yearly"}; +static constexpr std::initializer_list _autosave_interval{"off", "monthly", "quarterly", "half year", "yearly", "custom_days"}; static constexpr std::initializer_list _roadsides{"left", "right"}; static constexpr std::initializer_list _savegame_date{"long", "short", "iso"}; static constexpr std::initializer_list _savegame_overwrite_confirm{"no", "different", "not same", "yes"}; diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 9e1ba145d6..008b7aa29d 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -62,6 +62,7 @@ static void VelocityUnitsChanged(int32 new_value); static void ChangeTrackTypeSortMode(int32 new_value); static void PublicRoadsSettingChange(int32 new_value); static void TrainSpeedAdaptationChanged(int32 new_value); +static void AutosaveModeChanged(int32 new_value); static bool CheckSharingRail(int32 &new_value); static void SharingRailChanged(int32 new_value); static bool CheckSharingRoad(int32 &new_value); @@ -4084,11 +4085,25 @@ var = gui.autosave type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = 1 -max = 4 +max = 5 full = _autosave_interval str = STR_CONFIG_SETTING_AUTOSAVE strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT strval = STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF +post_cb = AutosaveModeChanged +cat = SC_BASIC + +[SDTC_VAR] +var = gui.autosave_custom_days +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 14 +min = 1 +max = 4000 +interval = 7 +str = STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_DAYS +strhelp = STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_DAYS_HELPTEXT +strval = STR_TIMETABLE_DAYS cat = SC_BASIC [SDTC_BOOL]