Store state ticks directly in savegame instead of the offset

Initialise the state ticks value to a constant for new games,
instead of using an implicit offset of 0
pull/647/head
Jonathan G Rennison 3 months ago
parent 0ea57528c9
commit d39236d50c

@ -33,7 +33,7 @@ uint64_t _tick_counter; ///< Ever incrementing tick counter f
uint8_t _tick_skip_counter; ///< Counter for ticks, when only vehicles are moving and nothing else happens
uint64_t _scaled_tick_counter; ///< Tick counter in daylength-scaled ticks
StateTicks _state_ticks; ///< Current state tick
StateTicks _state_ticks_offset; ///< Offset to add when calculating a StateTicks value from a date/date fract/tick skip counter
StateTicksDelta _state_ticks_offset; ///< Offset to add when calculating a StateTicks value from a date/date fract/tick skip counter
uint32_t _quit_after_days; ///< Quit after this many days of run time
YearMonthDay _game_load_cur_date_ymd;
@ -45,14 +45,14 @@ extern void ClearOutOfDateSignalSpeedRestrictions();
void CheckStateTicksWrap()
{
StateTicksDelta tick_adjust = 0;
auto get_tick_adjust = [&](StateTicks target) {
auto get_tick_adjust = [&](StateTicksDelta target) {
int32_t rounding = _settings_time.time_in_minutes * 1440;
return target.AsDelta() - (target.base() % rounding);
return target - (target.base() % rounding);
};
if (_state_ticks >= ((int64_t)1 << 60)) {
tick_adjust = get_tick_adjust(_state_ticks);
tick_adjust = get_tick_adjust(_state_ticks - INITIAL_STATE_TICKS_VALUE);
} else if (_state_ticks <= -((int64_t)1 << 60)) {
tick_adjust = -get_tick_adjust(-(_state_ticks.base()));
tick_adjust = -get_tick_adjust(INITIAL_STATE_TICKS_VALUE - _state_ticks);
} else {
return;
}
@ -70,23 +70,12 @@ void CheckStateTicksWrap()
AdjustLinkGraphStateTicksBase(-tick_adjust);
}
void RebaseStateTicksBase()
{
StateTicks old_state_ticks = _state_ticks;
SetScaledTickVariables();
_state_ticks_offset += (old_state_ticks - _state_ticks);
SetScaledTickVariables();
assert(old_state_ticks == _state_ticks);
CheckStateTicksWrap();
}
/**
* Set the date.
* @param date New date
* @param fract The number of ticks that have passed on this date.
*/
void SetDate(Date date, DateFract fract, bool preserve_state_tick)
void SetDate(Date date, DateFract fract)
{
assert(fract < DAY_TICKS);
@ -94,17 +83,18 @@ void SetDate(Date date, DateFract fract, bool preserve_state_tick)
_date_fract = fract;
YearMonthDay ymd = ConvertDateToYMD(date);
_cur_date_ymd = ymd;
if (preserve_state_tick) {
RebaseStateTicksBase();
} else {
SetScaledTickVariables();
}
RecalculateStateTicksOffset();
UpdateCachedSnowLine();
}
void SetScaledTickVariables()
StateTicks GetStateTicksFromCurrentDateWithoutOffset()
{
return ((int64_t)(DateToDateTicks(_date, _date_fract).base()) * _settings_game.economy.day_length_factor) + _tick_skip_counter;
}
void RecalculateStateTicksOffset()
{
_state_ticks = ((int64_t)(DateToDateTicks(_date, _date_fract).base()) * _settings_game.economy.day_length_factor) + _tick_skip_counter + _state_ticks_offset;
_state_ticks_offset = _state_ticks - GetStateTicksFromCurrentDateWithoutOffset();
}
#define M(a, b) ((a << 5) | b)
@ -270,7 +260,7 @@ static void OnNewYear()
LinkGraphSchedule::instance.ShiftDates(-days_this_year);
ShiftOrderDates(-days_this_year);
ShiftVehicleDates(-days_this_year);
_state_ticks_offset += ((int64_t)days_this_year) * (DAY_TICKS * _settings_game.economy.day_length_factor);
RecalculateStateTicksOffset();
/* 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 */

@ -21,17 +21,18 @@ extern uint64_t _tick_counter;
extern uint8_t _tick_skip_counter;
extern uint64_t _scaled_tick_counter;
extern StateTicks _state_ticks;
extern StateTicks _state_ticks_offset;
extern StateTicksDelta _state_ticks_offset;
extern uint32_t _quit_after_days;
extern YearMonthDay _game_load_cur_date_ymd;
extern DateFract _game_load_date_fract;
extern uint8_t _game_load_tick_skip_counter;
void SetDate(Date date, DateFract fract, bool preserve_scaled_ticks = true);
void SetDate(Date date, DateFract fract);
YearMonthDay ConvertDateToYMD(Date date);
Date ConvertYMDToDate(Year year, Month month, Day day);
void SetScaledTickVariables();
StateTicks GetStateTicksFromCurrentDateWithoutOffset();
void RecalculateStateTicksOffset();
inline Date ConvertYMDToDate(const YearMonthDay &ymd)
{

@ -200,6 +200,9 @@ static const Year MAX_YEAR = 5000000;
/** The number of days till the last day */
static constexpr Date MAX_DATE = DateAtStartOfYear(MAX_YEAR + 1) - 1;
/** An initial value for StateTicks when starting a new game */
static constexpr StateTicks INITIAL_STATE_TICKS_VALUE = 1 << 24;
/**
* Data structure to convert between Date and triplet (year, month, and day).
* @see ConvertDateToYMD(), ConvertYMDToDate()

@ -131,6 +131,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_tick_counter = 0;
_tick_skip_counter = 0;
_scaled_tick_counter = 0;
_state_ticks = INITIAL_STATE_TICKS_VALUE;
_state_ticks_offset = 0;
_cur_tileloop_tile = 1;
_aux_tileloop_tile = 1;
@ -153,10 +154,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_newgrf_profilers.clear();
if (reset_date) {
SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0, false);
SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
InitializeOldNames();
} else {
SetScaledTickVariables();
RecalculateStateTicksOffset();
}
SetupTileLoopCounts();
UpdateCargoScalers();

@ -11605,7 +11605,8 @@ void LoadNewGRF(uint load_index, uint num_baseset)
uint64_t tick_counter = _tick_counter;
uint8_t tick_skip_counter = _tick_skip_counter;
uint64_t scaled_tick_counter = _scaled_tick_counter;
StateTicks state_ticks_offset = _state_ticks_offset;
StateTicks state_ticks = _state_ticks;
StateTicksDelta state_ticks_offset = _state_ticks_offset;
byte display_opt = _display_opt;
if (_networking) {
@ -11615,10 +11616,10 @@ void LoadNewGRF(uint load_index, uint num_baseset)
_tick_counter = 0;
_tick_skip_counter = 0;
_scaled_tick_counter = 0;
_state_ticks_offset = 0;
_state_ticks = 0;
_display_opt = 0;
UpdateCachedSnowLine();
SetScaledTickVariables();
RecalculateStateTicksOffset();
}
InitializeGRFSpecial();
@ -11722,10 +11723,10 @@ void LoadNewGRF(uint load_index, uint num_baseset)
_tick_counter = tick_counter;
_tick_skip_counter = tick_skip_counter;
_scaled_tick_counter = scaled_tick_counter;
_state_ticks = state_ticks;
_state_ticks_offset = state_ticks_offset;
_display_opt = display_opt;
UpdateCachedSnowLine();
SetScaledTickVariables();
}
/**

@ -2149,7 +2149,7 @@ void StateGameLoop()
_tick_skip_counter++;
_scaled_tick_counter++;
if (_game_mode != GM_MENU && _game_mode != GM_BOOTSTRAP) {
_state_ticks++; // This must update in lock-step with _tick_skip_counter, such that it always matches what SetScaledTickVariables would return.
_state_ticks++; // This must update in lock-step with _tick_skip_counter, such that _state_ticks_offset doesn't need to be changed.
}
if (!(_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) && !_settings_client.gui.autosave_realtime &&

@ -862,10 +862,13 @@ bool AfterLoadGame()
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH, 3)) {
_scaled_tick_counter = (uint64_t)((_tick_counter * _settings_game.economy.day_length_factor) + _tick_skip_counter);
}
if (SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 1, 3)) {
_state_ticks = GetStateTicksFromCurrentDateWithoutOffset() + _state_ticks_offset;
}
/* Update current year
* must be done before loading sprites as some newgrfs check it */
SetDate(_date, _date_fract, false);
SetDate(_date, _date_fract);
SetupTileLoopCounts();
/*
@ -1796,7 +1799,7 @@ bool AfterLoadGame()
* Account for this in older games by adding an offset */
if (IsSavegameVersionBefore(SLV_31)) {
_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
SetScaledTickVariables();
RecalculateStateTicksOffset();
_cur_date_ymd = ConvertDateToYMD(_date);
UpdateCachedSnowLine();

@ -1850,8 +1850,7 @@ static bool DayLengthPreChange(int32_t &new_value)
static void DayLengthChanged(int32_t new_value)
{
extern void RebaseStateTicksBase();
RebaseStateTicksBase();
RecalculateStateTicksOffset();
SetupTileLoopCounts();
UpdateCargoScalers();

@ -103,7 +103,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", nullptr, nullptr, nullptr },
{ XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 4, 4, "enh_viewport_plans", nullptr, nullptr, "PLAN" },
{ XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 3, 3, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 4, 4, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr },
{ XSLFI_MORE_COND_ORDERS, XSCF_NULL, 17, 17, "more_cond_orders", nullptr, nullptr, nullptr },
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },

@ -91,7 +91,8 @@ static const SaveLoad _date_desc[] = {
SLEG_CONDVAR_X(_tick_counter, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_U64_TICK_COUNTER)),
SLEG_CONDVAR_X(_tick_skip_counter, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH)),
SLEG_CONDVAR_X(_scaled_tick_counter, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3)),
SLEG_CONDVAR_X(_state_ticks_offset, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3)),
SLEG_CONDVAR_X(_state_ticks_offset, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3, 3)),
SLEG_CONDVAR_X(_state_ticks, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 4)),
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_157), // _vehicle_id_ctr_day
SLEG_CONDVAR(_age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162),
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_46),
@ -128,7 +129,8 @@ static const SaveLoad _date_check_desc[] = {
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_U64_TICK_COUNTER)), // _tick_counter
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH)), // _tick_skip_counter
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3)), // _scaled_tick_counter
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3)), // _state_ticks_offset
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3, 3)), // _state_ticks_offset
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 4)), // _state_ticks
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_157), // _vehicle_id_ctr_day
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_162), // _age_cargo_skip_counter
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_46),
@ -160,7 +162,6 @@ static const SaveLoad _date_check_desc[] = {
static void SaveLoad_DATE()
{
SlGlobList(_date_desc);
SetScaledTickVariables();
}
static void Check_DATE()

Loading…
Cancel
Save