Index: src/aircraft_cmd.cpp =================================================================== --- src/aircraft_cmd.cpp (revision 27930) +++ src/aircraft_cmd.cpp (working copy) @@ -2085,7 +2085,19 @@ FOR_ALL_AIRCRAFT(v) { if (!v->IsNormalAircraft() || v->targetairport != st->index) continue; assert(v->state == FLYING); + + Order *o = &v->current_order; + /* The aircraft is heading to a hangar, but the new station doesn't have one, + * or the aircraft can't land on the new station. Cancel current order. */ + if (o->IsType(OT_GOTO_DEPOT) && !(o->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) && o->GetDestination() == st->index && + (!st->airport.HasHangar() || !CanVehicleUseStation(v, st))) { + o->MakeDummy(); + SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); + } v->pos = v->previous_pos = AircraftGetEntryPoint(v, ap, rotation); UpdateAircraftCache(v); } + + /* Heliports don't have a hangar. Invalidate all go to hangar orders from all aircraft. */ + if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, true); } Index: src/order_backup.cpp =================================================================== --- src/order_backup.cpp (revision 27930) +++ src/order_backup.cpp (working copy) @@ -256,8 +256,11 @@ * 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 airport or hangar order. */ -/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination) +/* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar) { OrderBackup *ob; FOR_ALL_ORDER_BACKUPS(ob) { @@ -264,7 +267,7 @@ for (Order *order = ob->orders; order != NULL; order = order->next) { OrderType ot = order->GetType(); if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; - if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION; + if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION; if (ot == type && order->GetDestination() == destination) { /* Remove the order backup! If a station/depot gets removed, we can't/shouldn't restore those broken orders. */ delete ob; Index: src/order_backup.h =================================================================== --- src/order_backup.h (revision 27930) +++ src/order_backup.h (working copy) @@ -63,7 +63,7 @@ static void ClearGroup(GroupID group); static void ClearVehicle(const Vehicle *v); - static void RemoveOrder(OrderType type, DestinationID destination); + static void RemoveOrder(OrderType type, DestinationID destination, bool hangar); }; /** Index: src/order_cmd.cpp =================================================================== --- src/order_cmd.cpp (revision 27930) +++ src/order_cmd.cpp (working copy) @@ -1833,8 +1833,11 @@ * 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 airport or hangar order. */ -void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination) +void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar) { Vehicle *v; @@ -1847,7 +1850,7 @@ Order *order; order = &v->current_order; - if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type && + if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : order->GetType()) == type && v->current_order.GetDestination() == destination) { order->MakeDummy(); SetWindowDirty(WC_VEHICLE_VIEW, v->index); @@ -1861,7 +1864,7 @@ OrderType ot = order->GetType(); if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; - if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION; + if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION; if (ot == type && order->GetDestination() == destination) { /* We want to clear implicit orders, but we don't want to make them * dummy orders. They should just vanish. Also check the actual order @@ -1895,7 +1898,7 @@ } } - OrderBackup::RemoveOrder(type, destination); + OrderBackup::RemoveOrder(type, destination, hangar); } /** Index: src/order_func.h =================================================================== --- src/order_func.h (revision 27930) +++ src/order_func.h (working copy) @@ -17,7 +17,7 @@ #include "company_type.h" /* Functions */ -void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination); +void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar = false); void InvalidateVehicleOrder(const Vehicle *v, int data); void CheckOrders(const Vehicle*); void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true);