| 1577 | } |
| 1578 | |
| 1579 | static bool RoadVehController(RoadVehicle *v) |
| 1580 | { |
| 1581 | /* decrease counters */ |
| 1582 | v->current_order_time++; |
| 1583 | if (v->reverse_ctr != 0) v->reverse_ctr--; |
| 1584 | |
| 1585 | /* handle crashed */ |
| 1586 | if (v->vehstatus.Test(VehState::Crashed) || RoadVehCheckTrainCrash(v)) { |
| 1587 | return RoadVehIsCrashed(v); |
| 1588 | } |
| 1589 | |
| 1590 | /* road vehicle has broken down? */ |
| 1591 | if (v->HandleBreakdown()) return true; |
| 1592 | if (v->vehstatus.Test(VehState::Stopped)) { |
| 1593 | v->SetLastSpeed(); |
| 1594 | return true; |
| 1595 | } |
| 1596 | |
| 1597 | ProcessOrders(v); |
| 1598 | v->HandleLoading(); |
| 1599 | |
| 1600 | if (v->current_order.IsType(OT_LOADING)) return true; |
| 1601 | |
| 1602 | if (v->IsInDepot()) { |
| 1603 | /* Check if we should wait here for unbunching. */ |
| 1604 | if (v->IsWaitingForUnbunching()) return true; |
| 1605 | if (RoadVehLeaveDepot(v, true)) return true; |
| 1606 | } |
| 1607 | |
| 1608 | v->ShowVisualEffect(); |
| 1609 | |
| 1610 | /* Check how far the vehicle needs to proceed */ |
| 1611 | int j = v->UpdateSpeed(); |
| 1612 | |
| 1613 | int adv_spd = v->GetAdvanceDistance(); |
| 1614 | bool blocked = false; |
| 1615 | while (j >= adv_spd) { |
| 1616 | j -= adv_spd; |
| 1617 | |
| 1618 | RoadVehicle *u = v; |
| 1619 | for (RoadVehicle *prev = nullptr; u != nullptr; prev = u, u = u->Next()) { |
| 1620 | if (!IndividualRoadVehicleController(u, prev)) { |
| 1621 | blocked = true; |
| 1622 | break; |
| 1623 | } |
| 1624 | } |
| 1625 | if (blocked) break; |
| 1626 | |
| 1627 | /* Determine distance to next map position */ |
| 1628 | adv_spd = v->GetAdvanceDistance(); |
| 1629 | |
| 1630 | /* Test for a collision, but only if another movement will occur. */ |
| 1631 | if (j >= adv_spd && RoadVehCheckTrainCrash(v)) break; |
| 1632 | } |
| 1633 | |
| 1634 | v->SetLastSpeed(); |
| 1635 | |
| 1636 | for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { |
no test coverage detected