diff --git a/src/landscape.cpp b/src/landscape.cpp index a4b12f8..e0d01bf 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -1044,15 +1044,40 @@ static void River_GetNeighbours(AyStar *aystar, OpenListNode *current) } } +/** Callback to widen a river tile. */ +static bool RiverMakeWider(TileIndex tile, void *data) +{ + if (IsValidTile(tile) && !IsWaterTile(tile) && GetTileSlope(tile) == GetTileSlope(*(TileIndex *)data)) { + MakeRiver(tile, Random()); + /* Remove desert directly around the river tile. */ + TileIndex cur_tile = tile; + CircularTileSearch(&cur_tile, 5, RiverModifyDesertZone, NULL); + } + return false; +} + /* AyStar callback when an route has been found. */ static void River_FoundEndNode(AyStar *aystar, OpenListNode *current) { + /* Count river length. */ + uint length = 0; for (PathNode *path = ¤t->path; path != NULL; path = path->parent) { + length++; + } + + uint cur_pos = 0; + for (PathNode *path = ¤t->path; path != NULL; path = path->parent, cur_pos++) { TileIndex tile = path->node.tile; if (!IsWaterTile(tile)) { MakeRiver(tile, Random()); - /* Remove desert directly around the river tile. */ - CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL); + /* Widen river depending on how far we are away from the source. */ + uint radius = min((length - cur_pos) / 15u, 3u); + if (radius > 1) { + CircularTileSearch(&tile, radius + RandomRange(1), RiverMakeWider, (void *)&path->node.tile); + } else { + /* Remove desert directly around the river tile. */ + CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL); + } } } }