diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index ca747ca262..30c8115cc6 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -31,6 +31,8 @@ #include "airport_cmd.h" #include "station_cmd.h" #include "zoom_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/airport_widget.h" @@ -581,6 +583,10 @@ public: { CheckRedrawStationCoverage(this); } + + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; }; static const NWidgetPart _nested_build_airport_widgets[] = { diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 34418c9840..a9b19c2f5a 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -30,6 +30,8 @@ #include "error.h" #include "misc_cmd.h" #include "core/geometry_func.hpp" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/cheat_widget.h" @@ -417,6 +419,10 @@ struct CheatWindow : Window { if (value != oldvalue) WriteValue(ce->variable, ce->type, (int64)value); this->SetDirty(); } + + IntervalTimer daily_interval = {{TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetDirty(); + }}; }; /** Window description of the cheats GUI. */ diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 3dcc2bd570..fab43052c2 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -36,6 +36,8 @@ #include "story_base.h" #include "widgets/statusbar_widget.h" #include "company_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -743,7 +745,7 @@ void OnTick_Companies() * A year has passed, update the economic data of all companies, and perhaps show the * financial overview window of the local company. */ -void CompaniesYearlyLoop() +static IntervalTimer _companies_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::COMPANY}, [](auto) { /* Copy statistics */ for (Company *c : Company::Iterate()) { @@ -761,7 +763,7 @@ void CompaniesYearlyLoop() if (_settings_client.sound.new_year) SndPlayFx(SND_00_GOOD_YEAR); } } -} +}); /** * Fill the CompanyNewsInformation struct with the required data. diff --git a/src/currency.cpp b/src/currency.cpp index 841f00d56a..ca75f3d656 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -15,6 +15,8 @@ #include "settings_type.h" #include "date_func.h" #include "string_type.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -138,7 +140,7 @@ uint64 GetMaskOfAllowedCurrencies() /** * Verify if the currency chosen by the user is about to be converted to Euro */ -void CheckSwitchToEuro() +static IntervalTimer _check_switch_to_euro({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) { if (_currency_specs[_settings_game.locale.currency].to_euro != CF_NOEURO && _currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO && @@ -146,7 +148,7 @@ void CheckSwitchToEuro() _settings_game.locale.currency = 2; // this is the index of euro above. AddNewsItem(STR_NEWS_EURO_INTRODUCTION, NT_ECONOMY, NF_NORMAL); } -} +}); /** * Will fill _currency_specs array with diff --git a/src/currency.h b/src/currency.h index 10caa59d3a..1825ababe0 100644 --- a/src/currency.h +++ b/src/currency.h @@ -102,7 +102,6 @@ extern CurrencySpec _currency_specs[CURRENCY_END]; #define _currency ((const CurrencySpec*)&_currency_specs[GetGameSettings().locale.currency]) uint64 GetMaskOfAllowedCurrencies(); -void CheckSwitchToEuro(); void ResetCurrencies(bool preserve_custom = true); StringID *BuildCurrencyDropdown(); byte GetNewgrfCurrencyIdConverted(byte grfcurr_id); diff --git a/src/date.cpp b/src/date.cpp index 9b51a4b01a..23bf5552ff 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -158,111 +158,3 @@ Date ConvertYMDToDate(Year year, Month month, Day day) return DAYS_TILL(year) + days; } - -/** Functions used by the IncreaseDate function */ - -extern void EnginesDailyLoop(); -extern void DisasterDailyLoop(); -extern void IndustryDailyLoop(); - -extern void CompaniesMonthlyLoop(); -extern void EnginesMonthlyLoop(); -extern void TownsMonthlyLoop(); -extern void IndustryMonthlyLoop(); -extern void StationMonthlyLoop(); -extern void SubsidyMonthlyLoop(); - -extern void CompaniesYearlyLoop(); -extern void VehiclesYearlyLoop(); -extern void TownsYearlyLoop(); - -extern void ShowEndGameChart(); - - -/** Available settings for autosave intervals. */ -static const Month _autosave_months[] = { - 0, ///< never - 1, ///< every month - 3, ///< every 3 months - 6, ///< every 6 months - 12, ///< every 12 months -}; - -/** - * Runs various procedures that have to be done yearly - */ -static IntervalTimer _on_new_year({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) -{ - CompaniesYearlyLoop(); - VehiclesYearlyLoop(); - TownsYearlyLoop(); - InvalidateWindowClassesData(WC_BUILD_STATION); - InvalidateWindowClassesData(WC_BUS_STATION); - InvalidateWindowClassesData(WC_TRUCK_STATION); - if (_network_server) NetworkServerYearlyLoop(); - - if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant(); - - /* check if we reached end of the game (end of ending year); 0 = never */ - if (_cur_year == _settings_game.game_creation.ending_year + 1 && _settings_game.game_creation.ending_year != 0) { - ShowEndGameChart(); - } - - /* check if we reached the maximum year, decrement dates by a year */ - if (_cur_year == MAX_YEAR + 1) { - int days_this_year; - - _cur_year--; - days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; - _date -= days_this_year; - for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); - for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); - - /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out - * all of them if the date is set back, else those messages will hang for ever */ - NetworkInitChatMessage(); - } - - if (_settings_client.gui.auto_euro) CheckSwitchToEuro(); -}); - -/** - * Runs various procedures that have to be done monthly - */ -static IntervalTimer _on_new_month({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto) -{ - if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) { - _do_autosave = true; - SetWindowDirty(WC_STATUS_BAR, 0); - } - - SetWindowClassesDirty(WC_CHEATS); - CompaniesMonthlyLoop(); - EnginesMonthlyLoop(); - TownsMonthlyLoop(); - IndustryMonthlyLoop(); - SubsidyMonthlyLoop(); - StationMonthlyLoop(); - if (_network_server) NetworkServerMonthlyLoop(); -}); - -/** - * Runs various procedures that have to be done daily - */ -static IntervalTimer _on_new_day({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) -{ - if (!_newgrf_profilers.empty() && _newgrf_profile_end_date <= _date) { - NewGRFProfiler::FinishAll(); - } - - if (_network_server) NetworkServerDailyLoop(); - - DisasterDailyLoop(); - IndustryDailyLoop(); - - SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_LEFT); - EnginesDailyLoop(); - - /* Refresh after possible snowline change */ - SetWindowClassesDirty(WC_TOWN_VIEW); -}); diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index e91e2fb842..528225cc1a 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -47,6 +47,8 @@ #include "core/random_func.hpp" #include "core/backup_type.hpp" #include "landscape_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -935,14 +937,14 @@ static void ResetDisasterDelay() _disaster_delay = GB(Random(), 0, 9) + 730; } -void DisasterDailyLoop() +static IntervalTimer _disaster_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::DISASTER}, [](auto) { if (--_disaster_delay != 0) return; ResetDisasterDelay(); if (_settings_game.difficulty.disasters != 0) DoDisaster(); -} +}); void StartupDisasters() { diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 2477450fa3..5b71a648cb 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -30,6 +30,8 @@ #include "station_cmd.h" #include "water_cmd.h" #include "waypoint_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/dock_widget.h" @@ -477,6 +479,10 @@ public: { CheckRedrawStationCoverage(this); } + + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; }; /** Nested widget parts of a build dock station window. */ diff --git a/src/economy.cpp b/src/economy.cpp index bf15a9f232..3b633d0fca 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -52,6 +52,8 @@ #include "company_cmd.h" #include "economy_cmd.h" #include "vehicle_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/pricebase.h" @@ -1983,7 +1985,7 @@ void LoadUnloadStation(Station *st) /** * Monthly update of the economic data (of the companies as well as economic fluctuations). */ -void CompaniesMonthlyLoop() +static IntervalTimer _companies_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto) { CompaniesGenStatistics(); if (_settings_game.economy.inflation) { @@ -1992,7 +1994,7 @@ void CompaniesMonthlyLoop() } CompaniesPayInterest(); HandleEconomyFluctuations(); -} +}); static void DoAcquireCompany(Company *c) { diff --git a/src/engine.cpp b/src/engine.cpp index c05bbc89e6..3ca54291cf 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -30,6 +30,8 @@ #include "articulated_vehicles.h" #include "error.h" #include "engine_base.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/engines.h" @@ -878,7 +880,7 @@ static bool IsVehicleTypeDisabled(VehicleType type, bool ai) } /** Daily check to offer an exclusive engine preview to the companies. */ -void EnginesDailyLoop() +static IntervalTimer _engines_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::ENGINE}, [](auto) { for (Company *c : Company::Iterate()) { c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, _date); @@ -915,7 +917,7 @@ void EnginesDailyLoop() } } } -} +}); /** * Clear the 'hidden' flag for all engines of a new company. @@ -1110,6 +1112,11 @@ void EnginesMonthlyLoop() } } +static IntervalTimer _engines_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::ENGINE}, [](auto) +{ + EnginesMonthlyLoop(); +}); + /** * Is \a name still free as name for an engine? * @param name New name of an engine. diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index f61bf46f37..8bc256067f 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -22,6 +22,9 @@ #include "hotkeys.h" #include "zoom_func.h" #include "misc_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" +#include "date_func.h" #include "widgets/highscore_widget.h" @@ -250,3 +253,14 @@ void ShowEndGameChart() CloseWindowByClass(WC_ENDSCREEN); new EndGameWindow(&_endgame_desc); } + +static IntervalTimer _check_end_game({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) +{ + /* 0 = never */ + if (_settings_game.game_creation.ending_year == 0) return; + + /* Show the end-game chart at the end of the ending year (hence the + 1). */ + if (_cur_year == _settings_game.game_creation.ending_year + 1) { + ShowEndGameChart(); + } +}); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 3facbb85d2..4afee2c4a8 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -44,6 +44,8 @@ #include "industry_cmd.h" #include "landscape_cmd.h" #include "terraform_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/industry_land.h" @@ -2947,7 +2949,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) * For small maps, it implies that less than one change per month is required, while on bigger maps, * it would be way more. The daily loop handles those changes. */ -void IndustryDailyLoop() +static IntervalTimer _industries_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::INDUSTRY}, [](auto) { _economy.industry_daily_change_counter += _economy.industry_daily_increment; @@ -2987,9 +2989,9 @@ void IndustryDailyLoop() /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); -} +}); -void IndustryMonthlyLoop() +static IntervalTimer _industries_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::INDUSTRY}, [](auto) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); @@ -3009,7 +3011,7 @@ void IndustryMonthlyLoop() /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); -} +}); void InitializeIndustries() diff --git a/src/network/network_func.h b/src/network/network_func.h index 618adc1949..73050737ea 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -65,9 +65,6 @@ void NetworkPrintClients(); void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode); /*** Commands ran by the server ***/ -void NetworkServerDailyLoop(); -void NetworkServerMonthlyLoop(); -void NetworkServerYearlyLoop(); void NetworkServerSendConfigUpdate(); void NetworkServerUpdateGameInfo(); void NetworkServerShowStatusToConsole(); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 3a61cab445..0d3a5aeaed 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -31,6 +31,8 @@ #include "../core/random_func.hpp" #include "../company_cmd.h" #include "../rev.h" +#include "../timer/timer.h" +#include "../timer/timer_game_calendar.h" #include #include @@ -1812,26 +1814,32 @@ void NetworkServer_Tick(bool send_frame) } /** Yearly "callback". Called whenever the year changes. */ -void NetworkServerYearlyLoop() +static IntervalTimer _network_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkCheckRestartMap(); NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY); -} +}); /** Monthly "callback". Called whenever the month changes. */ -void NetworkServerMonthlyLoop() +static IntervalTimer _network_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkAutoCleanCompanies(); NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY); if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY); -} +}); /** Daily "callback". Called whenever the date changes. */ -void NetworkServerDailyLoop() +static IntervalTimer _network_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY); if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY); -} +}); /** * Get the IP address/hostname of the connected client. diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp index 7f93e1d765..451af9a18e 100644 --- a/src/newgrf_profiling.cpp +++ b/src/newgrf_profiling.cpp @@ -14,6 +14,8 @@ #include "console_func.h" #include "spritecache.h" #include "walltime_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include @@ -158,3 +160,13 @@ uint32 NewGRFProfiler::FinishAll() return total_microseconds; } + +/** + * Check whether profiling is active and should be finished. + */ +static IntervalTimer _check_profiling_finished({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) +{ + if (_newgrf_profilers.empty() || _newgrf_profile_end_date > _date) return; + + NewGRFProfiler::FinishAll(); +}); diff --git a/src/openttd.cpp b/src/openttd.cpp index f719a4dcd5..d61a4145ee 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -101,6 +101,15 @@ bool _save_config = false; bool _request_newgrf_scan = false; NewGRFScanCallback *_request_newgrf_scan_callback = nullptr; +/** Available settings for autosave intervals. */ +static const Month _autosave_months[] = { + 0, ///< never + 1, ///< every month + 3, ///< every 3 months + 6, ///< every 6 months + 12, ///< every 12 months +}; + /** * Error handling for fatal user errors. * @param s the string to print. @@ -1432,6 +1441,15 @@ void StateGameLoop() assert(IsLocalCompany()); } +static IntervalTimer _autosave_interval({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::AUTOSAVE}, [](auto) +{ + if (_settings_client.gui.autosave == 0) return; + if ((_cur_month % _autosave_months[_settings_client.gui.autosave]) != 0) return; + + _do_autosave = true; + SetWindowDirty(WC_STATUS_BAR, 0); +}); + /** * Create an autosave. The default name is "autosave#.sav". However with * the setting 'keep_all_autosave' the name defaults to company-name + date diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 8532a04bd7..fa639344c7 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -40,6 +40,8 @@ #include "tunnelbridge_cmd.h" #include "waypoint_cmd.h" #include "rail_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "station_map.h" #include "tunnelbridge_map.h" @@ -1505,6 +1507,10 @@ public: CheckRedrawStationCoverage(this); } + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetDirty(); + }}; + static HotkeyList hotkeys; }; @@ -2201,6 +2207,13 @@ void ResetSignalVariant(int32 new_value) } } +static IntervalTimer _check_reset_signal({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) +{ + if (_cur_year != _settings_client.gui.semaphore_build_before) return; + + ResetSignalVariant(); +}); + /** * Resets the rail GUI - sets default railtype to build * and resets the signal GUI diff --git a/src/road_gui.cpp b/src/road_gui.cpp index ed5c0dc36f..a955fa27d7 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -39,6 +39,8 @@ #include "sortlist_type.h" #include "stringfilter_type.h" #include "string_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/road_widget.h" @@ -1586,6 +1588,10 @@ public: CheckRedrawStationCoverage(this); } + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; + static HotkeyList hotkeys; }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8735687fba..430ae942ee 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -60,6 +60,8 @@ #include "landscape_cmd.h" #include "rail_cmd.h" #include "newgrf_roadstop.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -4007,7 +4009,7 @@ void OnTick_Station() } /** Monthly loop for stations. */ -void StationMonthlyLoop() +static IntervalTimer _stations_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::STATION}, [](auto) { for (Station *st : Station::Iterate()) { for (CargoID i = 0; i < NUM_CARGO; i++) { @@ -4016,8 +4018,7 @@ void StationMonthlyLoop() ClrBit(ge->status, GoodsEntry::GES_CURRENT_MONTH); } } -} - +}); void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius) { diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 021025ddaa..ef5d16c488 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -27,6 +27,7 @@ #include "core/geometry_func.hpp" #include "zoom_func.h" #include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_window.h" #include "widgets/statusbar_widget.h" @@ -233,6 +234,10 @@ struct StatusBarWindow : Window { TimeoutTimer reminder_timeout = {REMINDER_START, [this]() { this->SetWidgetDirty(WID_S_MIDDLE); }}; + + IntervalTimer daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetWidgetDirty(WID_S_LEFT); + }}; }; static const NWidgetPart _nested_main_status_widgets[] = { diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 6b56feead2..25832a19b4 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -25,6 +25,8 @@ #include "string_func.h" #include "tile_cmd.h" #include "subsidy_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -477,7 +479,7 @@ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) } /** Perform the monthly update of open subsidies, and try to create a new one. */ -void SubsidyMonthlyLoop() +static IntervalTimer _subsidies_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::SUBSIDY}, [](auto) { bool modified = false; @@ -547,7 +549,7 @@ void SubsidyMonthlyLoop() modified |= passenger_subsidy || town_subsidy || industry_subsidy; if (modified) InvalidateWindowData(WC_SUBSIDIES_LIST, 0); -} +}); /** * Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 6ab290eb13..6fe804ecc8 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -86,4 +86,15 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) timer->Elapsed(TimerGameCalendar::YEAR); } } + + /* check if we reached the maximum year, decrement dates by a year */ + if (_cur_year == MAX_YEAR + 1) { + int days_this_year; + + _cur_year--; + days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + _date -= days_this_year; + for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); + for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); + } } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 81732f3941..265f10aecb 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -52,6 +52,8 @@ #include "road_cmd.h" #include "terraform_cmd.h" #include "tunnelbridge_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/town_land.h" @@ -3756,7 +3758,7 @@ CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType return CommandCost(); } -void TownsMonthlyLoop() +static IntervalTimer _towns_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::TOWN}, [](auto) { for (Town *t : Town::Iterate()) { if (t->road_build_months != 0) t->road_build_months--; @@ -3770,17 +3772,16 @@ void TownsMonthlyLoop() UpdateTownRating(t); UpdateTownUnwanted(t); } +}); -} - -void TownsYearlyLoop() +static IntervalTimer _towns_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::TOWN}, [](auto) { /* Increment house ages */ for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; IncrementHouseAge(t); } -} +}); static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { diff --git a/src/town_gui.cpp b/src/town_gui.cpp index c655fdb3a2..c9231288ae 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -35,6 +35,7 @@ #include "town_kdtree.h" #include "town_cmd.h" #include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_window.h" #include "widgets/town_widget.h" @@ -596,6 +597,11 @@ public: Command::Post(STR_ERROR_CAN_T_RENAME_TOWN, this->window_number, str); } + + IntervalTimer daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) { + /* Refresh after possible snowline change */ + this->SetDirty(); + }}; }; static const NWidgetPart _nested_town_game_view_widgets[] = { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index a979d4de3f..ea53dfacf3 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -56,6 +56,8 @@ #include "train_cmd.h" #include "vehicle_cmd.h" #include "newgrf_roadstop.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -2826,7 +2828,7 @@ void Vehicle::RemoveFromShared() this->previous_shared = nullptr; } -void VehiclesYearlyLoop() +static IntervalTimer _vehicles_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::VEHICLE}, [](auto) { for (Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { @@ -2851,8 +2853,7 @@ void VehiclesYearlyLoop() SetWindowClassesDirty(WC_SHIPS_LIST); SetWindowClassesDirty(WC_ROADVEH_LIST); SetWindowClassesDirty(WC_AIRCRAFT_LIST); -} - +}); /** * Can this station be used by the given engine type?