diff --git a/src/landscape.cpp b/src/landscape.cpp index adc5102..3e72968 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -1034,15 +1034,29 @@ static void River_GetNeighbours(AyStar *aystar, OpenListNode *current) } } +/** */ +static bool PlaceRiverTiles(TileIndex tile, void *data) +{ + if (!IsWaterTile(tile)) { + Slope s = GetTileSlope(tile, NULL); + if (s == SLOPE_FLAT || s == (Slope)(size_t)data) { + MakeRiver(tile, Random()); + CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL); + } + } + return false; +} + /* AyStar callback when an route has been found. */ static void River_FoundEndNode(AyStar *aystar, OpenListNode *current) { + uint width = aystar->user_data[0] / 5 + 1; for (PathNode *path = ¤t->path; path != NULL; path = path->parent) { TileIndex tile = path->node.tile; - if (!IsWaterTile(tile)) { - MakeRiver(tile, Random()); - /* Remove desert directly around the river tile. */ - CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL); + if (width > 1) { + CircularTileSearch(&tile, width, PlaceRiverTiles, (void *)GetTileSlope(tile, NULL)); + } else { + PlaceRiverTiles(tile, (void *)GetTileSlope(tile, NULL)); } } } @@ -1065,7 +1079,7 @@ static uint River_Hash(uint tile, uint dir) * @param begin The begin of the river. * @param end The end of the river. */ -static void BuildRiver(TileIndex begin, TileIndex end) +static void BuildRiver(TileIndex begin, TileIndex end, uint section) { AyStar finder; MemSetT(&finder, 0); @@ -1075,6 +1089,7 @@ static void BuildRiver(TileIndex begin, TileIndex end) finder.EndNodeCheck = River_EndNodeCheck; finder.FoundEndNode = River_FoundEndNode; finder.user_target = &end; + finder.user_data[0] = section; finder.Init(River_Hash, 1 << RIVER_HASH_SIZE); @@ -1093,7 +1108,7 @@ static void BuildRiver(TileIndex begin, TileIndex end) * @param begin The begin point we are looking from; somewhere down hill from the spring. * @return True iff a river could/has been built, otherwise false. */ -static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin) +static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin, uint section) { uint height = TileHeight(begin); if (IsWaterTile(begin)) return DistanceManhattan(spring, begin) > _settings_game.game_creation.min_river_length; @@ -1130,7 +1145,7 @@ static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin) if (found) { /* Flow further down hill. */ - found = FlowRiver(marks, spring, end); + found = FlowRiver(marks, spring, end, section + 1); } else if (count > 10) { /* Maybe we can make a lake. Find the Nth of the considered tiles. */ TileIndex lakeCenter = 0; @@ -1160,7 +1175,7 @@ static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin) } } - if (found) BuildRiver(begin, end); + if (found) BuildRiver(begin, end, section); return found; } @@ -1181,7 +1196,7 @@ static void CreateRivers() for (int tries = 0; tries < 128; tries++) { TileIndex t = RandomTile(); if (!CircularTileSearch(&t, 8, FindSpring, NULL)) continue; - if (FlowRiver(marks, t, t)) break; + if (FlowRiver(marks, t, t, 0)) break; } }