# HG changeset patch
# User HackaLittleBit
# Date 1390770038 0
#      Sun Jan 26 21:00:38 2014 +0000
# Node ID 7a0cbdc181637475c2c19663870ba70ac843faa4
# Parent  4cc9845483d90d260ca8f61b37b70eff8be2143e
Add platform height to airports for consistancy of holding pattern.
Add higher cruise altitude.

diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -768,12 +768,14 @@
 	TileIndex tile = INVALID_TILE;
 	Direction rotation = DIR_N;
 	uint size_x = 1, size_y = 1;
+	int platformheight = MIN_FLIGHT_ALTITUDE;
 	if (st != NULL) {
 		if (st->airport.tile != INVALID_TILE) {
 			tile = st->airport.tile;
 			rotation = st->airport.rotation;
 			size_x = st->airport.w;
 			size_y = st->airport.h;
+			platformheight = st->airport.platformheight;
 		} else {
 			tile = st->xy;
 		}
@@ -849,7 +851,7 @@
 		v->tile = tile;
 
 		/* Find altitude of landing position. */
-		int z = GetSlopePixelZ(x, y) + 1 + afc->delta_z;
+		int z = platformheight + afc->delta_z;
 
 		if (z == v->z_pos) {
 			Vehicle *u = v->Next()->Next();
@@ -970,42 +972,67 @@
 		}
 
 		v->tile = gp.new_tile;
-		/* If vehicle is in the air, use tile coordinate 0. */
-		if (amd.flag & (AMED_TAKEOFF | AMED_SLOWTURN | AMED_LAND)) v->tile = 0;
 
 		/* Adjust Z for land or takeoff? */
 		int z = v->z_pos;
+		if (amd.flag & (AMED_TAKEOFF | AMED_LAND | AMED_HOLD | AMED_SLOWTURN)) {
+			/* If vehicle is in the air, use tile coordinate 0. */
+			v->tile = 0;
 
-		if (amd.flag & AMED_TAKEOFF) {
-			z = min(z + 2, GetAircraftFlyingAltitude(v));
-		}
+			/* Aircraft is climbing. */
+			if (amd.flag & AMED_TAKEOFF) {
 
-		/* Let the plane drop from normal flight altitude to holding pattern altitude */
-		if ((amd.flag & AMED_HOLD) && (z > MIN_FLIGHT_ALTITUDE)) z--;
+				z += 2;
 
-		if (amd.flag & AMED_LAND) {
-			if (st->airport.tile == INVALID_TILE) {
-				/* Airport has been removed, abort the landing procedure */
-				v->state = FLYING;
-				UpdateAircraftCache(v);
-				AircraftNextAirportPos_and_Order(v);
-				/* get aircraft back on running altitude */
-				SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
-				continue;
+			/* Aircraft is going down for touch-down. */
+			} else if (amd.flag & AMED_LAND) {
+
+				if (st->airport.tile == INVALID_TILE) {
+					/* Airport has been removed, abort the landing procedure */
+					v->state = FLYING;
+					UpdateAircraftCache(v);
+					AircraftNextAirportPos_and_Order(v);
+					/* get aircraft back on running altitude */
+					SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
+					continue;
+				}
+
+				/* We're not flying below our destination, right? */
+				assert(platformheight <= z);
+
+				int t = max(1U, dist - 4);
+				int delta = z - platformheight;
+				/* Only start lowering when we're sufficiently close for a 1:1 glide */
+				if (delta >= t) {
+					z -= CeilDiv(z - platformheight, t);
+				}
+				if (z < platformheight) z = platformheight;
+
+			/* Let aircrafts drop from normal flight altitude to holding pattern altitude */
+			} else if (amd.flag & AMED_HOLD || dist < 480 || v->subtype == AIR_HELICOPTER) {
+
+				int holding_altitude = MIN_FLIGHT_ALTITUDE + platformheight;
+				/* Every 2nd tick. */
+				if (z > holding_altitude && (v->tick_counter & 1)) {
+					z--;
+				} else if (z < holding_altitude) {
+					z++;
+				}
+
+			/* Further raise plane after take-off to cruise altitude */
+			} else if ((amd.flag & AMED_SLOWTURN)){
+
+				int base_altitude = MIN_FLIGHT_ALTITUDE + MAX_TILE_HEIGHT * TILE_HEIGHT + (v->vcache.cached_max_speed / 10);
+				/* Make sure eastbound and westbound planes do not "crash" into each other by providing them with vertical separation */
+				if (v->direction == DIR_SE) base_altitude += 10;
+
+				/* Every 2nd tick. */
+				if (z < base_altitude && (v->tick_counter & 1))  {
+					z++;
+				} else if (z > base_altitude) {
+					z--;
+				}
 			}
-
-			int curz = GetSlopePixelZ(x + amd.x, y + amd.y) + 1;
-
-			/* We're not flying below our destination, right? */
-			assert(curz <= z);
-			int t = max(1U, dist - 4);
-			int delta = z - curz;
-
-			/* Only start lowering when we're sufficiently close for a 1:1 glide */
-			if (delta >= t) {
-				z -= CeilDiv(z - curz, t);
-			}
-			if (z < curz) z = curz;
 		}
 
 		/* We've landed. Decrease speed when we're reaching end of runway. */
@@ -1019,8 +1046,8 @@
 			}
 
 		}
+		SetAircraftPosition(v, gp.x, gp.y, z);
 
-		SetAircraftPosition(v, gp.x, gp.y, z);
 	} while (--count != 0);
 	return false;
 }
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -2921,6 +2921,17 @@
 		FOR_ALL_STATIONS(st) UpdateStationAcceptance(st, false);
 	}
 
+	if (IsSavegameVersionBefore(999)) {
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			if (st->airport.tile != INVALID_TILE) {
+				st->airport.platformheight = GetSlopePixelZ((TileX(st->airport.tile) * TILE_SIZE), (TileY(st->airport.tile) * TILE_SIZE)) + 1;
+			}
+		}
+	}
+
+
+
 	/* Road stops is 'only' updating some caches */
 	AfterLoadRoadStops();
 	AfterLoadLabelMaps();
diff --git a/src/station_base.h b/src/station_base.h
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -302,6 +302,7 @@
 	byte type;          ///< Type of this airport, @see AirportTypes
 	byte layout;        ///< Airport layout number.
 	Direction rotation; ///< How this airport is rotated.
+	int platformheight; ///< Height level of station.
 
 	PersistentStorage *psa; ///< Persistent storage for NewGRF airports.
 
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2200,6 +2200,7 @@
 	int h = as->size_y;
 	if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
 	TileArea airport_area = TileArea(tile, w, h);
+	int platformheight = GetSlopePixelZ((TileX(tile) * TILE_SIZE), (TileY(tile) * TILE_SIZE)) + 1;
 
 	if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) {
 		return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
@@ -2268,6 +2269,7 @@
 		st->airport.layout = layout;
 		st->airport.flags = 0;
 		st->airport.rotation = rotation;
+		st->airport.platformheight = platformheight;
 
 		st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
 
