(svn r5363) Revert 5312, 5288, 5248, 3992, 3249, 3228
authortron
Sun, 25 Jun 2006 17:39:19 +0000
changeset 4067 ab047dec0733
parent 4066 108eb446f1ae
child 4068 0c8b374a8ceb
(svn r5363) Revert 5312, 5288, 5248, 3992, 3249, 3228
They were all aimed at fixing the terraform-into-tunnel problem, but introduced new sideeffects while doing so
clear_cmd.c
rail_cmd.c
tile.c
tile.h
--- a/clear_cmd.c	Sun Jun 25 13:42:37 2006 +0000
+++ b/clear_cmd.c	Sun Jun 25 17:39:19 2006 +0000
@@ -87,25 +87,48 @@
 	TerraformAddDirtyTile(ts, tile);
 }
 
-static int TerraformProc(TerraformerState *ts, TileIndex tile)
+static int TerraformProc(TerraformerState *ts, TileIndex tile, int mode)
 {
 	int r;
+	int32 ret;
 
 	assert(tile < MapSize());
 
-	if ((r = TerraformAllowTileProcess(ts, tile)) <= 0) return r;
+	if ((r=TerraformAllowTileProcess(ts, tile)) <= 0)
+		return r;
 
-	if (!IsTileType(tile, MP_RAILWAY)) {
-		int32 ret = DoCommand(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
+	if (IsTileType(tile, MP_RAILWAY)) {
+		static const TrackBits _railway_modes[] = { TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER, TRACK_BIT_RIGHT };
+		static const byte _railway_dangslopes[4] = {0xd, 0xe, 7, 0xb};
+		static const byte _railway_dangslopes2[4] = {0x2, 0x1, 0x8, 0x4};
 
-		if (CmdFailed(ret)) {
+		// Nothing could be built at the steep slope - this avoids a bug
+		// when you have a single diagonal track in one corner on a
+		// basement and then you raise/lower the other corner.
+		int tileh = GetTileSlope(tile, NULL) & 0xF;
+		if (tileh == _railway_dangslopes[mode] ||
+				tileh == _railway_dangslopes2[mode]) {
 			_terraform_err_tile = tile;
+			_error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
 			return -1;
 		}
 
-		ts->cost += ret;
+		// If we have a single diagonal track there, the other side of
+		// tile can be terraformed.
+		if (IsPlainRailTile(tile) && GetTrackBits(tile) == _railway_modes[mode]) {
+			return 0;
+		}
 	}
 
+	ret = DoCommand(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
+
+	if (ret == CMD_ERROR) {
+		_terraform_err_tile = tile;
+		return -1;
+	}
+
+	ts->cost += ret;
+
 	if (ts->tile_table_count >= 625) return -1;
 	ts->tile_table[ts->tile_table_count++] = tile;
 
@@ -132,10 +155,10 @@
 	nh = TerraformGetHeightOfTile(ts, tile);
 	if (nh < 0 || height == nh) return false;
 
-	if (TerraformProc(ts, tile) < 0) return false;
-	if (TerraformProc(ts, tile + TileDiffXY( 0, -1)) < 0) return false;
-	if (TerraformProc(ts, tile + TileDiffXY(-1, -1)) < 0) return false;
-	if (TerraformProc(ts, tile + TileDiffXY(-1,  0)) < 0) return false;
+	if (TerraformProc(ts, tile, 0) < 0) return false;
+	if (TerraformProc(ts, tile + TileDiffXY( 0, -1), 1) < 0) return false;
+	if (TerraformProc(ts, tile + TileDiffXY(-1, -1), 2) < 0) return false;
+	if (TerraformProc(ts, tile + TileDiffXY(-1,  0), 3) < 0) return false;
 
 	mod = ts->modheight;
 	count = ts->modheight_count;
@@ -237,42 +260,26 @@
 		}
 	}
 
-	{ /* Check if tunnel or track would take damage */
+	if (direction == -1) {
+		/* Check if tunnel would take damage */
 		int count;
 		TileIndex *ti = ts.tile_table;
 
 		for (count = ts.tile_table_count; count != 0; count--, ti++) {
-			uint a, b, c, d, min;
-			Slope s;
+			uint z, t;
 			TileIndex tile = *ti;
 
-			_terraform_err_tile = tile;
-
-			a = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0));
-			b = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0));
-			c = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1));
-			d = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1));
-
-			s = GetTileh(a, b, c, d, &min);
-
-			if (IsTileType(tile, MP_RAILWAY)) {
-				if (IsSteepSlope(s)) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
+			z = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0));
+			t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0));
+			if (t <= z) z = t;
+			t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1));
+			if (t <= z) z = t;
+			t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1));
+			if (t <= z) z = t;
 
