Support PickAny templates in MultiBrushes

Allows PickAny templates to be used in MultiBrushes, which can be
painted with random selection. This avoids the need to define various
separate MultiBrushes for each tile combination.

Note that all combinations count as part of a single MultiBrush, which
may influence selection weighting.

This MultiBrush feature is not presently used in OpenRA's official
mods, but is useful for unofficial mods using more general PickAny
templates.
This commit is contained in:
Ashley Newson
2025-05-18 18:17:47 +01:00
committed by Gustas Kažukauskas
parent daf36769d6
commit 5c09d5d828
4 changed files with 84 additions and 29 deletions

View File

@@ -601,6 +601,7 @@ namespace OpenRA.Mods.Common.Traits
var repaintRandom = new MersenneTwister(random.Next());
var decorationRandom = new MersenneTwister(random.Next());
var decorationTilingRandom = new MersenneTwister(random.Next());
var pickAnyRandom = new MersenneTwister(random.Next());
TerrainTile PickTile(ushort tileType)
{
@@ -675,7 +676,7 @@ namespace OpenRA.Mods.Common.Traits
.OptimizeLoop();
var brush = beachPath.Tile(beachTilingRandom)
?? throw new MapGenerationException("Could not fit tiles for beach");
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile);
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile, pickAnyRandom);
tiledBeaches[i] = brush.Segment.Points.Select(vec => CPos.Zero + vec).ToArray();
foreach (var cvec in brush.Shape)
beachesShape.Add(CPos.Zero + cvec);
@@ -745,7 +746,7 @@ namespace OpenRA.Mods.Common.Traits
.OptimizeLoop();
var brush = cliffPath.Tile(cliffTilingRandom)
?? throw new MapGenerationException("Could not fit tiles for exterior circle cliffs");
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile);
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile, pickAnyRandom);
}
}
@@ -827,7 +828,7 @@ namespace OpenRA.Mods.Common.Traits
.OptimizeLoop();
var brush = cliffPath.Tile(cliffTilingRandom)
?? throw new MapGenerationException("Could not fit tiles for cliffs");
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile);
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile, pickAnyRandom);
}
}
}
@@ -1277,7 +1278,7 @@ namespace OpenRA.Mods.Common.Traits
var brush = path.Tile(roadTilingRandom)
?? throw new MapGenerationException("Could not fit tiles for roads");
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile);
brush.Paint(map, actorPlans, CPos.Zero, MultiBrush.Replaceability.Tile, pickAnyRandom);
}
}

View File

@@ -433,6 +433,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var (startType, endType) in terminalTypes)
{
var random = new MersenneTwister(RandomSeed);
var tilingPath = new TilingPath(
map,
points,
@@ -442,9 +443,9 @@ namespace OpenRA.Mods.Common.Traits
permittedTemplates);
tilingPath.Start.Direction = plan.AutoStart;
tilingPath.End.Direction = plan.AutoEnd;
var result = tilingPath.Tile(new MersenneTwister(RandomSeed));
var result = tilingPath.Tile(random);
if (result != null)
return result.ToEditorBlitSource(WorldRenderer);
return result.ToEditorBlitSource(WorldRenderer, random);
}
return null;