From 619d714923b0f8119afc9d3e1402fb1feeecb586 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Sun, 27 Dec 2020 17:07:48 +0000 Subject: Fix #8437: Planes landing at non-rectangular airports could be drawn at the wrong height Only the rotated intercontinental airport, don't get excited --- src/aircraft_cmd.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index c381fae97..10bdeddf4 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1092,6 +1092,19 @@ static bool AircraftController(Aircraft *v) z = GetAircraftFlightLevel(v); } + /* NewGRF airports (like a rotated intercontinental from OpenGFX+Airports) can be non-rectangular + * and their primary (north-most) tile does not have to be part of the airport. + * As such, the height of the primary tile can be different from the rest of the airport. + * Given we are landing/breaking, and as such are not a helicopter, we know that there has to be a hangar. + * We also know that the airport itself has to be completely flat (otherwise it is not a valid airport). + * Therefore, use the height of this hangar to calculate our z-value. */ + int airport_z = v->z_pos; + if ((amd.flag & (AMED_LAND | AMED_BRAKE)) && st != nullptr) { + assert(st->airport.HasHangar()); + TileIndex hangar_tile = st->airport.GetHangarTile(0); + airport_z = TilePixelHeight(hangar_tile) + 1; // To avoid clashing with the shadow + } + if (amd.flag & AMED_LAND) { if (st->airport.tile == INVALID_TILE) { /* Airport has been removed, abort the landing procedure */ @@ -1103,27 +1116,24 @@ static bool AircraftController(Aircraft *v) continue; } - int curz = GetSlopePixelZ(x + amd.x, y + amd.y) + 1; - /* We're not flying below our destination, right? */ - assert(curz <= z); + assert(airport_z <= z); int t = max(1U, dist - 4); - int delta = z - curz; + int delta = z - airport_z; /* Only start lowering when we're sufficiently close for a 1:1 glide */ if (delta >= t) { - z -= CeilDiv(z - curz, t); + z -= CeilDiv(z - airport_z, t); } - if (z < curz) z = curz; + if (z < airport_z) z = airport_z; } /* We've landed. Decrease speed when we're reaching end of runway. */ if (amd.flag & AMED_BRAKE) { - int curz = GetSlopePixelZ(x, y) + 1; - if (z > curz) { + if (z > airport_z) { z--; - } else if (z < curz) { + } else if (z < airport_z) { z++; } -- cgit v1.2.3-54-g00ecf