-				if (IsPlainRailTile(tile)) {
-					/* If a piece of rail is on a foundation, prohibit any terraforming
-					 * of that tile. We do need to check this with the original slope, not
-					 * the would-be one. */
-					extern const TrackBits _valid_tileh_slopes[2][15];
-					TrackBits tb = GetTrackBits(tile);
-
-					if (GetRailFoundation(GetTileSlope(tile, NULL), tb) != 0) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
-					if (tb & ~_valid_tileh_slopes[0][s]) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
-				} else return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
+			if (IsTunnelInWay(tile, z * TILE_HEIGHT)) {
+				return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
 			}
-
-			if (direction == -1 && IsTunnelInWay(tile, min)) return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
-
-			_terraform_err_tile = 0;
 		}
 	}
 
--- a/rail_cmd.c	Sun Jun 25 13:42:37 2006 +0000
+++ b/rail_cmd.c	Sun Jun 25 17:39:19 2006 +0000
@@ -105,7 +105,7 @@
 }
 
 
-const TrackBits _valid_tileh_slopes[2][15] = {
+static const TrackBits _valid_tileh_slopes[][15] = {
 
 // set of normal ones
 {
--- a/tile.c	Sun Jun 25 13:42:37 2006 +0000
+++ b/tile.c	Sun Jun 25 17:39:19 2006 +0000
@@ -3,37 +3,14 @@
 #include "stdafx.h"
 #include "tile.h"
 
-/** Converts the heights of 4 corners into a tileh, and returns the minimum height of the tile
-  * @param n,w,e,s the four corners
-  * @param h uint pointer to write the height to
-  * @return the tileh
-*/
-Slope GetTileh(uint n, uint w, uint e, uint s, uint *h)
-{
-	uint min = n;
-	Slope r;
-
-	if (min >= w) min = w;
-	if (min >= e) min = e;
-	if (min >= s) min = s;
-
-	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;
-}
-
 Slope GetTileSlope(TileIndex tile, uint *h)
 {
 	uint a;
 	uint b;
 	uint c;
 	uint d;
+	uint min;
+	uint r;
 
 	assert(tile < MapSize());
 
@@ -42,12 +19,23 @@
 		return 0;
 	}
 
-	a = TileHeight(tile);
+	min = a = TileHeight(tile);
 	b = TileHeight(tile + TileDiffXY(1, 0));
+	if (min >= b) min = b;
 	c = TileHeight(tile + TileDiffXY(0, 1));
+	if (min >= c) min = c;
 	d = TileHeight(tile + TileDiffXY(1, 1));
+	if (min >= d) min = d;
 
-	return GetTileh(a, b, c, d, h);
+	r = SLOPE_FLAT;
+	if ((a -= min) != 0) r += (--a << 4) + SLOPE_N;
+	if ((c -= min) != 0) r += (--c << 4) + SLOPE_E;
+	if ((d -= min) != 0) r += (--d << 4) + SLOPE_S;
+	if ((b -= min) != 0) r += (--b << 4) + SLOPE_W;
+
+	if (h != NULL) *h = min * TILE_HEIGHT;
+
+	return r;
 }
 
 uint GetTileZ(TileIndex tile)
--- a/tile.h	Sun Jun 25 13:42:37 2006 +0000
+++ b/tile.h	Sun Jun 25 17:39:19 2006 +0000
@@ -27,7 +27,6 @@
 	TROPICZONE_RAINFOREST = 2,
 } TropicZone;
 
-Slope GetTileh(uint n, uint w, uint e, uint s, uint *h);
 Slope GetTileSlope(TileIndex tile, uint *h);
 uint GetTileZ(TileIndex tile);
 uint GetTileMaxZ(TileIndex tile);