From 675b31887ab97a3bd851ec93da76c115ad16a886 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 21 Feb 2024 21:08:31 +0000 Subject: [PATCH] Saveload: Fix recalculation of _state_ticks For XSLFI_VARIABLE_DAY_LENGTH versions 1 to 3 --- src/date.cpp | 6 +++--- src/date_func.h | 2 +- src/saveload/afterload.cpp | 14 ++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/date.cpp b/src/date.cpp index 5ed74781a0..4f9aadf22b 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -110,14 +110,14 @@ EconTime::State EconTime::Detail::NewState(EconTime::Year year) return state; } -StateTicks GetStateTicksFromCurrentDateWithoutOffset() +StateTicks GetStateTicksFromDateWithoutOffset(EconTime::Date date, EconTime::DateFract date_fract) { - return ((int64_t)(EconTime::DateToDateTicks(EconTime::CurDate(), EconTime::CurDateFract()).base()) * DayLengthFactor()) + TickSkipCounter(); + return ((int64_t)(EconTime::DateToDateTicks(date, date_fract).base()) * DayLengthFactor()) + TickSkipCounter(); } void RecalculateStateTicksOffset() { - DateDetail::_state_ticks_offset = _state_ticks - GetStateTicksFromCurrentDateWithoutOffset(); + DateDetail::_state_ticks_offset = _state_ticks - GetStateTicksFromDateWithoutOffset(EconTime::CurDate(), EconTime::CurDateFract()); } void UpdateEffectiveDayLengthFactor() diff --git a/src/date_func.h b/src/date_func.h index 7da63076a4..44b71ff4ab 100644 --- a/src/date_func.h +++ b/src/date_func.h @@ -24,7 +24,7 @@ namespace DateDetail { extern uint8_t _effective_day_length; }; -StateTicks GetStateTicksFromCurrentDateWithoutOffset(); +StateTicks GetStateTicksFromDateWithoutOffset(EconTime::Date date, EconTime::DateFract date_fract); void RecalculateStateTicksOffset(); inline uint8_t TickSkipCounter() diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 12de639281..bb24ad3163 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -667,7 +667,12 @@ bool AfterLoadGame() TileIndex map_size = MapSize(); + /* Only new games can use wallclock units. */ + if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH, 5) && IsSavegameVersionBefore(SLV_ECONOMY_MODE_TIMEKEEPING_UNITS)) { + _settings_game.economy.timekeeping_units = TKU_CALENDAR; + } UpdateEffectiveDayLengthFactor(); + SetupTickRate(); extern TileIndex _cur_tileloop_tile; // From landscape.cpp. @@ -865,18 +870,15 @@ bool AfterLoadGame() _scaled_tick_counter = (uint64_t)((_tick_counter * DayLengthFactor()) + TickSkipCounter()); } if (SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 1, 3)) { - _state_ticks = GetStateTicksFromCurrentDateWithoutOffset() + DateDetail::_state_ticks_offset; + /* CalTime is used here because EconTime hasn't been set yet, but this needs to be done before setting EconTime::Detail::SetDate, + * because that calls RecalculateStateTicksOffset which overwrites DateDetail::_state_ticks_offset which is an input here */ + _state_ticks = GetStateTicksFromDateWithoutOffset(CalTime::CurDate().base(), CalTime::CurDateFract()) + DateDetail::_state_ticks_offset; } /* Update current year * must be done before loading sprites as some newgrfs check it */ CalTime::Detail::SetDate(CalTime::CurDate(), CalTime::CurDateFract()); - /* Only new games can use wallclock units. */ - if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH, 5) && IsSavegameVersionBefore(SLV_ECONOMY_MODE_TIMEKEEPING_UNITS)) { - _settings_game.economy.timekeeping_units = TKU_CALENDAR; - } - if (SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 5) || !IsSavegameVersionBefore(SLV_ECONOMY_DATE)) { EconTime::Detail::SetDate(EconTime::CurDate(), EconTime::CurDateFract()); } else {