From 2359dce21bb77b5e05604d88b0c6e6d220bee5c2 Mon Sep 17 00:00:00 2001 From: Ashley Newson Date: Sat, 8 Nov 2025 16:59:35 +0000 Subject: [PATCH] Relax TilingPath constraints on segments that don't make immediate progress The TilingPath algorithm previously rejected placing segments that do not make immediate progress, unless they faced towards positive progress. However, there are cases in some mods where zero-progress segments that end facing towards neutral progress are needed to arrive at a tiling solution. This change allows these neutral progressions, so long as they aren't for single-point segments. --- OpenRA.Mods.Common/MapGenerator/TilingPath.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Common/MapGenerator/TilingPath.cs b/OpenRA.Mods.Common/MapGenerator/TilingPath.cs index 5feba7a985..74ae15ae07 100644 --- a/OpenRA.Mods.Common/MapGenerator/TilingPath.cs +++ b/OpenRA.Mods.Common/MapGenerator/TilingPath.cs @@ -358,7 +358,9 @@ namespace OpenRA.Mods.Common.MapGenerator // order for a transition to be allowed at all, it must satisfy some constraints: // // - It must not regress backward along the path (but no immediate progress is OK). - // - If it makes exactly zero progress, it must end facing towards increasing progress. + // - If it makes exactly zero progress, it must not end facing towards overall + // decreasing progress or strictly neutral progress (neither earliest or latest + // closest points differ). // - It must not deviate at any point in the segment beyond MaxDeviation from the path. // - It must not skip to much later path points (which may be within MaxDeviation). // @@ -738,7 +740,7 @@ namespace OpenRA.Mods.Common.MapGenerator lowProgressionAcc = Progress(lowProgress[point.X, point.Y], lowProgress[pointNext.X, pointNext.Y]); highProgressionAcc = Progress(highProgress[point.X, point.Y], highProgress[pointNext.X, pointNext.Y]); - if (lowProgressionAcc < 0 || highProgressionAcc < 0 || (lowProgressionAcc == 0 && highProgressionAcc == 0)) + if ((lowProgressionAcc <= 0 && highProgressionAcc <= 0) || lowProgressionAcc + highProgressionAcc < 0) return MaxCost; }