diff options
author | rubidium <rubidium@openttd.org> | 2007-02-27 16:18:31 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2007-02-27 16:18:31 +0000 |
commit | 8877ef7478f253a22d6f2b2a45cccc2501eb3ada (patch) | |
tree | 4998551e8fa72791fbe55e93cf006825ae8624f0 | |
parent | 8eced4450609f82893fbb534c794081b82fb19d4 (diff) | |
download | openttd-8877ef7478f253a22d6f2b2a45cccc2501eb3ada.tar.xz |
(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).
-rw-r--r-- | src/aircraft_cmd.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 2c56069e9..c088bb388 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1215,14 +1215,39 @@ static void ProcessAircraftOrder(Vehicle *v) 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) |