Scheduled dispatch: Fix handling of missing last/next dispatch times
In some cases
This commit is contained in:
		@@ -3192,6 +3192,10 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v,
 | 
			
		||||
		offset = last % sched.GetScheduledDispatchDuration();
 | 
			
		||||
	} else {
 | 
			
		||||
		StateTicks slot = GetScheduledDispatchTime(sched, state_ticks);
 | 
			
		||||
		if (slot == INVALID_STATE_TICKS) {
 | 
			
		||||
			/* No next dispatch */
 | 
			
		||||
			return OrderConditionCompare(order->GetConditionComparator(), 0, 0);
 | 
			
		||||
		}
 | 
			
		||||
		offset = (slot - sched.GetScheduledDispatchStartTick()).base() % sched.GetScheduledDispatchDuration();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -508,7 +508,8 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					bool have_last = false;
 | 
			
		||||
					if (ds.GetScheduledDispatchLastDispatch() % ds.GetScheduledDispatchDuration() == slot->offset) {
 | 
			
		||||
					int32_t last_dispatch = ds.GetScheduledDispatchLastDispatch();
 | 
			
		||||
					if (last_dispatch != INVALID_SCHEDULED_DISPATCH_OFFSET && (last_dispatch % ds.GetScheduledDispatchDuration() == slot->offset)) {
 | 
			
		||||
						_temp_special_strings[0] += '\n';
 | 
			
		||||
						_temp_special_strings[0] += GetString(STR_SCHDISPATCH_SLOT_TOOLTIP_LAST);
 | 
			
		||||
						if (_settings_time.time_in_minutes) {
 | 
			
		||||
@@ -521,7 +522,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
						have_last = true;
 | 
			
		||||
					}
 | 
			
		||||
					StateTicks next_slot = GetScheduledDispatchTime(ds, _state_ticks);
 | 
			
		||||
					if ((next_slot - ds.GetScheduledDispatchStartTick()).AsTicks() % ds.GetScheduledDispatchDuration() == slot->offset) {
 | 
			
		||||
					if (next_slot != INVALID_STATE_TICKS && ((next_slot - ds.GetScheduledDispatchStartTick()).AsTicks() % ds.GetScheduledDispatchDuration() == slot->offset)) {
 | 
			
		||||
						if (!have_last) _temp_special_strings[0] += '\n';
 | 
			
		||||
						_temp_special_strings[0] += GetString(STR_SCHDISPATCH_SLOT_TOOLTIP_NEXT);
 | 
			
		||||
						if (_settings_time.time_in_minutes) {
 | 
			
		||||
@@ -631,9 +632,14 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
				const StateTicks end_tick = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchDuration();
 | 
			
		||||
 | 
			
		||||
				StateTicks slot = GetScheduledDispatchTime(ds, _state_ticks);
 | 
			
		||||
				int32_t next_offset = (slot - ds.GetScheduledDispatchStartTick()).AsTicks() % ds.GetScheduledDispatchDuration();
 | 
			
		||||
				int32_t next_offset = (slot != INVALID_STATE_TICKS) ? (slot - ds.GetScheduledDispatchStartTick()).AsTicks() % ds.GetScheduledDispatchDuration() : INT32_MIN;
 | 
			
		||||
 | 
			
		||||
				int32_t last_dispatch = ds.GetScheduledDispatchLastDispatch() % ds.GetScheduledDispatchDuration();
 | 
			
		||||
				int32_t last_dispatch;
 | 
			
		||||
				if (ds.GetScheduledDispatchLastDispatch() != INVALID_SCHEDULED_DISPATCH_OFFSET) {
 | 
			
		||||
					last_dispatch = ds.GetScheduledDispatchLastDispatch() % ds.GetScheduledDispatchDuration();
 | 
			
		||||
				} else {
 | 
			
		||||
					last_dispatch = INT32_MIN;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for (int y = r.top + 1; num < maxval; y += this->resize.step_height) { /* Draw the rows */
 | 
			
		||||
					for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
 | 
			
		||||
@@ -829,9 +835,11 @@ struct SchdispatchWindow : GeneralVehicleWindow {
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					const StateTicks next_departure = GetScheduledDispatchTime(ds, _state_ticks);
 | 
			
		||||
					set_next_departure_update(next_departure + ds.GetScheduledDispatchDelay());
 | 
			
		||||
					SetDParam(0, next_departure);
 | 
			
		||||
					DrawString(ir.left, ir.right, y, STR_SCHDISPATCH_SUMMARY_NEXT_AVAILABLE_DEPARTURE);
 | 
			
		||||
					if (next_departure != INVALID_STATE_TICKS) {
 | 
			
		||||
						set_next_departure_update(next_departure + ds.GetScheduledDispatchDelay());
 | 
			
		||||
						SetDParam(0, next_departure);
 | 
			
		||||
						DrawString(ir.left, ir.right, y, STR_SCHDISPATCH_SUMMARY_NEXT_AVAILABLE_DEPARTURE);
 | 
			
		||||
					}
 | 
			
		||||
					y += GetCharacterHeight(FS_NORMAL);
 | 
			
		||||
 | 
			
		||||
					departure_time_warnings(next_departure);
 | 
			
		||||
 
 | 
			
		||||
@@ -804,6 +804,12 @@ void UpdateSeparationOrder(Vehicle *v_start)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get next scheduled dispatch time
 | 
			
		||||
 * @param ds Dispatch schedule.
 | 
			
		||||
 * @param leave_time Leave time.
 | 
			
		||||
 * @return Dispatch time, or INVALID_STATE_TICKS
 | 
			
		||||
 */
 | 
			
		||||
StateTicks GetScheduledDispatchTime(const DispatchSchedule &ds, StateTicks leave_time)
 | 
			
		||||
{
 | 
			
		||||
	const uint32_t dispatch_duration = ds.GetScheduledDispatchDuration();
 | 
			
		||||
@@ -821,7 +827,7 @@ StateTicks GetScheduledDispatchTime(const DispatchSchedule &ds, StateTicks leave
 | 
			
		||||
		last_dispatched_offset = ds.GetScheduledDispatchLastDispatch();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StateTicks first_slot = -1;
 | 
			
		||||
	StateTicks first_slot = INVALID_STATE_TICKS;
 | 
			
		||||
 | 
			
		||||
	/* Find next available slots */
 | 
			
		||||
	for (const DispatchSlot &slot : ds.GetScheduledDispatch()) {
 | 
			
		||||
@@ -839,7 +845,7 @@ StateTicks GetScheduledDispatchTime(const DispatchSchedule &ds, StateTicks leave
 | 
			
		||||
			current_departure += dispatch_duration * ((minimum + dispatch_duration - current_departure - 1) / dispatch_duration);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (first_slot == -1 || first_slot > current_departure) {
 | 
			
		||||
		if (first_slot == INVALID_STATE_TICKS || first_slot > current_departure) {
 | 
			
		||||
			first_slot = current_departure;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -891,7 +897,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
 | 
			
		||||
 | 
			
		||||
			const int wait_offset = real_current_order->GetTimetabledWait();
 | 
			
		||||
			StateTicks slot = GetScheduledDispatchTime(ds, _state_ticks + wait_offset);
 | 
			
		||||
			if (slot > -1) {
 | 
			
		||||
			if (slot != INVALID_STATE_TICKS) {
 | 
			
		||||
				just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
 | 
			
		||||
				SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
 | 
			
		||||
				v->lateness_counter = (_state_ticks - slot + wait_offset).AsTicks();
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
 | 
			
		||||
				predicted_ds.UpdateScheduledDispatchToDate(_state_ticks + sum);
 | 
			
		||||
				StateTicks slot = GetScheduledDispatchTime(predicted_ds, _state_ticks + sum + order->GetTimetabledWait());
 | 
			
		||||
				predicted_ds.ReturnSchedule(ds);
 | 
			
		||||
				if (slot <= -1) return;
 | 
			
		||||
				if (slot == INVALID_STATE_TICKS) return;
 | 
			
		||||
				sum = (slot - _state_ticks).AsTicks();
 | 
			
		||||
				predicted = true;
 | 
			
		||||
				no_offset = true;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user