From d43fad56845130043cde1ae335a03f36fb60673f Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:01:01 +0000 Subject: [PATCH] Fix #10452: Support partially built rivers This is a workaround for river disconnection caused by RiverMakeWider terraform and/or AyStar being unable to find a path for one of the segments. Instead of jumping into building the next river segment uphill, it just stops at the point of disconnect. --- src/landscape.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/landscape.cpp b/src/landscape.cpp index 6fb980657c..2c27e072f1 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -1284,8 +1284,9 @@ static void River_FoundEndNode(AyStar *aystar, PathNode *current) * @param end The end of the river. * @param spring The springing point of the river. * @param main_river Whether the current river is a big river that others flow into. + * @return true if the river is successfully built, otherwise false. */ -static void BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool main_river) +static bool BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool main_river) { River_UserData user_data = { spring, main_river }; @@ -1302,7 +1303,7 @@ static void BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool ma start.tile = begin; start.td = INVALID_TRACKDIR; finder.AddStartNode(&start, 0); - finder.Main(); + return finder.Main() == AyStarStatus::FoundEndNode; } /** @@ -1312,8 +1313,9 @@ static void BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool ma * @param min_river_length The minimum length for the river. * @return First element: True iff a river could/has been built, otherwise false; second element: River ends at sea. */ -static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint min_river_length) +static std::tuple FlowRiver(TileIndex &spring, TileIndex begin, uint min_river_length) { + const TileIndex original_spring = spring; uint height_begin = TileHeight(begin); if (IsWaterTile(begin)) { @@ -1383,7 +1385,13 @@ static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint } marks.clear(); - if (found) BuildRiver(begin, end, spring, main_river); + if (found && spring == original_spring) { + /* This may end being a partially built river. Update the spring location. */ + if (!BuildRiver(begin, end, spring, main_river)) { + spring = end; + } + } + return { found, main_river }; }