diff options
author | celestar <celestar@openttd.org> | 2007-03-29 13:52:34 +0000 |
---|---|---|
committer | celestar <celestar@openttd.org> | 2007-03-29 13:52:34 +0000 |
commit | a1ab0d29fe5d5f0e5b90cc0908837f6b301d32f7 (patch) | |
tree | 37ea5878b75e7b5f0193b94c6d3c2aa3e1e9b498 /src/aircraft_cmd.cpp | |
parent | 386e298acd7855feb54d7b75ce0e3144db487649 (diff) | |
download | openttd-a1ab0d29fe5d5f0e5b90cc0908837f6b301d32f7.tar.xz |
(svn r9524) -Fix(FS#640,r8755): Implemented a "dummy" State Machine for stations who got their airport removed while there were still aircraft within the State Machine (and thus caused asserts)
Diffstat (limited to 'src/aircraft_cmd.cpp')
-rw-r--r-- | src/aircraft_cmd.cpp | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 6bd9a4a1c..caa6bfa85 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -944,6 +944,42 @@ static byte GetAircraftFlyingAltitude(const Vehicle *v) } /** + * Find the entry point to an airport depending on direction which + * the airport is being approached from. Each airport can have up to + * four entry points for its approach system so that approaching + * aircraft do not fly through each other or are forced to do 180 + * degree turns during the approach. The arrivals are grouped into + * four sectors dependent on the DiagDirection from which the airport + * is approached. + * + * @param v The vehicle that is approaching the airport + * @param apc The Airport Class being approached. + * @returns The index of the entry point + */ +static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc) +{ + assert(v != NULL); + assert(apc != NULL); + + const Station *st = GetStation(v->u.air.targetairport); + /* Make sure we don't go to 0,0 if the airport has been removed. */ + TileIndex tile = (st->airport_tile != 0) ? st->airport_tile : st->xy; + + int delta_x = v->x_pos - TileX(tile) * TILE_SIZE; + int delta_y = v->y_pos - TileY(tile) * TILE_SIZE; + + DiagDirection dir; + if (abs(delta_y) < abs(delta_x)) { + /* We are northeast or southwest of the airport */ + dir = delta_x < 0 ? DIAGDIR_NE : DIAGDIR_SW; + } else { + /* We are northwest or southeast of the airport */ + dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE; + } + return apc->entry_points[dir]; +} + +/** * Controls the movement of an aircraft. This function actually moves the vehicle * on the map and takes care of minor things like sound playback. * @todo De-mystify the cur_speed values for helicopter rotors. @@ -954,16 +990,23 @@ static bool AircraftController(Vehicle *v) { int count; const Station *st = GetStation(v->u.air.targetairport); + const AirportFTAClass *afc = st->Airport(); + const AirportMovingData *amd; /* prevent going to 0,0 if airport is deleted. */ TileIndex tile = st->airport_tile; - if (tile == 0) tile = st->xy; - int x = TileX(tile) * TILE_SIZE; - int y = TileY(tile) * TILE_SIZE; + if (tile == 0) { + tile = st->xy; + + /* Jump into our "holding pattern" state machine if possible */ + if (v->u.air.pos >= afc->nofelements) v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc); + } /* get airport moving data */ - const AirportFTAClass *afc = st->Airport(); - const AirportMovingData *amd = afc->MovingData(v->u.air.pos); + amd = afc->MovingData(v->u.air.pos); + + int x = TileX(tile) * TILE_SIZE; + int y = TileY(tile) * TILE_SIZE; /* Helicopter raise */ if (amd->flag & AMED_HELI_RAISE) { @@ -1470,42 +1513,6 @@ static void AircraftLandAirplane(Vehicle *v) MaybeCrashAirplane(v); } -/** - * Find the entry point to an airport depending on direction which - * the airport is being approached from. Each airport can have up to - * four entry points for its approach system so that approaching - * aircraft do not fly through each other or are forced to do 180 - * degree turns during the approach. The arrivals are grouped into - * four sectors dependent on the DiagDirection from which the airport - * is approached. - * - * @param v The vehicle that is approaching the airport - * @param apc The Airport Class being approached. - * @returns The index of the entry point - */ -static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc) -{ - assert(v != NULL); - assert(apc != NULL); - - const Station *st = GetStation(v->u.air.targetairport); - /* Make sure we don't go to 0,0 if the airport has been removed. */ - TileIndex tile = (st->airport_tile != 0) ? st->airport_tile : st->xy; - - int delta_x = v->x_pos - TileX(tile) * TILE_SIZE; - int delta_y = v->y_pos - TileY(tile) * TILE_SIZE; - - DiagDirection dir; - if (abs(delta_y) < abs(delta_x)) { - /* We are northeast or southwest of the airport */ - dir = delta_x < 0 ? DIAGDIR_NE : DIAGDIR_SW; - } else { - /* We are northwest or southeast of the airport */ - dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE; - } - return apc->entry_points[dir]; -} - /** set the right pos when heading to other airports after takeoff */ static void AircraftNextAirportPos_and_Order(Vehicle *v) |