Scheduled dispatch: Use an invalid value for no last dispatch, not 0

This commit is contained in:
Jonathan G Rennison
2024-01-22 18:27:28 +00:00
parent 11274feb35
commit 9be3dfa69c
7 changed files with 43 additions and 17 deletions

View File

@@ -2105,6 +2105,7 @@ STR_SCHDISPATCH_RENAME_SCHEDULE_CAPTION :{WHITE}Name sch
STR_ERROR_CAN_T_RENAME_SCHEDULE :{WHITE}Can't name schedule... STR_ERROR_CAN_T_RENAME_SCHEDULE :{WHITE}Can't name schedule...
STR_SCHDISPATCH_MOVE_SCHEDULE :{BLACK}Change position of current schedule in schedule list STR_SCHDISPATCH_MOVE_SCHEDULE :{BLACK}Change position of current schedule in schedule list
STR_SCHDISPATCH_SUMMARY_NO_LAST_DEPARTURE :{BLACK}No previous departures.
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}. STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}.
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}Last departure has not left yet, it will depart at {DATE_WALLCLOCK_TINY}. STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}Last departure has not left yet, it will depart at {DATE_WALLCLOCK_TINY}.
STR_SCHDISPATCH_SUMMARY_L1 :{BLACK}This schedule requires {COMMA} vehicle{P "" s}. STR_SCHDISPATCH_SUMMARY_L1 :{BLACK}This schedule requires {COMMA} vehicle{P "" s}.

View File

@@ -723,7 +723,7 @@ private:
uint32_t scheduled_dispatch_duration = 0; ///< Scheduled dispatch duration uint32_t scheduled_dispatch_duration = 0; ///< Scheduled dispatch duration
DateTicksScaled scheduled_dispatch_start_tick = -1; ///< Scheduled dispatch start tick DateTicksScaled scheduled_dispatch_start_tick = -1; ///< Scheduled dispatch start tick
/// this counts to (DAY_TICK * _settings_game.economy.day_length_factor) /// this counts to (DAY_TICK * _settings_game.economy.day_length_factor)
int32_t scheduled_dispatch_last_dispatch = 0; ///< Last vehicle dispatched offset int32_t scheduled_dispatch_last_dispatch = INVALID_SCHEDULED_DISPATCH_OFFSET; ///< Last vehicle dispatched offset
int32_t scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay int32_t scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay
uint8_t scheduled_dispatch_flags = 0; ///< Flags uint8_t scheduled_dispatch_flags = 0; ///< Flags

View File

@@ -3053,6 +3053,10 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v,
int32_t offset; int32_t offset;
if (order->GetConditionValue() & 2) { if (order->GetConditionValue() & 2) {
int32_t last = sched.GetScheduledDispatchLastDispatch(); int32_t last = sched.GetScheduledDispatchLastDispatch();
if (last == INVALID_SCHEDULED_DISPATCH_OFFSET) {
/* No last dispatched */
return OrderConditionCompare(order->GetConditionComparator(), 0, 0);
}
if (last < 0) { if (last < 0) {
last += sched.GetScheduledDispatchDuration() * (1 + (-last / sched.GetScheduledDispatchDuration())); last += sched.GetScheduledDispatchDuration() * (1 + (-last / sched.GetScheduledDispatchDuration()));
} }
@@ -3069,7 +3073,7 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v,
value = (offset == (int)sched.GetScheduledDispatch().front()); value = (offset == (int)sched.GetScheduledDispatch().front());
} }
return OrderConditionCompare(order->GetConditionComparator(), value, 0); return OrderConditionCompare(order->GetConditionComparator(), value ? 1 : 0, 0);
} }
static std::vector<TraceRestrictSlotID> _pco_deferred_slot_acquires; static std::vector<TraceRestrictSlotID> _pco_deferred_slot_acquires;

View File

