Scheduled dispatch: Use an invalid value for no last dispatch, not 0
This commit is contained in:
		@@ -2105,6 +2105,7 @@ STR_SCHDISPATCH_RENAME_SCHEDULE_CAPTION                         :{WHITE}Name sch
 | 
			
		||||
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_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_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}.
 | 
			
		||||
 
 | 
			
		||||
@@ -723,7 +723,7 @@ private:
 | 
			
		||||
	uint32_t scheduled_dispatch_duration = 0;                           ///< Scheduled dispatch duration
 | 
			
		||||
	DateTicksScaled scheduled_dispatch_start_tick = -1;                 ///< Scheduled dispatch start tick
 | 
			
		||||
	                                                                    ///  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
 | 
			
		||||
	uint8_t scheduled_dispatch_flags = 0;                               ///< Flags
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3053,6 +3053,10 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v,
 | 
			
		||||
	int32_t offset;
 | 
			
		||||
	if (order->GetConditionValue() & 2) {
 | 
			
		||||
		int32_t last = sched.GetScheduledDispatchLastDispatch();
 | 
			
		||||
		if (last == INVALID_SCHEDULED_DISPATCH_OFFSET) {
 | 
			
		||||
			/* No last dispatched */
 | 
			
		||||
			return OrderConditionCompare(order->GetConditionComparator(), 0, 0);
 | 
			
		||||
		}
 | 
			
		||||
		if (last < 0) {
 | 
			
		||||
			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());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return OrderConditionCompare(order->GetConditionComparator(), value, 0);
 | 
			
		||||
	return OrderConditionCompare(order->GetConditionComparator(), value ? 1 : 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static std::vector<TraceRestrictSlotID> _pco_deferred_slot_acquires;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@ static const OrderID INVALID_ORDER = 0xFFFFFF;
 | 
			
		||||
 */
 | 
			
		||||
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 */
 | 
			
		||||
enum OrderType : byte {
 | 
			
		||||
	OT_BEGIN         = 0,
 | 
			
		||||
 
 | 
			
		||||
@@ -307,7 +307,7 @@ CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag
 | 
			
		||||
	if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -506,7 +506,7 @@ CommandCost CmdScheduledDispatchDuplicateSchedule(TileIndex tile, DoCommandFlag
 | 
			
		||||
 | 
			
		||||
	if (flags & DC_EXEC) {
 | 
			
		||||
		DispatchSchedule &ds = v->orders->GetScheduledDispatchScheduleSet().emplace_back(v->orders->GetDispatchScheduleByIndex(schedule_index));
 | 
			
		||||
		ds.SetScheduledDispatchLastDispatch(0);
 | 
			
		||||
		ds.SetScheduledDispatchLastDispatch(INVALID_SCHEDULED_DISPATCH_OFFSET);
 | 
			
		||||
		ds.UpdateScheduledDispatch(nullptr);
 | 
			
		||||
		SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
 | 
			
		||||
	}
 | 
			
		||||
@@ -545,7 +545,7 @@ CommandCost CmdScheduledDispatchAppendVehicleSchedules(TileIndex tile, DoCommand
 | 
			
		||||
	if (flags & DC_EXEC) {
 | 
			
		||||
		for (uint i = 0; i < v2->orders->GetScheduledDispatchScheduleCount(); i++) {
 | 
			
		||||
			DispatchSchedule &ds = v1->orders->GetScheduledDispatchScheduleSet().emplace_back(v2->orders->GetDispatchScheduleByIndex(i));
 | 
			
		||||
			ds.SetScheduledDispatchLastDispatch(0);
 | 
			
		||||
			ds.SetScheduledDispatchLastDispatch(INVALID_SCHEDULED_DISPATCH_OFFSET);
 | 
			
		||||
			ds.UpdateScheduledDispatch(nullptr);
 | 
			
		||||
		}
 | 
			
		||||
		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 */
 | 
			
		||||
	while (this->GetScheduledDispatchStartTick() > now) {
 | 
			
		||||
		OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
 | 
			
		||||
		last_dispatch += this->GetScheduledDispatchDuration();
 | 
			
		||||
		this->scheduled_dispatch_last_dispatch = last_dispatch;
 | 
			
		||||
		if (last_dispatch != INVALID_SCHEDULED_DISPATCH_OFFSET) {
 | 
			
		||||
			last_dispatch += this->GetScheduledDispatchDuration();
 | 
			
		||||
			this->scheduled_dispatch_last_dispatch = last_dispatch;
 | 
			
		||||
		}
 | 
			
		||||
		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. */
 | 
			
		||||
	while (this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration() <= now) {
 | 
			
		||||
		OverflowSafeInt32 last_dispatch = this->scheduled_dispatch_last_dispatch;
 | 
			
		||||
		last_dispatch -= this->GetScheduledDispatchDuration();
 | 
			
		||||
		this->scheduled_dispatch_last_dispatch = last_dispatch;
 | 
			
		||||
		if (last_dispatch != INVALID_SCHEDULED_DISPATCH_OFFSET) {
 | 
			
		||||
			last_dispatch -= this->GetScheduledDispatchDuration();
 | 
			
		||||
			this->scheduled_dispatch_last_dispatch = last_dispatch;
 | 
			
		||||
		}
 | 
			
		||||
		this->SetScheduledDispatchStartTick(this->GetScheduledDispatchStartTick() + this->GetScheduledDispatchDuration());
 | 
			
		||||
		update_windows = true;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -585,7 +585,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
 | 
			
		||||
					const DateTicksScaled last_departure = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchLastDispatch();
 | 
			
		||||
					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;
 | 
			
		||||
						set_next_departure_update(last_departure);
 | 
			
		||||
					} else {
 | 
			
		||||
@@ -595,7 +597,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
					DrawString(ir.left, ir.right, y, str);
 | 
			
		||||
					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);
 | 
			
		||||
					set_next_departure_update(next_departure + ds.GetScheduledDispatchDelay());
 | 
			
		||||
 
 | 
			
		||||
@@ -789,12 +789,22 @@ void UpdateSeparationOrder(Vehicle *v_start)
 | 
			
		||||
 | 
			
		||||
DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, DateTicksScaled leave_time)
 | 
			
		||||
{
 | 
			
		||||
	DateTicksScaled first_slot            = -1;
 | 
			
		||||
	const DateTicksScaled begin_time      = ds.GetScheduledDispatchStartTick() - (ds.GetScheduledDispatchReuseSlots() ? ds.GetScheduledDispatchDuration() : 0);
 | 
			
		||||
	const int32_t last_dispatched_offset  = ds.GetScheduledDispatchReuseSlots() ? -1 : ds.GetScheduledDispatchLastDispatch();
 | 
			
		||||
	const uint32_t dispatch_duration      = ds.GetScheduledDispatchDuration();
 | 
			
		||||
	const int32_t max_delay               = ds.GetScheduledDispatchDelay();
 | 
			
		||||
	const DateTicksScaled minimum         = leave_time - max_delay;
 | 
			
		||||
	const uint32_t dispatch_duration = ds.GetScheduledDispatchDuration();
 | 
			
		||||
	const int32_t max_delay          = ds.GetScheduledDispatchDelay();
 | 
			
		||||
	const DateTicksScaled minimum    = leave_time - max_delay;
 | 
			
		||||
	DateTicksScaled begin_time       = ds.GetScheduledDispatchStartTick();
 | 
			
		||||
	if (ds.GetScheduledDispatchReuseSlots()) {
 | 
			
		||||
		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 */
 | 
			
		||||
	for (auto current_offset : ds.GetScheduledDispatch()) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user