Add CnC map generator support

Adds map generator support for CnC (all tilesets), largely on par with
RA.

Most tilesets do not have a complete set of beach templates and
therefore do not support terrain settings involving water. DESERT is the
only tileset supporting water. Unlike in RA, water is not playable space
in CnC (no naval units), so only terrain settings with small bodies of
water are available.

Most changes are configuration (tileset and map generator config), with
just a small number of code changes.
This commit is contained in:
Ashley Newson
2025-01-08 23:08:28 +00:00
committed by Gustas
parent bdc50899de
commit 2126f3c5a2
13 changed files with 4881 additions and 18 deletions

View File

@@ -174,6 +174,8 @@ namespace OpenRA.Mods.Common.Traits
public readonly IReadOnlyList<MultiBrush> ForestObstacles;
[FieldLoader.Ignore]
public readonly IReadOnlyList<MultiBrush> UnplayableObstacles;
[FieldLoader.Ignore]
public readonly IReadOnlyDictionary<ushort, IReadOnlyList<MultiBrush>> RepaintTiles;
[FieldLoader.Ignore]
public readonly IReadOnlyDictionary<string, ResourceTypeInfo> ResourceTypes;
@@ -221,6 +223,16 @@ namespace OpenRA.Mods.Common.Traits
TemplatedTerrainInfo = Map.Rules.TerrainInfo as ITemplatedTerrainInfo;
ForestObstacles = MultiBrush.LoadCollection(map, my.NodeWithKey("ForestObstacles").Value.Value);
UnplayableObstacles = MultiBrush.LoadCollection(map, my.NodeWithKey("UnplayableObstacles").Value.Value);
RepaintTiles = my.NodeWithKeyOrDefault("RepaintTiles")?.Value.ToDictionary(
k =>
{
if (Exts.TryParseUshortInvariant(k, out var tile))
return tile;
else
throw new YamlException($"RepaintTile {k} is not a ushort");
},
v => MultiBrush.LoadCollection(map, v.Value) as IReadOnlyList<MultiBrush>);
RepaintTiles ??= ImmutableDictionary<ushort, IReadOnlyList<MultiBrush>>.Empty;
ResourceTypes = map.Rules.Actors[SystemActors.World].TraitInfoOrDefault<ResourceLayerInfo>().ResourceTypes;
if (!ResourceTypes.TryGetValue(my.NodeWithKey("DefaultResource").Value.Value, out DefaultResource))
@@ -559,6 +571,7 @@ namespace OpenRA.Mods.Common.Traits
var expansionRandom = new MersenneTwister(random.Next());
var buildingRandom = new MersenneTwister(random.Next());
var topologyRandom = new MersenneTwister(random.Next());
var repaintRandom = new MersenneTwister(random.Next());
TerrainTile PickTile(ushort tileType)
{
@@ -1601,6 +1614,19 @@ namespace OpenRA.Mods.Common.Traits
}
}
// Cosmetically repaint tiles
foreach (var (tile, collection) in param.RepaintTiles.OrderBy(kv => kv.Key))
{
var replace = new CellLayer<MultiBrush.Replaceability>(map);
foreach (var mpos in replace.CellRegion.MapCoords)
replace[mpos] =
map.Tiles[mpos].Type == tile
? MultiBrush.Replaceability.Any
: MultiBrush.Replaceability.None;
MultiBrush.PaintArea(map, actorPlans, replace, collection, repaintRandom);
}
map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml();
map.ActorDefinitions = actorPlans
.Select((plan, i) => new MiniYamlNode($"Actor{i}", plan.Reference.Save()))