Scheduled dispatch: Remove scheduled_dispatch_start_full_date_fract

Use DateTicksScaled
wip-string
Jonathan G Rennison 4 months ago
parent c76a5ed638
commit e9599fd4be

@ -70,13 +70,6 @@ static inline DateTicksScaled DateTicksToScaledDateTicks(DateTicks date_ticks)
return ((int64)date_ticks * _settings_game.economy.day_length_factor) + _scaled_date_ticks_offset;
}
static inline std::pair<Date, uint16> ScaledDateTicksToDateAndFullSubTicks(DateTicksScaled ticks)
{
ticks -= _scaled_date_ticks_offset;
const int full_date = _settings_game.economy.day_length_factor * DAY_TICKS;
return std::make_pair<Date, uint16>(ticks / full_date, ticks % full_date);
}
/**
* Calculate the year of a given date.
* @param date The date to consider.

@ -715,8 +715,7 @@ private:
std::vector<uint32> scheduled_dispatch; ///< Scheduled dispatch time
uint32 scheduled_dispatch_duration = 0; ///< Scheduled dispatch duration
Date scheduled_dispatch_start_date = -1; ///< Scheduled dispatch start date
uint16 scheduled_dispatch_start_full_date_fract = 0; ///< Scheduled dispatch start full date fraction;
DateTicksScaled scheduled_dispatch_start_tick = -1; ///< Scheduled dispatch start tick
/// this counts to (DAY_TICK * _settings_game.economy.day_length_factor)
int32 scheduled_dispatch_last_dispatch = 0; ///< Last vehicle dispatched offset
int32 scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay
@ -726,8 +725,7 @@ private:
inline void CopyBasicFields(const DispatchSchedule &other)
{
this->scheduled_dispatch_duration = other.scheduled_dispatch_duration;
this->scheduled_dispatch_start_date = other.scheduled_dispatch_start_date;
this->scheduled_dispatch_start_full_date_fract = other.scheduled_dispatch_start_full_date_fract;
this->scheduled_dispatch_start_tick = other.scheduled_dispatch_start_tick;
this->scheduled_dispatch_last_dispatch = other.scheduled_dispatch_last_dispatch;
this->scheduled_dispatch_max_delay = other.scheduled_dispatch_max_delay;
}
@ -761,38 +759,24 @@ public:
/**
* Set the scheduled dispatch start
* @param start New start date
* @param fract New start full date fraction, see \c CmdScheduledDispatchSetStartDate
* @param start_ticks New start ticks
*/
inline void SetScheduledDispatchStartDate(Date start_date, uint16 start_full_date_fract)
inline void SetScheduledDispatchStartTick(DateTicksScaled start_tick)
{
this->scheduled_dispatch_start_date = start_date;
this->scheduled_dispatch_start_full_date_fract = start_full_date_fract;
this->scheduled_dispatch_start_tick = start_tick;
}
/**
* Get the scheduled dispatch start date part
* @return scheduled dispatch start date part
*/
inline Date GetScheduledDispatchStartDatePart() const { return this->scheduled_dispatch_start_date; }
/**
* Get the scheduled dispatch start date fract part
* @return scheduled dispatch start date fract part
*/
inline uint16 GetScheduledDispatchStartDateFractPart() const { return this->scheduled_dispatch_start_full_date_fract; }
/**
* Get the scheduled dispatch start date, in absolute scaled tick
* @return scheduled dispatch start date
*/
inline DateTicksScaled GetScheduledDispatchStartTick() const { return SchdispatchConvertToScaledTick(this->scheduled_dispatch_start_date, this->scheduled_dispatch_start_full_date_fract); }
inline DateTicksScaled GetScheduledDispatchStartTick() const { return this->scheduled_dispatch_start_tick; }
/**
* Whether the scheduled dispatch setting is valid
* @return scheduled dispatch start date fraction
*/
inline bool IsScheduledDispatchValid() const { return this->scheduled_dispatch_start_date >= 0 && this->scheduled_dispatch_duration > 0; }
inline bool IsScheduledDispatchValid() const { return this->scheduled_dispatch_duration > 0; }
/**
* Set the scheduled dispatch last dispatch offset, in scaled tick

@ -3692,14 +3692,6 @@ CommandCost CmdMassChangeOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, u
void ShiftOrderDates(int interval)
{
for (OrderList *orderlist : OrderList::Iterate()) {
for (DispatchSchedule &ds : orderlist->GetScheduledDispatchScheduleSet()) {
if (ds.GetScheduledDispatchStartDatePart() >= 0) {
ds.SetScheduledDispatchStartDate(ds.GetScheduledDispatchStartDatePart() + interval, ds.GetScheduledDispatchStartDateFractPart());
}
}
}
SetWindowClassesDirty(WC_VEHICLE_ORDERS);
SetWindowClassesDirty(WC_VEHICLE_TIMETABLE);
SetWindowClassesDirty(WC_SCHDISPATCH_SLOTS);

@ -4165,7 +4165,7 @@ bool AfterLoadGame()
for (OrderList *order_list : OrderList::Iterate()) {
if (order_list->GetScheduledDispatchScheduleCount() == 1) {
const DispatchSchedule &ds = order_list->GetDispatchScheduleByIndex(0);
if (!ds.IsScheduledDispatchValid() && ds.GetScheduledDispatch().empty()) {
if (!(ds.GetScheduledDispatchStartTick() >= 0 && ds.IsScheduledDispatchValid()) && ds.GetScheduledDispatch().empty()) {
order_list->GetScheduledDispatchScheduleSet().clear();
} else {
VehicleOrderID idx = order_list->GetFirstSharedVehicle()->GetFirstWaitingLocation(false);
@ -4176,6 +4176,18 @@ bool AfterLoadGame()
}
}
}
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4)) {
extern btree::btree_map<DispatchSchedule *, uint16> _old_scheduled_dispatch_start_full_date_fract_map;
for (OrderList *order_list : OrderList::Iterate()) {
for (DispatchSchedule &ds : order_list->GetScheduledDispatchScheduleSet()) {
DateTicksScaled start_tick = DateToScaledDateTicks(ds.GetScheduledDispatchStartTick()) + _old_scheduled_dispatch_start_full_date_fract_map[&ds];
ds.SetScheduledDispatchStartTick(start_tick);
}
}
_old_scheduled_dispatch_start_full_date_fract_map.clear();
}
if (SlXvIsFeaturePresent(XSLFI_TRACE_RESTRICT, 7, 12)) {
/* Move vehicle in slot flag */

