(svn r10698) -Codechange [FS#1082]: simplify the code related to foundations. Primarily removal of (duplicated|magic) code and introduction of few helper functions to ease foundation determination. Patch by frosch.
authorrubidium
Thu, 26 Jul 2007 16:51:10 +0000
changeset 7335 141c6b86ec1f
parent 7334 ed9a43cf642a
child 7336 180fe387acfc
(svn r10698) -Codechange [FS#1082]: simplify the code related to foundations. Primarily removal of (duplicated|magic) code and introduction of few helper functions to ease foundation determination. Patch by frosch.
src/ai/trolly/pathfinder.cpp
src/bridge.h
src/clear_cmd.cpp
src/dummy_land.cpp
src/elrail.cpp
src/industry_cmd.cpp
src/landscape.cpp
src/landscape.h
src/newgrf_house.cpp
src/newgrf_industrytiles.cpp
src/openttd.h
src/rail.h
src/rail_cmd.cpp
src/road_cmd.cpp
src/slope.h
src/station_cmd.cpp
src/table/sprites.h
src/town_cmd.cpp
src/tree_cmd.cpp
src/tunnelbridge_cmd.cpp
src/unmovable_cmd.cpp
src/variables.h
src/water_cmd.cpp
--- a/src/ai/trolly/pathfinder.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/ai/trolly/pathfinder.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -362,9 +362,9 @@
 }
 
 
-extern uint GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
-extern uint GetRoadFoundation(Slope tileh, RoadBits bits); // XXX function declaration in .c
-extern uint GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
+extern Foundation GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
+extern Foundation GetRoadFoundation(Slope tileh, RoadBits bits); // XXX function declaration in .c
+extern Foundation GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
 enum BridgeFoundation {
 	BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
 };
@@ -373,7 +373,7 @@
 static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
 {
 	Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
-	int r, res = 0;
+	int res = 0;
 	Slope tileh = GetTileSlope(current->tile, NULL);
 	Slope parent_tileh = GetTileSlope(parent->path.node.tile, NULL);
 
@@ -409,17 +409,17 @@
 		// Skip if the tile was from a bridge or tunnel
 		if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
 			if (PathFinderInfo->rail_or_road) {
-				r = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
+				Foundation f = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
 				// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
-				if (IS_INT_INSIDE(r, 15, 15 + 8) || (r == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
+				if (IsInclinedFoundation(f) || (!IsFoundation(f) && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
 				} else {
 					res += AI_PATHFINDER_FOUNDATION_PENALTY;
 				}
 			} else {
 				if (!IsRoad(parent->path.node.tile) || !IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE)) {
-					r = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
-					if (IS_INT_INSIDE(r, 15, 15 + 8) || (r == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
+					Foundation f = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
+					if (IsInclinedFoundation(f) || (!IsFoundation(f) == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
 					} else {
 						res += AI_PATHFINDER_FOUNDATION_PENALTY;
@@ -431,6 +431,7 @@
 
 	// Are we part of a tunnel?
 	if ((AI_PATHFINDER_FLAG_TUNNEL & current->user_data[0]) != 0) {
+		int r;
 		// Tunnels are very expensive when build on long routes..
 		// Ironicly, we are using BridgeCode here ;)
 		r = AI_PATHFINDER_TUNNEL_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
@@ -444,13 +445,13 @@
 		// Check if we are going up or down, first for the starting point
 		// In user_data[0] is at the 8th bit the direction
 		if (!HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh)) {
-			if (GetBridgeFoundation(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1)) < 15) {
+			if (IsLeveledFoundation(GetBridgeFoundation(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
 				res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
 			}
 		}
 		// Second for the end point
 		if (!HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
-			if (GetBridgeFoundation(tileh, (Axis)((current->user_data[0] >> 8) & 1)) < 15) {
+			if (IsLeveledFoundation(GetBridgeFoundation(tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
 				res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
 			}
 		}
--- a/src/bridge.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/bridge.h	Thu Jul 26 16:51:10 2007 +0000
@@ -27,7 +27,7 @@
 extern const Bridge orig_bridge[MAX_BRIDGES];
 extern Bridge _bridge[MAX_BRIDGES];
 
-uint GetBridgeFoundation(Slope tileh, Axis axis);
+Foundation GetBridgeFoundation(Slope tileh, Axis axis);
 
 static inline const Bridge *GetBridge(uint i)
 {
--- a/src/clear_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/clear_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -573,9 +573,9 @@
 	return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 }
 
-static Slope GetSlopeTileh_Clear(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Clear(TileIndex tile, Slope tileh)
 {
-	return tileh;
+	return FOUNDATION_NONE;
 }
 
 static void GetAcceptedCargo_Clear(TileIndex tile, AcceptedCargo ac)
@@ -819,5 +819,5 @@
 	ChangeTileOwner_Clear,    ///< change_tile_owner_clear
 	NULL,                     ///< get_produced_cargo_proc
 	NULL,                     ///< vehicle_enter_tile_proc
-	GetSlopeTileh_Clear,      ///< get_slope_tileh_proc
+	GetFoundation_Clear,      ///< get_foundation_proc
 };
--- a/src/dummy_land.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/dummy_land.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -21,9 +21,9 @@
 	return 0;
 }
 
-static Slope GetSlopeTileh_Dummy(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Dummy(TileIndex tile, Slope tileh)
 {
-	return SLOPE_FLAT;
+	return FOUNDATION_NONE;
 }
 
 static CommandCost ClearTile_Dummy(TileIndex tile, byte flags)
@@ -81,5 +81,5 @@
 	ChangeTileOwner_Dummy,    /* change_tile_owner_clear */
 	NULL,                     /* get_produced_cargo_proc */
 	NULL,                     /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Dummy,      /* get_slope_tileh_proc */
+	GetFoundation_Dummy,      /* get_foundation_proc */
 };
--- a/src/elrail.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/elrail.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -176,7 +176,7 @@
 
 	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
 		TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
-		uint foundation = 0;
+		Foundation foundation = FOUNDATION_NONE;
 		int k;
 
 		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
@@ -225,9 +225,7 @@
 			foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour)));
 		}
 
-		if (foundation != 0) {
-			tileh[TS_NEIGHBOUR] = foundation < 15 ? SLOPE_FLAT : _inclined_tileh[foundation - 15];
-		}
+		ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
 
 		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
 
--- a/src/industry_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/industry_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -255,7 +255,6 @@
 	Industry *ind = GetIndustryByTile(ti->tile);
 	const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
 	const DrawBuildingsTileStruct *dits;
-	byte z;
 	SpriteID image;
 	SpriteID pal;
 
@@ -287,12 +286,8 @@
 		pal = dits->ground.pal;
 	}
 
-	z = ti->z;
-	/* Add bricks below the industry? */
-	if (ti->tileh != SLOPE_FLAT) {
-		DrawFoundation(ti, ti->tileh);
-		z += TILE_HEIGHT;
-	}
+	/* DrawFoundation() modifes ti->z and ti->tileh */
+	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 	DrawGroundSprite(image, pal);
 
@@ -306,7 +301,7 @@
 			dits->width  + 1,
 			dits->height + 1,
 			dits->dz,
-			z,
+			ti->z,
 			HASBIT(_transparent_opt, TO_INDUSTRIES));
 
 		if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
@@ -323,9 +318,9 @@
 	return GetTileMaxZ(tile);
 }
 
-static Slope GetSlopeTileh_Industry(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
 {
-	return SLOPE_FLAT;
+	return FlatteningFoundation(tileh);
 }
 
 static void GetAcceptedCargo_Industry(TileIndex tile, AcceptedCargo ac)
@@ -1995,7 +1990,7 @@
 	ChangeTileOwner_Industry,    /* change_tile_owner_proc */
 	GetProducedCargo_Industry,   /* get_produced_cargo_proc */
 	NULL,                        /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Industry,      /* get_slope_tileh_proc */
+	GetFoundation_Industry,      /* get_foundation_proc */
 };
 
 static const SaveLoad _industry_desc[] = {
--- a/src/landscape.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/landscape.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -56,13 +56,51 @@
 	0, 0, 0, 0, 0, 0, 0, 16, 0, 0,  0, 17,  0, 15, 18, 0,
 };
 
-const Slope _inclined_tileh[] = {
-	SLOPE_SW,  SLOPE_NW,  SLOPE_SW,  SLOPE_SE, SLOPE_NE, SLOPE_SE, SLOPE_NE, SLOPE_NW,
-	SLOPE_E,   SLOPE_N,   SLOPE_W,   SLOPE_S,
-	SLOPE_NWS, SLOPE_WSE, SLOPE_SEN, SLOPE_ENW
-};
+SnowLine *_snow_line = NULL;
 
-SnowLine *_snow_line = NULL;
+/**
+ * Applys a foundation to a slope.
+ *
+ * @pre      Foundation and slope must be valid combined.
+ * @param f  The #Foundation.
+ * @param s  The #Slope to modify.
+ * @return   Increment to the tile Z coordinate.
+ */
+uint ApplyFoundationToSlope(Foundation f, Slope *s)
+{
+
+	if (!IsFoundation(f)) return 0;
+
+	if (IsLeveledFoundation(f)) {
+		*s = SLOPE_FLAT;
+		return TILE_HEIGHT;
+	}
+
+	uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
+	byte highest_corner = GetHighestSlopeCorner(*s);
+
+	switch (f) {
+		case FOUNDATION_INCLINED_X:
+			*s = (highest_corner <= 1 ? SLOPE_SW : SLOPE_NE);
+			break;
+
+		case FOUNDATION_INCLINED_Y:
+			*s = (((highest_corner == 1) || (highest_corner == 2)) ? SLOPE_SE : SLOPE_NW);
+			break;
+
+		case FOUNDATION_STEEP_LOWER:
+			*s = (Slope) (1 << highest_corner);
+			break;
+
+		case FOUNDATION_STEEP_HIGHER:
+			*s = (Slope) (*s & ~SLOPE_STEEP);
+			break;
+
+		default: NOT_REACHED();
+	}
+	return dz;
+}
+
 
 uint GetPartialZ(int x, int y, Slope corners)
 {
@@ -172,11 +210,9 @@
 static Slope GetFoundationSlope(TileIndex tile, uint* z)
 {
 	Slope tileh = GetTileSlope(tile, z);
-	Slope slope = _tile_type_procs[GetTileType(tile)]->get_slope_tileh_proc(tile, tileh);
-
-	/* Flatter slope -> higher base height */
-	if (slope < tileh) *z += TILE_HEIGHT;
-	return slope;
+	Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh);
+	*z += ApplyFoundationToSlope(f, &tileh);
+	return tileh;
 }
 
 
@@ -212,34 +248,43 @@
 }
 
 
-void DrawFoundation(TileInfo *ti, uint f)
+void DrawFoundation(TileInfo *ti, Foundation f)
 {
-	SpriteID sprite_base = SPR_SLOPES_BASE - 15;
-	Slope slope;
+	if (!IsFoundation(f)) return;
+
+	SpriteID sprite_base = SPR_SLOPES_VIRTUAL_BASE;
 	uint z;
+	Slope slope = GetFoundationSlope(ti->tile, &z);
 
-	slope = GetFoundationSlope(ti->tile, &z);
-	if (!HasFoundationNW(ti->tile, slope, z)) sprite_base += 22;
-	if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += 44;
+	if (!HasFoundationNW(ti->tile, slope, z)) sprite_base += SPR_SLOPES_NO_FOUNDATION_NW_OFFSET;
+	if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += SPR_SLOPES_NO_FOUNDATION_NE_OFFSET;
 
 	if (IsSteepSlope(ti->tileh)) {
 		SpriteID lower_base;
 
-		/* Lower part of foundation */
+		/* Lower part of foundation
+		 * Use the original slope sprites if NW and NE borders should be visible
+		 */
 		lower_base = sprite_base;
-		if (lower_base == SPR_SLOPES_BASE - 15) lower_base = SPR_FOUNDATION_BASE;
+		if (lower_base == SPR_SLOPES_VIRTUAL_BASE) lower_base = SPR_FOUNDATION_BASE;
 		AddSortableSpriteToDraw(
 			lower_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
 		);
-		ti->z += TILE_HEIGHT;
-		ti->tileh = _inclined_tileh[f - 15];
-		if (f < 15 + 8) {
-			/* inclined */
-			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
+
+		byte highest_corner = GetHighestSlopeCorner(ti->tileh);
+		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
+
+		if (IsInclinedFoundation(f)) {
+			/* inclined foundation */
+			byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
+
+			AddSortableSpriteToDraw(sprite_base + SPR_SLOPES_INCLINED_OFFSET + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			OffsetGroundSprite(31, 9);
-		} else if (f >= 15 + 8 + 4) {
-			/* three corners raised */
-			SpriteID upper = sprite_base + 15 + (f - 15 - 8 - 4) * 2;
+		} else if (f >= FOUNDATION_STEEP_HIGHER) {
+			/* three corners raised:
+			 * Draw inclined foundations for both axes, that results in the needed image.
+			 */
+			SpriteID upper = sprite_base + SPR_SLOPES_INCLINED_OFFSET + highest_corner * 2;
 
 			AddSortableSpriteToDraw(upper, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			AddChildSpriteScreen(upper + 1, PAL_NONE, 31, 9);
@@ -249,21 +294,22 @@
 			OffsetGroundSprite(31, 1);
 		}
 	} else {
-		if (f < 15) {
+		if (IsLeveledFoundation(f)) {
 			/* leveled foundation
-			 * Use the original slope sprites if NW and NE borders should be visible */
-			if (sprite_base == SPR_SLOPES_BASE - 15) sprite_base = SPR_FOUNDATION_BASE;
+			 * Use the original slope sprites if NW and NE borders should be visible
+			 */
+			if (sprite_base == SPR_SLOPES_VIRTUAL_BASE) sprite_base = SPR_FOUNDATION_BASE;
 
-			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
-			ti->z += TILE_HEIGHT;
-			ti->tileh = SLOPE_FLAT;
+			AddSortableSpriteToDraw(sprite_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
 			OffsetGroundSprite(31, 1);
 		} else {
 			/* inclined foundation */
-			AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
-			ti->tileh = _inclined_tileh[f - 15];
+			byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
+
+			AddSortableSpriteToDraw(sprite_base + SPR_SLOPES_INCLINED_OFFSET + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			OffsetGroundSprite(31, 9);
 		}
+		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
 	}
 }
 
--- a/src/landscape.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/landscape.h	Thu Jul 26 16:51:10 2007 +0000
@@ -39,7 +39,8 @@
 	return RemapCoords(x, y, GetSlopeZ(x, y));
 }
 
-void DrawFoundation(TileInfo *ti, uint f);
+uint ApplyFoundationToSlope(Foundation f, Slope *s);
+void DrawFoundation(TileInfo *ti, Foundation f);
 
 void DoClearSquare(TileIndex tile);
 void RunTileLoop();
--- a/src/newgrf_house.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/newgrf_house.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -351,7 +351,7 @@
 	const SpriteGroup *group;
 	ResolverObject object;
 
-	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 	NewHouseResolver(&object, house_id, ti->tile, GetTownByTile(ti->tile));
 
--- a/src/newgrf_industrytiles.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/newgrf_industrytiles.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -215,7 +215,7 @@
 			draw_old_one = callback_res != 0;
 		}
 
-		if (draw_old_one) DrawFoundation(ti, ti->tileh);
+		if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
 	}
 
 	NewIndustryTileResolver(&object, gfx, ti->tile, i);
--- a/src/openttd.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/openttd.h	Thu Jul 26 16:51:10 2007 +0000
@@ -472,7 +472,7 @@
 typedef void ChangeTileOwnerProc(TileIndex tile, PlayerID old_player, PlayerID new_player);
 /** @see VehicleEnterTileStatus to see what the return values mean */
 typedef uint32 VehicleEnterTileProc(Vehicle *v, TileIndex tile, int x, int y);
-typedef Slope GetSlopeTilehProc(TileIndex, Slope tileh);
+typedef Foundation GetFoundationProc(TileIndex tile, Slope tileh);
 
 struct TileTypeProcs {
 	DrawTileProc *draw_tile_proc;
@@ -487,7 +487,7 @@
 	ChangeTileOwnerProc *change_tile_owner_proc;
 	GetProducedCargoProc *get_produced_cargo_proc;
 	VehicleEnterTileProc *vehicle_enter_tile_proc;
-	GetSlopeTilehProc *get_slope_tileh_proc;
+	GetFoundationProc *get_foundation_proc;
 };
 
 
--- a/src/rail.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/rail.h	Thu Jul 26 16:51:10 2007 +0000
@@ -567,7 +567,7 @@
  */
 void DrawCatenary(const TileInfo *ti);
 
-uint GetRailFoundation(Slope tileh, TrackBits bits);
+Foundation GetRailFoundation(Slope tileh, TrackBits bits);
 
 int32 SettingsDisableElrail(int32 p1); ///< _patches.disable_elrail callback
 
--- a/src/rail_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/rail_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -156,36 +156,22 @@
 }
 };
 
-uint GetRailFoundation(Slope tileh, TrackBits bits)
+Foundation GetRailFoundation(Slope tileh, TrackBits bits)
 {
-	uint i;
-
 	if (!IsSteepSlope(tileh)) {
-		if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return 0;
-		if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return tileh;
+		if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return FOUNDATION_NONE;
+		if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return FOUNDATION_LEVELED;
 	}
 
 	switch (bits) {
 		default: NOT_REACHED();
-		case TRACK_BIT_X: i = 0; break;
-		case TRACK_BIT_Y: i = 1; break;
-		case TRACK_BIT_LEFT:  return 15 + 8 + (tileh == SLOPE_STEEP_W ? 4 : 0);
-		case TRACK_BIT_LOWER: return 15 + 8 + (tileh == SLOPE_STEEP_S ? 5 : 1);
-		case TRACK_BIT_RIGHT: return 15 + 8 + (tileh == SLOPE_STEEP_E ? 6 : 2);
-		case TRACK_BIT_UPPER: return 15 + 8 + (tileh == SLOPE_STEEP_N ? 7 : 3);
+		case TRACK_BIT_X:     return FOUNDATION_INCLINED_X;
+		case TRACK_BIT_Y:     return FOUNDATION_INCLINED_Y;
+		case TRACK_BIT_LEFT:  return (tileh == SLOPE_STEEP_W ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
+		case TRACK_BIT_LOWER: return (tileh == SLOPE_STEEP_S ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
+		case TRACK_BIT_RIGHT: return (tileh == SLOPE_STEEP_E ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
+		case TRACK_BIT_UPPER: return (tileh == SLOPE_STEEP_N ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER);
 	}
-	switch (tileh) {
-		case SLOPE_W:
-		case SLOPE_STEEP_W: i += 0; break;
-		case SLOPE_S:
-		case SLOPE_STEEP_S: i += 2; break;
-		case SLOPE_E:
-		case SLOPE_STEEP_E: i += 4; break;
-		case SLOPE_N:
-		case SLOPE_STEEP_N: i += 6; break;
-		default: return 0;
-	}
-	return i + 15;
 }
 
 
@@ -1362,14 +1348,11 @@
 	(image++, true);
 
 	if (ti->tileh != SLOPE_FLAT) {
-		uint foundation = GetRailFoundation(ti->tileh, track);
-
-		if (foundation != 0) DrawFoundation(ti, foundation);
+		DrawFoundation(ti, GetRailFoundation(ti->tileh, track));
 
 		/* DrawFoundation() modifies it.
 		 * Default sloped sprites.. */
-		if (ti->tileh != SLOPE_FLAT)
-			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
+		if (ti->tileh != SLOPE_FLAT) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
 	}
 
 	switch (GetRailGroundType(ti->tile)) {
@@ -1446,7 +1429,7 @@
 		const DrawTileSeqStruct* dtss;
 		uint32 relocation;
 
-		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 		if (IsRailDepot(ti->tile)) {
 			dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
@@ -1850,34 +1833,16 @@
 
 	if (tileh == SLOPE_FLAT) return z;
 	if (IsPlainRailTile(tile)) {
-		uint f = GetRailFoundation(tileh, GetTrackBits(tile));
-
-		if (f != 0) {
-			if (IsSteepSlope(tileh)) {
-				z += TILE_HEIGHT;
-			} else if (f < 15) {
-				return z + TILE_HEIGHT; // leveled foundation
-			}
-			tileh = _inclined_tileh[f - 15]; // inclined foundation
-		}
+		z += ApplyFoundationToSlope(GetRailFoundation(tileh, GetTrackBits(tile)), &tileh);
 		return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 	} else {
 		return z + TILE_HEIGHT;
 	}
 }
 
-static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Track(TileIndex tile, Slope tileh)
 {
-	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
-	if (IsPlainRailTile(tile)) {
-		uint f = GetRailFoundation(tileh, GetTrackBits(tile));
-
-		if (f == 0) return tileh;
-		if (f < 15) return SLOPE_FLAT; // leveled foundation
-		return _inclined_tileh[f - 15]; // inclined foundation
-	} else {
-		return SLOPE_FLAT;
-	}
+	return IsPlainRailTile(tile) ? GetRailFoundation(tileh, GetTrackBits(tile)) : FlatteningFoundation(tileh);
 }
 
 static void GetAcceptedCargo_Track(TileIndex tile, AcceptedCargo ac)
@@ -2186,5 +2151,5 @@
 	ChangeTileOwner_Track,    /* change_tile_owner_clear */
 	NULL,                     /* get_produced_cargo_proc */
 	VehicleEnter_Track,       /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Track,      /* get_slope_tileh_proc */
+	GetFoundation_Track,      /* get_foundation_proc */
 };
--- a/src/road_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/road_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -839,34 +839,14 @@
 #include "table/road_land.h"
 
 
-uint GetRoadFoundation(Slope tileh, RoadBits bits)
+Foundation GetRoadFoundation(Slope tileh, RoadBits bits)
 {
-	uint i;
-
-	/* normal level sloped building */
-	if (!IsSteepSlope(tileh) &&
-			(~_valid_tileh_slopes_road[1][tileh] & bits) == 0) {
-		return tileh;
+	if (!IsSteepSlope(tileh)) {
+		if ((~_valid_tileh_slopes_road[0][tileh] & bits) == 0) return FOUNDATION_NONE;
+		if ((~_valid_tileh_slopes_road[1][tileh] & bits) == 0) return FOUNDATION_LEVELED;
 	}
 
-	/* inclined sloped building */
-	switch (bits) {
-		case ROAD_X: i = 0; break;
-		case ROAD_Y: i = 1; break;
-		default:     return 0;
-	}
-	switch (tileh) {
-		case SLOPE_W:
-		case SLOPE_STEEP_W: i += 0; break;
-		case SLOPE_S:
-		case SLOPE_STEEP_S: i += 2; break;
-		case SLOPE_E:
-		case SLOPE_STEEP_E: i += 4; break;
-		case SLOPE_N:
-		case SLOPE_STEEP_N: i += 6; break;
-		default: return 0;
-	}
-	return i + 15;
+	return (bits == ROAD_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
 }
 
 const byte _road_sloped_sprites[14] = {
@@ -954,9 +934,7 @@
 	Roadside roadside;
 
 	if (ti->tileh != SLOPE_FLAT) {
-		int foundation = GetRoadFoundation(ti->tileh, road | tram);
-
-		if (foundation != 0) DrawFoundation(ti, foundation);
+		DrawFoundation(ti, GetRoadFoundation(ti->tileh, road | tram));
 
 		/* DrawFoundation() modifies ti.
 		 * Default sloped sprites.. */
@@ -1029,7 +1007,7 @@
 			SpriteID pal = PAL_NONE;
 			Roadside roadside = GetRoadside(ti->tile);
 
-			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.crossing;
 
@@ -1061,7 +1039,7 @@
 			const DrawTileSeqStruct* dtss;
 			SpriteID palette;
 
-			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
@@ -1123,33 +1101,20 @@
 
 	if (tileh == SLOPE_FLAT) return z;
 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
-		uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
-
-		if (f != 0) {
-			if (IsSteepSlope(tileh)) {
-				z += TILE_HEIGHT;
-			} else if (f < 15) {
-				return z + TILE_HEIGHT; // leveled foundation
-			}
-			tileh = _inclined_tileh[f - 15]; // inclined foundation
-		}
+		Foundation f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
+		z += ApplyFoundationToSlope(f, &tileh);
 		return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 	} else {
 		return z + TILE_HEIGHT;
 	}
 }
 
-static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
 {
-	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
-		uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
-
-		if (f == 0) return tileh;
-		if (f < 15) return SLOPE_FLAT; // leveled foundation
-		return _inclined_tileh[f - 15]; // inclined foundation
+		return GetRoadFoundation(tileh, GetAllRoadBits(tile));
 	} else {
-		return SLOPE_FLAT;
+		return FlatteningFoundation(tileh);
 	}
 }
 
@@ -1407,5 +1372,5 @@
 	ChangeTileOwner_Road,    /* change_tile_owner_clear */
 	NULL,                    /* get_produced_cargo_proc */
 	VehicleEnter_Road,       /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Road,      /* get_slope_tileh_proc */
+	GetFoundation_Road,      /* get_foundation_proc */
 };
--- a/src/slope.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/slope.h	Thu Jul 26 16:51:10 2007 +0000
@@ -68,4 +68,97 @@
 	return (Slope)(0xF ^ s);
 }
 
+/**
+ * Returns the highest corner of a slope (one corner raised or a steep slope).
+ *
+ * @pre      The slope must be a slope with one corner raised or a steep slope.
+ * @param s  The #Slope.
+ * @return   Number of the highest corner. (0 west, 1 south, 2 east, 3 north)
+ */
+static inline byte GetHighestSlopeCorner(Slope s)
+{
+	switch (s) {
+		case SLOPE_W:
+		case SLOPE_STEEP_W: return 0;
+		case SLOPE_S:
+		case SLOPE_STEEP_S: return 1;
+		case SLOPE_E:
+		case SLOPE_STEEP_E: return 2;
+		case SLOPE_N:
+		case SLOPE_STEEP_N: return 3;
+		default: NOT_REACHED();
+	}
+}
+
+
+/**
+ * Enumeration for Foundations.
+ */
+enum Foundation {
+	FOUNDATION_NONE,             ///< The tile has no foundation, the slope remains unchanged.
+	FOUNDATION_LEVELED,          ///< The tile is leveled up to a flat slope.
+	FOUNDATION_INCLINED_X,       ///< The tile has an along X-axis inclined foundation.
+	FOUNDATION_INCLINED_Y,       ///< The tile has an along Y-axis inclined foundation.
+	FOUNDATION_STEEP_LOWER,      ///< The tile has a steep slope. The lowerst corner is raised by a foundation to allow building railroad on the lower halftile.
+	FOUNDATION_STEEP_HIGHER,     ///< The tile has a steep slope. Three corners are raised by a foundation to allow building railroad on the higher halftile.
+};
+
+/**
+ * Tests for FOUNDATION_NONE.
+ *
+ * @param f  Maybe a #Foundation.
+ * @return   true iff f is a foundation.
+ */
+static inline bool IsFoundation(Foundation f)
+{
+	return f != FOUNDATION_NONE;
+}
+
+/**
+ * Tests if the foundation is a leveled foundation.
+ *
+ * @param f  The #Foundation.
+ * @return   true iff f is a leveled foundation.
+ */
+static inline bool IsLeveledFoundation(Foundation f)
+{
+	return f == FOUNDATION_LEVELED;
+}
+
+/**
+ * Tests if the foundation is an inclined foundation.
+ *
+ * @param f  The #Foundation.
+ * @return   true iff f is an inclined foundation.
+ */
+static inline bool IsInclinedFoundation(Foundation f)
+{
+	return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y);
+}
+
+/**
+ * Returns the foundation needed to flatten a slope.
+ * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED.
+ *
+ * @pre      The slope must not be steep.
+ * @param s  The current #Slope.
+ * @return   The needed #Foundation.
+ */
+static inline Foundation FlatteningFoundation(Slope s)
+{
+	assert(!IsSteepSlope(s));
+	return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED);
+}
+
+/**
+ * Returns the along a specific axis inclined foundation.
+ *
+ * @param axis  The #Axis.
+ * @return      The needed #Foundation.
+ */
+static inline Foundation InclinedFoundation(Axis axis)
+{
+	return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
+}
+
 #endif /* SLOPE_H */
--- a/src/station_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/station_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -2071,7 +2071,7 @@
 
 	// don't show foundation for docks
 	if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
-		DrawFoundation(ti, ti->tileh);
+		DrawFoundation(ti, FOUNDATION_LEVELED);
 
 	if (IsCustomStationSpecIndex(ti->tile)) {
 		// look for customization
@@ -2176,9 +2176,9 @@
 	return GetTileMaxZ(tile);
 }
 
-static Slope GetSlopeTileh_Station(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Station(TileIndex tile, Slope tileh)
 {
-	return SLOPE_FLAT;
+	return FlatteningFoundation(tileh);
 }
 
 static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac)
@@ -2921,7 +2921,7 @@
 	ChangeTileOwner_Station,    /* change_tile_owner_clear */
 	NULL,                       /* get_produced_cargo_proc */
 	VehicleEnter_Station,       /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Station,      /* get_slope_tileh_proc */
+	GetFoundation_Station,      /* get_foundation_proc */
 };
 
 static const SaveLoad _roadstop_desc[] = {
--- a/src/table/sprites.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/table/sprites.h	Thu Jul 26 16:51:10 2007 +0000
@@ -50,7 +50,13 @@
 	OPENTTD_SPRITES_COUNT = 112, // number of gfx-sprites in openttd.grf
 	SPR_SIGNALS_BASE  = 4896,
 	SPR_CANALS_BASE   = SPR_SIGNALS_BASE + 486,
-	SPR_SLOPES_BASE   = SPR_CANALS_BASE + 70,
+
+	SPR_SLOPES_BASE                    = SPR_CANALS_BASE + 70,
+	SPR_SLOPES_INCLINED_OFFSET         = 15,
+	SPR_SLOPES_VIRTUAL_BASE            = SPR_SLOPES_BASE - SPR_SLOPES_INCLINED_OFFSET, // The original foundations (see SPR_FOUNDATION_BASE below) are mapped before the additional foundations.
+	SPR_SLOPES_NO_FOUNDATION_NW_OFFSET = 22, // no wall on the NW edge of the tile.
+	SPR_SLOPES_NO_FOUNDATION_NE_OFFSET = 44, // no wall on the NE edge of the tile.
+
 	SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78,
 	SPR_ELRAIL_BASE   = SPR_AUTORAIL_BASE + 55,
 	SPR_2CCMAP_BASE   = SPR_ELRAIL_BASE + 53,
--- a/src/town_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/town_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -154,7 +154,7 @@
 	/* Retrieve pointer to the draw town tile struct */
 	dcts = &_town_draw_tile_data[house_id << 4 | OriginalTileRandomiser(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
 
-	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+	if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 	image = dcts->ground.sprite;
 	pal   = dcts->ground.pal;
@@ -188,9 +188,9 @@
 	return GetTileMaxZ(tile);
 }
 
-static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
 {
-	return SLOPE_FLAT;
+	return FlatteningFoundation(tileh);
 }
 
 /**
@@ -2350,7 +2350,7 @@
 	ChangeTileOwner_Town,    /* change_tile_owner_clear */
 	NULL,                    /* get_produced_cargo_proc */
 	NULL,                    /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Town,      /* get_slope_tileh_proc */
+	GetFoundation_Town,      /* get_foundation_proc */
 };
 
 
--- a/src/tree_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/tree_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -416,9 +416,9 @@
 	return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 }
 
-static Slope GetSlopeTileh_Trees(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Trees(TileIndex tile, Slope tileh)
 {
-	return tileh;
+	return FOUNDATION_NONE;
 }
 
 static CommandCost ClearTile_Trees(TileIndex tile, byte flags)
@@ -670,5 +670,5 @@
 	ChangeTileOwner_Trees,    /* change_tile_owner_clear */
 	NULL,                     /* get_produced_cargo_proc */
 	NULL,                     /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Trees,      /* get_slope_tileh_proc */
+	GetFoundation_Trees,      /* get_foundation_proc */
 };
--- a/src/tunnelbridge_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/tunnelbridge_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -863,26 +863,11 @@
 	}
 }
 
-uint GetBridgeFoundation(Slope tileh, Axis axis)
+Foundation GetBridgeFoundation(Slope tileh, Axis axis)
 {
-	uint i;
-
-	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
-
-	/* inclined sloped building */
-	switch (tileh) {
-		case SLOPE_W:
-		case SLOPE_STEEP_W: i = 0; break;
-		case SLOPE_S:
-		case SLOPE_STEEP_S: i = 2; break;
-		case SLOPE_E:
-		case SLOPE_STEEP_E: i = 4; break;
-		case SLOPE_N:
-		case SLOPE_STEEP_N: i = 6; break;
-		default: return 0;
-	}
-	if (axis != AXIS_X) ++i;
-	return i + 15;
+	if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) return FOUNDATION_NONE;
+	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return FlatteningFoundation(tileh);
+	return InclinedFoundation(axis);
 }
 
 /**
@@ -968,10 +953,7 @@
 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
 		assert( (base_offset & 0x07) == 0x00);
 
-		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
-			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
-			if (f != 0) DrawFoundation(ti, f);
-		}
+		DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))));
 
 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
@@ -1156,14 +1138,14 @@
 		DiagDirection dir = GetBridgeRampDirection(tile);
 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
 
+		z += ApplyFoundationToSlope(GetBridgeFoundation(tileh, DiagDirToAxis(dir)), &tileh);
+
 		/* On the bridge ramp? */
 		if (5 <= pos && pos <= 10) {
 			uint delta;
 
-			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
 
-			if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
 			switch (dir) {
 				default: NOT_REACHED();
 				case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
@@ -1172,38 +1154,15 @@
 				case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
 			}
 			return z + 1 + delta;
-		} else {
-			uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
-
-			if (f != 0) {
-				if (IsSteepSlope(tileh)) {
-					z += TILE_HEIGHT;
-				} else if (f < 15) {
-					return z + TILE_HEIGHT;
-				}
-				tileh = (Slope)_inclined_tileh[f - 15];
-			}
 		}
 	}
 
 	return z + GetPartialZ(x, y, tileh);
 }
 
-static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_TunnelBridge(TileIndex tile, Slope tileh)
 {
-	if (IsTunnel(tile)) {
-		return tileh;
-	} else {
-		if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
-			return tileh;
-		} else {
-			uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
-
-			if (f == 0) return tileh;
-			if (f < 15) return SLOPE_FLAT;
-			return (Slope)_inclined_tileh[f - 15];
-		}
-	}
+	return IsTunnel(tile) ? FOUNDATION_NONE : GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
 }
 
 
