diff --git a/src/lang/english.txt b/src/lang/english.txt index fb74d3389d..ce1b00486c 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1037,10 +1037,13 @@ 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_MINUTES_CUSTOM_LABEL :Custom interval (real-time minutes) 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_DROPDOWN_EVERY_MINUTES_CUSTOM :Every {COMMA} real-time minutes -STR_GAME_OPTIONS_AUTOSAVE_QUERY_CAPT :{WHITE}Autosave interval in days +STR_GAME_OPTIONS_AUTOSAVE_DAYS_QUERY_CAPT :{WHITE}Autosave interval in days +STR_GAME_OPTIONS_AUTOSAVE_MINUTES_QUERY_CAPT :{WHITE}Autosave interval in real-time minutes STR_GAME_OPTIONS_LANGUAGE :{BLACK}Language STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Select the interface language to use @@ -1796,6 +1799,9 @@ STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Select interval 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_CUSTOM_MINUTES :Custom autosave interval in real-time minutes: {STRING2} +STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_MINUTES_HELPTEXT :Set custom real-time minutes of game time 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/openttd.cpp b/src/openttd.cpp index 7a4016d0e8..969d2d8c00 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1893,6 +1893,14 @@ void StateGameLoop() _tick_skip_counter++; _scaled_tick_counter++; // This must update in lock-step with _tick_skip_counter, such that it always matches what SetScaledTickVariables would return. _scaled_date_ticks++; // " + + if (_settings_client.gui.autosave == 6 && !(_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) && + (_scaled_date_ticks % (_settings_client.gui.autosave_custom_minutes * (60000 / MILLISECONDS_PER_TICK))) == 0) { + _do_autosave = true; + _check_special_modes = true; + SetWindowDirty(WC_STATUS_BAR, 0); + } + if (_tick_skip_counter < _settings_game.economy.day_length_factor) { AnimateAnimatedTiles(); CallVehicleTicks(); diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 298b70dc7c..e34fddd5e0 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -62,6 +62,7 @@ static const StringID _autosave_dropdown[] = { 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, + STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_MINUTES_CUSTOM_LABEL, INVALID_STRING_ID, }; @@ -173,6 +174,7 @@ struct GameOptionsWindow : Window { enum class QueryTextItem { None, AutosaveCustomDays, + AutosaveCustomRealTimeMinutes, }; QueryTextItem current_query_text_item = QueryTextItem::None; @@ -319,6 +321,9 @@ struct GameOptionsWindow : Window { 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 if (_settings_client.gui.autosave == 6) { + SetDParam(0, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_MINUTES_CUSTOM); + SetDParam(1, _settings_client.gui.autosave_custom_minutes); } else { SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); } @@ -553,7 +558,11 @@ struct GameOptionsWindow : Window { 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); + ShowQueryString(STR_JUST_INT, STR_GAME_OPTIONS_AUTOSAVE_DAYS_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); + } else if (index == 6) { + this->current_query_text_item = QueryTextItem::AutosaveCustomRealTimeMinutes; + SetDParam(0, _settings_client.gui.autosave_custom_minutes); + ShowQueryString(STR_JUST_INT, STR_GAME_OPTIONS_AUTOSAVE_MINUTES_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); } else { _settings_client.gui.autosave = index; this->SetDirty(); @@ -650,6 +659,12 @@ struct GameOptionsWindow : Window { _settings_client.gui.autosave_custom_days = Clamp(value, 1, 4000); this->SetDirty(); break; + + case QueryTextItem::AutosaveCustomRealTimeMinutes: + _settings_client.gui.autosave = 6; + _settings_client.gui.autosave_custom_minutes = Clamp(value, 1, 8000); + this->SetDirty(); + break; } } } @@ -1883,6 +1898,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 ConditionallyHiddenSettingEntry("gui.autosave_custom_minutes", []() -> bool { return _settings_client.gui.autosave != 6; })); 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 dcdeecd350..43c0046090 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -148,6 +148,7 @@ struct GUISettings : public TimeSettings { 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 + uint16 autosave_custom_minutes; ///< custom autosave interval in real-time minutes 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 2df5c7a976..4a4a0614ff 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", "custom_days"}; +static constexpr std::initializer_list _autosave_interval{"off", "monthly", "quarterly", "half year", "yearly", "custom_days", "custom_realtime_minutes"}; 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 008b7aa29d..9e1816f5b5 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -4085,7 +4085,7 @@ var = gui.autosave type = SLE_UINT8 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = 1 -max = 5 +max = 6 full = _autosave_interval str = STR_CONFIG_SETTING_AUTOSAVE strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT @@ -4106,6 +4106,19 @@ strhelp = STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_DAYS_HELPTEXT strval = STR_TIMETABLE_DAYS cat = SC_BASIC +[SDTC_VAR] +var = gui.autosave_custom_minutes +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 30 +min = 3 +max = 8000 +interval = 10 +str = STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_MINUTES +strhelp = STR_CONFIG_SETTING_AUTOSAVE_CUSTOM_MINUTES_HELPTEXT +strval = STR_TIMETABLE_MINUTES +cat = SC_BASIC + [SDTC_BOOL] var = gui.threaded_saves flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC