(svn r2595) -Codechange: Introduced "IsSteepTileh" to find whether a tile is steep
authorcelestar
Sat, 16 Jul 2005 23:47:37 +0000
changeset 2085 ae9e92ffe168
parent 2084 d67790a49f78
child 2086 dbe5faa270e0
(svn r2595) -Codechange: Introduced "IsSteepTileh" to find whether a tile is steep
(i.e. spans two height levels) and use it throughout the code.
-Codechange: Add CanBuildDepotByTileh to find if a tile is suitable to
build a depot on it. Wraps some bitmagic which seems quite unreadable at
first glance
depot.h
industry_cmd.c
main_gui.c
rail_cmd.c
road_cmd.c
station_cmd.c
tile.h
tree_cmd.c
tunnelbridge_cmd.c
viewport.c
waypoint.c
--- a/depot.h	Sat Jul 16 20:58:04 2005 +0000
+++ b/depot.h	Sat Jul 16 23:47:37 2005 +0000
@@ -1,6 +1,9 @@
 #ifndef DEPOT_H
 #define DEPOT_H
 
+/** @file depot.h Header files for depots (not hangars)
+  * @see depot.c */
+
 #include "pool.h"
 #include "tile.h"
 
@@ -112,6 +115,28 @@
 	}
 }
 
+/**
+	Find out if the slope of the tile is suitable to build a depot of given direction
+	@param direction The direction in which the depot's exit points. Starts with 0 as NE and goes Clockwise
+	@param tileh The slope of the tile in question
+	@return true if the construction is possible
+
+
+    This is checked by the ugly 0x4C >> direction magic, which does the following:
+      0x4C is 0100 1100 and tileh has only bits 0..3 set (steep tiles are ruled out)
+      So: for direction (only the significant bits are shown)<p>
+      00 (exit towards NE) we need either bit 2 or 3 set in tileh: 0x4C >> 0 = 1100<p>
+      01 (exit towards SE) we need either bit 1 or 2 set in tileh: 0x4C >> 1 = 0110<p>
+      02 (exit towards SW) we need either bit 0 or 1 set in tileh: 0x4C >> 2 = 0011<p>
+      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)
+{
+	return (0x4C >> direction) & tileh;
+}
+
+
 Depot *GetDepotByTile(TileIndex tile);
 void InitializeDepot(void);
 Depot *AllocateDepot(void);
--- a/industry_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/industry_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -1339,7 +1339,7 @@
 			} else {
 				if (ti.type == MP_WATER && ti.map5 == 0)
 					return false;
-				if (ti.tileh & 0x10)
+				if (IsSteepTileh(ti.tileh))
 					return false;
 
 				if (ti.tileh != 0) {
--- a/main_gui.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/main_gui.c	Sat Jul 16 23:47:37 2005 +0000
@@ -1218,7 +1218,7 @@
 	TileInfo ti;
 
 	FindLandscapeHeightByTile(&ti, tile);
-	if (ti.type != MP_CLEAR || (ti.tileh & 0x10))
+	if (IsTileType(tile, MP_CLEAR) || IsSteepTileh(ti.tileh))
 		return;
 
 	ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 1);
@@ -1230,7 +1230,7 @@
 	TileInfo ti;
 
 	FindLandscapeHeightByTile(&ti, tile);
-	if (ti.type != MP_CLEAR || (ti.tileh & 0x10))
+	if (IsTileType(tile, MP_CLEAR) || IsSteepTileh(ti.tileh))
 		return;
 
 	ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 0);
--- a/rail_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/rail_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -217,7 +217,7 @@
 static uint32 CheckRailSlope(uint tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
 {
 	// never allow building on top of steep tiles
-	if (!(tileh & 0x10)) {
+	if (!IsSteepTileh(tileh)) {
 		rail_bits |= existing;
 
 		// don't allow building on the lower side of a coast
@@ -634,7 +634,10 @@
 /** Build a train depot
  * @param x,y position of the train depot
  * @param p1 rail type
- * @param p2 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
+ * @param p2 depot direction (0 through 3), where 0 is NE, 1 is SE, 2 is SW, 3 is NW
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
  */
 int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -650,8 +653,23 @@
 	if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
-	if (tileh != 0) {
-		if ((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes || (tileh & 0x10 || !((0x4C >> p2) & tileh) ))
+
+	/* Prohibit construction if
+		The tile is non-flat AND
+		1) The AI is "old-school"
+		2) build-on-slopes is disabled
+		3) the tile is steep i.e. spans two height levels
+		4) the exit points in the wrong direction
+
+	*/
+
+	if (tileh != 0 && (
+			(!_patches.ainew_active && _is_ai_player) ||
+			!_patches.build_on_slopes ||
+			IsSteepTileh(tileh) ||
+			!CanBuildDepotByTileh(p2, tileh)
+		)
+	) {
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
--- a/road_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/road_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -322,7 +322,7 @@
 
 static uint32 CheckRoadSlope(int tileh, byte *pieces, byte existing)
 {
-	if (!(tileh & 0x10)) {
+	if (!IsSteepTileh(tileh)) {
 		byte road_bits = *pieces | existing;
 
 		// no special foundation
@@ -385,7 +385,7 @@
 	} else if (ti.type == MP_RAILWAY) {
 		byte m5;
 
-		if (ti.tileh & 0x10) // very steep tile
+		if (IsSteepTileh(ti.tile)) // very steep tile
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
 		if(!_valid_tileh_slopes_road[2][ti.tileh]) // prevent certain slopes
@@ -417,7 +417,7 @@
 	} else if (ti.type == MP_TUNNELBRIDGE) {
 
 		/* check for flat land */
-		if (ti.tileh & 0x10) // very steep tile
+		if (IsSteepTileh(ti.tileh)) // very steep tile
 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
 		/* is this middle part of a bridge? */
@@ -620,6 +620,9 @@
  * @param x,y tile coordinates where the depot will be built
  * @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
  * @param p2 unused
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
  */
 int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -639,8 +642,12 @@
 	if (!EnsureNoVehicle(tile))
 		return CMD_ERROR;
 
-	if (ti.tileh != 0) {
-		if (!_patches.build_on_slopes || (ti.tileh & 0x10 || !((0x4C >> p1) & ti.tileh) ))
+	if ((ti.tileh != 0) && (
+			!_patches.build_on_slopes ||
+			IsSteepTileh(ti.tileh) ||
+			!CanBuildDepotByTileh(p1, ti.tileh)
+		)
+	) {
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
--- a/station_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/station_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -764,8 +764,18 @@
 
 		tileh = GetTileSlope(tile_cur, &z);
 
-		// steep slopes are completely prohibited
-		if (tileh & 0x10 || (((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes) && tileh != 0)) {
+		/* Prohibit building if
+			1) The tile is "steep" (i.e. stretches two height levels)
+			-OR-
+			2) The tile is non-flat if
+				a) the player building is an "old-school" AI
+				-OR-
+				b) the build_on_slopes switch is disabled
+		*/
+		if (IsSteepTileh(tileh) ||
+			(((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes)
+			&& tileh != 0)) {
+
 			_error_message = STR_0007_FLAT_LAND_REQUIRED;
 			return CMD_ERROR;
 		}
--- a/tile.h	Sat Jul 16 20:58:04 2005 +0000
+++ b/tile.h	Sat Jul 16 23:47:37 2005 +0000
@@ -61,6 +61,11 @@
 	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/tree_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/tree_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -289,7 +289,7 @@
 	z = ti->z;
 	if (ti->tileh != 0) {
 		z += 4;
-		if (ti->tileh & 0x10)
+		if (IsSteepTileh(ti->tileh))
 			z += 4;
 	}
 
--- a/tunnelbridge_cmd.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/tunnelbridge_cmd.c	Sat Jul 16 23:47:37 2005 +0000
@@ -88,7 +88,7 @@
  */
 static uint32 CheckBridgeSlope(uint direction, uint tileh, bool is_start_tile)
 {
-	if (!(tileh & 0x10)) {	// disable building on very steep slopes
+	if (!IsSteepTileh(tileh)) {	// disable building on very steep slopes
 
 		if (is_start_tile) {
 			/* check slope at start tile
@@ -981,7 +981,7 @@
 		p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)];
 		front_height = ti->z + ((ti->tileh & p[0])?8:0);
 		back_height = ti->z + ((ti->tileh & p[1])?8:0);
-		if (ti->tileh & 0x10) {
+		if (IsSteepTileh(ti->tileh)) {
 			if (!(ti->tileh & p[2])) front_height += 8;
 			if (!(ti->tileh & p[3])) back_height += 8;
 		}
--- a/viewport.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/viewport.c	Sat Jul 16 23:47:37 2005 +0000
@@ -669,7 +669,7 @@
 			byte z = ti->z;
 			if (ti->tileh & 8) {
 				z += 8;
-				if (!(ti->tileh & 2) && (ti->tileh & 0x10)) {
+				if (!(ti->tileh & 2) && (IsSteepTileh(ti->tileh))) {
 					z += 8;
 				}
 			}
--- a/waypoint.c	Sat Jul 16 20:58:04 2005 +0000
+++ b/waypoint.c	Sat Jul 16 23:47:37 2005 +0000
@@ -152,6 +152,9 @@
  * @param x,y coordinates where waypoint will be built
  * @param p1 graphics for waypoint type, bit 8 signifies custom waypoint gfx (& 0x100)
  * @param p2 unused
+ *
+ * @todo When checking for the tile slope,
+ * distingush between "Flat land required" and "land sloped in wrong direction"
  */
 int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -175,7 +178,7 @@
 
 	tileh = GetTileSlope(tile, NULL);
 	if (tileh != 0) {
-		if (!_patches.build_on_slopes || tileh & 0x10 || !(tileh & (0x3 << dir)) || !(tileh & ~(0x3 << dir)))
+		if (!_patches.build_on_slopes || IsSteepTileh(tileh) || !(tileh & (0x3 << dir)) || !(tileh & ~(0x3 << dir)))
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}