* Update the timetable for the vehicle. * @param v The vehicle to update the timetable for. * @param travelling Whether we just travelled or waited at a station. */
| 467 | * @param travelling Whether we just travelled or waited at a station. |
| 468 | */ |
| 469 | void UpdateVehicleTimetable(Vehicle *v, bool travelling) |
| 470 | { |
| 471 | TimerGameTick::Ticks time_taken = v->current_order_time; |
| 472 | |
| 473 | v->current_order_time = 0; |
| 474 | |
| 475 | if (v->current_order.IsType(OT_IMPLICIT)) return; // no timetabling of auto orders |
| 476 | |
| 477 | if (v->cur_real_order_index >= v->GetNumOrders()) return; |
| 478 | Order *real_current_order = v->GetOrder(v->cur_real_order_index); |
| 479 | assert(real_current_order != nullptr); |
| 480 | |
| 481 | VehicleOrderID first_manual_order = 0; |
| 482 | for (const Order &o : v->Orders()) { |
| 483 | if (!o.IsType(OT_IMPLICIT)) break; |
| 484 | ++first_manual_order; |
| 485 | } |
| 486 | |
| 487 | bool just_started = false; |
| 488 | |
| 489 | /* This vehicle is arriving at the first destination in the timetable. */ |
| 490 | if (v->cur_real_order_index == first_manual_order && travelling) { |
| 491 | /* If the start date hasn't been set, or it was set automatically when |
| 492 | * the vehicle last arrived at the first destination, update it to the |
| 493 | * current time. Otherwise set the late counter appropriately to when |
| 494 | * the vehicle should have arrived. */ |
| 495 | just_started = !v->vehicle_flags.Test(VehicleFlag::TimetableStarted); |
| 496 | |
| 497 | if (v->timetable_start != 0) { |
| 498 | v->lateness_counter = TimerGameTick::counter - v->timetable_start; |
| 499 | v->timetable_start = 0; |
| 500 | } |
| 501 | |
| 502 | v->vehicle_flags.Set(VehicleFlag::TimetableStarted); |
| 503 | SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); |
| 504 | } |
| 505 | |
| 506 | if (!v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) return; |
| 507 | |
| 508 | bool autofilling = v->vehicle_flags.Test(VehicleFlag::AutofillTimetable); |
| 509 | bool remeasure_wait_time = !real_current_order->IsWaitTimetabled() || |
| 510 | (autofilling && !v->vehicle_flags.Test(VehicleFlag::AutofillPreserveWaitTime)); |
| 511 | |
| 512 | if (travelling && remeasure_wait_time) { |
| 513 | /* We just finished travelling and want to remeasure the loading time, |
| 514 | * so do not apply any restrictions for the loading to finish. */ |
| 515 | v->current_order.SetWaitTime(0); |
| 516 | } |
| 517 | |
| 518 | if (just_started) return; |
| 519 | |
| 520 | /* Before modifying waiting times, check whether we want to preserve bigger ones. */ |
| 521 | if (!real_current_order->IsType(OT_CONDITIONAL) && |
| 522 | (travelling || time_taken > real_current_order->GetWaitTime() || remeasure_wait_time)) { |
| 523 | /* Round up to the smallest unit of time commonly shown in the GUI (seconds) to avoid confusion. |
| 524 | * Players timetabling in Ticks can adjust later. |
| 525 | * For trains/aircraft multiple movement cycles are done in one |
| 526 | * tick. This makes it possible to leave the station and process |
no test coverage detected