@@ -1475,5 +1434,5 @@
 	ChangeTileOwner_TunnelBridge,    /* change_tile_owner_clear */
 	NULL,                            /* get_produced_cargo_proc */
 	VehicleEnter_TunnelBridge,       /* vehicle_enter_tile_proc */
-	GetSlopeTileh_TunnelBridge,      /* get_slope_tileh_proc */
+	GetFoundation_TunnelBridge,      /* get_foundation_proc */
 };
--- a/src/unmovable_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/unmovable_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -118,7 +118,7 @@
 		case UNMOVABLE_LIGHTHOUSE: {
 			const DrawTileUnmovableStruct* dtus;
 
-			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 			DrawClearLandTile(ti, 2);
 
 			dtus = &_draw_tile_unmovable_data[GetUnmovableType(ti->tile)];
@@ -153,7 +153,7 @@
 			SpriteID palette;
 
 			assert(IsCompanyHQ(ti->tile));
-			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 
 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
@@ -186,9 +186,9 @@
 	}
 }
 
-static Slope GetSlopeTileh_Unmovable(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Unmovable(TileIndex tile, Slope tileh)
 {
-	return IsOwnedLand(tile) ? tileh : SLOPE_FLAT;
+	return IsOwnedLand(tile) ? FOUNDATION_NONE : FlatteningFoundation(tileh);
 }
 
 static CommandCost ClearTile_Unmovable(TileIndex tile, byte flags)
@@ -411,5 +411,5 @@
 	ChangeTileOwner_Unmovable,      /* change_tile_owner_clear */
 	NULL,                           /* get_produced_cargo_proc */
 	NULL,                           /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Unmovable,        /* get_slope_tileh_proc */
+	GetFoundation_Unmovable,        /* get_foundation_proc */
 };