@ -17,26 +17,4 @@
void ShowSchdispatchWindow(const Vehicle *v);
void SchdispatchInvalidateWindows(const Vehicle *v);
/**
* Convert date and full date fraction to DateTicksScaled
* @param date Current date
* @param full_date_fract full date fraction, the number of scaled tick in current day
* @return DateTicksScaled for ths specified date/faction
*/
inline DateTicksScaled SchdispatchConvertToScaledTick(Date date, uint16 full_date_fract)
{
return DateToScaledDateTicks(date) + full_date_fract;
}
/**
* Convert DateTicksScaled to date and full date fraction format
* @param tick DateTicksScaled to convert
* @param date Point to date, for ourput
* @param full_date_fract Pointer to uint16, for output
*/
inline void SchdispatchConvertToFullDateFract(DateTicksScaled tick, Date* date, uint16* full_date_fract)
{
std::tie(*date, *full_date_fract) = ScaledDateTicksToDateAndFullSubTicks(tick);
}
#endif /* SCHDISPATCH_H */

@ -180,9 +180,8 @@ CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags,
* @param tile Not used.
* @param flags Operation to perform.
* @param p1 Vehicle index
* @param p2 Date to add.
* @param p3 various bitstuffed elements
* - p3 = (bit 0 - 15) - Full date fraction
* @param p2 Unused.
* @param p3 Start tick
* @param text unused
* @return the cost of this operation or an error
*/
@ -201,12 +200,9 @@ CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags
if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
int32 date = (int32)p2;
uint16 full_date_fract = GB(p3, 0, 16);
if (flags & DC_EXEC) {
DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(schedule_index);
ds.SetScheduledDispatchStartDate(date, full_date_fract);
ds.SetScheduledDispatchStartTick((DateTicksScaled)p3);
ds.UpdateScheduledDispatch(nullptr);
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
}
@ -325,9 +321,7 @@ CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint3
* @param flags Operation to perform.
* @param p1 Vehicle index
* @param p2 Duration, in scaled tick
* @param p3 various bitstuffed elements
* - p3 = (bit 0 - 31) - Start date
* - p3 = (bit 32 - 47) - Full date fraction
* @param p3 Start tick
* @param text unused
* @return the cost of this operation or an error
*/
@ -344,14 +338,11 @@ CommandCost CmdScheduledDispatchAddNewSchedule(TileIndex tile, DoCommandFlag fla
if (v->orders == nullptr) return CMD_ERROR;
if (v->orders->GetScheduledDispatchScheduleCount() >= 4096) return CMD_ERROR;
int32 date = GB(p3, 0, 32);
uint16 full_date_fract = GB(p3, 32, 16);
if (flags & DC_EXEC) {
v->orders->GetScheduledDispatchScheduleSet().emplace_back();
DispatchSchedule &ds = v->orders->GetScheduledDispatchScheduleSet().back();
ds.SetScheduledDispatchDuration(p2);
ds.SetScheduledDispatchStartDate(date, full_date_fract);
ds.SetScheduledDispatchStartTick((DateTicksScaled)p3);
ds.UpdateScheduledDispatch(nullptr);
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
}
@ -683,10 +674,8 @@ bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now)
{
bool update_windows = false;
if (this->GetScheduledDispatchStartTick() == 0) {
int64 start = now - (now % this->GetScheduledDispatchDuration());
SchdispatchConvertToFullDateFract(
start,
&this->scheduled_dispatch_start_date, &this->scheduled_dispatch_start_full_date_fract);
DateTicksScaled start = now - (now % this->GetScheduledDispatchDuration());
this->SetScheduledDispatchStartTick(start);
int64 last_dispatch = -start;
if (last_dispatch < INT_MIN && _settings_game.game_time.time_in_minutes) {
/* Advance by multiples of 24 hours */
@ -696,14 +685,12 @@ bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now)
this->scheduled_dispatch_last_dispatch = ClampTo<int32>(last_dispatch);
}
}
/* Most of the time this loop does not runs. It makes sure start date in in past */
/* Most of the time this loop does not run. It makes sure start date in in past */
while (this->GetScheduledDispatchStartTick() > now) {
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch += this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
SchdispatchConvertToFullDateFract(
this->GetScheduledDispatchStartTick() - this->GetScheduledDispatchDuration(),
&this->scheduled_dispatch_start_date, &this->scheduled_dispatch_start_full_date_fract);
this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() - this->GetScheduledDispatchDuration());
update_windows = true;
}
/* Most of the time this loop runs once. It makes sure the start date is as close to current time as possible. */
@ -711,9 +698,7 @@ bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now)
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch -= this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
SchdispatchConvertToFullDateFract(
this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration(),
&this->scheduled_dispatch_start_date, &this->scheduled_dispatch_start_full_date_fract);
this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration());
update_windows = true;
}
return update_windows;

