diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 1aefc842d5..cab96aa36a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -911,29 +911,36 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) int32 new_time; if (travelling) { new_time = time_taken; + if (new_time > (int32)timetabled * 4) { + /* Possible jam, clear time and restart timetable for all vehicles. + * Otherwise we risk trains blocking 1-lane stations for long times. */ + ChangeTimetable(v, v->cur_timetable_order_index, 0, travel_field ? MTF_TRAVEL_TIME : MTF_WAIT_TIME, true); + for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { + v2->ClearSeparation(); + ClrBit(v2->vehicle_flags, VF_TIMETABLE_STARTED); + SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); + } + return; + } else if (new_time >= (int32)timetabled / 2) { + /* Compute running average, with sign conversion to avoid negative overflow. + * This is biased to favour negative adjustments */ + if (new_time < (int32)timetabled) { + new_time = ((int32)timetabled * 3 + new_time * 2 + 2) / 5; + } else { + new_time = ((int32)timetabled * 9 + new_time + 5) / 10; + } + } else { + /* new time is less than half the old time, set value directly */ + } } else { new_time = time_loading; - } - - if (new_time > (int32)timetabled * 4 && travelling) { - /* Possible jam, clear time and restart timetable for all vehicles. - * Otherwise we risk trains blocking 1-lane stations for long times. */ - ChangeTimetable(v, v->cur_timetable_order_index, 0, travel_field ? MTF_TRAVEL_TIME : MTF_WAIT_TIME, true); - for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { - v2->ClearSeparation(); - ClrBit(v2->vehicle_flags, VF_TIMETABLE_STARTED); - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); - } - return; - } else if (new_time >= (int32)timetabled / 2) { - /* Compute running average, with sign conversion to avoid negative overflow. */ - if (new_time < (int32)timetabled) { + /* Compute running average, with sign conversion to avoid negative overflow. + * This is biased to favour positive adjustments */ + if (new_time > (int32)timetabled) { new_time = ((int32)timetabled * 3 + new_time * 2 + 2) / 5; } else { new_time = ((int32)timetabled * 9 + new_time + 5) / 10; } - } else { - /* new time is less than hald old time, set value directly */ } if (new_time < 1) new_time = 1;