From 934545a674b1ccb9a29d30e04d8a5d44c2eca45e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 31 Dec 2023 15:47:32 +0000 Subject: [PATCH] Fix: Calculation of initial engine age was inaccurate. (#11660) Engine age in months was calculated as the difference in days / 32, instead of the actually difference in months. This would result in engines being artificially younger if a game was started at a later date. --- src/engine.cpp | 11 ++++++++--- src/engine_func.h | 2 +- src/saveload/oldloader_sl.cpp | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 80b8896cff..4f9b3b5da2 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -675,7 +675,7 @@ void SetYearEngineAgingStops() * @param aging_date The date used for age calculations. * @param seed Random seed. */ -void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed) +void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed) { const EngineInfo *ei = &e->info; @@ -699,7 +699,11 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se * Note: TTDP uses fixed 1922 */ e->intro_date = ei->base_intro <= TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro; if (e->intro_date <= TimerGameCalendar::date) { - e->age = (aging_date - e->intro_date).base() >> 5; + TimerGameCalendar::YearMonthDay intro_ymd = TimerGameCalendar::ConvertDateToYMD(e->intro_date); + int aging_months = aging_ymd.year.base() * 12 + aging_ymd.month; + int intro_months = intro_ymd.year.base() * 12 + intro_ymd.month; + if (intro_ymd.day > 1) intro_months++; // Engines are introduced at the first month start at/after intro date. + e->age = aging_months - intro_months; e->company_avail = MAX_UVALUE(CompanyMask); e->flags |= ENGINE_AVAILABLE; } @@ -756,10 +760,11 @@ void StartupEngines() { /* Aging of vehicles stops, so account for that when starting late */ const TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date, TimerGameCalendar::ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); + TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date); uint32_t seed = Random(); for (Engine *e : Engine::Iterate()) { - StartupOneEngine(e, aging_date, seed); + StartupOneEngine(e, aging_ymd, seed); } for (Engine *e : Engine::Iterate()) { CalcEngineReliability(e, false); diff --git a/src/engine_func.h b/src/engine_func.h index 8036134c8e..533d13acfa 100644 --- a/src/engine_func.h +++ b/src/engine_func.h @@ -27,7 +27,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company); bool IsEngineRefittable(EngineID engine); void SetYearEngineAgingStops(); void CalcEngineReliability(Engine *e, bool new_month); -void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t seed); +void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ymd, uint32_t seed); uint GetTotalCapacityOfArticulatedParts(EngineID engine); diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 9668054b9d..9fd71b2017 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -399,6 +399,7 @@ static bool FixTTOEngines() } TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1)); + TimerGameCalendar::YearMonthDay aging_ymd = TimerGameCalendar::ConvertDateToYMD(aging_date); for (EngineID i = 0; i < 256; i++) { int oi = ttd_to_tto[i]; @@ -407,7 +408,7 @@ static bool FixTTOEngines() if (oi == 255) { /* Default engine is used */ TimerGameCalendar::date += CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; - StartupOneEngine(e, aging_date, 0); + StartupOneEngine(e, aging_ymd, 0); CalcEngineReliability(e, false); e->intro_date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR; TimerGameCalendar::date -= CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR;