(svn r11984) -Fix: Also draw corner shores under rail tracks.
authorfrosch
Fri, 25 Jan 2008 16:51:35 +0000
changeset 8910 b261b6cb9b21
parent 8909 fa15e9afad2f
child 8911 06c7912f14b9
(svn r11984) -Fix: Also draw corner shores under rail tracks.
docs/landscape.html
src/rail_cmd.cpp
src/rail_map.h
src/water_cmd.cpp
--- a/docs/landscape.html	Fri Jan 25 15:47:58 2008 +0000
+++ b/docs/landscape.html	Fri Jan 25 16:51:35 2008 +0000
@@ -263,7 +263,7 @@
 
          <tr>
           <td nowrap valign=top><tt>D</tt>&nbsp; </td>
-          <td align=left>on grass with fence and water on the lower halftile</td>
+          <td align=left>on grass with fence and shore or water on the free halftile</td>
          </tr>
         </table>
        </li>
--- a/src/rail_cmd.cpp	Fri Jan 25 15:47:58 2008 +0000
+++ b/src/rail_cmd.cpp	Fri Jan 25 16:51:35 2008 +0000
@@ -396,6 +396,7 @@
 			/* FALLTHROUGH */
 
 		default:
+			/* Will there be flat water on the lower halftile? */
 			bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
 
 			ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
@@ -486,7 +487,9 @@
 				owner = GetTileOwner(tile);
 				present ^= trackbit;
 				if (present == 0) {
-					if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
+					Slope tileh = GetTileSlope(tile, NULL);
+					/* If there is flat water on the lower halftile, convert the tile to shore so the water remains */
+					if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)) {
 						MakeShore(tile);
 					} else {
 						DoClearSquare(tile);
@@ -561,6 +564,15 @@
 			SetRailGroundType(t, RAIL_GROUND_WATER);
 			MarkTileDirtyByTile(t);
 		}
+	} else {
+		/* Make shore on steep slopes and 'three-corners-raised'-slopes. */
+		if (ApplyFoundationToSlope(GetRailFoundation(tileh, rail_bits), &tileh) == 0) {
+			if (IsSteepSlope(tileh) || IsSlopeWithThreeCornersRaised(tileh)) {
+				flooded = true;
+				SetRailGroundType(t, RAIL_GROUND_WATER);
+				MarkTileDirtyByTile(t);
+			}
+		}
 	}
 	return flooded;
 }
@@ -1354,7 +1366,9 @@
 	switch (GetRailTileType(tile)) {
 		case RAIL_TILE_SIGNALS:
 		case RAIL_TILE_NORMAL: {
-			bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER);
+			Slope tileh = GetTileSlope(tile, NULL);
+			/* Is there flat water on the lower halftile, that gets cleared expensively? */
+			bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh));
 
 			TrackBits tracks = GetTrackBits(tile);
 			while (tracks != TRACK_BIT_NONE) {
@@ -1546,8 +1560,16 @@
 		case RAIL_GROUND_FENCE_VERT2:  DrawTrackFence_NS_2(ti);  break;
 		case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti);  break;
 		case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti);  break;
-		case RAIL_GROUND_WATER:
-			switch (GetHalftileSlopeCorner(ti->tileh)) {
+		case RAIL_GROUND_WATER: {
+			Corner track_corner;
+			if (IsHalftileSlope(ti->tileh)) {
+				/* Steep slope or one-corner-raised slope with halftile foundation */
+				track_corner = GetHalftileSlopeCorner(ti->tileh);
+			} else {
+				/* Three-corner-raised slope */
+				track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
+			}
+			switch (track_corner) {
 				case CORNER_W: DrawTrackFence_NS_1(ti); break;
 				case CORNER_S: DrawTrackFence_WE_2(ti); break;
 				case CORNER_E: DrawTrackFence_NS_2(ti); break;
@@ -1555,6 +1577,7 @@
 				default: NOT_REACHED();
 			}
 			break;
+		}
 		default: break;
 	}
 }
