(svn r4541) Add a type for slopes and replace many magic numbers by the appropriate enums
authortron
Sun, 23 Apr 2006 13:48:16 +0000
changeset 3636 a36cc46e754d
parent 3635 26da0c860a64
child 3637 74ecd9adcbb4
(svn r4541) Add a type for slopes and replace many magic numbers by the appropriate enums
bridge.h
clear_cmd.c
depot.h
dock_gui.c
dummy_land.c
elrail.c
functions.h
industry_cmd.c
landscape.c
main_gui.c
openttd.h
rail.h
rail_cmd.c
road_cmd.c
slope.h
station_cmd.c
tile.c
tile.h
town_cmd.c
train_cmd.c
tree_cmd.c
tunnelbridge_cmd.c
unmovable_cmd.c
vehicle.c
viewport.c
water_cmd.c
water_map.h
waypoint.c
--- a/bridge.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/bridge.h	Sun Apr 23 13:48:16 2006 +0000
@@ -26,6 +26,6 @@
 extern const Bridge orig_bridge[MAX_BRIDGES];
 extern Bridge _bridge[MAX_BRIDGES];
 
-uint GetBridgeFoundation(uint tileh, Axis axis);
+uint GetBridgeFoundation(Slope tileh, Axis axis);
 
 #endif /* BRIDGE_H */