@ -67,11 +67,7 @@ enum SchdispatchWidgets {
*/
static void SetScheduleStartDateIntl(uint32 p1, DateTicksScaled date)
{
Date start_date;
uint16 start_full_date_fract;
SchdispatchConvertToFullDateFract(date, &start_date, &start_full_date_fract);
DoCommandPEx(0, p1, start_date, start_full_date_fract, CMD_SCHEDULED_DISPATCH_SET_START_DATE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0);
DoCommandPEx(0, p1, 0, (uint64)date, CMD_SCHEDULED_DISPATCH_SET_START_DATE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0);
}
/**
@ -161,32 +157,24 @@ static int CalculateMaxRequiredVehicle(Ticks timetable_duration, uint32 schedule
static void AddNewScheduledDispatchSchedule(VehicleID vindex)
{
Date start_date;
uint16 start_full_date_fract;
DateTicksScaled start_tick;
uint32 duration;
if (_settings_time.time_in_minutes) {
/* Set to 00:00 of today, and 1 day */
DateTicksScaled val;
val = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, 0);
val -= _settings_time.clock_offset;
val *= _settings_time.ticks_per_minute;
SchdispatchConvertToFullDateFract(val, &start_date, &start_full_date_fract);
start_tick = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, 0);
start_tick -= _settings_time.clock_offset;
start_tick *= _settings_time.ticks_per_minute;
duration = 24 * 60 * _settings_time.ticks_per_minute;
} else {
/* Set Jan 1st and 365 day */
start_date = DAYS_TILL(_cur_year);
start_full_date_fract = 0;
start_tick = DateToScaledDateTicks(DAYS_TILL(_cur_year));
duration = 365 * DAY_TICKS;
}
uint64 p3 = 0;
SB(p3, 0, 32, start_date);
SB(p3, 32, 16, start_full_date_fract);
DoCommandPEx(0, vindex, duration, p3, CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), CcAddNewSchDispatchSchedule, nullptr, 0);
DoCommandPEx(0, vindex, duration, (uint64)start_tick, CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), CcAddNewSchDispatchSchedule, nullptr, 0);
}
struct SchdispatchWindow : GeneralVehicleWindow {

@ -1770,15 +1770,9 @@ static bool DayLengthPreChange(int32 &new_value)
static void DayLengthChanged(int32 new_value)
{
DateTicksScaled old_scaled_date_ticks = _scaled_date_ticks;
DateTicksScaled old_scaled_date_ticks_offset = _scaled_date_ticks_offset;
extern void RebaseScaledDateTicksBase();
RebaseScaledDateTicksBase();
extern void VehicleDayLengthChanged(DateTicksScaled old_scaled_date_ticks, DateTicksScaled old_scaled_date_ticks_offset, uint8 old_day_length_factor);
VehicleDayLengthChanged(old_scaled_date_ticks, old_scaled_date_ticks_offset, _pre_change_day_length_factor);
SetupTileLoopCounts();
MarkWholeScreenDirty();

@ -117,7 +117,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_STATION_CATCHMENT_INC, XSCF_NULL, 1, 1, "station_catchment_inc", nullptr, nullptr, nullptr },
{ XSLFI_CUSTOM_BRIDGE_HEADS, XSCF_NULL, 4, 4, "custom_bridge_heads", nullptr, nullptr, nullptr },
{ XSLFI_CHUNNEL, XSCF_NULL, 2, 2, "chunnel", nullptr, nullptr, "TUNN" },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 4, 4, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 5, 5, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr },
{ XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr },
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" },

