* Removes an order from all vehicles. Triggers when, say, a station is removed. * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]). * @param destination The destination. Can be a StationID, DepotID or WaypointID. * @param hangar Only used for airports in the destination. * When false, remove airport and hangar orders. * When true, remove either
| 1754 | * When true, remove either airport or hangar order. |
| 1755 | */ |
| 1756 | void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar) |
| 1757 | { |
| 1758 | /* Aircraft have StationIDs for depot orders and never use DepotIDs |
| 1759 | * This fact is handled specially below |
| 1760 | */ |
| 1761 | |
| 1762 | /* Go through all vehicles */ |
| 1763 | for (Vehicle *v : Vehicle::Iterate()) { |
| 1764 | if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type && |
| 1765 | (!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) { |
| 1766 | v->current_order.MakeDummy(); |
| 1767 | SetWindowDirty(WC_VEHICLE_VIEW, v->index); |
| 1768 | } |
| 1769 | |
| 1770 | if (v->orders == nullptr) continue; |
| 1771 | |
| 1772 | /* Clear the order from the order-list */ |
| 1773 | for (VehicleOrderID id = 0, next_id = 0; id < v->GetNumOrders(); id = next_id) { |
| 1774 | next_id = id + 1; |
| 1775 | Order *order = v->orders->GetOrderAt(id); |
| 1776 | OrderType ot = order->GetType(); |
| 1777 | if (ot == OT_GOTO_DEPOT && order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) continue; |
| 1778 | if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order. |
| 1779 | if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION; |
| 1780 | if (ot == type && order->GetDestination() == destination) { |
| 1781 | /* We want to clear implicit orders, but we don't want to make them |
| 1782 | * dummy orders. They should just vanish. Also check the actual order |
| 1783 | * type as ot is currently OT_GOTO_STATION. */ |
| 1784 | if (order->IsType(OT_IMPLICIT)) { |
| 1785 | DeleteOrder(v, id); |
| 1786 | next_id = id; |
| 1787 | continue; |
| 1788 | } |
| 1789 | |
| 1790 | /* Clear wait time */ |
| 1791 | v->orders->UpdateTotalDuration(-order->GetWaitTime()); |
| 1792 | if (order->IsWaitTimetabled()) { |
| 1793 | v->orders->UpdateTimetableDuration(-order->GetTimetabledWait()); |
| 1794 | order->SetWaitTimetabled(false); |
| 1795 | } |
| 1796 | order->SetWaitTime(0); |
| 1797 | |
| 1798 | /* Clear order, preserving travel time */ |
| 1799 | bool travel_timetabled = order->IsTravelTimetabled(); |
| 1800 | order->MakeDummy(); |
| 1801 | order->SetTravelTimetabled(travel_timetabled); |
| 1802 | |
| 1803 | for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) { |
| 1804 | /* In GUI, simulate by removing the order and adding it back */ |
| 1805 | InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); |
| 1806 | InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); |
| 1807 | } |
| 1808 | } |
| 1809 | } |
| 1810 | } |
| 1811 | |
| 1812 | OrderBackup::RemoveOrder(type, destination, hangar); |
| 1813 | } |
no test coverage detected