@@ -32,6 +32,9 @@ static const OrderID INVALID_ORDER = 0xFFFFFF;
*/ */
static const uint IMPLICIT_ORDER_ONLY_CAP = 32; static const uint IMPLICIT_ORDER_ONLY_CAP = 32;
/** Invalid scheduled dispatch offset from current schedule */
static const int32_t INVALID_SCHEDULED_DISPATCH_OFFSET = INT32_MIN;
/** Order types. It needs to be 8bits, because we save and load it as such */ /** Order types. It needs to be 8bits, because we save and load it as such */
enum OrderType : byte { enum OrderType : byte {
OT_BEGIN = 0, OT_BEGIN = 0,

View File

@@ -307,7 +307,7 @@ CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag
if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR; if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
v->orders->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchLastDispatch(0); v->orders->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchLastDispatch(INVALID_SCHEDULED_DISPATCH_OFFSET);
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH); SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
} }
@@ -506,7 +506,7 @@ CommandCost CmdScheduledDispatchDuplicateSchedule(TileIndex tile, DoCommandFlag
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
DispatchSchedule &ds = v->orders->GetScheduledDispatchScheduleSet().emplace_back(v->orders->GetDispatchScheduleByIndex(schedule_index)); DispatchSchedule &ds = v->orders->GetScheduledDispatchScheduleSet().emplace_back(v->orders->GetDispatchScheduleByIndex(schedule_index));
ds.SetScheduledDispatchLastDispatch(0); ds.SetScheduledDispatchLastDispatch(INVALID_SCHEDULED_DISPATCH_OFFSET);
ds.UpdateScheduledDispatch(nullptr); ds.UpdateScheduledDispatch(nullptr);
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH); SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
} }
@@ -545,7 +545,7 @@ CommandCost CmdScheduledDispatchAppendVehicleSchedules(TileIndex tile, DoCommand
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
for (uint i = 0; i < v2->orders->GetScheduledDispatchScheduleCount(); i++) { for (uint i = 0; i < v2->orders->GetScheduledDispatchScheduleCount(); i++) {
DispatchSchedule &ds = v1->orders->GetScheduledDispatchScheduleSet().emplace_back(v2->orders->GetDispatchScheduleByIndex(i)); DispatchSchedule &ds = v1->orders->GetScheduledDispatchScheduleSet().emplace_back(v2->orders->GetDispatchScheduleByIndex(i));
ds.SetScheduledDispatchLastDispatch(0); ds.SetScheduledDispatchLastDispatch(INVALID_SCHEDULED_DISPATCH_OFFSET);
ds.UpdateScheduledDispatch(nullptr); ds.UpdateScheduledDispatch(nullptr);
} }
SetTimetableWindowsDirty(v1, STWDF_SCHEDULED_DISPATCH); SetTimetableWindowsDirty(v1, STWDF_SCHEDULED_DISPATCH);
@@ -721,16 +721,20 @@ bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now)
/* Most of the time this loop does not run. 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) { while (this->GetScheduledDispatchStartTick() > now) {
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch; OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch += this->GetScheduledDispatchDuration(); if (last_dispatch != INVALID_SCHEDULED_DISPATCH_OFFSET) {
this->scheduled_dispatch_last_dispatch = last_dispatch; last_dispatch += this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
}
this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() - this->GetScheduledDispatchDuration()); this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() - this->GetScheduledDispatchDuration());
update_windows = true; 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. */ /* Most of the time this loop runs once. It makes sure the start date is as close to current time as possible. */
while (this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration() <= now) { while (this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration() <= now) {
OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch; OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
last_dispatch -= this->GetScheduledDispatchDuration(); if (last_dispatch != INVALID_SCHEDULED_DISPATCH_OFFSET) {
this->scheduled_dispatch_last_dispatch = last_dispatch; last_dispatch -= this->GetScheduledDispatchDuration();
this->scheduled_dispatch_last_dispatch = last_dispatch;
}
this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration()); this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration());
update_windows = true; update_windows = true;
} }

View File

@@ -585,7 +585,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
const DateTicksScaled last_departure = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchLastDispatch(); const DateTicksScaled last_departure = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchLastDispatch();
StringID str; StringID str;
if (_scaled_date_ticks < last_departure) { if (last_departure == INVALID_SCHEDULED_DISPATCH_OFFSET) {
str = STR_SCHDISPATCH_SUMMARY_NO_LAST_DEPARTURE;
} else if (_scaled_date_ticks < last_departure) {
str = STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE; str = STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE;
set_next_departure_update(last_departure); set_next_departure_update(last_departure);
} else { } else {
@@ -595,7 +597,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
DrawString(ir.left, ir.right, y, str); DrawString(ir.left, ir.right, y, str);
y += GetCharacterHeight(FS_NORMAL); y += GetCharacterHeight(FS_NORMAL);
departure_time_warnings(last_departure); if (last_departure != INVALID_SCHEDULED_DISPATCH_OFFSET) {
departure_time_warnings(last_departure);
}
const DateTicksScaled next_departure = GetScheduledDispatchTime(ds, _scaled_date_ticks); const DateTicksScaled next_departure = GetScheduledDispatchTime(ds, _scaled_date_ticks);
set_next_departure_update(next_departure + ds.GetScheduledDispatchDelay()); set_next_departure_update(next_departure + ds.GetScheduledDispatchDelay());

View File

@@ -789,12 +789,22 @@ void UpdateSeparationOrder(Vehicle *v_start)
DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, DateTicksScaled leave_time) DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, DateTicksScaled leave_time)
{ {
DateTicksScaled first_slot = -1; const uint32_t dispatch_duration = ds.GetScheduledDispatchDuration();
const DateTicksScaled begin_time = ds.GetScheduledDispatchStartTick() - (ds.GetScheduledDispatchReuseSlots() ? ds.GetScheduledDispatchDuration() : 0); const int32_t max_delay = ds.GetScheduledDispatchDelay();
const int32_t last_dispatched_offset = ds.GetScheduledDispatchReuseSlots() ? -1 : ds.GetScheduledDispatchLastDispatch(); const DateTicksScaled minimum = leave_time - max_delay;
const uint32_t dispatch_duration = ds.GetScheduledDispatchDuration(); DateTicksScaled begin_time = ds.GetScheduledDispatchStartTick();
const int32_t max_delay = ds.GetScheduledDispatchDelay(); if (ds.GetScheduledDispatchReuseSlots()) {
const DateTicksScaled minimum = leave_time - max_delay; begin_time -= dispatch_duration;
}
int32_t last_dispatched_offset;
if (ds.GetScheduledDispatchLastDispatch() == INVALID_SCHEDULED_DISPATCH_OFFSET || ds.GetScheduledDispatchReuseSlots()) {
last_dispatched_offset = -1;
} else {
last_dispatched_offset = ds.GetScheduledDispatchLastDispatch();
}
DateTicksScaled first_slot = -1;
/* Find next available slots */ /* Find next available slots */
for (auto current_offset : ds.GetScheduledDispatch()) { for (auto current_offset : ds.GetScheduledDispatch()) {