# HG changeset patch # User rubidium # Date 1172593111 0 # Node ID 6b525eeff5f92f282895e40e215a8dca5636d553 # Parent a6dd37242b77643479c999d967e318f43dbf0e52 (svn r8921) -Fix (FS#654): several issues related to removing all orders from an aircraft and removing the airport it was heading: - the aircraft would go to (0, 0) and circle there. Clicking the 'eye' to jump to the aircraft in the main window could cause a segmentation fault. - when rebuilding an airport with the StationID of the old airport could crash as the FTA state of the aircraft is higher than the number of states of the new airport, causing a crash of all clients and the server when assertions are enabled. - when rebuilding an airport with the StationID of the old airport can bring the aircraft in a state where is keeps circling the airport. To solve these issues all aircraft without a valid order will try to go to the nearest hangar it can safely get to (large jets do not land on small airports). If there is no hangar to go to, the airplane crashes (out of fuel). diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1215,14 +1215,39 @@ const Order *order = GetVehicleOrder(v, v->cur_order_index); - if (order == NULL) { - v->current_order.type = OT_NOTHING; - v->current_order.flags = 0; + if (order == NULL|| (order->type == OT_DUMMY && !CheckForValidOrders(v))) { + /* + * We do not have an order. This can be divided into two cases: + * 1) we are heading to an invalid station. In this case we must + * find another airport to go to. If there is nowhere to go, + * we will destroy the aircraft as it otherwise will enter + * the holding pattern for the first airport, which can cause + * the plane to go into an undefined state when building an + * airport with the same StationID. + * 2) we are (still) heading to a (still) valid airport, then we + * can continue going there. This can happen when you are + * changing the aircraft's orders while in-flight or in for + * example a depot. However, when we have a current order to + * go to a depot, we have to keep that order so the aircraft + * actually stops. + */ + const Station *st = GetStation(v->u.air.targetairport); + if (!st->IsValid() || st->airport_tile == 0) { + int32 ret; + PlayerID old_player = _current_player; + + _current_player = v->owner; + ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); + _current_player = old_player; + + if (CmdFailed(ret)) CrashAirplane(v); + } else if (v->current_order.type != OT_GOTO_DEPOT) { + v->current_order.type = OT_NOTHING; + v->current_order.flags = 0; + } return; } - if (order->type == OT_DUMMY && !CheckForValidOrders(v)) CrashAirplane(v); - if (order->type == v->current_order.type && order->flags == v->current_order.flags && order->dest == v->current_order.dest)