@@ -1567,6 +1590,15 @@
  */
 static void DrawTrackBits(TileInfo* ti, TrackBits track)
 {
+	/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
+	static const int INF = 1000; // big number compared to tilesprite size
+	static const SubSprite _halftile_sub_sprite[4] = {
+		{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
+		{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
+		{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
+		{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
+	};
+
 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 	RailGroundType rgt = GetRailGroundType(ti->tile);
 	Foundation f = GetRailFoundation(ti->tileh, track);
@@ -1585,13 +1617,19 @@
 
 	SpriteID image;
 	SpriteID pal = PAL_NONE;
+	const SubSprite *sub = NULL;
 	bool junction = false;
 
 	/* Select the sprite to use. */
 	if (track == 0) {
 		/* Clear ground (only track on halftile foundation) */
 		if (rgt == RAIL_GROUND_WATER) {
-			image = SPR_FLAT_WATER_TILE;
+			if (IsSteepSlope(ti->tileh)) {
+				DrawShoreTile(ti->tileh);
+				image = 0;
+			} else {
+				image = SPR_FLAT_WATER_TILE;
+			}
 		} else {
 			switch (rgt) {
 				case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
@@ -1628,12 +1666,18 @@
 		switch (rgt) {
 			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
-			case RAIL_GROUND_WATER:      NOT_REACHED();
+			case RAIL_GROUND_WATER: {
+				/* three-corner-raised slope */
+				DrawShoreTile(ti->tileh);
+				Corner track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
+				sub = &(_halftile_sub_sprite[track_corner]);
+				break;
+			}
 			default: break;
 		}
 	}
 
-	DrawGroundSprite(image, pal);
+	if (image != 0) DrawGroundSprite(image, pal, sub);
 
 	/* Draw track pieces individually for junction tiles */
 	if (junction) {
@@ -1657,15 +1701,6 @@
 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
 			default: break;
 		}
-
-		static const int INF = 1000; // big number compared to tilesprite size
-		static const SubSprite _halftile_sub_sprite[4] = {
-			{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
-			{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
-			{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
-			{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
-		};
-
 		DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner]));
 	}
 }
@@ -2216,7 +2251,8 @@
 	CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
 	/* Make the ground dirty, if surface slope has changed */
 	if (tileh_old != tileh_new) {
-		if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water);
+		/* If there is flat water on the lower halftile add the cost for clearing it */
+		if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)) cost.AddCost(_price.clear_water);
 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
 	}
 	return  cost;
@@ -2228,7 +2264,8 @@
 	Slope tileh_old = GetTileSlope(tile, &z_old);
 	if (IsPlainRailTile(tile)) {
 		TrackBits rail_bits = GetTrackBits(tile);
-		bool was_water = GetRailGroundType(tile) == RAIL_GROUND_WATER;
+		/* Is there flat water on the lower halftile, that must be cleared expensively? */
+		bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old));
 
 		_error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
 
--- a/src/rail_map.h	Fri Jan 25 15:47:58 2008 +0000
+++ b/src/rail_map.h	Fri Jan 25 16:51:35 2008 +0000
@@ -408,7 +408,7 @@
 	RAIL_GROUND_FENCE_HORIZ1 = 10, ///< Grass with a fence at the southern side
 	RAIL_GROUND_FENCE_HORIZ2 = 11, ///< Grass with a fence at the northern side
 	RAIL_GROUND_ICE_DESERT   = 12, ///< Icy or sandy
-	RAIL_GROUND_WATER        = 13, ///< Grass with a fence and water on the lower halftile
+	RAIL_GROUND_WATER        = 13, ///< Grass with a fence and shore or water on the free halftile
 };
 
 static inline void SetRailGroundType(TileIndex t, RailGroundType rgt)
--- a/src/water_cmd.cpp	Fri Jan 25 15:47:58 2008 +0000
+++ b/src/water_cmd.cpp	Fri Jan 25 16:51:35 2008 +0000
@@ -94,9 +94,18 @@
 
 	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
 		TileIndex neighbour = TileAddByDiagDir(t, dir);
-		if (IsTileType(neighbour, MP_WATER)) {
-			has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER);
-			has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER);
+		switch (GetTileType(neighbour)) {
+			case MP_WATER:
+				has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER);
+				has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER);
+				break;
+
+			case MP_RAILWAY:
+				/* Shore or flooded halftile */
+				has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER);
+				break;
+
+			default: break;
 		}
 	}
 	if (has_canal || !has_water) {
@@ -414,7 +423,13 @@
 			if (!IsCoast(tile)) return true;
 			return IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL));
 
-		case MP_RAILWAY:  return GetRailGroundType(tile) == RAIL_GROUND_WATER;
+		case MP_RAILWAY:
+			if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
+				assert(IsPlainRailTile(tile));
+				return IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL));
+			}
+			return false;
+
 		case MP_STATION:  return IsOilRig(tile) || IsDock(tile) || IsBuoy(tile);
 		case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
 		default:          return false;
@@ -781,7 +796,7 @@
 static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
 {
 	/* FLOOD_ACTIVE:  'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, rail with flooded halftile
-	 * FLOOD_DRYUP:   coast with more than one corner raised
+	 * FLOOD_DRYUP:   coast with more than one corner raised, coast with rail-track
 	 * FLOOD_PASSIVE: oilrig, dock, water-industries
 	 * FLOOD_NONE:    canals, rivers, everything else
 	 */
@@ -795,7 +810,10 @@
 			}
 
 		case MP_RAILWAY:
-			return ((GetRailGroundType(tile) == RAIL_GROUND_WATER) ? FLOOD_ACTIVE : FLOOD_NONE);
+			if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
+				return (IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL)) ? FLOOD_ACTIVE : FLOOD_DRYUP);
+			}
+			return FLOOD_NONE;
 
 		case MP_STATION:
 			if (IsSeaBuoyTile(tile)) return FLOOD_ACTIVE;
@@ -878,12 +896,35 @@
  */
 static void DoDryUp(TileIndex tile)
 {
-	assert(IsTileType(tile, MP_WATER) && IsCoast(tile));
 	_current_player = OWNER_WATER;
 
-	if (CmdSucceeded(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
-		MakeClear(tile, CLEAR_GRASS, 3);
-		MarkTileDirtyByTile(tile);
+	switch (GetTileType(tile)) {
+		case MP_RAILWAY:
+			assert(IsPlainRailTile(tile));
+			assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
+
+			RailGroundType new_ground;
+			switch (GetTrackBits(tile)) {
+				case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
+				case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
+				case TRACK_BIT_LEFT:  new_ground = RAIL_GROUND_FENCE_VERT1;  break;
+				case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2;  break;
+				default: NOT_REACHED();
+			}
+			SetRailGroundType(tile, new_ground);
+			MarkTileDirtyByTile(tile);
+			break;
+
+		case MP_WATER:
+			assert(IsCoast(tile));
+
+			if (CmdSucceeded(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
+				MakeClear(tile, CLEAR_GRASS, 3);
+				MarkTileDirtyByTile(tile);
+			}
+			break;
+
+		default: NOT_REACHED();
 	}
 
 	_current_player = OWNER_NONE;