diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index d226591add..477fa3d748 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -113,7 +113,7 @@ static int32_t ClickChangeDateCheat(int32_t new_value, int32_t) /* If not using wallclock units, we keep economy date in sync with calendar date and must change it also. */ if (!TimerGameEconomy::UsingWallclockUnits()) { /* Keep economy and calendar dates synced. */ - TimerGameEconomy::Date new_economy_date = new_calendar_date.base(); + TimerGameEconomy::Date new_economy_date{new_calendar_date.base()}; /* Shift cached dates before we change the date. */ for (auto v : Vehicle::Iterate()) v->ShiftDates(new_economy_date - TimerGameEconomy::date); diff --git a/src/engine.cpp b/src/engine.cpp index 6e920d87f6..f2516ec505 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -443,7 +443,7 @@ uint Engine::GetDisplayMaxTractiveEffort() const TimerGameCalendar::Date Engine::GetLifeLengthInDays() const { /* Assume leap years; this gives the player a bit more than the given amount of years, but never less. */ - return (this->info.lifelength + _settings_game.vehicle.extend_vehicle_life).base() * CalendarTime::DAYS_IN_LEAP_YEAR; + return TimerGameCalendar::Date{(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life).base() * CalendarTime::DAYS_IN_LEAP_YEAR}; } /** @@ -1320,7 +1320,7 @@ bool IsEngineRefittable(EngineID engine) */ void CheckEngines() { - TimerGameCalendar::Date min_date = INT32_MAX; + TimerGameCalendar::Date min_date{INT32_MAX}; for (const Engine *e : Engine::Iterate()) { if (!e->IsEnabled()) continue; diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 72f28a3270..d9bee368d3 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -202,7 +202,7 @@ void AfterLoad_LinkGraphPauseControl() void OnTick_LinkGraph() { if (TimerGameEconomy::date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return; - TimerGameEconomy::Date offset = TimerGameEconomy::date.base() % (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY); + TimerGameEconomy::Date offset{TimerGameEconomy::date.base() % (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY)}; if (offset == 0) { LinkGraphSchedule::instance.SpawnNext(); } else if (offset == (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) / 2) { diff --git a/src/misc.cpp b/src/misc.cpp index 72701ff23c..ad44417367 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -112,10 +112,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin if (TimerGameEconomy::UsingWallclockUnits()) { /* If using wallclock units, start at year 1. */ - TimerGameEconomy::SetDate(TimerGameEconomy::ConvertYMDToDate(1, 0, 1), 0); + TimerGameEconomy::SetDate(TimerGameEconomy::ConvertYMDToDate(TimerGameEconomy::Year{1}, 0, 1), 0); } else { /* Otherwise, we always keep the economy date synced with the calendar date. */ - TimerGameEconomy::SetDate(new_date.base(), 0); + TimerGameEconomy::SetDate(TimerGameEconomy::Date{new_date.base()}, 0); } InitializeOldNames(); } diff --git a/src/newgrf.cpp b/src/newgrf.cpp index bae0c25a96..1382b3731f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2264,7 +2264,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR case 0x08: { // Year of availability /* We treat '0' as always available */ uint8_t year = buf.ReadByte(); - bridge->avail_year = (year > 0 ? CalendarTime::ORIGINAL_BASE_YEAR + year : 0); + bridge->avail_year = (year > 0 ? CalendarTime::ORIGINAL_BASE_YEAR + year : TimerGameCalendar::Year{}); break; } @@ -2856,7 +2856,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By case 0x0F: { // Euro introduction dates uint curidx = GetNewgrfCurrencyIdConverted(gvid + i); - TimerGameCalendar::Year year_euro = buf.ReadWord(); + TimerGameCalendar::Year year_euro{buf.ReadWord()}; if (curidx < CURRENCY_END) { _currency_specs[curidx].to_euro = year_euro; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 106c279b18..5d3c327789 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -740,7 +740,7 @@ bool AfterLoadGame() /* Update economy year. If we don't have a separate economy date saved, follow the calendar date. */ if (IsSavegameVersionBefore(SLV_ECONOMY_DATE)) { - TimerGameEconomy::SetDate(TimerGameCalendar::date.base(), TimerGameCalendar::date_fract); + TimerGameEconomy::SetDate(TimerGameEconomy::Date{TimerGameCalendar::date.base()}, TimerGameCalendar::date_fract); } else { TimerGameEconomy::SetDate(TimerGameEconomy::date, TimerGameEconomy::date_fract); } @@ -1965,7 +1965,7 @@ bool AfterLoadGame() /* Replace "house construction year" with "house age" */ if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) { - t.m5() = ClampTo(TimerGameCalendar::year - (t.m5() + CalendarTime::ORIGINAL_BASE_YEAR)); + t.m5() = ClampTo(TimerGameCalendar::year - (CalendarTime::ORIGINAL_BASE_YEAR + t.m5())); } } } diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 73479ce2a0..409631911b 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -39,7 +39,7 @@ public: { SlIndustryAccepted::old_cargo.fill(INVALID_CARGO); SlIndustryAccepted::old_waiting.fill(0); - SlIndustryAccepted::old_last_accepted.fill(0); + SlIndustryAccepted::old_last_accepted.fill(TimerGameEconomy::Date{}); } }; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 064f53d5fa..a8b7a452e4 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -387,7 +387,7 @@ static bool FixTTOEngines() for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i); } - TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1)); + TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::Year{2050}, 0, 1)); TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date); for (EngineID i = 0; i < 256; i++) { diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 22c4dbf105..31d0a39c6c 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -396,7 +396,7 @@ void AfterLoadVehiclesPhase1(bool part_of_load) /* If the start date is 0, the vehicle is not waiting to start and can be ignored. */ if (v->timetable_start == 0) continue; - v->timetable_start = GetStartTickFromDate(v->timetable_start); + v->timetable_start = GetStartTickFromDate(TimerGameEconomy::Date(v->timetable_start)); } } diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp index cffa57fea9..3ff39b6232 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -29,7 +29,7 @@ { if (date < 0) return DATE_INVALID; - ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date}); return ymd.year.base(); } @@ -37,7 +37,7 @@ { if (date < 0) return DATE_INVALID; - ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date}); return ymd.month + 1; } @@ -45,7 +45,7 @@ { if (date < 0) return DATE_INVALID; - ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(date); + ::TimerGameEconomy::YearMonthDay ymd = ::TimerGameEconomy::ConvertDateToYMD(::TimerGameEconomy::Date{date}); return ymd.day; } @@ -53,9 +53,11 @@ { if (month < 1 || month > 12) return DATE_INVALID; if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID; - if (year < 0 || year > EconomyTime::MAX_YEAR) return DATE_INVALID; - return (ScriptDate::Date)::TimerGameEconomy::ConvertYMDToDate(year, month - 1, day_of_month).base(); + ::TimerGameEconomy::Year timer_year{ClampTo(year)}; + if (timer_year < EconomyTime::MIN_YEAR || timer_year > EconomyTime::MAX_YEAR) return DATE_INVALID; + + return static_cast(::TimerGameEconomy::ConvertYMDToDate(timer_year, month - 1, day_of_month).base()); } /* static */ SQInteger ScriptDate::GetSystemTime() diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index 2471d35745..f664c7771f 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -196,7 +196,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforceDeityMode(false); - return ScriptObject::Command::Do(story_page_id, date); + return ScriptObject::Command::Do(story_page_id, ::TimerGameCalendar::Date{date}); } diff --git a/src/script/api/script_subsidy.cpp b/src/script/api/script_subsidy.cpp index 02f283d87a..e8d2905cb6 100644 --- a/src/script/api/script_subsidy.cpp +++ b/src/script/api/script_subsidy.cpp @@ -58,7 +58,7 @@ ymd.day = 1; auto m = ymd.month + ::Subsidy::Get(subsidy_id)->remaining; ymd.month = (m - 1) % 12 + 1; - ymd.year += (m - 1) / 12; + ymd.year += TimerGameEconomy::Year{(m - 1) / 12}; return (ScriptDate::Date)TimerGameEconomy::ConvertYMDToDate(ymd.year, ymd.month, ymd.day).base(); } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index c4c660bf31..a88195043e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -3151,7 +3151,7 @@ struct CustomCurrencyWindow : Window { break; case WID_CC_YEAR: { // Year to switch to euro - TimerGameCalendar::Year val = atoi(str->c_str()); + TimerGameCalendar::Year val{atoi(str->c_str())}; GetCustomCurrency().to_euro = (val < MIN_EURO_YEAR ? CF_NOEURO : std::min(val, CalendarTime::MAX_YEAR)); break; diff --git a/src/settings_table.cpp b/src/settings_table.cpp index 2ebb856d41..95ecac46f2 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -604,7 +604,7 @@ static void ChangeTimekeepingUnits(int32_t) if (TimerGameEconomy::UsingWallclockUnits()) { /* If the new mode is wallclock units, set the economy year back to 1. */ - new_economy_date = TimerGameEconomy::ConvertYMDToDate(1, 0, 1); + new_economy_date = TimerGameEconomy::ConvertYMDToDate(TimerGameEconomy::Year{1}, 0, 1); new_economy_date_fract = 0; } else { /* If the new mode is calendar units, sync the economy year with the calendar year. */ diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 30f938464c..34300ae2a7 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -70,7 +70,7 @@ uint16_t TimerGameCalendar::sub_date_fract = {}; TimerGameCalendar::date = date; TimerGameCalendar::date_fract = fract; TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(date); - TimerGameCalendar::year = ymd.year; + TimerGameCalendar::year = TimerGameCalendar::Year{ymd.year}; TimerGameCalendar::month = ymd.month; } @@ -157,10 +157,8 @@ bool TimerManager::Elapsed([[maybe_unused]] TimerGameCalendar /* If we reached the maximum year, decrement dates by a year. */ if (TimerGameCalendar::year == CalendarTime::MAX_YEAR + 1) { - int days_this_year; - TimerGameCalendar::year--; - days_this_year = TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR; + TimerGameCalendar::Date days_this_year{TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? CalendarTime::DAYS_IN_LEAP_YEAR : CalendarTime::DAYS_IN_YEAR}; TimerGameCalendar::date -= days_this_year; } diff --git a/src/timer/timer_game_common.cpp b/src/timer/timer_game_common.cpp index 01b9a1a5a3..ff263979c4 100644 --- a/src/timer/timer_game_common.cpp +++ b/src/timer/timer_game_common.cpp @@ -68,28 +68,28 @@ template */ /* There are 97 leap years in 400 years */ - Year yr = 400 * (date.base() / (TimerGameConst::DAYS_IN_YEAR * 400 + 97)); + Year yr{400 * (date.base() / (TimerGameConst::DAYS_IN_YEAR * 400 + 97))}; int rem = date.base() % (TimerGameConst::DAYS_IN_YEAR * 400 + 97); if (rem >= TimerGameConst::DAYS_IN_YEAR * 100 + 25) { /* There are 25 leap years in the first 100 years after * every 400th year, as every 400th year is a leap year */ - yr += 100; + yr += Year{100}; rem -= TimerGameConst::DAYS_IN_YEAR * 100 + 25; /* There are 24 leap years in the next couple of 100 years */ - yr += 100 * (rem / (TimerGameConst::DAYS_IN_YEAR * 100 + 24)); + yr += Year{100 * (rem / (TimerGameConst::DAYS_IN_YEAR * 100 + 24))}; rem = (rem % (TimerGameConst::DAYS_IN_YEAR * 100 + 24)); } if (!IsLeapYear(yr) && rem >= TimerGameConst::DAYS_IN_YEAR * 4) { /* The first 4 year of the century are not always a leap year */ - yr += 4; + yr += Year{4}; rem -= TimerGameConst::DAYS_IN_YEAR * 4; } /* There is 1 leap year every 4 years */ - yr += 4 * (rem / (TimerGameConst::DAYS_IN_YEAR * 4 + 1)); + yr += Year{4 * (rem / (TimerGameConst::DAYS_IN_YEAR * 4 + 1))}; rem = rem % (TimerGameConst::DAYS_IN_YEAR * 4 + 1); /* The last (max 3) years to account for; the first one diff --git a/src/timer/timer_game_common.h b/src/timer/timer_game_common.h index 8ab619e51f..ca6b7e13fa 100644 --- a/src/timer/timer_game_common.h +++ b/src/timer/timer_game_common.h @@ -77,7 +77,7 @@ public: static constexpr Year DateToYear(Date date) { /* Hardcode the number of days in a year because we can't access CalendarTime from here. */ - return date.base() / 366; + return Year{date.base() / 366}; } /** @@ -88,10 +88,10 @@ public: static constexpr Date DateAtStartOfYear(Year year) { int32_t year_as_int = year.base(); - uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1); + int32_t number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1); /* Hardcode the number of days in a year because we can't access CalendarTime from here. */ - return (365 * year_as_int) + number_of_leap_years; + return Date{(365 * year_as_int) + number_of_leap_years}; } enum Trigger { diff --git a/src/timer/timer_game_economy.cpp b/src/timer/timer_game_economy.cpp index cd78aa74af..6eac8c7be1 100644 --- a/src/timer/timer_game_economy.cpp +++ b/src/timer/timer_game_economy.cpp @@ -70,7 +70,7 @@ TimerGameEconomy::DateFract TimerGameEconomy::date_fract = {}; /* If we're using wallclock units, economy months have 30 days and an economy year has 360 days. */ const int total_months = (year.base() * EconomyTime::MONTHS_IN_YEAR) + month; - return (total_months * EconomyTime::DAYS_IN_ECONOMY_MONTH) + day - 1; // Day is 1-indexed but Date is 0-indexed, hence the - 1. + return TimerGameEconomy::Date{(total_months * EconomyTime::DAYS_IN_ECONOMY_MONTH) + day - 1}; // Day is 1-indexed but Date is 0-indexed, hence the - 1. } /** @@ -179,13 +179,11 @@ bool TimerManager::Elapsed([[maybe_unused]] TimerGameEconomy:: /* check if we reached the maximum year, decrement dates by a year */ if (TimerGameEconomy::year == EconomyTime::MAX_YEAR + 1) { - int days_this_year; - TimerGameEconomy::year--; - days_this_year = TimerGameEconomy::IsLeapYear(TimerGameEconomy::year) ? EconomyTime::DAYS_IN_LEAP_YEAR : EconomyTime::DAYS_IN_YEAR; - TimerGameEconomy::date -= days_this_year; - for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); - for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); + int days_this_year = TimerGameEconomy::IsLeapYear(TimerGameEconomy::year) ? EconomyTime::DAYS_IN_LEAP_YEAR : EconomyTime::DAYS_IN_YEAR; + TimerGameEconomy::date -= TimerGameEconomy::Date{days_this_year}; + for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(TimerGameEconomy::Date{-days_this_year}); + for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(TimerGameEconomy::Date{-days_this_year}); } return true; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index d2a46b349b..91d7b470df 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -1113,7 +1113,7 @@ void SetStartingYear(TimerGameCalendar::Year year) { _settings_game.game_creation.starting_year = Clamp(year, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR); TimerGameCalendar::Date new_calendar_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); - TimerGameEconomy::Date new_economy_date = new_calendar_date.base(); + TimerGameEconomy::Date new_economy_date{new_calendar_date.base()}; /* We must set both Calendar and Economy dates to keep them in sync. Calendar first. */ TimerGameCalendar::SetDate(new_calendar_date, 0); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 848cc13aee..947796fe8e 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -998,7 +998,7 @@ static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate() best = rti; } - if (best == nullptr) return INT32_MAX; + if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX); return best->introduction_date; } diff --git a/src/town_map.h b/src/town_map.h index aae94676ac..6cd041643a 100644 --- a/src/town_map.h +++ b/src/town_map.h @@ -249,7 +249,7 @@ inline void IncrementHouseAge(Tile t) inline TimerGameCalendar::Year GetHouseAge(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return IsHouseCompleted(t) ? t.m5() : 0; + return TimerGameCalendar::Year{IsHouseCompleted(t) ? t.m5() : 0}; } /** diff --git a/src/vehicle.cpp b/src/vehicle.cpp index aecc7138f7..06876853d9 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1446,7 +1446,7 @@ void AgeVehicle(Vehicle *v) auto age = v->age - v->max_age; for (int32_t i = 0; i <= 4; i++) { - if (age == TimerGameCalendar::DateAtStartOfYear(i)) { + if (age == TimerGameCalendar::DateAtStartOfYear(TimerGameCalendar::Year{i})) { v->reliability_spd_dec <<= 1; break; } @@ -1467,11 +1467,11 @@ void AgeVehicle(Vehicle *v) if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return; StringID str; - if (age == TimerGameCalendar::DateAtStartOfYear(-1)) { + if (age == TimerGameCalendar::DateAtStartOfYear(TimerGameCalendar::Year{-1})) { str = STR_NEWS_VEHICLE_IS_GETTING_OLD; - } else if (age == TimerGameCalendar::DateAtStartOfYear(0)) { + } else if (age == TimerGameCalendar::DateAtStartOfYear(TimerGameCalendar::Year{0})) { str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD; - } else if (age > TimerGameCalendar::DateAtStartOfYear(0) && (age.base() % CalendarTime::DAYS_IN_LEAP_YEAR) == 0) { + } else if (age > TimerGameCalendar::DateAtStartOfYear(TimerGameCalendar::Year{0}) && (age.base() % CalendarTime::DAYS_IN_LEAP_YEAR) == 0) { str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND; } else { return;