water_cmd.c
changeset 3977 513433ebd092
parent 3940 8965b9bfaabc
child 4077 d4d440dd8925
--- a/water_cmd.c	Wed Jun 07 18:41:58 2006 +0000
+++ b/water_cmd.c	Wed Jun 07 19:35:21 2006 +0000
@@ -20,7 +20,7 @@
 #include "train.h"
 #include "water_map.h"
 
-static const SpriteID _water_shore_sprites[] = {
+const SpriteID _water_shore_sprites[15] = {
 	0,
 	SPR_SHORE_TILEH_1,
 	SPR_SHORE_TILEH_2,
@@ -65,8 +65,6 @@
 	if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
 		return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
 
-	if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
-
 	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 	if (CmdFailed(ret)) return CMD_ERROR;
 	ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -141,12 +139,6 @@
 		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 	}
 
-	if ((MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) ||
-	    (MayHaveBridgeAbove(tile - delta) && IsBridgeAbove(tile - delta)) ||
-	    (MayHaveBridgeAbove(tile + delta) && IsBridgeAbove(tile + delta))) {
-		return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
-	}
-
 	if (flags & DC_EXEC) {
 		MakeLock(tile, _current_player, dir);
 		MarkTileDirtyByTile(tile);
@@ -237,8 +229,6 @@
 
 	cost = 0;
 	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
-		int32 ret;
-
 		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) {
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 		}
@@ -246,16 +236,38 @@
 		// can't make water of water!
 		if (IsTileType(tile, MP_WATER)) continue;
 
-		ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
-		if (CmdFailed(ret)) return ret;
-		cost += ret;
+		/* is middle piece of a bridge? */
+		if (IsBridgeTile(tile) && IsBridgeMiddle(tile)) {
+			if (IsTransportUnderBridge(tile)) {
+				return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
+			}
+
+			if (IsWaterUnderBridge(tile)) return_cmd_error(STR_1007_ALREADY_BUILT);
+
+			if (flags & DC_EXEC) {
+				if (TileHeight(tile) == 0) {
+					SetWaterUnderBridge(tile);
+				} else {
+					SetCanalUnderBridge(tile, _current_player);
+				}
+			}
+		} else {
+			/* no bridge, try to clear it. */
+			int32 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+
+			if (CmdFailed(ret)) return ret;
+			cost += ret;
+
+			if (flags & DC_EXEC) {
+				if (TileHeight(tile) == 0) {
+					MakeWater(tile);
+				} else {
+					MakeCanal(tile, _current_player);
+				}
+			}
+		}
 
 		if (flags & DC_EXEC) {
-			if (TileHeight(tile) == 0) {
-				MakeWater(tile);
-			} else {
-				MakeCanal(tile, _current_player);
-			}
 			MarkTileDirtyByTile(tile);
 			MarkTilesAroundDirty(tile);
 		}
@@ -340,9 +352,17 @@
 static bool IsWateredTile(TileIndex tile)
 {
 	switch (GetTileType(tile)) {
-		case MP_WATER:   return !IsCoast(tile);
-		case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy_(tile);
-		default:         return false;
+		case MP_WATER:
+			return !IsCoast(tile);
+
+		case MP_STATION:
+			return IsOilRig(tile) || IsDock(tile) || IsBuoy_(tile);
+
+		case MP_TUNNELBRIDGE:
+			return IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile);
+
+		default:
+			return false;
 	}
 }
 
@@ -418,13 +438,11 @@
 		case WATER_CLEAR:
 			DrawGroundSprite(SPR_FLAT_WATER_TILE);
 			if (ti->z != 0) DrawCanalWater(ti->tile);
-			DrawBridgeMiddle(ti);
 			break;
 
 		case WATER_COAST:
 			assert(!IsSteepSlope(ti->tileh));
 			DrawGroundSprite(_water_shore_sprites[ti->tileh]);
-			DrawBridgeMiddle(ti);
 			break;
 
 		case WATER_LOCK: {
@@ -534,10 +552,27 @@
 				}
 				break;
 
+			case MP_TUNNELBRIDGE:
+				if (IsBridge(target) && IsBridgeMiddle(target) && IsClearUnderBridge(target)) {
+					SetWaterUnderBridge(target);
+					MarkTileDirtyByTile(target);
+				}
+				break;
+
 			default:
 				break;
 		}
 	} else {
+		if (IsBridgeTile(target) && IsBridgeMiddle(target)) {
+			if (IsWaterUnderBridge(target) ||
+					(IsTransportUnderBridge(target) && GetTransportTypeUnderBridge(target) == TRANSPORT_WATER)) { // XXX does this happen at all?
+				return;
+			}
+			SetWaterUnderBridge(target);
+			MarkTileDirtyByTile(target);
+			return;
+		}
+
 		_current_player = OWNER_WATER;
 		{
 			Vehicle *v = FindVehicleOnTileZ(target, 0);