--- a/clear_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/clear_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -252,7 +252,7 @@
 			r = GetTileh(a, b, c, d, &min);
 
 			if (IsTileType(tile, MP_RAILWAY)) {
-				if (IsSteepTileh(r)) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
+				if (IsSteepSlope(r)) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
 
 				if (IsPlainRailTile(tile)) {
 					extern const TrackBits _valid_tileh_slopes[2][15];
@@ -448,7 +448,7 @@
 
 void DrawHillyLandTile(const TileInfo *ti)
 {
-	if (ti->tileh != 0) {
+	if (ti->tileh != SLOPE_FLAT) {
 		DrawGroundSprite(SPR_FLAT_ROUGH_LAND + _tileh_to_sprite[ti->tileh]);
 	} else {
 		DrawGroundSprite(_landscape_clear_sprites[GB(ti->x ^ ti->y, 4, 3)]);
@@ -459,9 +459,9 @@
 {
 	byte z = ti->z;
 
-	if (ti->tileh & 2) {
+	if (ti->tileh & SLOPE_S) {
 		z += 8;
-		if (ti->tileh == 0x17) z += 8;
+		if (ti->tileh == SLOPE_STEEP_S) z += 8;
 	}
 
 	if (GetFenceSW(ti->tile) != 0) {
@@ -509,7 +509,7 @@
 	return GetPartialZ(ti->x & 0xF, ti->y & 0xF, ti->tileh) + ti->z;
 }
 
-static uint GetSlopeTileh_Clear(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Clear(TileIndex tile, Slope tileh)
 {
 	return tileh;
 }
--- a/depot.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/depot.h	Sun Apr 23 13:48:16 2006 +0000
@@ -135,7 +135,7 @@
       03 (exit towards NW) we need either bit 0 or 4 set in tileh: 0x4C >> 3 = 1001<p>
       So ((0x4C >> p2) & tileh) determines whether the depot can be built on the current tileh
 */
-static inline bool CanBuildDepotByTileh(uint32 direction, uint tileh)
+static inline bool CanBuildDepotByTileh(uint32 direction, Slope tileh)
 {
 	return (0x4C >> direction) & tileh;
 }
--- a/dock_gui.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/dock_gui.c	Sun Apr 23 13:48:16 2006 +0000
@@ -173,10 +173,11 @@
 
 		tile_from = tile_to = e->place.tile;
 		switch (GetTileSlope(tile_from, NULL)) {
-			case  3: tile_to += TileDiffXY(-1,  0); break;
-			case  6: tile_to += TileDiffXY( 0, -1); break;
-			case  9: tile_to += TileDiffXY( 0,  1); break;
-			case 12: tile_to += TileDiffXY( 1,  0); break;
+			case SLOPE_SW: tile_to += TileDiffXY(-1,  0); break;
+			case SLOPE_SE: tile_to += TileDiffXY( 0, -1); break;
+			case SLOPE_NW: tile_to += TileDiffXY( 0,  1); break;
+			case SLOPE_NE: tile_to += TileDiffXY( 1,  0); break;
+			default: break;
 		}
 		VpSetPresizeRange(tile_from, tile_to);
 	} break;
--- a/dummy_land.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/dummy_land.c	Sun Apr 23 13:48:16 2006 +0000
@@ -19,9 +19,9 @@
 	return 0;
 }
 
-static uint GetSlopeTileh_Dummy(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Dummy(TileIndex tile, Slope tileh)
 {
-	return 0;
+	return SLOPE_FLAT;
 }
 
 static int32 ClearTile_Dummy(TileIndex tile, byte flags)
--- a/elrail.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/elrail.c	Sun Apr 23 13:48:16 2006 +0000
@@ -121,18 +121,18 @@
   * @param tile The tile to analyse
   * @param *tileh the tileh
   */
-static void AdjustTileh(TileIndex tile, uint *tileh)
+static void AdjustTileh(TileIndex tile, Slope* tileh)
 {
-	if (IsTunnelTile(tile)) *tileh = 0;
+	if (IsTunnelTile(tile)) *tileh = SLOPE_FLAT;
 	if (IsBridgeTile(tile) && IsBridgeRamp(tile)) {
-		if (*tileh != 0) {
-			*tileh = 0;
+		if (*tileh != SLOPE_FLAT) {
+			*tileh = SLOPE_FLAT;
 		} else {
 			switch (GetBridgeRampDirection(tile)) {
-				case DIAGDIR_NE: *tileh = 12; break;
-				case DIAGDIR_SE: *tileh =  6; break;
-				case DIAGDIR_SW: *tileh =  3; break;
-				case DIAGDIR_NW: *tileh =  9; break;
+				case DIAGDIR_NE: *tileh = SLOPE_NE; break;
+				case DIAGDIR_SE: *tileh = SLOPE_SE; break;
+				case DIAGDIR_SW: *tileh = SLOPE_SW; break;
+				case DIAGDIR_NW: *tileh = SLOPE_NW; break;
 				default: break;
 			}
 		}
@@ -150,7 +150,7 @@
 	TrackBits trackconfig[TS_END];
 	bool isflat[TS_END];
 	/* Note that ti->tileh has already been adjusted for Foundations */
-	uint tileh[TS_END] = {ti->tileh, 0};
+	Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
 
 	TLG tlg = GetTLG(ti->tile);
 	byte PCPstatus = 0;
@@ -214,7 +214,7 @@
 		PPPallowed[i] *= HASBIT(PCPstatus, i);
 
 		/* Station on a non-flat tile means foundation. add one height level and adjust tileh */
-		if (IsTileType(neighbour, MP_STATION) && tileh[TS_NEIGHBOUR] != 0) tileh[TS_NEIGHBOUR] = 0;
+		if (IsTileType(neighbour, MP_STATION) && tileh[TS_NEIGHBOUR] != SLOPE_FLAT) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
 
 		/* Read the foundataions if they are present, and adjust the tileh */
 		if (IsTileType(neighbour, MP_RAILWAY)) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]);
@@ -224,7 +224,7 @@
 
 		if (foundation != 0) {
 			if (foundation < 15) {
-				tileh[TS_NEIGHBOUR] = 0;
+				tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
 			} else {
 				tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
 			}
@@ -286,7 +286,7 @@
 			   ) return;
 
 			assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */
-			assert(!IsSteepTileh(tileh[TS_HOME]));
+			assert(!IsSteepSlope(tileh[TS_HOME]));
 			sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]];
 
 			AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
--- a/functions.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/functions.h	Sun Apr 23 13:48:16 2006 +0000
@@ -9,7 +9,7 @@
 void DoClearSquare(TileIndex tile);
 void RunTileLoop(void);
 
-uint GetPartialZ(int x, int y, int corners);
+uint GetPartialZ(int x, int y, Slope corners);
 uint GetSlopeZ(int x, int y);
 uint32 GetTileTrackStatus(TileIndex tile, TransportType mode);
 void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac);
--- a/industry_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/industry_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -384,8 +384,8 @@
 
 	z = ti->z;
 	/* Add bricks below the industry? */
-	if (ti->tileh & 0xF) {
-		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + (ti->tileh & 0xF), ti->x, ti->y, 16, 16, 7, z);
+	if (ti->tileh != SLOPE_FLAT) {
+		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
 		AddChildSpriteScreen(image, 31, 1);
 		z += 8;
 	} else {
@@ -420,12 +420,12 @@
 
 static uint GetSlopeZ_Industry(const TileInfo* ti)
 {
-	return ti->z + (ti->tileh == 0 ? 0 : 8);
+	return ti->z + (ti->tileh == SLOPE_FLAT ? 0 : 8);
 }
 
-static uint GetSlopeTileh_Industry(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Industry(TileIndex tile, Slope tileh)
 {
-	return 0;
+	return SLOPE_FLAT;
 }
 
 static void GetAcceptedCargo_Industry(TileIndex tile, AcceptedCargo ac)
@@ -694,7 +694,7 @@
 
 static void CreateIndustryEffectSmoke(TileIndex tile)
 {
-	uint tileh;
+	Slope tileh;
 	uint x;
 	uint y;
 	uint z;
@@ -702,7 +702,7 @@
 	tileh = GetTileSlope(tile, &z);
 	x = TileX(tile) * TILE_SIZE;
 	y = TileY(tile) * TILE_SIZE;
-	CreateEffectVehicle(x + 15, y + 14, z + 59 + (tileh != 0 ? 8 : 0), EV_CHIMNEY_SMOKE);
+	CreateEffectVehicle(x + 15, y + 14, z + 59 + (tileh != SLOPE_FLAT ? 8 : 0), EV_CHIMNEY_SMOKE);
 }
 
 static void MakeIndustryTileBigger(TileIndex tile)
@@ -1329,7 +1329,7 @@
 
 		if (it->gfx == 0xFF) {
 			if (!IsTileType(cur_tile, MP_WATER) ||
-					GetTileSlope(cur_tile, NULL) != 0) {
+					GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) {
 				return false;
 			}
 		} else {
@@ -1338,25 +1338,25 @@
 			if (type == IT_OIL_RIG)  {
 				if (!IsTileType(cur_tile, MP_WATER) || _m[cur_tile].m5 != 0) return false;
 			} else {
-				uint tileh;
+				Slope tileh;
 
 				if (IsTileType(cur_tile, MP_WATER) && _m[cur_tile].m5 == 0) return false;
 
 				tileh = GetTileSlope(cur_tile, NULL);
-				if (IsSteepTileh(tileh)) return false;
+				if (IsSteepSlope(tileh)) return false;
 
-				if (tileh != 0) {
-					int t;
+				if (tileh != SLOPE_FLAT) {
+					Slope t;
 					byte bits = _industry_section_bits[it->gfx];
 
 					if (bits & 0x10) return false;
 
-					t = ~tileh;
+					t = ComplementSlope(tileh);
 
-					if (bits & 1 && (t & (1 + 8))) return false;
-					if (bits & 2 && (t & (4 + 8))) return false;
-					if (bits & 4 && (t & (1 + 2))) return false;
-					if (bits & 8 && (t & (2 + 4))) return false;
+					if (bits & 1 && (t & SLOPE_NW)) return false;
+					if (bits & 2 && (t & SLOPE_NE)) return false;
+					if (bits & 4 && (t & SLOPE_SW)) return false;
+					if (bits & 8 && (t & SLOPE_SE)) return false;
 				}
 
 				if (type == IT_BANK_TEMP) {
--- a/landscape.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/landscape.c	Sun Apr 23 13:48:16 2006 +0000
@@ -51,7 +51,7 @@
 };
 
 const byte _inclined_tileh[] = {
-	3, 9, 3, 6, 12, 6, 12, 9
+	SLOPE_SW, SLOPE_NW, SLOPE_SW, SLOPE_SE, SLOPE_NE, SLOPE_SE, SLOPE_NE, SLOPE_NW
 };
 
 
@@ -62,7 +62,7 @@
 	ti->y = y;
 
 	if (x >= MapMaxX() * TILE_SIZE - 1 || y >= MapMaxY() * TILE_SIZE - 1) {
-		ti->tileh = 0;
+		ti->tileh = SLOPE_FLAT;
 		ti->type = MP_VOID;
 		ti->tile = 0;
 		ti->z = 0;
@@ -75,96 +75,98 @@
 	}
 }
 
-uint GetPartialZ(int x, int y, int corners)
+uint GetPartialZ(int x, int y, Slope corners)
 {
 	int z = 0;
 
 	switch (corners) {
-	case 1:
+	case SLOPE_W:
 		if (x - y >= 0)
 			z = (x - y) >> 1;
 		break;
 
-	case 2:
+	case SLOPE_S:
 		y^=0xF;
 		if ( (x - y) >= 0)
 			z = (x - y) >> 1;
 		break;
 
-	case 3:
+	case SLOPE_SW:
 		z = (x>>1) + 1;
 		break;
 
-	case 4:
+	case SLOPE_E:
 		if (y - x >= 0)
 			z = (y - x) >> 1;
 		break;
 
-	case 5:
-	case 10:
-	case 15:
+	case SLOPE_EW:
+	case SLOPE_NS:
+	case SLOPE_ELEVATED:
 		z = 4;
 		break;
 
-	case 6:
+	case SLOPE_SE:
 		z = (y>>1) + 1;
 		break;
 
-	case 7:
+	case SLOPE_WSE:
 		z = 8;
 		y^=0xF;
 		if (x - y < 0)
 			z += (x - y) >> 1;
 		break;
 
-	case 8:
+	case SLOPE_N:
 		y ^= 0xF;
 		if (y - x >= 0)
 			z = (y - x) >> 1;
 		break;
 
-	case 9:
+	case SLOPE_NW:
 		z = (y^0xF)>>1;
 		break;
 
-	case 11:
+	case SLOPE_NWS:
 		z = 8;
 		if (x - y < 0)
 			z += (x - y) >> 1;
 		break;
 
-	case 12:
+	case SLOPE_NE:
 		z = (x^0xF)>>1;
 		break;
 
-	case 13:
+	case SLOPE_ENW:
 		z = 8;
 		y ^= 0xF;
 		if (y - x < 0)
 			z += (y - x) >> 1;
 		break;
 
-	case 14:
+	case SLOPE_SEN:
 		z = 8;
 		if (y - x < 0)
 			z += (y - x) >> 1;
 		break;
 
-	case 23:
+	case SLOPE_STEEP_S:
 		z = 1 + ((x+y)>>1);
 		break;
 
-	case 27:
+	case SLOPE_STEEP_W:
 		z = 1 + ((x+(y^0xF))>>1);
 		break;
 
-	case 29:
+	case SLOPE_STEEP_N:
 		z = 1 + (((x^0xF)+(y^0xF))>>1);
 		break;
 
-	case 30:
+	case SLOPE_STEEP_E:
 		z = 1 + (((x^0xF)+(y^0xF))>>1);
 		break;
+
+		default: break;
 	}
 
 	return z;
@@ -184,16 +186,16 @@
 static bool HasFoundation(TileIndex tile, bool direction)
 {
 	bool south, other; // southern corner and east/west corner
-	uint tileh = GetTileSlope(tile, NULL);
-	uint slope = _tile_type_procs[GetTileType(tile)]->get_slope_tileh_proc(tile, tileh);
+	Slope tileh = GetTileSlope(tile, NULL);
+	Slope slope = _tile_type_procs[GetTileType(tile)]->get_slope_tileh_proc(tile, tileh);
 
-	if (slope == 0 && slope != tileh) tileh = 15;
-	south = (tileh & 2) != (slope & 2);
+	if (slope == SLOPE_FLAT && slope != tileh) tileh = SLOPE_ELEVATED;
+	south = (tileh & SLOPE_S) != (slope & SLOPE_S);
 
 	if (direction) {
-		other = (tileh & 4) != (slope & 4);
+		other = (tileh & SLOPE_E) != (slope & SLOPE_E);
 	} else {
-		other = (tileh & 1) != (slope & 1);
+		other = (tileh & SLOPE_W) != (slope & SLOPE_W);
 	}
 	return south || other;
 }
@@ -211,16 +213,19 @@
 
 		AddSortableSpriteToDraw(f - 1 + sprite_base, ti->x, ti->y, 16, 16, 7, ti->z);
 		ti->z += 8;
-		ti->tileh = 0;
+		ti->tileh = SLOPE_FLAT;
 		OffsetGroundSprite(31, 1);
 	} else {
 		// inclined foundation
 		sprite_base += 14;
 
+#define M(x) (1 << (x))
 		AddSortableSpriteToDraw(
-			HASBIT((1<<1) | (1<<2) | (1<<4) | (1<<8), ti->tileh) ? sprite_base + (f - 15) : SPR_FOUNDATION_BASE + ti->tileh,
+			HASBIT(M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N), ti->tileh) ?
+				sprite_base + (f - 15) : SPR_FOUNDATION_BASE + ti->tileh,
 			ti->x, ti->y, 1, 1, 1, ti->z
 		);
+#undef M
 
 		ti->tileh = _inclined_tileh[f - 15];
 		OffsetGroundSprite(31, 9);
@@ -394,7 +399,7 @@
 	uint h;
 
 	for (tile = 0; tile < MapSize(); ++tile) {
-		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == 0 && h == 0) {
+		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h == 0) {
 			MakeWater(tile);
 		}
 	}
--- a/main_gui.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/main_gui.c	Sun Apr 23 13:48:16 2006 +0000
@@ -1204,7 +1204,7 @@
 
 static void PlaceProc_LightHouse(TileIndex tile)
 {
-	if (!IsTileType(tile, MP_CLEAR) || IsSteepTileh(GetTileSlope(tile, NULL))) {
+	if (!IsTileType(tile, MP_CLEAR) || IsSteepSlope(GetTileSlope(tile, NULL))) {
 		return;
 	}
 
@@ -1215,7 +1215,7 @@
 
 static void PlaceProc_Transmitter(TileIndex tile)
 {
-	if (!IsTileType(tile, MP_CLEAR) || IsSteepTileh(GetTileSlope(tile, NULL))) {
+	if (!IsTileType(tile, MP_CLEAR) || IsSteepSlope(GetTileSlope(tile, NULL))) {
 		return;
 	}
 
--- a/openttd.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/openttd.h	Sun Apr 23 13:48:16 2006 +0000
@@ -48,6 +48,7 @@
 #define MAX_YEAR_END 170
 
 #include "map.h"
+#include "slope.h"
 
 // Forward declarations of structs.
 typedef struct Vehicle Vehicle;
@@ -127,7 +128,7 @@
 typedef struct TileInfo {
 	uint x;
 	uint y;
-	uint tileh;
+	Slope tileh;
 	uint type;
 	TileIndex tile;
 	uint z;
@@ -331,7 +332,7 @@
  * other bits that can be set? */
 typedef uint32 VehicleEnterTileProc(Vehicle *v, TileIndex tile, int x, int y);
 typedef void VehicleLeaveTileProc(Vehicle *v, TileIndex tile, int x, int y);
-typedef uint GetSlopeTilehProc(TileIndex, uint tileh);
+typedef Slope GetSlopeTilehProc(TileIndex, Slope tileh);
 
 typedef struct {
 	DrawTileProc *draw_tile_proc;
--- a/rail.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/rail.h	Sun Apr 23 13:48:16 2006 +0000
@@ -480,5 +480,5 @@
  */
 void DrawCatenary(const TileInfo *ti);
 
-uint GetRailFoundation(uint tileh, TrackBits bits);
+uint GetRailFoundation(Slope tileh, TrackBits bits);
 #endif /* RAIL_H */
--- a/rail_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/rail_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -150,7 +150,7 @@
 }
 };
 
-uint GetRailFoundation(uint tileh, TrackBits bits)
+uint GetRailFoundation(Slope tileh, TrackBits bits)
 {
 	int i;
 
@@ -161,10 +161,10 @@
 		return tileh;
 
 	if ((
-				(i  = 0, tileh == 1) ||
-				(i += 2, tileh == 2) ||
-				(i += 2, tileh == 4) ||
-				(i += 2, tileh == 8)
+				(i  = 0, tileh == SLOPE_W) ||
+				(i += 2, tileh == SLOPE_S) ||
+				(i += 2, tileh == SLOPE_E) ||
+				(i += 2, tileh == SLOPE_N)
 			) && (
 				bits == TRACK_BIT_X ||
 				(i++, bits == TRACK_BIT_Y)
@@ -176,10 +176,10 @@
 }
 
 
-static uint32 CheckRailSlope(uint tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
+static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
 {
 	// never allow building on top of steep tiles
-	if (!IsSteepTileh(tileh)) {
+	if (!IsSteepSlope(tileh)) {
 		rail_bits |= existing;
 
 		// don't allow building on the lower side of a coast
@@ -194,7 +194,7 @@
 
 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
-					(tileh == 1 || tileh == 2 || tileh == 4 || tileh == 8)
+					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
 				)) { // partly up
 			if (existing != 0) {
 				return 0;
@@ -218,7 +218,7 @@
  */
 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	uint tileh;
+	Slope tileh;
 	Track track = (Track)p2;
 	TrackBits trackbit;
 	int32 cost = 0;
@@ -280,7 +280,7 @@
 		case MP_STREET:
 #define M(x) (1 << (x))
 			/* Level crossings may only be built on these slopes */
-			if (!HASBIT(M(14) | M(13) | M(11) | M(10) | M(7) | M(5) | M(0), tileh)) {
+			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 			}
 #undef M
@@ -556,7 +556,7 @@
 {
 	Depot *d;
 	int32 cost, ret;
-	uint tileh;
+	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -575,10 +575,10 @@
 
 	*/
 
-	if (tileh != 0 && (
+	if (tileh != SLOPE_FLAT && (
 				_is_old_ai_player ||
 				!_patches.build_on_slopes ||
-				IsSteepTileh(tileh) ||
+				IsSteepSlope(tileh) ||
 				!CanBuildDepotByTileh(p2, tileh)
 			)) {
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
@@ -1058,7 +1058,7 @@
 static void DrawTrackFence_NW(const TileInfo *ti)
 {
 	uint32 image = 0x515;
-	if (ti->tileh != 0) image = (ti->tileh & 2) ? 0x519 : 0x51B;
+	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
 	AddSortableSpriteToDraw(image | _drawtile_track_palette,
 		ti->x, ti->y + 1, 16, 1, 4, ti->z);
 }
@@ -1066,7 +1066,7 @@
 static void DrawTrackFence_SE(const TileInfo *ti)
 {
 	uint32 image = 0x515;
-	if (ti->tileh != 0) image = (ti->tileh & 2) ? 0x519 : 0x51B;
+	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B;
 	AddSortableSpriteToDraw(image | _drawtile_track_palette,
 		ti->x, ti->y + 15, 16, 1, 4, ti->z);
 }
@@ -1080,7 +1080,7 @@
 static void DrawTrackFence_NE(const TileInfo *ti)
 {
 	uint32 image = 0x516;
-	if (ti->tileh != 0) image = (ti->tileh & 2) ? 0x51A : 0x51C;
+	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
 	AddSortableSpriteToDraw(image | _drawtile_track_palette,
 		ti->x + 1, ti->y, 1, 16, 4, ti->z);
 }
@@ -1088,7 +1088,7 @@
 static void DrawTrackFence_SW(const TileInfo *ti)
 {
 	uint32 image = 0x516;
-	if (ti->tileh != 0) image = (ti->tileh & 2) ? 0x51A : 0x51C;
+	if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C;
 	AddSortableSpriteToDraw(image | _drawtile_track_palette,
 		ti->x + 15, ti->y, 1, 16, 4, ti->z);
 }
@@ -1102,7 +1102,7 @@
 static void DrawTrackFence_NS_1(const TileInfo *ti)
 {
 	int z = ti->z;
-	if (ti->tileh & 1) z += 8;
+	if (ti->tileh & SLOPE_W) z += 8;
 	AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
 		ti->x + 8, ti->y + 8, 1, 1, 4, z);
 }
@@ -1110,7 +1110,7 @@
 static void DrawTrackFence_NS_2(const TileInfo *ti)
 {
 	int z = ti->z;
-	if (ti->tileh & 4) z += 8;
+	if (ti->tileh & SLOPE_E) z += 8;
 	AddSortableSpriteToDraw(0x517 | _drawtile_track_palette,
 		ti->x + 8, ti->y + 8, 1, 1, 4, z);
 }
@@ -1118,7 +1118,7 @@
 static void DrawTrackFence_WE_1(const TileInfo *ti)
 {
 	int z = ti->z;
-	if (ti->tileh & 8) z += 8;
+	if (ti->tileh & SLOPE_N) z += 8;
 	AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
 		ti->x + 8, ti->y + 8, 1, 1, 4, z);
 }
@@ -1126,7 +1126,7 @@
 static void DrawTrackFence_WE_2(const TileInfo *ti)
 {
 	int z = ti->z;
-	if (ti->tileh & 2) z += 8;
+	if (ti->tileh & SLOPE_S) z += 8;
 	AddSortableSpriteToDraw(0x518 | _drawtile_track_palette,
 		ti->x + 8, ti->y + 8, 1, 1, 4, z);
 }
@@ -1208,7 +1208,7 @@
 	(image++,                          (track & TRACK_BIT_3WAY_SE) == 0) ||
 	(image++, true);
 
-	if (ti->tileh != 0) {
+	if (ti->tileh != SLOPE_FLAT) {
 		int foundation;
 
 		if (flat) {
@@ -1222,7 +1222,7 @@
 
 		// DrawFoundation() modifies ti.
 		// Default sloped sprites..
-		if (ti->tileh != 0)
+		if (ti->tileh != SLOPE_FLAT)
 			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
 	}
 
@@ -1302,7 +1302,7 @@
 		const DrawTrackSeqStruct *drss;
 		bool is_depot = GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT;
 
-		if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
+		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
 		if (IsRailWaypoint(ti->tile) && IsCustomWaypoint(ti->tile)) {
 			// look for customization
@@ -1688,10 +1688,10 @@
 
 static uint GetSlopeZ_Track(const TileInfo* ti)
 {
-	uint tileh = ti->tileh;
+	Slope tileh = ti->tileh;
 	uint z = ti->z;
 
-	if (tileh == 0) return z;
+	if (tileh == SLOPE_FLAT) return z;
 	if (GetRailTileType(ti->tile) == RAIL_TYPE_DEPOT_WAYPOINT) {
 		return z + 8;
 	} else {
@@ -1705,16 +1705,16 @@
 	}
 }
 
-static uint GetSlopeTileh_Track(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh)
 {
-	if (tileh == 0) return 0;
+	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
 	if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT) {
-		return 0;
+		return SLOPE_FLAT;
 	} else {
 		uint f = GetRailFoundation(tileh, GetTrackBits(tile));
 
 		if (f == 0) return tileh;
-		if (f < 15) return 0; // leveled foundation
+		if (f < 15) return SLOPE_FLAT; // leveled foundation
 		return _inclined_tileh[f - 15]; // inclined foundation
 	}
 }
--- a/road_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/road_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -154,7 +154,7 @@
 					RoadBits present = GetRoadBits(tile);
 					RoadBits c = pieces;
 
-					if (GetTileSlope(tile, NULL) != 0  &&
+					if (GetTileSlope(tile, NULL) != SLOPE_FLAT &&
 							(present == ROAD_Y || present == ROAD_X)) {
 						c |= (c & 0xC) >> 2;
 						c |= (c & 0x3) << 2;
@@ -235,17 +235,17 @@
 };
 
 
-static uint32 CheckRoadSlope(int tileh, RoadBits* pieces, RoadBits existing)
+static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
 {
 	RoadBits road_bits;
 
-	if (IsSteepTileh(tileh)) return CMD_ERROR;
+	if (IsSteepSlope(tileh)) return CMD_ERROR;
 	road_bits = *pieces | existing;
 
 	// no special foundation
 	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
 		// force that all bits are set when we have slopes
-		if (tileh != 0) *pieces |= _valid_tileh_slopes_road[0][tileh];
+		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
 		return 0; // no extra cost
 	}
 
@@ -255,7 +255,7 @@
 	}
 
 	// partly leveled up tile, only if there's no road on that tile
-	if (existing == 0 && (tileh == 1 || tileh == 2 || tileh == 4 || tileh == 8)) {
+	if (existing == 0 && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 		// force full pieces.
 		*pieces |= (*pieces & 0xC) >> 2;
 		*pieces |= (*pieces & 0x3) << 2;
@@ -275,7 +275,7 @@
 	int32 ret;
 	RoadBits existing = 0;
 	RoadBits pieces;
-	byte tileh;
+	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -312,13 +312,13 @@
 		case MP_RAILWAY: {
 			Axis roaddir;
 
-			if (IsSteepTileh(tileh)) { // very steep tile
+			if (IsSteepSlope(tileh)) {
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 			}
 
 #define M(x) (1 << (x))
 			/* Level crossings may only be built on these slopes */
-			if (!HASBIT(M(14) | M(13) | M(11) | M(10) | M(7) | M(5) | M(0), tileh)) {
+			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 			}
 #undef M
@@ -349,7 +349,7 @@
 
 		case MP_TUNNELBRIDGE:
 			/* check for flat land */
-			if (IsSteepTileh(tileh)) { // very steep tile
+			if (IsSteepSlope(tileh)) {
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 			}
 
@@ -551,7 +551,7 @@
 {
 	int32 cost;
 	Depot *dep;
-	uint tileh;
+	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -560,9 +560,9 @@
 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
-	if (tileh != 0 && (
+	if (tileh != SLOPE_FLAT && (
 				!_patches.build_on_slopes ||
-				IsSteepTileh(tileh) ||
+				IsSteepSlope(tileh) ||
 				!CanBuildDepotByTileh(p1, tileh)
 			)) {
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
@@ -655,7 +655,7 @@
 #include "table/road_land.h"
 
 
-uint GetRoadFoundation(uint tileh, RoadBits bits)
+uint GetRoadFoundation(Slope tileh, RoadBits bits)
 {
 	int i;
 	// normal level sloped building
@@ -663,10 +663,10 @@
 
 	// inclined sloped building
 	if ((
-				(i  = 0, tileh == 1) ||
-				(i += 2, tileh == 2) ||
-				(i += 2, tileh == 4) ||
-				(i += 2, tileh == 8)
+				(i  = 0, tileh == SLOPE_W) ||
+				(i += 2, tileh == SLOPE_S) ||
+				(i += 2, tileh == SLOPE_E) ||
+				(i += 2, tileh == SLOPE_N)
 			) && (
 				(     bits == ROAD_X) ||
 				(i++, bits == ROAD_Y)
@@ -694,14 +694,14 @@
 	const DrawRoadTileStruct *drts;
 	PalSpriteID image = 0;
 
-	if (ti->tileh != 0) {
+	if (ti->tileh != SLOPE_FLAT) {
 		int foundation = GetRoadFoundation(ti->tileh, road);
 
 		if (foundation != 0) DrawFoundation(ti, foundation);
 
 		// DrawFoundation() modifies ti.
 		// Default sloped sprites..
-		if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
+		if (ti->tileh != SLOPE_FLAT) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
 	}
 
 	if (image == 0) image = _road_tile_sprites_1[road];
@@ -731,7 +731,7 @@
 		int x = ti->x | drts->subcoord_x;
 		int y = ti->y | drts->subcoord_y;
 		byte z = ti->z;
-		if (ti->tileh != 0) z = GetSlopeZ(x, y);
+		if (ti->tileh != SLOPE_FLAT) z = GetSlopeZ(x, y);
 		AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z);
 	}
 }
@@ -746,7 +746,7 @@
 			break;
 
 		case ROAD_CROSSING: {
-			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
 			image = GetRailTypeInfo(GetRailTypeCrossing(ti->tile))->base_sprites.crossing;
 
@@ -772,7 +772,7 @@
 			PlayerID player;
 			const DrawRoadSeqStruct* drss;
 
-			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
+			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
 			ormod = PALETTE_TO_GREY;	//was this a bug/problem?
 			player = GetTileOwner(ti->tile);
@@ -823,10 +823,10 @@
 
 static uint GetSlopeZ_Road(const TileInfo* ti)
 {
-	uint tileh = ti->tileh;
+	Slope tileh = ti->tileh;
 	uint z = ti->z;
 
-	if (tileh == 0) return z;
+	if (tileh == SLOPE_FLAT) return z;
 	if (GetRoadType(ti->tile) == ROAD_NORMAL) {
 		uint f = GetRoadFoundation(tileh, GetRoadBits(ti->tile));
 
@@ -840,17 +840,17 @@
 	}
 }
 
-static uint GetSlopeTileh_Road(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
 {
-	if (tileh == 0) return 0;
+	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
 	if (GetRoadType(tile) == ROAD_NORMAL) {
 		uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
 
 		if (f == 0) return tileh;
-		if (f < 15) return 0; // leveled foundation
+		if (f < 15) return SLOPE_FLAT; // leveled foundation
 		return _inclined_tileh[f - 15]; // inclined foundation
 	} else {
-		return 0;
+		return SLOPE_FLAT;
 	}
 }
 
@@ -915,7 +915,7 @@
 			if (t->road_build_months != 0 &&
 					!(DistanceManhattan(t->xy, tile) >= 8 && grp == 0) &&
 					GetRoadType(tile) == ROAD_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) {
-				if (GetTileSlope(tile, NULL) == 0 && EnsureNoVehicle(tile) && CHANCE16(1, 20)) {
+				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicle(tile) && CHANCE16(1, 20)) {
 					StartRoadWorks(tile);
 
 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/slope.h	Sun Apr 23 13:48:16 2006 +0000
@@ -0,0 +1,41 @@
+/* $Id$ */
+
+#ifndef SLOPE_H
+#define SLOPE_H
+
+typedef enum Slope {
+	SLOPE_FLAT  = 0x00,
+	SLOPE_W     = 0x01,
+	SLOPE_S     = 0x02,
+	SLOPE_E     = 0x04,
+	SLOPE_N     = 0x08,
+	SLOPE_STEEP = 0x10,
+	SLOPE_NW = SLOPE_N | SLOPE_W,
+	SLOPE_SW = SLOPE_S | SLOPE_W,
+	SLOPE_SE = SLOPE_S | SLOPE_E,
+	SLOPE_NE = SLOPE_N | SLOPE_E,
+	SLOPE_EW = SLOPE_E | SLOPE_W,
+	SLOPE_NS = SLOPE_N | SLOPE_S,
+	SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W,
+	SLOPE_NWS = SLOPE_N | SLOPE_W | SLOPE_S,
+	SLOPE_WSE = SLOPE_W | SLOPE_S | SLOPE_E,
+	SLOPE_SEN = SLOPE_S | SLOPE_E | SLOPE_N,
+	SLOPE_ENW = SLOPE_E | SLOPE_N | SLOPE_W,
+	SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS,
+	SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE,
+	SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN,
+	SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW
+} Slope;
+
+static inline bool IsSteepSlope(Slope s)
+{
+	return (s & SLOPE_STEEP) != 0;
+}
+
+static inline Slope ComplementSlope(Slope s)
+{
+	assert(!IsSteepSlope(s));
+	return (Slope)(0xF ^ s);
+}
+
+#endif
--- a/station_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/station_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -776,7 +776,7 @@
 {
 	int32 cost = 0, ret;
 
-	uint tileh;
+	Slope tileh;
 	uint z;
 	int allowed_z = -1;
 	int flat_z;
@@ -794,18 +794,18 @@
 				-OR-
 				b) the build_on_slopes switch is disabled
 		*/
-		if (IsSteepTileh(tileh) ||
-				((_is_old_ai_player || !_patches.build_on_slopes) && tileh != 0)) {
+		if (IsSteepSlope(tileh) ||
+				((_is_old_ai_player || !_patches.build_on_slopes) && tileh != SLOPE_FLAT)) {
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 		}
 
 		flat_z = z;
-		if (tileh) {
+		if (tileh != SLOPE_FLAT) {
 			// need to check so the entrance to the station is not pointing at a slope.
-			if ((invalid_dirs&1 && !(tileh & 0xC) && (uint)w_cur == w) ||
-					(invalid_dirs&2 && !(tileh & 6) &&	h_cur == 1) ||
-					(invalid_dirs&4 && !(tileh & 3) && w_cur == 1) ||
-					(invalid_dirs&8 && !(tileh & 9) && (uint)h_cur == h)) {
+			if ((invalid_dirs&1 && !(tileh & SLOPE_NE) && (uint)w_cur == w) ||
+					(invalid_dirs&2 && !(tileh & SLOPE_SE) &&	h_cur == 1) ||
+					(invalid_dirs&4 && !(tileh & SLOPE_SW) && w_cur == 1) ||
+					(invalid_dirs&8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
 				return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 			}
 			cost += _price.terraform;
@@ -1823,10 +1823,10 @@
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	switch (GetTileSlope(tile, NULL)) {
-		case  3: direction = DIAGDIR_NE; break;
-		case  6: direction = DIAGDIR_NW; break;
-		case  9: direction = DIAGDIR_SE; break;
-		case 12: direction = DIAGDIR_SW; break;
+		case SLOPE_SW: direction = DIAGDIR_NE; break;
+		case SLOPE_SE: direction = DIAGDIR_NW; break;
+		case SLOPE_NW: direction = DIAGDIR_SE; break;
+		case SLOPE_NE: direction = DIAGDIR_SW; break;
 		default: return_cmd_error(STR_304B_SITE_UNSUITABLE);
 	}
 
@@ -1839,7 +1839,7 @@
 
 	if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
 
-	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != 0) {
+	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 	}
 
@@ -1847,7 +1847,7 @@
 	if (CmdFailed(cost)) return CMD_ERROR;
 
 	tile_cur = tile_cur + TileOffsByDir(direction);
-	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != 0) {
+	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
 		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 	}
 
@@ -1957,7 +1957,7 @@
 	}
 
 	// don't show foundation for docks
-	if (ti->tileh != 0 && !IsDock(ti->tile))
+	if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
 		DrawFoundation(ti, ti->tileh);
 
 	if (IsCustomStationSpecIndex(ti->tile)) {
@@ -2032,12 +2032,12 @@
 
 static uint GetSlopeZ_Station(const TileInfo* ti)
 {
-	return ti->z + (ti->tileh == 0 ? 0 : 8);
+	return ti->z + (ti->tileh == SLOPE_FLAT ? 0 : 8);
 }
 
-static uint GetSlopeTileh_Station(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Station(TileIndex tile, Slope tileh)
 {
-	return 0;
+	return SLOPE_FLAT;
 }
 
 static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac)
--- a/tile.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/tile.c	Sun Apr 23 13:48:16 2006 +0000
@@ -8,27 +8,27 @@
   * @param h uint pointer to write the height to
   * @return the tileh
 */
-uint GetTileh(uint n, uint w, uint e, uint s, uint *h)
+Slope GetTileh(uint n, uint w, uint e, uint s, uint *h)
 {
 	uint min = n;
-	uint r;
+	Slope r;
 
 	if (min >= w) min = w;
 	if (min >= e) min = e;
 	if (min >= s) min = s;
 
-	r = 0;
-	if ((n -= min) != 0) r += (--n << 4) + 8;
-	if ((e -= min) != 0) r += (--e << 4) + 4;
-	if ((s -= min) != 0) r += (--s << 4) + 2;
-	if ((w -= min) != 0) r += (--w << 4) + 1;
+	r = SLOPE_FLAT;
+	if ((n -= min) != 0) r += (--n << 4) + SLOPE_N;
+	if ((e -= min) != 0) r += (--e << 4) + SLOPE_E;
+	if ((s -= min) != 0) r += (--s << 4) + SLOPE_S;
+	if ((w -= min) != 0) r += (--w << 4) + SLOPE_W;
 
 	if (h != NULL) *h = min * TILE_HEIGHT;
 
 	return r;
 }
 
-uint GetTileSlope(TileIndex tile, uint *h)
+Slope GetTileSlope(TileIndex tile, uint *h)
 {
 	uint a;
 	uint b;
--- a/tile.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/tile.h	Sun Apr 23 13:48:16 2006 +0000
@@ -5,6 +5,7 @@
 
 #include "macros.h"
 #include "map.h"
+#include "slope.h"
 
 typedef enum TileTypes {
 	MP_CLEAR,
@@ -26,11 +27,11 @@
 	TROPICZONE_RAINFOREST = 2,
 } TropicZone;
 
-uint GetTileh(uint n, uint w, uint e, uint s, uint *h);
-uint GetTileSlope(TileIndex tile, uint *h);
+Slope GetTileh(uint n, uint w, uint e, uint s, uint *h);
+Slope GetTileSlope(TileIndex tile, uint *h);
 uint GetTileZ(TileIndex tile);
 
-static inline bool CorrectZ(uint tileh)
+static inline bool CorrectZ(Slope tileh)
 {
 	/* tile height must be corrected if the north corner is not raised, but
 	 * any other corner is. These are the cases 1 till 7 */
@@ -43,11 +44,6 @@
 	return GB(_m[tile].type_height, 0, 4);
 }
 
-static inline bool IsSteepTileh(uint tileh)
-{
-	return (tileh & 0x10);
-}
-
 static inline void SetTileHeight(TileIndex tile, uint height)
 {
 	assert(tile < MapSize());
--- a/town_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/town_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -103,7 +103,7 @@
 	z = ti->z;
 
 	/* Add bricks below the house? */
-	if (ti->tileh) {
+	if (ti->tileh != SLOPE_FLAT) {
 		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
 		AddChildSpriteScreen(dcts->sprite_1, 31, 1);
 		z += 8;
@@ -137,12 +137,12 @@
 
 static uint GetSlopeZ_Town(const TileInfo* ti)
 {
-	return ti->z + (ti->tileh == 0 ? 0 : 8);
+	return ti->z + (ti->tileh == SLOPE_FLAT ? 0 : 8);
 }
 
-static uint GetSlopeTileh_Town(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
 {
-	return 0;
+	return SLOPE_FLAT;
 }
 
 static void AnimateTile_Town(TileIndex tile)
@@ -458,8 +458,8 @@
 
 static bool IsRoadAllowedHere(TileIndex tile, int dir)
 {
-	uint k;
-	uint slope;
+	Slope k;
+	Slope slope;
 
 	// If this assertion fails, it might be because the world contains
 	//  land at the edges. This is not ok.
@@ -477,7 +477,7 @@
 		}
 
 		slope = GetTileSlope(tile, NULL);
-		if (slope == 0) {
+		if (slope == SLOPE_FLAT) {
 no_slope:
 			// Tile has no slope
 			// Disallow the road if any neighboring tile has a road.
@@ -493,7 +493,8 @@
 
 		// If the tile is not a slope in the right direction, then
 		// maybe terraform some.
-		if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) {
+		k = (dir & 1) ? SLOPE_NE : SLOPE_NW;
+		if (k != slope && ComplementSlope(k) != slope) {
 			uint32 r = Random();
 
 			if (CHANCE16I(1, 8, r) && !_generating_world) {
@@ -503,7 +504,7 @@
 					res = DoCommand(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER,
 					                      CMD_TERRAFORM_LAND);
 				} else {
-					res = DoCommand(tile, slope ^ 0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER,
+					res = DoCommand(tile, ComplementSlope(slope), 1, DC_EXEC | DC_AUTO | DC_NO_WATER,
 					                      CMD_TERRAFORM_LAND);
 				}
 				if (CmdFailed(res) && CHANCE16I(1, 3, r)) {
@@ -531,14 +532,14 @@
 
 static void LevelTownLand(TileIndex tile)
 {
-	uint tileh;
+	Slope tileh;
 
 	TILE_ASSERT(tile);
 
 	// Don't terraform if land is plain or if there's a house there.
 	if (IsTileType(tile, MP_HOUSE)) return;
 	tileh = GetTileSlope(tile, NULL);
-	if (tileh == 0) return;
+	if (tileh == SLOPE_FLAT) return;
 
 	// First try up, then down
 	if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) {
@@ -647,10 +648,10 @@
 	// Determine direction of slope,
 	//  and build a road if not a special slope.
 	switch (GetTileSlope(tile, NULL)) {
-		case  3: i = DIAGDIR_NE; break;
-		case  6: i = DIAGDIR_NW; break;
-		case  9: i = DIAGDIR_SE; break;
-		case 12: i = DIAGDIR_SW; break;
+		case SLOPE_SW: i = DIAGDIR_NE; break;
+		case SLOPE_SE: i = DIAGDIR_NW; break;
+		case SLOPE_NW: i = DIAGDIR_SE; break;
+		case SLOPE_NE: i = DIAGDIR_SW; break;
 
 		default:
 build_road_and_exit:
@@ -794,7 +795,7 @@
 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 		// Only work with plain land that not already has a house with GetHouseConstructionTick=0
 		if ((!IsTileType(tile, MP_HOUSE) || GetHouseConstructionTick(tile) != 0) &&
-				GetTileSlope(tile, NULL) == 0) {
+				GetTileSlope(tile, NULL) == SLOPE_FLAT) {
 			if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) {
 				DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
 				_current_player = old_player;
@@ -1013,7 +1014,7 @@
 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
 
 	// Can only build on clear flat areas.
-	if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != 0) {
+	if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
 		return_cmd_error(STR_0239_SITE_UNSUITABLE);
 	}
 
@@ -1050,7 +1051,7 @@
 		if (DistanceFromEdge(tile) < 20) continue;
 
 		// Make sure the tile is plain
-		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != 0) continue;
+		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
 
 		// Check not too close to a town
 		if (IsCloseToTown(tile, 20)) continue;
@@ -1093,10 +1094,10 @@
 	return true;
 }
 
-static bool CheckBuildHouseMode(TileIndex tile, uint tileh, int mode)
+static bool CheckBuildHouseMode(TileIndex tile, Slope tileh, int mode)
 {
 	int b;
-	uint slope;
+	Slope slope;
 
 	static const byte _masks[8] = {
 		0xC,0x3,0x9,0x6,
@@ -1104,12 +1105,11 @@
 	};
 
 	slope = GetTileSlope(tile, NULL);
-	if (slope & 0x10)
-		return false;
+	if (IsSteepSlope(slope)) return false;
 
 	b = 0;
-	if ((slope & 0xF && ~slope & _masks[mode])) b = ~b;
-	if ((tileh & 0xF && ~tileh & _masks[mode+4])) b = ~b;
+	if ((slope != SLOPE_FLAT && ~slope & _masks[mode])) b = ~b;
+	if ((tileh != SLOPE_FLAT && ~tileh & _masks[mode+4])) b = ~b;
 	if (b)
 		return false;
 
@@ -1148,7 +1148,7 @@
 	for (i = 0; i != 4; i++) {
 		tile += ToTileIndexDiff(_tile_add[i]);
 
-		if (GetTileSlope(tile, NULL)) return false;
+		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
 
 		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
 			return false;
@@ -1162,7 +1162,7 @@
 	int i;
 	uint bitmask;
 	int house;
-	uint slope;
+	Slope slope;
 	uint z;
 	uint oneof = 0;
 
@@ -1220,7 +1220,7 @@
 			if (HASBITS(t->flags12 , oneof)) continue;
 
 			// Make sure there is no slope?
-			if (_housetype_extra_flags[house] & 0x12 && slope) continue;
+			if (_housetype_extra_flags[house] & 0x12 && slope != SLOPE_FLAT) continue;
 
 			if (_housetype_extra_flags[house] & 0x10) {
 				if (CheckFree2x2Area(tile) ||
@@ -1283,7 +1283,7 @@
 
 	// make sure it's possible
 	if (!EnsureNoVehicle(tile)) return false;
-	if (GetTileSlope(tile, NULL) & 0x10) return false;
+	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
 
 	r = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(r)) return false;
@@ -1488,7 +1488,7 @@
 	PlayerID old;
 	int32 r;
 
-	if (GetTileSlope(tile, NULL) != 0) return false;
+	if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
 
 	if (!IsTileType(tile, MP_HOUSE) &&
 			!IsTileType(tile, MP_CLEAR) &&
--- a/train_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/train_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -2612,7 +2612,7 @@
 		case MP_TUNNELBRIDGE:
 			if (IsBridge(tile) && IsBridgeMiddle(tile)) {
 				uint height;
-				uint tileh = GetTileSlope(tile, &height);
+				Slope tileh = GetTileSlope(tile, &height);
 
 				// correct Z position of a train going under a bridge on slopes
 				if (CorrectZ(tileh)) height += 8;
--- a/tree_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/tree_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -250,10 +250,9 @@
 	DrawClearLandFence(ti);
 
 	z = ti->z;
-	if (ti->tileh != 0) {
+	if (ti->tileh != SLOPE_FLAT) {
 		z += 4;
-		if (IsSteepTileh(ti->tileh))
-			z += 4;
+		if (IsSteepSlope(ti->tileh)) z += 4;
 	}
 
 	{
@@ -329,7 +328,7 @@
 	return GetPartialZ(ti->x & 0xF, ti->y & 0xF, ti->tileh) + ti->z;
 }
 
-static uint GetSlopeTileh_Trees(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Trees(TileIndex tile, Slope tileh)
 {
 	return tileh;
 }
--- a/tunnelbridge_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/tunnelbridge_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -77,15 +77,17 @@
 	}
 }
 
+#define M(x) (1 << (x))
 enum {
-	// foundation, whole tile is leveled up (tileh's 7, 11, 13, 14) --> 3 corners raised
-	BRIDGE_FULL_LEVELED_FOUNDATION = 1 << 7 | 1 << 11 | 1 << 13 | 1 << 14,
-	// foundation, tile is partly leveled up (tileh's 1, 2, 4, 8) --> 1 corner raised
-	BRIDGE_PARTLY_LEVELED_FOUNDATION = 1 << 1 | 1 << 2 | 1 << 4 | 1 << 8,
-	// no foundations (X,Y direction) (tileh's 0, 3, 6, 9, 12)
-	BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
-	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~(1 << 0)
+	// foundation, whole tile is leveled up --> 3 corners raised
+	BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
+	// foundation, tile is partly leveled up --> 1 corner raised
+	BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
+	// no foundations (X,Y direction)
+	BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
+	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
 };
+#undef M
 
 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table)
 {
@@ -105,43 +107,41 @@
  *	is_start_tile = false		<-- end tile
  *	is_start_tile = true		<-- start tile
  */
-static uint32 CheckBridgeSlope(Axis direction, uint tileh, bool is_start_tile)
+static uint32 CheckBridgeSlope(Axis direction, Slope tileh, bool is_start_tile)
 {
-	if (IsSteepTileh(tileh)) return CMD_ERROR;
+	if (IsSteepSlope(tileh)) return CMD_ERROR;
 
 	if (is_start_tile) {
 		/* check slope at start tile
 				- no extra cost
-				- direction X: tiles 0, 12
-				- direction Y: tiles 0,  9
 		*/
-		if ((direction == AXIS_X ? 0x1001 : 0x201) & (1 << tileh)) return 0;
+#define M(x) (1 << (x))
+		if (HASBIT(M(SLOPE_FLAT) | (direction == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW)), tileh)) return 0;
 
 		// disallow certain start tiles to avoid certain crooked bridges
-		if (tileh == 2) return CMD_ERROR;
+		if (tileh == SLOPE_S) return CMD_ERROR;
 	} else {
 		/*	check slope at end tile
 				- no extra cost
-				- direction X: tiles 0, 3
-				- direction Y: tiles 0, 6
 		*/
-		if ((direction == AXIS_X ? 0x9 : 0x41) & (1 << tileh)) return 0;
+		if (HASBIT(M(SLOPE_FLAT) | (direction == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE)), tileh)) return 0;
+#undef M
 
 		// disallow certain end tiles to avoid certain crooked bridges
-		if (tileh == 8) return CMD_ERROR;
+		if (tileh == SLOPE_N) return CMD_ERROR;
 	}
 
 	/*	disallow common start/end tiles to avoid certain crooked bridges e.g.
 	 *	start-tile:	X 2,1 Y 2,4 (2 was disabled before)
 	 *	end-tile:		X 8,4 Y 8,1 (8 was disabled before)
 	 */
-	if ((tileh == 1 && is_start_tile != (direction != AXIS_X)) ||
-			(tileh == 4 && is_start_tile == (direction != AXIS_X))) {
+	if ((tileh == SLOPE_W && is_start_tile != (direction != AXIS_X)) ||
+			(tileh == SLOPE_E && is_start_tile == (direction != AXIS_X))) {
 		return CMD_ERROR;
 	}
 
 	// slope foundations
-	if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh) || BRIDGE_PARTLY_LEVELED_FOUNDATION & (1 << tileh))
+	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION | BRIDGE_PARTLY_LEVELED_FOUNDATION, tileh))
 		return _price.terraform;
 
 	return CMD_ERROR;
@@ -188,8 +188,8 @@
 	int sx,sy;
 	TileIndex tile_start;
 	TileIndex tile_end;
-	uint tileh_start;
-	uint tileh_end;
+	Slope tileh_start;
+	Slope tileh_end;
 	uint z_start;
 	uint z_end;
 	TileIndex tile;
@@ -253,14 +253,14 @@
 	tileh_start = GetTileSlope(tile_start, &z_start);
 	tileh_end = GetTileSlope(tile_end, &z_end);
 
-	if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh_start)) {
+	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_start)) {
 		z_start += 8;
-		tileh_start = 0;
+		tileh_start = SLOPE_FLAT;
 	}
 
-	if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh_end)) {
+	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_end)) {
 		z_end += 8;
-		tileh_end = 0;
+		tileh_end = SLOPE_FLAT;
 	}
 
 	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
@@ -322,7 +322,7 @@
 
 		tile += delta;
 
-		if (GetTileSlope(tile, &z) != 0 && z >= z_start) {
+		if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) {
 			return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
 		}
 
@@ -437,8 +437,8 @@
 	TileIndexDiff delta;
 	TileIndex end_tile;
 	DiagDirection direction;
-	uint start_tileh;
-	uint end_tileh;
+	Slope start_tileh;
+	Slope end_tileh;
 	uint start_z;
 	uint end_z;
 	int32 cost;
@@ -451,10 +451,10 @@
 	start_tileh = GetTileSlope(start_tile, &start_z);
 
 	switch (start_tileh) {
-		case  3: direction = DIAGDIR_SW; break;
-		case  6: direction = DIAGDIR_SE; break;
-		case  9: direction = DIAGDIR_NW; break;
-		case 12: direction = DIAGDIR_NE; break;
+		case SLOPE_SW: direction = DIAGDIR_SW; break;
+		case SLOPE_SE: direction = DIAGDIR_SE; break;
+		case SLOPE_NW: direction = DIAGDIR_NW; break;
+		case SLOPE_NE: direction = DIAGDIR_NE; break;
 		default: return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL);
 	}
 
@@ -483,7 +483,7 @@
 	_build_tunnel_endtile = end_tile;
 
 	// slope of end tile must be complementary to the slope of the start tile
-	if (end_tileh != (15 ^ start_tileh)) {
+	if (end_tileh != ComplementSlope(start_tileh)) {
 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
 	} else {
@@ -687,7 +687,7 @@
 				if (IsClearUnderBridge(c)) {
 					DoClearSquare(c);
 				} else {
-					if (GetTileSlope(c, NULL) == 0) {
+					if (GetTileSlope(c, NULL) == SLOPE_FLAT) {
 						MakeWater(c);
 					} else {
 						MakeShore(c);
@@ -805,9 +805,9 @@
 	TileIndex tile = GetSouthernBridgeEnd(t);
 
 	/* Return the height there (the height of the NORTH CORNER)
-	 * If the end of the bridge is on a tileh 7 (all raised, except north corner),
+	 * If the end of the bridge is on a tile with all corners except the north corner raised,
 	 * the z coordinate is 1 height level too low. Compensate for that */
-	return TilePixelHeight(tile) + (GetTileSlope(tile, NULL) == 7 ? 8 : 0);
+	return TilePixelHeight(tile) + (GetTileSlope(tile, NULL) == SLOPE_WSE ? 8 : 0);
 }
 
 static const byte _bridge_foundations[2][16] = {
@@ -840,7 +840,7 @@
 		front_height = ti->z + ((ti->tileh & p[0])?8:0);
 		back_height = ti->z + ((ti->tileh & p[1])?8:0);
 
-		if (IsSteepTileh(ti->tileh)) {
+		if (IsSteepSlope(ti->tileh)) {
 			if (!(ti->tileh & p[2])) front_height += 8;
 			if (!(ti->tileh & p[3])) back_height += 8;
 		}
@@ -857,18 +857,17 @@
 	}
 }
 
-uint GetBridgeFoundation(uint tileh, Axis axis)
+uint GetBridgeFoundation(Slope tileh, Axis axis)
 {
 	int i;
-	// normal level sloped building (7, 11, 13, 14)
-	if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh)) return tileh;
+	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
 
 	// inclined sloped building
 	if ((
-				(i  = 0, tileh == 1) ||
-				(i += 2, tileh == 2) ||
-				(i += 2, tileh == 4) ||
-				(i += 2, tileh == 8)
+				(i  = 0, tileh == SLOPE_W) ||
+				(i += 2, tileh == SLOPE_S) ||
+				(i += 2, tileh == SLOPE_E) ||
+				(i += 2, tileh == SLOPE_N)
 			) && (
 				      axis == AXIS_X ||
 				(i++, axis == AXIS_Y)
@@ -938,7 +937,7 @@
 		assert( (base_offset & 0x07) == 0x00);
 
 		if (IsBridgeRamp(ti->tile)) {
-			if (!(BRIDGE_NO_FOUNDATION & (1 << ti->tileh))) {	// no foundations for 0, 3, 6, 9, 12
+			if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
 				int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
 				if (f) DrawFoundation(ti, f);
 			}
@@ -946,7 +945,7 @@
 			// HACK Wizardry to convert the bridge ramp direction into a sprite offset
 			base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
 
-			if (ti->tileh == 0) base_offset += 4; // sloped bridge head
+			if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 
 			/* Table number 6 always refers to the bridge heads for any bridge type */
 			image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
@@ -976,7 +975,7 @@
 				if (GetTransportTypeUnderBridge(ti->tile) == TRANSPORT_RAIL) {
 					const RailtypeInfo* rti = GetRailTypeInfo(GetRailType(ti->tile));
 
-					if (ti->tileh == 0) {
+					if (ti->tileh == SLOPE_FLAT) {
 						image = (axis == AXIS_X ? SPR_RAIL_TRACK_Y : SPR_RAIL_TRACK_X);
 					} else {
 						image = SPR_RAIL_TRACK_Y + _track_sloped_sprites[ti->tileh - 1];
@@ -984,7 +983,7 @@
 					image += rti->total_offset;
 					if (ice) image += rti->snow_offset;
 				} else {
-					if (ti->tileh == 0) {
+					if (ti->tileh == SLOPE_FLAT) {
 						image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
 					} else {
 						image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
@@ -997,7 +996,7 @@
 					image = (ice ? SPR_FLAT_SNOWY_TILE : SPR_FLAT_GRASS_TILE);
 					DrawGroundSprite(image + _tileh_to_sprite[ti->tileh]);
 				} else {
-					if (ti->tileh == 0) {
+					if (ti->tileh == SLOPE_FLAT) {
 						DrawGroundSprite(SPR_FLAT_WATER_TILE);
 						if (ti->z != 0) DrawCanalWater(ti->tile);
 					} else {
@@ -1061,7 +1060,7 @@
 	uint z = ti->z;
 	uint x = ti->x & 0xF;
 	uint y = ti->y & 0xF;
-	uint tileh = ti->tileh;
+	Slope tileh = ti->tileh;
 
 	if (IsTunnel(tile)) {
 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
@@ -1098,7 +1097,7 @@
 			}
 		} else {
 			// HACK on the bridge?
-			if (_get_z_hint >= z + 8 + (tileh == 0 ? 0 : 8)) return _get_z_hint;
+			if (_get_z_hint >= z + 8 + (tileh == SLOPE_FLAT ? 0 : 8)) return _get_z_hint;
 
 			if (IsTransportUnderBridge(tile)) {
 				uint f = _bridge_foundations[GetBridgeAxis(tile)][tileh];
@@ -1114,10 +1113,10 @@
 	return z + GetPartialZ(x, y, tileh);
 }
 
-static uint GetSlopeTileh_TunnelBridge(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh)
 {
 	// not accurate, but good enough for slope graphics drawing
-	return 0;
+	return SLOPE_FLAT;
 }
 
 
@@ -1361,7 +1360,7 @@
 			uint h;
 
 			// Compensate for possible foundation
-			if (GetTileSlope(tile, &h) != 0) h += 8;
+			if (GetTileSlope(tile, &h) != SLOPE_FLAT) h += 8;
 			if (IsBridgeRamp(tile) ||
 					myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
 				/* modify speed of vehicle */
--- a/unmovable_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/unmovable_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -141,7 +141,7 @@
 			{
 				const DrawTileUnmovableStruct *dtus;
 
-				if (ti->tileh) DrawFoundation(ti, ti->tileh);
+				if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 				DrawClearLandTile(ti, 2);
 
 				dtus = &_draw_tile_unmovable_data[GetUnmovableType(ti->tile)];
@@ -175,7 +175,7 @@
 				const DrawTileSprites *t;
 
 				assert(IsCompanyHQ(ti->tile));
-				if (ti->tileh) DrawFoundation(ti, ti->tileh);
+				if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 
 				ormod = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
 
@@ -201,13 +201,13 @@
 	if (IsOwnedLand(ti->tile)) {
 		return ti->z + GetPartialZ(ti->x & 0xF, ti->y & 0xF, ti->tileh);
 	} else {
-		return ti->z + (ti->tileh == 0 ? 0 : 8);
+		return ti->z + (ti->tileh == SLOPE_FLAT ? 0 : 8);
 	}
 }
 
-static uint GetSlopeTileh_Unmovable(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Unmovable(TileIndex tile, Slope tileh)
 {
-	return IsOwnedLand(tile) ? tileh : 0;
+	return IsOwnedLand(tile) ? tileh : SLOPE_FLAT;
 }
 
 static int32 ClearTile_Unmovable(TileIndex tile, byte flags)
@@ -341,7 +341,7 @@
 	j = ScaleByMapSize(40); // maximum number of radio towers on the map
 	do {
 		tile = RandomTile();
-		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == 0 && h >= 32) {
+		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h >= 32) {
 			if (!checkRadioTowerNearby(tile)) continue;
 			MakeTransmitter(tile);
 			if (--j == 0) break;
@@ -372,7 +372,7 @@
 		do {
 			if (--j == 0) goto restart;
 			tile = TILE_MASK(tile + TileOffsByDir(dir));
-		} while (!(IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == 0 && h <= TILE_HEIGHT * 2));
+		} while (!(IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h <= TILE_HEIGHT * 2));
 
 		assert(tile == TILE_MASK(tile));
 
--- a/vehicle.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/vehicle.c	Sun Apr 23 13:48:16 2006 +0000
@@ -137,10 +137,9 @@
 	return v;
 }
 
-static inline uint Correct_Z(uint tileh)
+static inline uint Correct_Z(Slope tileh)
 {
 	// needs z correction for slope-type graphics that have the NORTHERN tile lowered
-	// 1, 2, 3, 4, 5, 6 and 7
 	return CorrectZ(tileh) ? 8 : 0;
 }
 
--- a/viewport.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/viewport.c	Sun Apr 23 13:48:16 2006 +0000
@@ -610,9 +610,9 @@
 		} else if (_thd.drawstyle & HT_POINT) {
 			// Figure out the Z coordinate for the single dot.
 			byte z = ti->z;
-			if (ti->tileh & 8) {
+			if (ti->tileh & SLOPE_N) {
 				z += 8;
-				if (!(ti->tileh & 2) && (IsSteepTileh(ti->tileh))) z += 8;
+				if (ti->tileh == SLOPE_STEEP_N) z += 8;
 			}
 			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, ti->x, ti->y, z);
 		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
--- a/water_cmd.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/water_cmd.c	Sun Apr 23 13:48:16 2006 +0000
@@ -129,12 +129,16 @@
 	// lower tile
 	ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(ret)) return CMD_ERROR;
-	if (GetTileSlope(tile - delta, NULL)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+	if (GetTileSlope(tile - delta, NULL) != SLOPE_FLAT) {
+		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+	}
 
 	// upper tile
 	ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(ret)) return CMD_ERROR;
-	if (GetTileSlope(tile + delta, NULL)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+	if (GetTileSlope(tile + delta, NULL) != SLOPE_FLAT) {
+		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
+	}
 
 	if (flags & DC_EXEC) {
 		MakeLock(tile, dir);
@@ -183,10 +187,10 @@
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	switch (GetTileSlope(tile, NULL)) {
-		case  3: dir = DIAGDIR_SW; break;
-		case  6: dir = DIAGDIR_SE; break;
-		case  9: dir = DIAGDIR_NW; break;
-		case 12: dir = DIAGDIR_NE; break;
+		case SLOPE_SW: dir = DIAGDIR_SW; break;
+		case SLOPE_SE: dir = DIAGDIR_SE; break;
+		case SLOPE_NW: dir = DIAGDIR_NW; break;
+		case SLOPE_NE: dir = DIAGDIR_NE; break;
 		default: return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 	}
 	return DoBuildShiplift(tile, dir, flags);
@@ -224,7 +228,9 @@
 
 	cost = 0;
 	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
-		if (GetTileSlope(tile, NULL) != 0) return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) {
+			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
+		}
 
 		// can't make water of water!
 		if (IsTileType(tile, MP_WATER)) continue;
@@ -282,7 +288,7 @@
 			return _price.clear_water;
 
 		case WATER_COAST: {
-			uint slope = GetTileSlope(tile, NULL);
+			Slope slope = GetTileSlope(tile, NULL);
 
 			// Make sure no vehicle is on the tile
 			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
@@ -294,7 +300,7 @@
 			}
 
 			if (flags & DC_EXEC) DoClearSquare(tile);
-			if (slope == 8 || slope == 4 || slope == 2 || slope == 1) {
+			if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
 				return _price.clear_water;
 			} else {
 				return _price.purchase_land;
@@ -418,7 +424,7 @@
 			break;
 
 		case WATER_COAST:
-			assert(!IsSteepTileh(ti->tileh));
+			assert(!IsSteepSlope(ti->tileh));
 			DrawGroundSprite(_water_shore_sprites[ti->tileh]);
 			break;
 
@@ -451,7 +457,7 @@
 	return GetPartialZ(ti->x & 0xF, ti->y & 0xF, ti->tileh) + ti->z;
 }
 
-static uint GetSlopeTileh_Water(TileIndex tile, uint tileh)
+static Slope GetSlopeTileh_Water(TileIndex tile, Slope tileh)
 {
 	return tileh;
 }
@@ -503,17 +509,17 @@
 		switch (GetTileType(target)) {
 			case MP_RAILWAY: {
 				TrackBits tracks;
-				uint slope;
+				Slope slope;
 
 				if (!IsPlainRailTile(target)) break;
 
 				tracks = GetTrackBits(target);
 				slope = GetTileSlope(target, NULL);
 				if (!(
-							(slope == 1 && tracks == TRACK_BIT_RIGHT) ||
-							(slope == 2 && tracks == TRACK_BIT_UPPER) ||
-							(slope == 4 && tracks == TRACK_BIT_LEFT)  ||
-							(slope == 8 && tracks == TRACK_BIT_LOWER)
+							(slope == SLOPE_W && tracks == TRACK_BIT_RIGHT) ||
+							(slope == SLOPE_S && tracks == TRACK_BIT_UPPER) ||
+							(slope == SLOPE_E && tracks == TRACK_BIT_LEFT)  ||
+							(slope == SLOPE_N && tracks == TRACK_BIT_LOWER)
 						)) {
 					break;
 				}
--- a/water_map.h	Sun Apr 23 11:13:06 2006 +0000
+++ b/water_map.h	Sun Apr 23 13:48:16 2006 +0000
@@ -45,7 +45,7 @@
 
 static inline bool IsClearWaterTile(TileIndex t)
 {
-	return IsTileType(t, MP_WATER) && IsWater(t) && GetTileSlope(t, NULL) == 0;
+	return IsTileType(t, MP_WATER) && IsWater(t) && GetTileSlope(t, NULL) == SLOPE_FLAT;
 }
 
 static inline TileIndex GetOtherShipDepotTile(TileIndex t)
--- a/waypoint.c	Sun Apr 23 11:13:06 2006 +0000
+++ b/waypoint.c	Sun Apr 23 13:48:16 2006 +0000
@@ -174,7 +174,7 @@
 int32 CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Waypoint *wp;
-	uint tileh;
+	Slope tileh;
 	Axis axis;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@@ -196,8 +196,8 @@
 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
-	if (tileh != 0) {
-		if (!_patches.build_on_slopes || IsSteepTileh(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))
+	if (tileh != SLOPE_FLAT) {
+		if (!_patches.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}