@ -20,6 +20,9 @@ static uint32 _jokerpp_separation_mode;
std::vector<OrderList *> _jokerpp_auto_separation;
std::vector<OrderList *> _jokerpp_non_auto_separation;
static uint16 _old_scheduled_dispatch_start_full_date_fract;
btree::btree_map<DispatchSchedule *, uint16> _old_scheduled_dispatch_start_full_date_fract_map;
/**
* Converts this order from an old savegame's version;
* it moves all bits to the new location.
@ -263,8 +266,9 @@ SaveLoadTable GetDispatchScheduleDescription()
static const SaveLoad _order_extra_info_desc[] = {
SLE_VARVEC(DispatchSchedule, scheduled_dispatch, SLE_UINT32),
SLE_VAR(DispatchSchedule, scheduled_dispatch_duration, SLE_UINT32),
SLE_VAR(DispatchSchedule, scheduled_dispatch_start_date, SLE_INT32),
SLE_VAR(DispatchSchedule, scheduled_dispatch_start_full_date_fract, SLE_UINT16),
SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4)),
SLEG_CONDVAR_X(_old_scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4)),
SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 5)),
SLE_VAR(DispatchSchedule, scheduled_dispatch_last_dispatch, SLE_INT32),
SLE_VAR(DispatchSchedule, scheduled_dispatch_max_delay, SLE_INT32),
SLE_CONDSSTR_X(DispatchSchedule, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 4)),
@ -303,8 +307,11 @@ static void Load_ORDL()
{
_jokerpp_auto_separation.clear();
_jokerpp_non_auto_separation.clear();
int index;
_old_scheduled_dispatch_start_full_date_fract = 0;
_old_scheduled_dispatch_start_full_date_fract_map.clear();
int index;
while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */
OrderList *list = new (index) OrderList(0);
@ -321,6 +328,9 @@ static void Load_ORDL()
list->GetScheduledDispatchScheduleSet().resize(count);
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
SlObject(&ds, GetDispatchScheduleDescription());
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4) && _old_scheduled_dispatch_start_full_date_fract != 0) {
_old_scheduled_dispatch_start_full_date_fract_map[&ds] = _old_scheduled_dispatch_start_full_date_fract;
}
}
}
}

@ -4654,6 +4654,12 @@ void AdjustVehicleScaledTickBase(int64 delta)
for (Vehicle *v : Vehicle::Iterate()) {
if (v->timetable_start != 0) v->timetable_start += delta;
}
for (OrderList *order_list : OrderList::Iterate()) {
for (DispatchSchedule &ds : order_list->GetScheduledDispatchScheduleSet()) {
ds.SetScheduledDispatchStartTick(ds.GetScheduledDispatchStartTick() + delta);
}
}
}
void ShiftVehicleDates(int interval)
@ -4665,25 +4671,6 @@ void ShiftVehicleDates(int interval)
* for vehicles outside of a depot. */
}
extern void VehicleDayLengthChanged(DateTicksScaled old_scaled_date_ticks, DateTicksScaled old_scaled_date_ticks_offset, uint8 old_day_length_factor)
{
if (_settings_game.economy.day_length_factor == old_day_length_factor || !_settings_game.game_time.time_in_minutes) return;
for (OrderList *orderlist : OrderList::Iterate()) {
for (DispatchSchedule &ds : orderlist->GetScheduledDispatchScheduleSet()) {
if (ds.GetScheduledDispatchStartDatePart() >= 0) {
DateTicksScaled start = ((int64)ds.GetScheduledDispatchStartDatePart() * DAY_TICKS * old_day_length_factor) +
ds.GetScheduledDispatchStartDateFractPart() + old_scaled_date_ticks_offset;
start += (_scaled_date_ticks - old_scaled_date_ticks);
Date date;
uint16 full_date_fract;
std::tie(date, full_date_fract) = ScaledDateTicksToDateAndFullSubTicks(start);
ds.SetScheduledDispatchStartDate(date, full_date_fract);
}
}
}
}
/**
* Calculates the maximum weight of the ground vehicle when loaded.
* @return Weight in tonnes

Loading…
Cancel
Save