--- a/src/variables.h	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/variables.h	Thu Jul 26 16:51:10 2007 +0000
@@ -330,7 +330,6 @@
 
 /* landscape.cpp */
 extern const byte _tileh_to_sprite[32];
-extern const Slope _inclined_tileh[16];
 
 extern const TileTypeProcs * const _tile_type_procs[16];
 
--- a/src/water_cmd.cpp	Thu Jul 26 15:37:19 2007 +0000
+++ b/src/water_cmd.cpp	Thu Jul 26 16:51:10 2007 +0000
@@ -500,9 +500,9 @@
 	return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
 }
 
-static Slope GetSlopeTileh_Water(TileIndex tile, Slope tileh)
+static Foundation GetFoundation_Water(TileIndex tile, Slope tileh)
 {
-	return tileh;
+	return FOUNDATION_NONE;
 }
 
 static void GetAcceptedCargo_Water(TileIndex tile, AcceptedCargo ac)
@@ -812,5 +812,5 @@
 	ChangeTileOwner_Water,    /* change_tile_owner_clear */
 	NULL,                     /* get_produced_cargo_proc */
 	VehicleEnter_Water,       /* vehicle_enter_tile_proc */
-	GetSlopeTileh_Water,      /* get_slope_tileh_proc */
+	GetFoundation_Water,      /* get_foundation_proc */
 };