Index: src/landscape.cpp
===================================================================
--- src/landscape.cpp (revision 27795)
+++ src/landscape.cpp (working copy)
@@ -992,6 +992,32 @@
}
/**
+ * Check whether a river could (logically) flow into a lock.
+ * @param tile the middle tile of a lock.
+ * @return true iff the water can be flowing into a lock.
+ */
+static bool FlowsLock(TileIndex tile)
+{
+ DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
+ if (dir == INVALID_DIAGDIR) return false;
+
+ int delta = TileOffsByDiagDir(dir);
+
+ int height_tile;
+ if (DistanceFromEdge(tile - delta) <= 1 || !(GetTileSlope(tile - 2 * delta, &height_tile) == SLOPE_FLAT) && height_tile != 0 ||
+ DistanceFromEdge(tile - 2 * delta) <= 1 || !(GetTileSlope(tile - 2 * delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT)), &height_tile) == SLOPE_FLAT) && height_tile != 0 ||
+ !(GetTileSlope(tile - 2 * delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT)), &height_tile) == SLOPE_FLAT) && height_tile != 0 ||
+ DistanceFromEdge(tile - 2 * delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT))) <= 1 || !(GetTileSlope(tile - 3 * delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT)), &height_tile) == SLOPE_FLAT) && height_tile != 0 ||
+ !(GetTileSlope(tile - 3 * delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT)), &height_tile) == SLOPE_FLAT) && height_tile != 0) return false;
+
+ if (DistanceFromEdge(tile + delta) <= 1 || !IsTileFlat(tile + delta + delta) ||
+ DistanceFromEdge(tile + delta + delta) <= 1 || !IsTileFlat(tile + delta + delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT))) ||
+ !IsTileFlat(tile + delta + delta + TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT)))) return false;
+
+ return true;
+}
+
+/**
* Check whether a river at begin could (logically) flow down to end.
* @param begin The origin of the flow.
* @param end The destination of the flow.
@@ -1008,9 +1034,9 @@
return heightEnd <= heightBegin &&
/* Slope either is inclined or flat; rivers don't support other slopes. */
- (slopeEnd == SLOPE_FLAT || IsInclinedSlope(slopeEnd)) &&
+ (slopeEnd == SLOPE_FLAT || (IsInclinedSlope(slopeEnd) && FlowsLock(end))) &&
/* Slope continues, then it must be lower... or either end must be flat. */
- ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || slopeBegin == SLOPE_FLAT);
+ ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || (slopeBegin == SLOPE_FLAT && GetTileMaxZ(end) == heightBegin));
}
/* AyStar callback for checking whether we reached our destination. */
@@ -1056,6 +1082,45 @@
MakeRiver(tile, Random());
/* Remove desert directly around the river tile. */
CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL);
+
+// /* Connect the water if a lock would be build on the inclined slope */
+// int height_tile;
+// Slope slope = GetTileSlope(path->node.tile, &height_tile);
+// if (IsInclinedSlope(slope)) {
+// DiagDirection dir = GetInclinedSlopeDirection(slope);
+// int delta_mid = TileOffsByDiagDir(dir);
+// int delta = TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT));
+// TileIndex tile_upper = path->node.tile + 2 * delta_mid;
+// TileIndex tile_upper_right = tile_upper + delta;
+// TileIndex tile_upper_right_far = tile_upper_right + delta_mid;
+// TileIndex tile_upper_left = tile_upper - delta;
+// TileIndex tile_upper_left_far = tile_upper_left + delta_mid;
+// TileIndex tile_lower = path->node.tile - 2 * delta_mid;
+// TileIndex tile_lower_right = tile_lower + delta;
+// TileIndex tile_lower_right_far = tile_lower_right - delta_mid;
+// TileIndex tile_lower_left = tile_lower - delta;
+// TileIndex tile_lower_left_far = tile_lower_left - delta_mid;
+
+// int height_tile_delta;
+// TileIndex tiles_lower[] = {tile_lower, tile_lower_right, tile_lower_right_far, tile_lower_left, tile_lower_left_far};
+// for (int i = 0; i < lengthof(tiles_lower); i++) {
+// if (!IsWaterTile(tiles_lower[i]) && (GetTileSlope(tiles_lower[i], &height_tile_delta) == SLOPE_FLAT) && height_tile_delta == height_tile) {
+// MakeRiver(tiles_lower[i], Random());
+// /* Remove desert directly around the river tile. */
+// CircularTileSearch(&tiles_lower[i], 5, RiverModifyDesertZone, NULL);
+// }
+// }
+//
+// TileIndex tiles_upper[] = {tile_upper, tile_upper_right, tile_upper_right_far, tile_upper_left, tile_upper_left_far};
+// for (int i = 0; i < lengthof(tiles_upper); i++) {
+// if (!IsWaterTile(tiles_upper[i]) && (GetTileSlope(tiles_upper[i], &height_tile_delta) == SLOPE_FLAT) && height_tile_delta == height_tile + 1) {
+// MakeRiver(tiles_upper[i], Random());
+// /* Remove desert directly around the river tile. */
+// CircularTileSearch(&tiles_upper[i], 5, RiverModifyDesertZone, NULL);
+// }
+// }
+// }
+
}
}
}