diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorBlit.cs b/OpenRA.Mods.Common/EditorBrushes/EditorBlit.cs
index e31313eab6..71bca90ffe 100644
--- a/OpenRA.Mods.Common/EditorBrushes/EditorBlit.cs
+++ b/OpenRA.Mods.Common/EditorBrushes/EditorBlit.cs
@@ -12,6 +12,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
namespace OpenRA.Mods.Common.EditorBrushes
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
readonly MapBlitFilters blitFilters;
readonly IResourceLayer resourceLayer;
readonly EditorActorLayer editorActorLayer;
- readonly EditorBlitSource blitSource;
+ readonly EditorBlitSource commitBlitSource;
readonly EditorBlitSource revertBlitSource;
readonly CPos blitPosition;
readonly Map map;
@@ -56,30 +57,39 @@ namespace OpenRA.Mods.Common.EditorBrushes
{
this.blitFilters = blitFilters;
this.resourceLayer = resourceLayer;
- this.blitSource = blitSource;
this.blitPosition = blitPosition;
this.editorActorLayer = editorActorLayer;
this.map = map;
this.respectBounds = respectBounds;
var blitSize = blitSource.CellRegion.BottomRight - blitSource.CellRegion.TopLeft;
+
+ // Only include into the revert blit stuff which would be modified by the main blit.
+ var mask = GetBlitSourceMask(
+ blitSource, blitPosition - blitSource.CellRegion.TopLeft);
+
+ commitBlitSource = blitSource;
revertBlitSource = CopyRegionContents(
map,
editorActorLayer,
resourceLayer,
new CellRegion(map.Grid.Type, blitPosition, blitPosition + blitSize),
- blitFilters);
+ blitFilters,
+ mask);
}
///
/// Returns an EditorBlitSource containing the map contents for a given region.
+ /// If a mask is supplied, only tiles and actors (fully or partially) overlapping the mask
+ /// are included in the EditorBlitSource.
///
public static EditorBlitSource CopyRegionContents(
Map map,
EditorActorLayer editorActorLayer,
IResourceLayer resourceLayer,
CellRegion region,
- MapBlitFilters blitFilters)
+ MapBlitFilters blitFilters,
+ IReadOnlySet mask = null)
{
var mapTiles = map.Tiles;
var mapHeight = map.Height;
@@ -90,7 +100,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
foreach (var cell in region.CellCoords)
{
- if (!mapTiles.Contains(cell))
+ if (!mapTiles.Contains(cell) || (mask != null && !mask.Contains(cell)))
continue;
tiles.Add(
@@ -103,13 +113,15 @@ namespace OpenRA.Mods.Common.EditorBrushes
if (blitFilters.HasFlag(MapBlitFilters.Actors))
foreach (var preview in editorActorLayer.PreviewsInCellRegion(region.CellCoords))
- previews.TryAdd(preview.ID, preview);
+ if (mask == null || preview.Footprint.Keys.Any(mask.Contains))
+ previews.TryAdd(preview.ID, preview);
return new EditorBlitSource(region, previews, tiles);
}
- void Blit(EditorBlitSource source, bool isRevert)
+ void Blit(bool isRevert)
{
+ var source = isRevert ? revertBlitSource : commitBlitSource;
var blitPos = isRevert ? source.CellRegion.TopLeft : blitPosition;
var blitVec = blitPos - source.CellRegion.TopLeft;
var blitSize = source.CellRegion.BottomRight - source.CellRegion.TopLeft;
@@ -118,8 +130,25 @@ namespace OpenRA.Mods.Common.EditorBrushes
if (blitFilters.HasFlag(MapBlitFilters.Actors))
{
// Clear any existing actors in the paste cells.
- foreach (var regionActor in editorActorLayer.PreviewsInCellRegion(blitRegion.CellCoords).ToList())
- editorActorLayer.Remove(regionActor);
+ var regionActors = editorActorLayer.PreviewsInCellRegion(blitRegion.CellCoords).ToList();
+
+ // revertBlitSource's mask may be a superset of the commitBlitSource's mask if
+ // - Its a sparse blit; and
+ // - The revert actors removed by the commit are partially outside of the commit mask.
+ // Otherwise, it's a (practically) equal set. (Subject to map bounds.)
+ //
+ // This implies that:
+ // - commitBlitSource's mask will overlap all commit actors.
+ // - revertBlitSource's mask will overlap all revert actors.
+ // - commitBlitSource's mask will overlap all and no more than the revert actors.
+ // - revertBlitSource's mask will overlap all revert actors BUT MAY OVERLAP MORE!
+ //
+ // This means we use the commit mask, not the revert one.
+ var commitBlitVec = blitPosition - commitBlitSource.CellRegion.TopLeft;
+ var mask = GetBlitSourceMask(commitBlitSource, commitBlitVec);
+ foreach (var regionActor in regionActors)
+ if (regionActor.Footprint.Any(kv => mask.Contains(kv.Key)))
+ editorActorLayer.Remove(regionActor);
}
foreach (var tileKeyValuePair in source.Tiles)
@@ -178,12 +207,104 @@ namespace OpenRA.Mods.Common.EditorBrushes
}
}
- public void Commit() => Blit(blitSource, false);
- public void Revert() => Blit(revertBlitSource, true);
+ public static IEnumerable PreviewBlitSource(
+ EditorBlitSource blitSource,
+ MapBlitFilters filters,
+ CVec offset,
+ WorldRenderer wr)
+ {
+ var world = wr.World;
+ var map = world.Map;
+
+ var terrainRenderer = world.WorldActor.Trait();
+ var resourceRenderers = world.WorldActor.TraitsImplementing().ToArray();
+
+ var wOffset = map.CenterOfCell(CPos.Zero + offset) - map.CenterOfCell(CPos.Zero);
+
+ if (filters.HasFlag(MapBlitFilters.Terrain))
+ {
+ foreach (var (cpos, tile) in blitSource.Tiles)
+ {
+ var preview =
+ terrainRenderer.RenderPreview(
+ wr,
+ tile.TerrainTile,
+ map.CenterOfCell(cpos + offset));
+ foreach (var renderable in preview)
+ yield return renderable;
+ }
+ }
+
+ if (filters.HasFlag(MapBlitFilters.Resources))
+ {
+ foreach (var (cpos, tile) in blitSource.Tiles)
+ {
+ if (tile.ResourceLayerContents == null || tile.ResourceLayerContents.Value.Type == null)
+ continue;
+
+ var preview = resourceRenderers
+ .SelectMany(r => r.RenderPreview(
+ wr,
+ tile.ResourceLayerContents.Value.Type,
+ map.CenterOfCell(cpos + offset)));
+ foreach (var renderable in preview)
+ yield return renderable;
+ }
+ }
+
+ if (filters.HasFlag(MapBlitFilters.Actors))
+ {
+ foreach (var (_, editorActorPreview) in blitSource.Actors)
+ {
+ var preview = editorActorPreview.RenderWithOffset(wOffset);
+ foreach (var renderable in preview)
+ yield return renderable;
+ }
+ }
+ }
+
+ ///
+ /// Find the set of cells within an EditorBlitSource that are actually occupied by a
+ /// BlitTile or actor. Note that all tiles must be inside the CellRegion, and actors must
+ /// be at least partially inside the CellRegion. If an actor partially lies outside of the
+ /// CellRegion, only cells within the CellRegion are included in the output set.
+ ///
+ static HashSet GetBlitSourceMask(
+ EditorBlitSource blitSource,
+ CVec offset)
+ {
+ var mask = new HashSet();
+
+ foreach (var (cpos, _) in blitSource.Tiles)
+ {
+ if (!blitSource.CellRegion.Contains(cpos))
+ throw new ArgumentException("EditorBlitSource contains a BlitTile outside of its CellRegion");
+ mask.Add(cpos + offset);
+ }
+
+ foreach (var (_, editorActorPreview) in blitSource.Actors)
+ {
+ var anyContained = false;
+ foreach (var cpos in editorActorPreview.Footprint.Keys)
+ if (blitSource.CellRegion.Contains(cpos))
+ {
+ mask.Add(cpos + offset);
+ anyContained = true;
+ }
+
+ if (!anyContained)
+ throw new ArgumentException("EditorBlitSource contains an actor entirely outside of its CellRegion");
+ }
+
+ return mask;
+ }
+
+ public void Commit() => Blit(false);
+ public void Revert() => Blit(true);
public int TileCount()
{
- return blitSource.Tiles.Count;
+ return commitBlitSource.Tiles.Count;
}
}
}
diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorTilingPathBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorTilingPathBrush.cs
new file mode 100644
index 0000000000..841d4f92b1
--- /dev/null
+++ b/OpenRA.Mods.Common/EditorBrushes/EditorTilingPathBrush.cs
@@ -0,0 +1,371 @@
+#region Copyright & License Information
+/*
+ * Copyright (c) The OpenRA Developers and Contributors
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.EditorBrushes;
+using OpenRA.Mods.Common.Graphics;
+using OpenRA.Mods.Common.MapGenerator;
+using OpenRA.Mods.Common.Traits;
+using OpenRA.Primitives;
+
+namespace OpenRA.Mods.Common.Widgets
+{
+ public sealed class EditorTilingPathBrush : IEditorBrush
+ {
+ readonly TilingPathTool tool;
+ readonly WorldRenderer worldRenderer;
+ readonly EditorActionManager editorActionManager;
+
+ MouseInput? startingMouseInput = null;
+ bool isDragging = false;
+ TilingPathTool.PathPlan previewPlan = null;
+
+ public EditorTilingPathBrush(TilingPathTool tool)
+ {
+ this.tool = tool;
+ worldRenderer = tool.WorldRenderer;
+ editorActionManager = worldRenderer.World.WorldActor.Trait();
+ }
+
+ public bool HandleMouseInput(MouseInput mouseInput)
+ {
+ if (mouseInput.Button != MouseButton.Left)
+ return false;
+
+ var isFinal = false;
+ if (mouseInput.Event == MouseInputEvent.Down)
+ {
+ startingMouseInput = mouseInput;
+ isDragging = false;
+ }
+ else if (startingMouseInput != null)
+ {
+ if (mouseInput.Event == MouseInputEvent.Up)
+ {
+ isFinal = true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ CPos ViewToWorldCorner(int2 xy) =>
+ CellLayerUtils.WPosToCorner(
+ worldRenderer.ProjectedPosition(
+ worldRenderer.Viewport.ViewToWorldPx(xy)),
+ worldRenderer.World.Map.Grid.Type);
+
+ var from = ViewToWorldCorner(startingMouseInput.Value.Location);
+ var to = ViewToWorldCorner(mouseInput.Location);
+
+ void UpdatePlan(TilingPathTool.PathPlan newPlan, bool preview)
+ {
+ if (isFinal)
+ {
+ editorActionManager.Add(
+ new UpdateTilingPathPlanEditorAction(tool, newPlan));
+ }
+ else if (preview)
+ {
+ previewPlan = newPlan;
+ }
+ }
+
+ if (isFinal)
+ {
+ previewPlan = null;
+ startingMouseInput = null;
+ }
+
+ isDragging |= to != from;
+ var plan = tool.Plan;
+
+ if (plan == null)
+ {
+ UpdatePlan(new TilingPathTool.PathPlan(to), true);
+ return true;
+ }
+
+ var points = plan.PointsWithRallyIndex();
+
+ (bool IsInside, bool IsRally, int RallyIndex, bool IsStartDirector, bool IsEndDirector)
+ AssessCPos(CPos cpos)
+ {
+ var isInside = points.Select(p => p.CPos).Contains(cpos);
+ var isRally = plan.Rallies.Contains(cpos);
+ var rallyIndex =
+ points
+ .Where(p => p.CPos == cpos)
+ .Select(p => p.RallyIndex)
+ .FirstOrDefault(0);
+ var isStartDirector =
+ plan.AutoStart != Direction.None
+ && cpos == plan.FirstPoint - Direction.ToCVec(plan.AutoStart);
+ var isEndDirector =
+ plan.AutoEnd != Direction.None
+ && cpos == plan.LastPoint + Direction.ToCVec(plan.AutoEnd);
+ return (isInside, isRally, rallyIndex, isStartDirector, isEndDirector);
+ }
+
+ var (fromIsInside, fromIsRally, fromRallyIndex, fromIsStartDirector, fromIsEndDirector) =
+ AssessCPos(from);
+ var (toIsInside, toIsRally, toRallyIndex, toIsStartDirector, toIsEndDirector) =
+ AssessCPos(to);
+
+ if (isDragging)
+ {
+ if (fromIsStartDirector)
+ {
+ var offset = plan.FirstPoint - to;
+ var direction =
+ offset != CVec.Zero
+ ? Direction.FromCVecRounding(offset)
+ : Direction.None;
+ UpdatePlan(plan.WithStart(direction), true);
+ }
+ else if (fromIsEndDirector)
+ {
+ var offset = to - plan.LastPoint;
+ var direction =
+ offset != CVec.Zero
+ ? Direction.FromCVecRounding(offset)
+ : Direction.None;
+ UpdatePlan(plan.WithEnd(direction), true);
+ }
+ else if (fromIsInside)
+ {
+ if (fromIsRally)
+ {
+ if (!toIsRally || to == from)
+ {
+ UpdatePlan(plan.WithRallyReplaced(fromRallyIndex, to), true);
+ }
+ }
+ else
+ {
+ UpdatePlan(plan.Moved(to - from), true);
+ }
+ }
+ else
+ {
+ if (!toIsRally)
+ {
+ UpdatePlan(plan.WithRallyAppended(to), true);
+ }
+ }
+ }
+ else
+ {
+ if (toIsInside)
+ {
+ if (toIsRally)
+ {
+ if (toRallyIndex == 0)
+ {
+ UpdatePlan(plan.WithLoop(!plan.Loop), false);
+ }
+ else
+ {
+ UpdatePlan(plan.WithRallyRemoved(toRallyIndex), false);
+ }
+ }
+ else
+ {
+ UpdatePlan(plan.WithRallyInserted(toRallyIndex, to), false);
+ }
+ }
+ else
+ {
+ UpdatePlan(plan.WithRallyAppended(to), true);
+ }
+ }
+
+ return true;
+ }
+
+ void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { }
+ IEnumerable IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr)
+ {
+ if (tool.EditorBlitSource == null)
+ yield break;
+
+ var preview = EditorBlit.PreviewBlitSource(
+ tool.EditorBlitSource.Value,
+ MapBlitFilters.Terrain | MapBlitFilters.Actors,
+ CVec.Zero,
+ wr);
+ foreach (var renderable in preview)
+ yield return renderable;
+ }
+
+ IEnumerable IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr)
+ {
+ var plan = previewPlan ?? tool.Plan;
+ if (plan == null)
+ yield break;
+
+ var mainColor = tool.EditorBlitSource != null ? Color.Cyan : Color.Red;
+
+ var gridType = worldRenderer.World.Map.Grid.Type;
+ WPos CornerOfCell(CPos cpos) => CellLayerUtils.CornerToWPos(cpos, gridType);
+
+ var points = plan.Points();
+ for (var i = 1; i < points.Length; i++)
+ {
+ yield return new CircleAnnotationRenderable(
+ CornerOfCell(points[i]), new WDist(128), 1, Color.Yellow, false);
+ yield return new LineAnnotationRenderable(
+ CornerOfCell(points[i - 1]),
+ CornerOfCell(points[i]),
+ 1,
+ Color.Yellow,
+ Color.Yellow);
+ }
+
+ for (var i = 1; i < plan.Rallies.Length; i++)
+ {
+ yield return new CircleAnnotationRenderable(
+ CornerOfCell(plan.Rallies[i]), new WDist(512), 1, mainColor, false);
+ yield return new LineAnnotationRenderable(
+ CornerOfCell(plan.Rallies[i - 1]),
+ CornerOfCell(plan.Rallies[i]),
+ 1,
+ mainColor,
+ mainColor);
+ }
+
+ if (plan.AutoEnd != Direction.None)
+ yield return new CircleAnnotationRenderable(
+ CornerOfCell(plan.LastPoint) + Direction.ToWVec(plan.AutoEnd) * 768,
+ new WDist(256),
+ 2,
+ plan.End != Direction.None ? Color.Magenta : Color.Gray,
+ false);
+
+ if (plan.AutoStart != Direction.None)
+ yield return new CircleAnnotationRenderable(
+ CornerOfCell(plan.FirstPoint) - Direction.ToWVec(plan.AutoStart) * 768,
+ new WDist(256),
+ 2,
+ plan.Start != Direction.None ? Color.Magenta : Color.Gray,
+ true);
+
+ yield return new CircleAnnotationRenderable(
+ CornerOfCell(plan.Rallies[0]), new WDist(512), 1, mainColor, true);
+ }
+
+ public void Tick() { }
+
+ public void Dispose() { }
+ }
+
+ sealed class UpdateTilingPathPlanEditorAction : IEditorAction
+ {
+ [FluentReference]
+ const string StartedPlan = "notification-tiling-path-started";
+ [FluentReference]
+ const string UpdatedPlan = "notification-tiling-path-updated";
+ [FluentReference]
+ const string ResetPlan = "notification-tiling-path-reset";
+
+ public string Text { get; }
+
+ readonly TilingPathTool tool;
+ readonly TilingPathTool.PathPlan oldPlan;
+ readonly TilingPathTool.PathPlan newPlan;
+
+ public UpdateTilingPathPlanEditorAction(
+ TilingPathTool tool,
+ TilingPathTool.PathPlan newPlan)
+ {
+ this.tool = tool;
+ oldPlan = tool.Plan;
+ this.newPlan = newPlan;
+ if (oldPlan == null && newPlan == null)
+ throw new ArgumentException("oldPlan and newPlan cannot both be null");
+ else if (oldPlan == null)
+ Text = FluentProvider.GetMessage(StartedPlan);
+ else if (newPlan == null)
+ Text = FluentProvider.GetMessage(ResetPlan);
+ else
+ Text = FluentProvider.GetMessage(UpdatedPlan);
+ }
+
+ public void Execute()
+ {
+ Do();
+ }
+
+ public void Do()
+ {
+ tool.SetPlan(newPlan);
+ }
+
+ public void Undo()
+ {
+ tool.SetPlan(oldPlan);
+ }
+ }
+
+ sealed class PaintTilingPathEditorAction : IEditorAction
+ {
+ [FluentReference]
+ const string Painted = "notification-tiling-path-painted";
+
+ public string Text { get; }
+
+ readonly TilingPathTool tool;
+ readonly TilingPathTool.PathPlan plan;
+ readonly EditorBlit editorBlit;
+
+ public PaintTilingPathEditorAction(TilingPathTool tool)
+ {
+ this.tool = tool;
+ plan = tool.Plan;
+ Text = FluentProvider.GetMessage(Painted);
+
+ var world = tool.World;
+ var editorActorLayer = world.WorldActor.Trait();
+
+ var blitSource = tool.EditorBlitSource.Value;
+
+ editorBlit = new EditorBlit(
+ MapBlitFilters.Terrain | MapBlitFilters.Actors,
+ null,
+ blitSource.CellRegion.TopLeft,
+ world.Map,
+ blitSource,
+ editorActorLayer,
+ false);
+ }
+
+ public void Execute()
+ {
+ Do();
+ }
+
+ public void Do()
+ {
+ tool.SetPlan(null);
+ editorBlit.Commit();
+ }
+
+ public void Undo()
+ {
+ editorBlit.Revert();
+ tool.SetPlan(plan);
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/MapGenerator/CellLayerUtils.cs b/OpenRA.Mods.Common/MapGenerator/CellLayerUtils.cs
index d92bf196f2..746641e70a 100644
--- a/OpenRA.Mods.Common/MapGenerator/CellLayerUtils.cs
+++ b/OpenRA.Mods.Common/MapGenerator/CellLayerUtils.cs
@@ -61,19 +61,39 @@ namespace OpenRA.Mods.Common.MapGenerator
}
/// Get the WPos of the -X-Y corner of a CPos cell.
- public static WPos CornerToWPos(CPos xy, MapGridType gridType)
+ public static WPos CornerToWPos(CPos cpos, MapGridType gridType)
{
switch (gridType)
{
case MapGridType.Rectangular:
return new WPos(
- xy.X * 1024,
- xy.Y * 1024,
+ cpos.X * 1024,
+ cpos.Y * 1024,
0);
case MapGridType.RectangularIsometric:
return new WPos(
- (xy.X - xy.Y) * 724 + 724,
- (xy.X + xy.Y) * 724,
+ (cpos.X - cpos.Y) * 724 + 724,
+ (cpos.X + cpos.Y) * 724,
+ 0);
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
+ /// Get the closest -X-Y corner of a CPos cell to a WPos.
+ public static CPos WPosToCorner(WPos cpos, MapGridType gridType)
+ {
+ switch (gridType)
+ {
+ case MapGridType.Rectangular:
+ return new CPos(
+ FloorDiv(cpos.X + 512, 1024),
+ FloorDiv(cpos.Y + 512, 1024),
+ 0);
+ case MapGridType.RectangularIsometric:
+ return new CPos(
+ FloorDiv(cpos.Y + cpos.X, 1448),
+ FloorDiv(cpos.Y - cpos.X, 1448),
0);
default:
throw new NotImplementedException();
diff --git a/OpenRA.Mods.Common/MapGenerator/Direction.cs b/OpenRA.Mods.Common/MapGenerator/Direction.cs
index 662c6f6be6..5da45e5975 100644
--- a/OpenRA.Mods.Common/MapGenerator/Direction.cs
+++ b/OpenRA.Mods.Common/MapGenerator/Direction.cs
@@ -125,6 +125,18 @@ namespace OpenRA.Mods.Common.MapGenerator
throw new ArgumentException("bad direction");
}
+ static readonly ImmutableArray KiloVectors =
+ [
+ new(1024, 0),
+ new(724, 724),
+ new(0, 1024),
+ new(-724, 724),
+ new(-1024, 0),
+ new(-724, -724),
+ new(0, -1024),
+ new(724, -724),
+ ];
+
///
/// Convert a non-none direction to a CVec offset. Assumes that
/// CVec(1, 0) corresponds to Direction.R.
@@ -137,8 +149,21 @@ namespace OpenRA.Mods.Common.MapGenerator
throw new ArgumentException("bad direction");
}
+ ///
+ /// Convert a non-none direction to a WVec offset. Assumes that
+ /// WVec(1, 0, 0) corresponds to Direction.R.
+ ///
+ public static WVec ToWVec(int d)
+ {
+ if (d >= 0 && d < 8)
+ return new WVec(Spread8[d].X, Spread8[d].Y, 0);
+ else
+ throw new ArgumentException("bad direction");
+ }
+
///
/// Convert an offset (of arbitrary non-zero magnitude) to a direction.
+ /// The direction is based purely on the signs of the inputs.
/// Supplying a zero-offset will throw.
///
public static int FromOffset(int dx, int dy)
@@ -172,6 +197,32 @@ namespace OpenRA.Mods.Common.MapGenerator
}
}
+ ///
+ /// Convert an offset (of arbitrary non-zero magnitude) to a direction.
+ /// The direction with the closest angle wins. Keep inputs to 1000000 or less.
+ /// Supplying a zero-offset will throw.
+ ///
+ public static int FromOffsetRounding(int dx, int dy)
+ {
+ if (dx == 0 && dy == 0)
+ throw new ArgumentException("Bad direction");
+
+ var d = new int2(dx, dy);
+ var direction = None;
+ var best = 0;
+ for (var i = 0; i < KiloVectors.Length; i++)
+ {
+ var score = int2.Dot(d, KiloVectors[i]);
+ if (score > best)
+ {
+ best = score;
+ direction = i;
+ }
+ }
+
+ return direction;
+ }
+
///
/// Convert an offset (of arbitrary non-zero magnitude) to a direction.
/// Supplying a zero-offset will throw.
@@ -187,6 +238,14 @@ namespace OpenRA.Mods.Common.MapGenerator
public static int FromCVec(CVec delta)
=> FromOffset(delta.X, delta.Y);
+ ///
+ /// Convert an offset (of arbitrary non-zero magnitude) to a direction.
+ /// Supplying a zero-offset will throw. Assumes that CVec(1, 0)
+ /// corresponds to Direction.R.
+ ///
+ public static int FromCVecRounding(CVec delta)
+ => FromOffsetRounding(delta.X, delta.Y);
+
///
/// Convert an offset (of arbitrary non-zero magnitude) to a non-diagonal direction.
/// Supplying a zero-offset will throw.
diff --git a/OpenRA.Mods.Common/MapGenerator/MultiBrush.cs b/OpenRA.Mods.Common/MapGenerator/MultiBrush.cs
index 76945aff2c..9d7fac695c 100644
--- a/OpenRA.Mods.Common/MapGenerator/MultiBrush.cs
+++ b/OpenRA.Mods.Common/MapGenerator/MultiBrush.cs
@@ -14,7 +14,10 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.EditorBrushes;
using OpenRA.Mods.Common.Terrain;
+using OpenRA.Mods.Common.Traits;
using OpenRA.Support;
namespace OpenRA.Mods.Common.MapGenerator
@@ -236,8 +239,12 @@ namespace OpenRA.Mods.Common.MapGenerator
/// Total area covered by the MultiBrush.
public int Area => GetShape().Length;
- /// The CVec of the top-left most cell covered by the MultiBrush.
- public CVec TopLeft => GetShape()[0];
+ ///
+ /// The CVec of the first cell covered by the MultiBrush. This is the left-most cell in the
+ /// top-row. Note that this does not necessarily correspond to the top-left corner of the
+ /// rectangular bounds of the MultiBrush.
+ ///
+ public CVec FirstCell => GetShape()[0];
public Replaceability Contract()
{
@@ -618,7 +625,7 @@ namespace OpenRA.Mods.Common.MapGenerator
foreach (var mpos in mposes)
{
var brush = brushes[random.PickWeighted(brushWeights)];
- var paintAt = mpos.ToCPos(map) - brush.TopLeft;
+ var paintAt = mpos.ToCPos(map) - brush.FirstCell;
var contract = ReserveShape(paintAt, brush.Shape, brush.Contract());
if (contract != Replaceability.None)
brush.Paint(map, actorPlans, paintAt, contract);
@@ -629,5 +636,71 @@ namespace OpenRA.Mods.Common.MapGenerator
}
}
}
+
+ ///
+ /// Create a sparse EditorBlitSource from this MultiBrush. The EditorBlitSource will have
+ /// the minimum bounding CellRegion fully containing all content. For actors without a
+ /// preconfigured owner, a default owner can be specified or derived automatically.
+ ///
+ public EditorBlitSource ToEditorBlitSource(
+ WorldRenderer worldRenderer,
+ PlayerReference defaultActorOwner = null)
+ {
+ var world = worldRenderer.World;
+ var map = world.Map;
+
+ if (defaultActorOwner == null)
+ {
+ var editorActorLayer = world.WorldActor.Trait();
+ if (editorActorLayer != null)
+ defaultActorOwner = editorActorLayer.Players.Players.Values.First();
+ }
+
+ var players = world.Players.ToDictionary(
+ player => player.InternalName,
+ player => player.PlayerReference);
+
+ var topLeft = new CPos(
+ Shape.Min(cvec => cvec.X),
+ Shape.Min(cvec => cvec.Y));
+ var bottomRight = new CPos(
+ Shape.Max(cvec => cvec.X),
+ Shape.Max(cvec => cvec.Y));
+ var cellRegion = new CellRegion(map.Grid.Type, topLeft, bottomRight);
+
+ var actorPreviews = new Dictionary();
+ for (var i = 0; i < actorPlans.Count; i++)
+ {
+ // A (non-revert) EditorBlitSource's actors' names are generally unimportant beyond
+ // needing to be distinct. They will get renamed when blitting.
+ var name = $"Actor{i}";
+ var actorReference = actorPlans[i].Reference.Clone();
+ var ownerInit = actorReference.Get();
+ if (!players.TryGetValue(ownerInit.InternalName, out var owner))
+ owner = defaultActorOwner;
+
+ if (owner == null)
+ throw new InvalidOperationException("MultiBrush actor has invalid (or no) owner and no default available.");
+
+ actorPreviews[name] = new EditorActorPreview(
+ worldRenderer,
+ name,
+ actorReference,
+ owner);
+ }
+
+ var blitTiles =
+ Tiles
+ .Where(t => map.Tiles.Contains(CPos.Zero + t.XY))
+ .DistinctBy(t => t.XY)
+ .ToDictionary(
+ t => CPos.Zero + t.XY,
+ t => new BlitTile(t.Tile, default, null, map.Height[CPos.Zero + t.XY]));
+
+ return new EditorBlitSource(
+ cellRegion,
+ actorPreviews,
+ blitTiles);
+ }
}
}
diff --git a/OpenRA.Mods.Common/MapGenerator/TilingPath.cs b/OpenRA.Mods.Common/MapGenerator/TilingPath.cs
index 61ce8254c0..6ac1315353 100644
--- a/OpenRA.Mods.Common/MapGenerator/TilingPath.cs
+++ b/OpenRA.Mods.Common/MapGenerator/TilingPath.cs
@@ -109,6 +109,25 @@ namespace OpenRA.Mods.Common.MapGenerator
FindSegments(multiBrushes, innerTypesArray, innerTypesArray, terminalTypesArray));
}
+ ///
+ /// Creates a PermittedSegments suitable for a path with given inner and terminal types
+ /// at the start and end.
+ ///
+ public static PermittedSegments FromTypes(
+ IReadOnlyList multiBrushes,
+ IEnumerable startTypes,
+ IEnumerable innerTypes,
+ IEnumerable endTypes)
+ {
+ var startTypesArray = startTypes.ToImmutableArray();
+ var innerTypesArray = innerTypes.ToImmutableArray();
+ var endTypesArray = endTypes.ToImmutableArray();
+ return new(
+ FindSegments(multiBrushes, startTypesArray, innerTypesArray, innerTypesArray),
+ FindSegments(multiBrushes, innerTypesArray),
+ FindSegments(multiBrushes, innerTypesArray, innerTypesArray, endTypesArray));
+ }
+
///
/// Equivalent to FindSegments(multiBrushes, types, types, types).
///
@@ -604,8 +623,10 @@ namespace OpenRA.Mods.Common.MapGenerator
return (typeId, new CVec(xy % size.X, xy / size.X), priority);
}
- var pathStartTypeId = segmentTypeToId[start.SegmentType];
- var pathEndTypeId = segmentTypeToId[end.SegmentType];
+ if (!segmentTypeToId.TryGetValue(start.SegmentType, out var pathStartTypeId))
+ return null;
+ if (!segmentTypeToId.TryGetValue(end.SegmentType, out var pathEndTypeId))
+ return null;
// Lower (closer to zero) costs are better matches.
// MaxScore means totally unacceptable.
diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs
index 4abf3d19ac..44c1d6a8c4 100644
--- a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs
+++ b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs
@@ -137,7 +137,17 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable Render()
{
- var items = previews.SelectMany(p => p.Render(worldRenderer, CenterPosition));
+ return RenderAt(CenterPosition);
+ }
+
+ public IEnumerable RenderWithOffset(WVec offset)
+ {
+ return RenderAt(CenterPosition + offset);
+ }
+
+ public IEnumerable RenderAt(WPos centerPosition)
+ {
+ var items = previews.SelectMany(p => p.Render(worldRenderer, centerPosition));
if (Selected)
{
var overlay = items.Where(r => !r.IsDecoration && r is IModifyableRenderable)
diff --git a/OpenRA.Mods.Common/Traits/World/TerrainRenderer.cs b/OpenRA.Mods.Common/Traits/World/TerrainRenderer.cs
index 036c8a7d02..63f5d27d66 100644
--- a/OpenRA.Mods.Common/Traits/World/TerrainRenderer.cs
+++ b/OpenRA.Mods.Common/Traits/World/TerrainRenderer.cs
@@ -207,5 +207,16 @@ namespace OpenRA.Mods.Common.Traits
}
}
}
+
+ IEnumerable ITiledTerrainRenderer.RenderPreview(WorldRenderer wr, TerrainTile tile, WPos origin)
+ {
+ if (!terrainInfo.TryGetTileInfo(tile, out var tileInfo))
+ yield break;
+ var sprite = tileCache.TileSprite(tile, 0);
+ var offset = map.Offset(new CVec(0, 0), tileInfo.Height);
+ var palette = wr.Palette(terrainInfo.Palette);
+
+ yield return new SpriteRenderable(sprite, origin, offset, 0, palette, 1f, 1f, float3.Ones, TintModifiers.None, false);
+ }
}
}
diff --git a/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs b/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs
new file mode 100644
index 0000000000..a63f4d9021
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs
@@ -0,0 +1,497 @@
+#region Copyright & License Information
+/*
+ * Copyright (c) The OpenRA Developers and Contributors
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.EditorBrushes;
+using OpenRA.Mods.Common.MapGenerator;
+using OpenRA.Mods.Common.Terrain;
+using OpenRA.Support;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ [TraitLocation(SystemActors.EditorWorld)]
+ public sealed class TilingPathToolInfo : TraitInfo, IEditorToolInfo
+ {
+ [FluentReference]
+ const string Label = "label-tool-tiling-path";
+
+ [Desc("The widget tree to open when the tool is selected.")]
+ const string PanelWidget = "TILING_PATH_TOOL_PANEL";
+
+ [Desc("The preferred defaults for the start type.")]
+ public readonly string[] DefaultStart = [];
+ [Desc("The preferred defaults for the inner type.")]
+ public readonly string[] DefaultInner = [];
+ [Desc("The preferred defaults for the end type.")]
+ public readonly string[] DefaultEnd = [];
+
+ public override object Create(ActorInitializer init)
+ {
+ return new TilingPathTool(init.Self, this);
+ }
+
+ string IEditorToolInfo.Label => Label;
+ string IEditorToolInfo.PanelWidget => PanelWidget;
+ }
+
+ public sealed class TilingPathTool : IRenderAnnotations, INotifyActorDisposing, IWorldLoaded
+ {
+ ///
+ /// Holds the shape of a path being planned out in the map editor.
+ ///
+ public sealed class PathPlan
+ {
+ public readonly int Start;
+ public readonly int End;
+ public readonly bool Loop;
+ public readonly ImmutableArray Rallies;
+ public int AutoStart
+ {
+ get
+ {
+ if (Start != Direction.None)
+ {
+ return Start;
+ }
+ else
+ {
+ if (Rallies.Length >= 2)
+ return Direction.FromCVecRounding(Rallies[1] - Rallies[0]);
+ else
+ return Direction.None;
+ }
+ }
+ }
+
+ public int AutoEnd
+ {
+ get
+ {
+ if (End != Direction.None)
+ {
+ return End;
+ }
+ else if (Loop)
+ {
+ return AutoStart;
+ }
+ else
+ {
+ if (Rallies.Length >= 2)
+ return Direction.FromCVecRounding(Rallies[^1] - Rallies[^2]);
+ else
+ return Direction.None;
+ }
+ }
+ }
+
+ public CPos FirstPoint => Rallies[0];
+ public CPos LastPoint => Loop ? Rallies[0] : Rallies[^1];
+
+ PathPlan(int start, int end, bool loop, ImmutableArray rallies)
+ {
+ if (rallies == null || rallies.Length == 0)
+ throw new ArgumentException("rallies must have at least one point");
+
+ Start = start;
+ End = end;
+ Loop = loop && rallies.Length >= 3;
+ Rallies = rallies;
+ }
+
+ /// Start a new path with a given first point.
+ public PathPlan(CPos first)
+ {
+ Start = Direction.None;
+ End = Direction.None;
+ Loop = false;
+ Rallies = [first];
+ }
+
+ /// Return a copy, modifying the start direction.
+ public PathPlan WithStart(int start)
+ {
+ return new PathPlan(start, End, Loop, Rallies);
+ }
+
+ /// Return a copy, modifying the end direction.
+ public PathPlan WithEnd(int end)
+ {
+ return new PathPlan(Start, end, Loop, Rallies);
+ }
+
+ /// Return a copy, modifying whether the path is looped.
+ public PathPlan WithLoop(bool loop)
+ {
+ return new PathPlan(Start, End, loop, Rallies);
+ }
+
+ /// Return a copy, with a rally appended.
+ public PathPlan WithRallyAppended(CPos cpos)
+ {
+ return new PathPlan(Start, Direction.None, Loop, [.. Rallies, cpos]);
+ }
+
+ /// Return a copy, with the rally at index removed.
+ public PathPlan WithRallyRemoved(int index)
+ {
+ if (Rallies.Length == 1)
+ return null;
+
+ return new PathPlan(
+ index != 0 ? Start : Direction.None,
+ index != Rallies.Length - 1 ? End : Direction.None,
+ Loop,
+ [.. Rallies[..index], .. Rallies[(index + 1)..]]);
+ }
+
+ /// Return a copy, with the rally at index replace/moved.
+ public PathPlan WithRallyReplaced(int index, CPos cpos)
+ {
+ return new PathPlan(Start, End, Loop, [.. Rallies[..index], cpos, .. Rallies[(index + 1)..]]);
+ }
+
+ /// Return a copy, with a rally inserted before index.
+ public PathPlan WithRallyInserted(int index, CPos cpos)
+ {
+ return new PathPlan(Start, End, Loop, [.. Rallies[..index], cpos, .. Rallies[index..]]);
+ }
+
+ /// Return a copy, with everything translated by offset.
+ public PathPlan Moved(CVec offset)
+ {
+ var rallies = Rallies.Select(r => r + offset).ToImmutableArray();
+ return new PathPlan(Start, End, Loop, rallies);
+ }
+
+ /// Return a copy, with rallies reversed and directions swapped.
+ public PathPlan Reversed()
+ {
+ if (Loop)
+ {
+ var reversedStart = End;
+ var reversedEnd = Start;
+ if (Start != Direction.None && End == Direction.None)
+ {
+ reversedStart = AutoEnd;
+ reversedEnd = Direction.None;
+ }
+
+ return new PathPlan(
+ Direction.Reverse(reversedStart),
+ Direction.Reverse(reversedEnd),
+ Loop,
+ Rallies.Skip(1).Append(Rallies[0]).Reverse().ToImmutableArray());
+ }
+ else
+ {
+ return new PathPlan(
+ Direction.Reverse(End),
+ Direction.Reverse(Start),
+ Loop,
+ Rallies.Reverse().ToImmutableArray());
+ }
+ }
+
+ ///
+ /// Convert the rally points into a sequence of unit-space CPos points, suitable for
+ /// processing with TilingPath.
+ ///
+ public CPos[] Points()
+ {
+ return PointsWithRallyIndex().Select(pair => pair.CPos).ToArray();
+ }
+
+ ///
+ /// Convert the rally points into a sequence of unit-space CPos points and their
+ /// associated latest rally index. For loops, the last rally index is the number of the
+ /// rallies.
+ ///
+ public (CPos CPos, int RallyIndex)[] PointsWithRallyIndex()
+ {
+ if (Rallies.Length == 1)
+ return [(Rallies[0], 0)];
+
+ var points = new List<(CPos CPos, int RallyIndex)>();
+ var cpos = Rallies[0];
+ points.Add((cpos, 0));
+ var inertia = Direction.ToCVec(AutoStart);
+ if (inertia.X != 0 && inertia.Y != 0)
+ inertia = new CVec(inertia.X, 0);
+
+ void AddPointsUpTo(CPos target, int i)
+ {
+ if (cpos == target)
+ throw new InvalidOperationException("there are duplicate rally points");
+
+ var offset = target - cpos;
+ var xStep = Math.Sign(offset.X);
+ var yStep = Math.Sign(offset.Y);
+
+ var axisAligned = xStep == 0 || yStep == 0;
+
+ if (axisAligned)
+ {
+ while (cpos != target)
+ {
+ inertia = new CVec(xStep, yStep);
+ cpos += inertia;
+ points.Add((cpos, i));
+ }
+ }
+ else
+ {
+ var xUnderModulo = Math.Abs(offset.Y);
+ var yUnderModulo = Math.Abs(offset.X);
+
+ // Technically, these range from 0 inclusive to modulo inclusive!
+ var xModulo = xUnderModulo * 2;
+ var yModulo = yUnderModulo * 2;
+
+ if (xUnderModulo < yUnderModulo)
+ inertia = new CVec(xStep, 0);
+ else if (yUnderModulo > xUnderModulo)
+ inertia = new CVec(0, yStep);
+ else
+ inertia =
+ Direction.ToCVec(
+ Direction.FromCVecNonDiagonal(
+ inertia + new CVec(xStep * 2, yStep * 2)));
+
+ while (cpos != target)
+ {
+ if (xUnderModulo < yUnderModulo)
+ {
+ yUnderModulo -= xUnderModulo;
+ xUnderModulo = xModulo;
+ inertia = new CVec(xStep, 0);
+ }
+ else if (xUnderModulo > yUnderModulo)
+ {
+ xUnderModulo -= yUnderModulo;
+ yUnderModulo = yModulo;
+ inertia = new CVec(0, yStep);
+ }
+ else if (inertia.X != 0)
+ {
+ xUnderModulo = xModulo;
+ yUnderModulo = 0;
+ }
+ else
+ {
+ yUnderModulo = yModulo;
+ xUnderModulo = 0;
+ }
+
+ cpos += inertia;
+ points.Add((cpos, i));
+ }
+ }
+ }
+
+ for (var i = 1; i < Rallies.Length; i++)
+ AddPointsUpTo(Rallies[i], i);
+
+ if (Loop)
+ AddPointsUpTo(Rallies[0], Rallies.Length);
+
+ return points.ToArray();
+ }
+ }
+
+ /// Whether the TilingPathTool can be used.
+ public readonly bool Available;
+
+ public readonly World World;
+ public WorldRenderer WorldRenderer = null;
+ public readonly ImmutableArray SegmentedBrushes;
+ public readonly ImmutableArray StartTypes;
+ public readonly ImmutableArray InnerTypes;
+ public readonly ImmutableArray EndTypes;
+ public PathPlan Plan { get; private set; } = null;
+ public string StartType { get; private set; } = null;
+ public string InnerType { get; private set; } = null;
+ public string EndType { get; private set; } = null;
+ public bool ClosedLoops { get; private set; } = true;
+ public int RandomSeed { get; private set; } = 0;
+ public int MaxDeviation { get; private set; } = 5;
+ public EditorBlitSource? EditorBlitSource { get; private set; } = null;
+
+ bool disposed;
+
+ public TilingPathTool(Actor self, TilingPathToolInfo info)
+ {
+ World = self.World;
+
+ var templatedTerrainInfo = World.Map.Rules.TerrainInfo as ITemplatedTerrainInfo;
+ SegmentedBrushes =
+ templatedTerrainInfo.MultiBrushCollections.Keys
+ .Order()
+ .SelectMany(name => MultiBrush.LoadCollection(World.Map, name))
+ .Where(multiBrush => multiBrush.Segment != null)
+ .ToImmutableArray();
+
+ Available = SegmentedBrushes.Length > 0;
+
+ if (!Available)
+ return;
+
+ StartTypes = SegmentedBrushes
+ .Where(b => b.Segment != null)
+ .Select(b => string.Join(".", b.Segment.Start.Split('.').SkipLast(1)))
+ .Distinct()
+ .Order()
+ .ToImmutableArray();
+
+ InnerTypes = SegmentedBrushes
+ .Where(b => b.Segment != null)
+ .Select(b => b.Segment.Inner.Split('.')[0])
+ .Distinct()
+ .Order()
+ .ToImmutableArray();
+
+ EndTypes = SegmentedBrushes
+ .Where(b => b.Segment != null)
+ .Select(b => string.Join(".", b.Segment.End.Split('.').SkipLast(1)))
+ .Distinct()
+ .Order()
+ .ToImmutableArray();
+
+ StartType = info.DefaultStart
+ .FirstOrDefault(StartTypes.Contains, StartTypes[0]);
+ InnerType = info.DefaultInner
+ .FirstOrDefault(InnerTypes.Contains, InnerTypes[0]);
+ EndType = info.DefaultEnd
+ .FirstOrDefault(EndTypes.Contains, EndTypes[0]);
+ }
+
+ public void WorldLoaded(World w, WorldRenderer wr)
+ {
+ WorldRenderer = wr;
+ }
+
+ void INotifyActorDisposing.Disposing(Actor self)
+ {
+ if (disposed)
+ return;
+
+ disposed = true;
+ }
+
+ IEnumerable IRenderAnnotations.RenderAnnotations(Actor self, WorldRenderer wr)
+ {
+ yield break;
+ }
+
+ bool IRenderAnnotations.SpatiallyPartitionable => false;
+
+ EditorBlitSource? TilePlan(PathPlan plan)
+ {
+ if (WorldRenderer == null)
+ return null;
+
+ if (plan == null || plan.Rallies.Length < 2)
+ return null;
+
+ var points = plan.Points();
+ if (points == null)
+ return null;
+
+ (string Start, string End)[] terminalTypes = [(StartType, EndType)];
+ if (ClosedLoops && plan.Loop)
+ {
+ terminalTypes = StartTypes.Concat(EndTypes)
+ .Distinct()
+ .Where(t => t.Split('.')[0] == InnerType)
+ .Select(t => (t, t))
+ .ToArray();
+ }
+
+ var map = World.Map;
+ var permittedTemplates =
+ TilingPath.PermittedSegments.FromTypes(
+ SegmentedBrushes,
+ terminalTypes.Select(t => t.Start),
+ [InnerType],
+ terminalTypes.Select(t => t.End));
+
+ foreach (var (startType, endType) in terminalTypes)
+ {
+ var tilingPath = new TilingPath(
+ map,
+ points,
+ MaxDeviation,
+ startType,
+ endType,
+ permittedTemplates);
+ tilingPath.Start.Direction = plan.AutoStart;
+ tilingPath.End.Direction = plan.AutoEnd;
+ var result = tilingPath.Tile(new MersenneTwister(RandomSeed));
+ if (result != null)
+ return result.ToEditorBlitSource(WorldRenderer);
+ }
+
+ return null;
+ }
+
+ void Update()
+ {
+ EditorBlitSource = TilePlan(Plan);
+ }
+
+ public void SetPlan(PathPlan value)
+ {
+ Plan = value;
+ Update();
+ }
+
+ public void SetStartType(string value)
+ {
+ StartType = value;
+ Update();
+ }
+
+ public void SetInnerType(string value)
+ {
+ InnerType = value;
+ Update();
+ }
+
+ public void SetEndType(string value)
+ {
+ EndType = value;
+ Update();
+ }
+
+ public void SetClosedLoops(bool value)
+ {
+ ClosedLoops = value;
+ Update();
+ }
+
+ public void SetRandomSeed(int value)
+ {
+ RandomSeed = value;
+ Update();
+ }
+
+ public void SetMaxDeviation(int value)
+ {
+ MaxDeviation = value;
+ Update();
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs
index d5c35f99b9..a81164e3aa 100644
--- a/OpenRA.Mods.Common/TraitsInterfaces.cs
+++ b/OpenRA.Mods.Common/TraitsInterfaces.cs
@@ -779,6 +779,7 @@ namespace OpenRA.Mods.Common.Traits
Rectangle TemplateBounds(TerrainTemplateInfo template);
IEnumerable RenderUIPreview(WorldRenderer wr, TerrainTemplateInfo template, int2 origin, float scale);
IEnumerable RenderPreview(WorldRenderer wr, TerrainTemplateInfo template, WPos origin);
+ IEnumerable RenderPreview(WorldRenderer wr, TerrainTile tile, WPos origin);
}
public interface IResourceLayerInfo : ITraitInfoInterface
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs
new file mode 100644
index 0000000000..2d75a380d2
--- /dev/null
+++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs
@@ -0,0 +1,111 @@
+#region Copyright & License Information
+/*
+ * Copyright (c) The OpenRA Developers and Contributors
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using OpenRA.Graphics;
+using OpenRA.Mods.Common.Traits;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.Common.Widgets.Logic
+{
+ [IncludeStaticFluentReferences(
+ typeof(UpdateTilingPathPlanEditorAction),
+ typeof(PaintTilingPathEditorAction),
+ typeof(TilingPathToolInfo))]
+ public sealed class TilingPathToolLogic : ChromeLogic
+ {
+ [ObjectCreator.UseCtor]
+ public TilingPathToolLogic(
+ Widget widget,
+ World world,
+ ModData modData,
+ WorldRenderer worldRenderer,
+ Dictionary logicArgs)
+ {
+ var tool = world.WorldActor.Trait();
+ var editorActionManager = world.WorldActor.Trait();
+
+ var editorWidget = widget.Parent.Parent.Parent.Parent.Get("MAP_EDITOR");
+
+ ((ScrollPanelWidget)widget).Layout.AdjustChildren();
+
+ var editCheckbox = widget.Get("EDIT");
+ editCheckbox.Disabled = !tool.Available;
+ if (!tool.Available)
+ return;
+
+ editCheckbox.IsChecked = () => editorWidget.CurrentBrush is EditorTilingPathBrush;
+ editCheckbox.OnClick = () =>
+ editorWidget.SetBrush(
+ editCheckbox.IsChecked()
+ ? null
+ : new EditorTilingPathBrush(tool));
+
+ void SetupDropDown(
+ string name,
+ ImmutableArray choices,
+ Func read,
+ Action write)
+ {
+ var dropDown = widget
+ .Get(name)
+ .Get("DROPDOWN");
+ dropDown.GetText = read;
+ dropDown.OnMouseDown = _ =>
+ {
+ ScrollItemWidget SetupItem(string choice, ScrollItemWidget template)
+ {
+ bool IsSelected() => choice == read();
+ void OnClick() => write(choice);
+ var item = ScrollItemWidget.Setup(template, IsSelected, OnClick);
+ item.Get("LABEL").GetText = () => choice;
+ return item;
+ }
+
+ dropDown.ShowDropDown("LABEL_DROPDOWN_WITH_TOOLTIP_TEMPLATE", choices.Length * 30, choices, SetupItem);
+ };
+ }
+
+ SetupDropDown("START_TYPE", tool.StartTypes, () => tool.StartType, tool.SetStartType);
+ SetupDropDown("INNER_TYPE", tool.InnerTypes, () => tool.InnerType, tool.SetInnerType);
+ SetupDropDown("END_TYPE", tool.EndTypes, () => tool.EndType, tool.SetEndType);
+
+ var deviationSlider = widget.Get("DEVIATION").Get("SLIDER");
+ deviationSlider.GetValue = () => tool.MaxDeviation;
+ deviationSlider.OnChange += (value) => tool.SetMaxDeviation((int)value);
+
+ var closedLoopsCheckbox = widget.Get("CLOSED_LOOPS");
+ closedLoopsCheckbox.IsChecked = () => tool.ClosedLoops;
+ closedLoopsCheckbox.OnClick = () => tool.SetClosedLoops(!tool.ClosedLoops);
+
+ var resetButton = widget.Get("RESET");
+ resetButton.IsDisabled = () => tool.Plan == null;
+ resetButton.OnClick = () => editorActionManager.Add(
+ new UpdateTilingPathPlanEditorAction(tool, null));
+
+ var reverseButton = widget.Get("REVERSE");
+ reverseButton.IsDisabled = () => tool.Plan == null;
+ reverseButton.OnClick = () => editorActionManager.Add(
+ new UpdateTilingPathPlanEditorAction(tool, tool.Plan.Reversed()));
+
+ var randomizeButton = widget.Get("RANDOMIZE");
+ randomizeButton.IsDisabled = () => tool.Plan == null;
+ randomizeButton.OnClick = () => tool.SetRandomSeed(Environment.TickCount);
+
+ var paintButton = widget.Get("PAINT");
+ paintButton.IsDisabled = () => tool.EditorBlitSource == null;
+ paintButton.OnClick = () => editorActionManager.Add(
+ new PaintTilingPathEditorAction(tool));
+ }
+ }
+}
diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml
index 0251190b21..5317c6be23 100644
--- a/mods/cnc/chrome/editor.yaml
+++ b/mods/cnc/chrome/editor.yaml
@@ -1077,3 +1077,108 @@ Container@MAP_GENERATOR_TOOL_PANEL:
Width: PARENT_WIDTH
Height: 25
PanelRoot: EDITOR_WORLD_ROOT
+
+
+ScrollPanel@TILING_PATH_TOOL_PANEL:
+ Y: 24
+ Width: PARENT_WIDTH
+ Height: PARENT_HEIGHT - 25
+ TopBottomSpacing: 5
+ ItemSpacing: 5
+ Background: scrollpanel-bg
+ Visible: false
+ Logic: TilingPathToolLogic
+ Children:
+ Checkbox@EDIT:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: checkbox-tiling-path-edit
+ Container@START_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-start
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@INNER_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-inner
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@END_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-end
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@DEVIATION:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-deviation
+ For: SLIDER
+ Slider@SLIDER:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ MinimumValue: 0
+ MaximumValue: 10
+ Ticks: 11
+ Checkbox@CLOSED_LOOPS:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: checkbox-tiling-path-closed-loops
+ Button@REVERSE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-reverse
+ Button@RESET:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-reset
+ Button@RANDOMIZE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-randomize
+ Button@PAINT:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-paint
diff --git a/mods/cnc/fluent/chrome.ftl b/mods/cnc/fluent/chrome.ftl
index 6266604a7f..adedae06e2 100644
--- a/mods/cnc/fluent/chrome.ftl
+++ b/mods/cnc/fluent/chrome.ftl
@@ -78,6 +78,16 @@ label-marker-mirror-mode = Mirror Mode
label-marker-axis-angle = Axis Angle
button-map-generator-generate = Generate
button-map-generator-generate-random = Generate Random
+checkbox-tiling-path-edit = Enable editing
+label-tiling-path-type-start = Start type
+label-tiling-path-type-inner = Inner type
+label-tiling-path-type-end = End type
+label-tiling-path-deviation = Deviation limit
+checkbox-tiling-path-closed-loops = Loops use only inner types
+button-tiling-path-reverse = Reverse path
+button-tiling-path-reset = Discard path
+button-tiling-path-randomize = Re-randomize tiling
+button-tiling-path-paint = Paint tiling to map
button-map-editor-tab-container-select-tooltip = Selection
button-map-editor-tab-container-tiles-tooltip = Tiles
@@ -115,6 +125,7 @@ button-select-categories-buttons-all = All
button-select-categories-buttons-none = None
label-tool-marker-tiles = Marker Tiles
+label-tool-tiling-path = Path Tiler
## encyclopedia.yaml, mainmenu.yaml
label-encyclopedia-title = EVA Database
diff --git a/mods/cnc/rules/map-generators.yaml b/mods/cnc/rules/map-generators.yaml
index 6ff4704999..67fa326efa 100644
--- a/mods/cnc/rules/map-generators.yaml
+++ b/mods/cnc/rules/map-generators.yaml
@@ -68,7 +68,7 @@
ClearSegmentTypes: Clear
BeachSegmentTypes: Beach
CliffSegmentTypes: Cliff
- RoadSegmentTypes: Road,RoadIn,RoadOut
+ RoadSegmentTypes: Road
ForestObstacles: Trees
UnplayableObstacles: Obstructions
CivilianBuildingsObstacles: CivilianBuildings
diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml
index 1cd29325c7..c94b24ec93 100644
--- a/mods/cnc/rules/world.yaml
+++ b/mods/cnc/rules/world.yaml
@@ -301,4 +301,8 @@ EditorWorld:
BuildableTerrainOverlay:
AllowedTerrainTypes: Clear, Road
MarkerLayerOverlay:
+ TilingPathTool:
+ DefaultStart: Clear
+ DefaultInner: Beach
+ DefaultEnd: Clear
Inherits@MapGenerators: ^MapGenerators
diff --git a/mods/cnc/tilesets/desert.yaml b/mods/cnc/tilesets/desert.yaml
index f34576644f..6f83ddaed8 100644
--- a/mods/cnc/tilesets/desert.yaml
+++ b/mods/cnc/tilesets/desert.yaml
@@ -2484,11 +2484,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@93reverse:
Template: 93
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -2498,11 +2498,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@94reverse:
Template: 94
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -2512,11 +2512,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@95reverse:
Template: 95
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -2526,420 +2526,420 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@96reverse:
Template: 96
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@97:
Template: 97
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@97reverse:
Template: 97
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@98:
Template: 98
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@98reverse:
Template: 98
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@99:
Template: 99
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@99reverse:
Template: 99
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@100:
Template: 100
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@100reverse:
Template: 100
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@101:
Template: 101
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@101reverse:
Template: 101
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@102:
Template: 102
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@102reverse:
Template: 102
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@103:
Template: 103
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@103reverse:
Template: 103
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@104:
Template: 104
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@104reverse:
Template: 104
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@105:
Template: 105
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@105reverse:
Template: 105
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@112:
Template: 112
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@112reverse:
Template: 112
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@113:
Template: 113
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@113reverse:
Template: 113
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@114:
Template: 114
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@114reverse:
Template: 114
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@115:
Template: 115
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@115reverse:
Template: 115
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@116:
Template: 116
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@116reverse:
Template: 116
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@117:
Template: 117
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@117:
Template: 117
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@118:
Template: 118
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@118:
Template: 118
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@119:
Template: 119
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@119:
Template: 119
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@120:
Template: 120
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@120:
Template: 120
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@121:
Template: 121
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@121:
Template: 121
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@123:
Template: 123
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@123:
Template: 123
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@124:
Template: 124
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@124:
Template: 124
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@126:
Template: 126
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@126:
Template: 126
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@127:
Template: 127
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@127:
Template: 127
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@128:
Template: 128
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@128:
Template: 128
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@129:
Template: 129
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@129:
Template: 129
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@130:
Template: 130
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@130:
Template: 130
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@131:
Template: 131
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@131:
Template: 131
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@133:
Template: 133
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@133:
Template: 133
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@134:
Template: 134
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@134:
Template: 134
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@174:
Template: 174
Segment:
diff --git a/mods/cnc/tilesets/snow.yaml b/mods/cnc/tilesets/snow.yaml
index 25f113646a..fc3ac39aa0 100644
--- a/mods/cnc/tilesets/snow.yaml
+++ b/mods/cnc/tilesets/snow.yaml
@@ -2145,11 +2145,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@93reverse:
Template: 93
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -2159,11 +2159,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@94reverse:
Template: 94
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -2173,11 +2173,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@95reverse:
Template: 95
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -2187,420 +2187,420 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@96reverse:
Template: 96
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@97:
Template: 97
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@97reverse:
Template: 97
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@98:
Template: 98
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@98reverse:
Template: 98
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@99:
Template: 99
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@99reverse:
Template: 99
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@100:
Template: 100
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@100reverse:
Template: 100
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@101:
Template: 101
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@101reverse:
Template: 101
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@102:
Template: 102
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@102reverse:
Template: 102
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@103:
Template: 103
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@103reverse:
Template: 103
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@104:
Template: 104
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@104reverse:
Template: 104
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@105:
Template: 105
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@105reverse:
Template: 105
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@112:
Template: 112
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@112reverse:
Template: 112
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@113:
Template: 113
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@113reverse:
Template: 113
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@114:
Template: 114
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@114reverse:
Template: 114
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@115:
Template: 115
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@115reverse:
Template: 115
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@116:
Template: 116
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@116reverse:
Template: 116
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@117:
Template: 117
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@117reverse:
Template: 117
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@118:
Template: 118
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@118reverse:
Template: 118
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@119:
Template: 119
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@119reverse:
Template: 119
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@120:
Template: 120
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@120reverse:
Template: 120
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@121:
Template: 121
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@121reverse:
Template: 121
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@123:
Template: 123
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@123reverse:
Template: 123
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@124:
Template: 124
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@124reverse:
Template: 124
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@126:
Template: 126
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@126reverse:
Template: 126
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@127:
Template: 127
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@127reverse:
Template: 127
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@128:
Template: 128
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@128reverse:
Template: 128
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@129:
Template: 129
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@129reverse:
Template: 129
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@130:
Template: 130
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@130reverse:
Template: 130
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@131:
Template: 131
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@131reverse:
Template: 131
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@133:
Template: 133
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@133reverse:
Template: 133
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@134:
Template: 134
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@134reverse:
Template: 134
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@186:
Template: 186
Segment:
diff --git a/mods/cnc/tilesets/temperat.yaml b/mods/cnc/tilesets/temperat.yaml
index 7b4371211a..6495a86aa8 100644
--- a/mods/cnc/tilesets/temperat.yaml
+++ b/mods/cnc/tilesets/temperat.yaml
@@ -2146,11 +2146,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@93reverse:
Template: 93
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -2160,11 +2160,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@94reverse:
Template: 94
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -2174,11 +2174,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@95reverse:
Template: 95
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -2188,420 +2188,420 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@96reverse:
Template: 96
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@97:
Template: 97
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@97reverse:
Template: 97
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@98:
Template: 98
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@98reverse:
Template: 98
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@99:
Template: 99
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@99reverse:
Template: 99
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@100:
Template: 100
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@100reverse:
Template: 100
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@101:
Template: 101
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@101reverse:
Template: 101
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@102:
Template: 102
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@102reverse:
Template: 102
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@103:
Template: 103
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@103reverse:
Template: 103
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@104:
Template: 104
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@104reverse:
Template: 104
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@105:
Template: 105
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@105reverse:
Template: 105
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@112:
Template: 112
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@112reverse:
Template: 112
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@113:
Template: 113
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@113reverse:
Template: 113
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@114:
Template: 114
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@114reverse:
Template: 114
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@115:
Template: 115
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@115reverse:
Template: 115
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@116:
Template: 116
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@116reverse:
Template: 116
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@117:
Template: 117
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@117reverse:
Template: 117
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@118:
Template: 118
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@118reverse:
Template: 118
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@119:
Template: 119
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@119reverse:
Template: 119
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@120:
Template: 120
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@120reverse:
Template: 120
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@121:
Template: 121
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@121reverse:
Template: 121
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@123:
Template: 123
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@123reverse:
Template: 123
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@124:
Template: 124
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@124reverse:
Template: 124
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@126:
Template: 126
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@126reverse:
Template: 126
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@127:
Template: 127
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@127reverse:
Template: 127
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@128:
Template: 128
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@128reverse:
Template: 128
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@129:
Template: 129
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@129reverse:
Template: 129
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@130:
Template: 130
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@130reverse:
Template: 130
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@131:
Template: 131
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@131reverse:
Template: 131
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@133:
Template: 133
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@133reverse:
Template: 133
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@134:
Template: 134
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@134reverse:
Template: 134
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@186:
Template: 186
Segment:
diff --git a/mods/cnc/tilesets/winter.yaml b/mods/cnc/tilesets/winter.yaml
index b970aec1ab..646f568cb8 100644
--- a/mods/cnc/tilesets/winter.yaml
+++ b/mods/cnc/tilesets/winter.yaml
@@ -2181,11 +2181,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@93reverse:
Template: 93
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -2195,11 +2195,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@94reverse:
Template: 94
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -2209,11 +2209,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@95reverse:
Template: 95
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -2223,420 +2223,420 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@96reverse:
Template: 96
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@97:
Template: 97
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@97reverse:
Template: 97
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@98:
Template: 98
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@98reverse:
Template: 98
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@99:
Template: 99
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@99reverse:
Template: 99
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@100:
Template: 100
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@100reverse:
Template: 100
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@101:
Template: 101
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@101reverse:
Template: 101
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@102:
Template: 102
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@102reverse:
Template: 102
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@103:
Template: 103
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@103reverse:
Template: 103
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@104:
Template: 104
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@104reverse:
Template: 104
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@105:
Template: 105
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@105reverse:
Template: 105
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@112:
Template: 112
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@112reverse:
Template: 112
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@113:
Template: 113
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@113reverse:
Template: 113
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@114:
Template: 114
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@114reverse:
Template: 114
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@115:
Template: 115
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@115reverse:
Template: 115
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@116:
Template: 116
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@116reverse:
Template: 116
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@117:
Template: 117
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@117reverse:
Template: 117
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@118:
Template: 118
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@118reverse:
Template: 118
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@119:
Template: 119
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@119reverse:
Template: 119
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@120:
Template: 120
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@120reverse:
Template: 120
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@121:
Template: 121
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@121reverse:
Template: 121
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@123:
Template: 123
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@123reverse:
Template: 123
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@124:
Template: 124
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@124reverse:
Template: 124
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@126:
Template: 126
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@126reverse:
Template: 126
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@127:
Template: 127
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@127reverse:
Template: 127
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@128:
Template: 128
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@128reverse:
Template: 128
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@129:
Template: 129
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@129reverse:
Template: 129
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@130:
Template: 130
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@130reverse:
Template: 130
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@131:
Template: 131
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@131reverse:
Template: 131
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@133:
Template: 133
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@133reverse:
Template: 133
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@134:
Template: 134
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@134reverse:
Template: 134
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@186:
Template: 186
Segment:
diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml
index e5d9dac1a1..aae22c0457 100644
--- a/mods/common/chrome/editor.yaml
+++ b/mods/common/chrome/editor.yaml
@@ -855,6 +855,7 @@ Background@MARKER_TOOL_PANEL:
Width: PARENT_WIDTH - 20
Height: WINDOW_HEIGHT - 490
Background: scrollpanel-bg
+ Visible: false
Logic: MapMarkerTilesLogic
Children:
ScrollPanel@TILE_COLOR_PANEL:
@@ -1049,4 +1050,109 @@ ScrollPanel@MAP_GENERATOR_TOOL_PANEL:
Y: 20
Width: PARENT_WIDTH
Height: 25
- PanelRoot: EDITOR_WORLD_ROOT
\ No newline at end of file
+ PanelRoot: EDITOR_WORLD_ROOT
+
+ScrollPanel@TILING_PATH_TOOL_PANEL:
+ X: 10
+ Y: 35
+ Width: PARENT_WIDTH - 20
+ Height: WINDOW_HEIGHT - 490
+ TopBottomSpacing: 5
+ ItemSpacing: 5
+ Background: scrollpanel-bg
+ Visible: false
+ Logic: TilingPathToolLogic
+ Children:
+ Checkbox@EDIT:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: checkbox-tiling-path-edit
+ Container@START_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-start
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@INNER_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-inner
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@END_TYPE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-type-end
+ For: DROPDOWN
+ DropDownButton@DROPDOWN:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ Container@DEVIATION:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 50
+ Children:
+ LabelForInput@LABEL:
+ Y: 0
+ Width: PARENT_WIDTH
+ Height: 20
+ Text: label-tiling-path-deviation
+ For: SLIDER
+ Slider@SLIDER:
+ Y: 20
+ Width: PARENT_WIDTH
+ Height: 25
+ MinimumValue: 0
+ MaximumValue: 10
+ Ticks: 11
+ Checkbox@CLOSED_LOOPS:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: checkbox-tiling-path-closed-loops
+ Button@REVERSE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-reverse
+ Button@RESET:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-reset
+ Button@RANDOMIZE:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-randomize
+ Button@PAINT:
+ X: 5
+ Width: PARENT_WIDTH - 35
+ Height: 25
+ Text: button-tiling-path-paint
diff --git a/mods/common/fluent/chrome.ftl b/mods/common/fluent/chrome.ftl
index e22a54bb3d..9c1920f7c6 100644
--- a/mods/common/fluent/chrome.ftl
+++ b/mods/common/fluent/chrome.ftl
@@ -74,6 +74,16 @@ label-marker-mirror-mode = Mirror Mode
label-marker-axis-angle = Axis Angle
button-map-generator-generate = Generate
button-map-generator-generate-random = Generate Random
+checkbox-tiling-path-edit = Enable editing
+label-tiling-path-type-start = Start type
+label-tiling-path-type-inner = Inner type
+label-tiling-path-type-end = End type
+label-tiling-path-deviation = Deviation limit
+checkbox-tiling-path-closed-loops = Loops use only inner types
+button-tiling-path-reverse = Reverse path
+button-tiling-path-reset = Discard path
+button-tiling-path-randomize = Re-randomize tiling
+button-tiling-path-paint = Paint tiling to map
button-map-editor-tab-container-select-tooltip = Selection
button-map-editor-tab-container-tiles-tooltip = Tiles
@@ -115,6 +125,7 @@ button-select-categories-buttons-all = All
button-select-categories-buttons-none = None
label-tool-marker-tiles = Marker Tiles
+label-tool-tiling-path = Path Tiler
## gamesave-browser.yaml
label-gamesave-browser-panel-load-title = Load game
diff --git a/mods/common/fluent/common.ftl b/mods/common/fluent/common.ftl
index 0fa8ffee2f..2f04fea455 100644
--- a/mods/common/fluent/common.ftl
+++ b/mods/common/fluent/common.ftl
@@ -1107,3 +1107,9 @@ keycode =
label-map-generator-failed-cancel = Dismiss
notification-map-generator-generated = Generated using { $name }
notification-map-generator-failed = Map generation failed
+
+## EditorTilingPathBrush
+notification-tiling-path-started = Started tiling path
+notification-tiling-path-updated = Updated tiling path
+notification-tiling-path-reset = Discarded tiling path
+notification-tiling-path-painted = Painted tiling path
diff --git a/mods/ra/fluent/chrome.ftl b/mods/ra/fluent/chrome.ftl
index ff97d47b17..93bd0b4a53 100644
--- a/mods/ra/fluent/chrome.ftl
+++ b/mods/ra/fluent/chrome.ftl
@@ -190,4 +190,3 @@ button-production-types-aircraft-tooltip = Aircraft
button-production-types-naval-tooltip = Naval
button-production-types-scroll-up-tooltip = Scroll up
button-production-types-scroll-down-tooltip = Scroll down
-
diff --git a/mods/ra/rules/map-generators.yaml b/mods/ra/rules/map-generators.yaml
index 0e5ae3b744..b9ae34b2b1 100644
--- a/mods/ra/rules/map-generators.yaml
+++ b/mods/ra/rules/map-generators.yaml
@@ -67,7 +67,7 @@
ClearSegmentTypes: Clear
BeachSegmentTypes: Beach
CliffSegmentTypes: Cliff
- RoadSegmentTypes: Road,RoadIn,RoadOut
+ RoadSegmentTypes: Road
ForestObstacles: Trees
UnplayableObstacles: Obstructions
CivilianBuildingsObstacles: CivilianBuildings
diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml
index 8ae590d1ee..7b8dc6eedd 100644
--- a/mods/ra/rules/world.yaml
+++ b/mods/ra/rules/world.yaml
@@ -319,4 +319,8 @@ EditorWorld:
BuildableTerrainOverlay:
AllowedTerrainTypes: Clear, Road
MarkerLayerOverlay:
+ TilingPathTool:
+ DefaultStart: Clear
+ DefaultInner: Beach
+ DefaultEnd: Clear
Inherits@MapGenerators: ^MapGenerators
diff --git a/mods/ra/tilesets/desert.yaml b/mods/ra/tilesets/desert.yaml
index eddb8796a8..37f5123bb0 100644
--- a/mods/ra/tilesets/desert.yaml
+++ b/mods/ra/tilesets/desert.yaml
@@ -3437,42 +3437,42 @@ MultiBrushCollections:
MultiBrush@164:
Template: 164
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@164reverse:
Template: 164
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@165:
Template: 165
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@165reverse:
Template: 165
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@120:
Template: 120
Segment:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@120reverse:
Template: 120
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -3482,11 +3482,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@121reverse:
Template: 121
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -3496,11 +3496,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@122reverse:
Template: 122
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -3510,420 +3510,420 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@123reverse:
Template: 123
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@124:
Template: 124
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@124reverse:
Template: 124
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@125:
Template: 125
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@125reverse:
Template: 125
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@126:
Template: 126
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@126reverse:
Template: 126
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@127:
Template: 127
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@127reverse:
Template: 127
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@128:
Template: 128
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@128reverse:
Template: 128
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@129:
Template: 129
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@129reverse:
Template: 129
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@130:
Template: 130
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@130reverse:
Template: 130
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@500:
Template: 500
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@500reverse:
Template: 500
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@501:
Template: 501
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@501reverse:
Template: 501
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@139:
Template: 139
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@139reverse:
Template: 139
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@140:
Template: 140
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@140reverse:
Template: 140
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@141:
Template: 141
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@141reverse:
Template: 141
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@142:
Template: 142
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@142reverse:
Template: 142
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@143:
Template: 143
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@143reverse:
Template: 143
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@144:
Template: 144
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@144reverse:
Template: 144
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@145:
Template: 145
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@145reverse:
Template: 145
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@146:
Template: 146
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@146reverse:
Template: 146
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@147:
Template: 147
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@147reverse:
Template: 147
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@148:
Template: 148
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@148reverse:
Template: 148
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@151:
Template: 151
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@151reverse:
Template: 151
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@152:
Template: 152
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@152reverse:
Template: 152
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@154:
Template: 154
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@154reverse:
Template: 154
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@155:
Template: 155
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@155reverse:
Template: 155
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@156:
Template: 156
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@156reverse:
Template: 156
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@157:
Template: 157
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@157reverse:
Template: 157
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@158:
Template: 158
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@158reverse:
Template: 158
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@159:
Template: 159
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@159reverse:
Template: 159
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@161:
Template: 161
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@161reverse:
Template: 161
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@162:
Template: 162
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@162reverse:
Template: 162
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@400:
Template: 400
Segment:
diff --git a/mods/ra/tilesets/snow.yaml b/mods/ra/tilesets/snow.yaml
index 887ec0365e..65cffffed8 100644
--- a/mods/ra/tilesets/snow.yaml
+++ b/mods/ra/tilesets/snow.yaml
@@ -3833,11 +3833,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@173reverse:
Template: 173
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -3847,11 +3847,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@174reverse:
Template: 174
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -3861,11 +3861,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@175reverse:
Template: 175
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -3875,448 +3875,448 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@176reverse:
Template: 176
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@177:
Template: 177
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@177reverse:
Template: 177
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@178:
Template: 178
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@178reverse:
Template: 178
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@179:
Template: 179
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@179reverse:
Template: 179
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@180:
Template: 180
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@180reverse:
Template: 180
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@181:
Template: 181
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@181reverse:
Template: 181
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@182:
Template: 182
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@182reverse:
Template: 182
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@183:
Template: 183
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@183reverse:
Template: 183
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@184:
Template: 184
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@184reverse:
Template: 184
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@185:
Template: 185
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@185reverse:
Template: 185
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@192:
Template: 192
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@192reverse:
Template: 192
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@193:
Template: 193
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@193reverse:
Template: 193
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@194:
Template: 194
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@194reverse:
Template: 194
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@195:
Template: 195
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@195reverse:
Template: 195
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@196:
Template: 196
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@196reverse:
Template: 196
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@197:
Template: 197
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@197reverse:
Template: 197
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@198:
Template: 198
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@198reverse:
Template: 198
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@199:
Template: 199
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@199reverse:
Template: 199
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@200:
Template: 200
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@200reverse:
Template: 200
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@201:
Template: 201
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@201reverse:
Template: 201
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@203:
Template: 203
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@203reverse:
Template: 203
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@204:
Template: 204
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@204reverse:
Template: 204
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@206:
Template: 206
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@206reverse:
Template: 206
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@207:
Template: 207
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@207reverse:
Template: 207
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@208:
Template: 208
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@208reverse:
Template: 208
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@209:
Template: 209
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@209reverse:
Template: 209
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@210:
Template: 210
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@210reverse:
Template: 210
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@211:
Template: 211
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@211reverse:
Template: 211
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@213:
Template: 213
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@213reverse:
Template: 213
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@214:
Template: 214
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@214reverse:
Template: 214
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@227:
Template: 227
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@227reverse:
Template: 227
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@228:
Template: 228
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@228reverse:
Template: 228
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@401:
Template: 401
Segment:
diff --git a/mods/ra/tilesets/temperat.yaml b/mods/ra/tilesets/temperat.yaml
index 170e30d9f6..46f2e57367 100644
--- a/mods/ra/tilesets/temperat.yaml
+++ b/mods/ra/tilesets/temperat.yaml
@@ -4293,11 +4293,11 @@ MultiBrushCollections:
End: Clear.D
Inner: Road
Points: 1,0, 1,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@173reverse:
Template: 173
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 2,0
Start: Clear.U
@@ -4307,11 +4307,11 @@ MultiBrushCollections:
End: Clear.L
Inner: Road
Points: 2,0, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@174reverse:
Template: 174
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,1, 2,1
Start: Clear.R
@@ -4321,11 +4321,11 @@ MultiBrushCollections:
End: Clear.U
Inner: Road
Points: 1,2, 1,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@175reverse:
Template: 175
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
Start: Clear.D
@@ -4335,448 +4335,448 @@ MultiBrushCollections:
End: Clear.R
Inner: Road
Points: 0,2, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@176reverse:
Template: 176
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,1, 0,1
Start: Clear.L
MultiBrush@177:
Template: 177
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 0,1, 0,2, 0,3, 0,4, 1,4
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@177reverse:
Template: 177
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,4, 2,3, 1,3, 1,2, 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@178:
Template: 178
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1, 0,2, 0,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@178reverse:
Template: 178
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,3, 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@179:
Template: 179
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@179reverse:
Template: 179
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@180:
Template: 180
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 1,1, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@180reverse:
Template: 180
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,2, 2,1, 2,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@181:
Template: 181
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@181reverse:
Template: 181
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@182:
Template: 182
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2, 3,2, 4,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@182reverse:
Template: 182
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,1, 3,1, 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@183:
Template: 183
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@183reverse:
Template: 183
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@184:
Template: 184
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,2, 1,2, 2,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@184reverse:
Template: 184
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 1,1, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@185:
Template: 185
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1, 1,2, 2,2, 2,3, 3,3, 4,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@185reverse:
Template: 185
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 4,2, 3,2, 3,1, 2,1, 2,0, 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@192:
Template: 192
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2, 1,3, 2,3, 3,3
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@192reverse:
Template: 192
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 3,2, 2,2, 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@193:
Template: 193
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 2,2, 2,1, 3,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@193reverse:
Template: 193
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 3,0, 2,0, 1,0, 1,1, 1,2
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@194:
Template: 194
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,2, 1,2, 1,3
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@194reverse:
Template: 194
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,3, 2,2, 2,1, 1,1, 0,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@195:
Template: 195
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 0,3, 1,3, 2,3, 2,2, 2,1, 2,0
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@195reverse:
Template: 195
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 1,2, 0,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@196:
Template: 196
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@196reverse:
Template: 196
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@197:
Template: 197
Segment:
- End: RoadOut.RD
+ End: Road.Out.RD
Inner: Road
Points: 0,1, 0,2, 1,2, 1,3, 2,3
- Start: RoadIn.RD
+ Start: Road.In.RD
MultiBrush@197reverse:
Template: 197
Segment:
- End: RoadOut.LU
+ End: Road.Out.LU
Inner: Road
Points: 3,2, 3,1, 2,1, 2,0, 1,0
- Start: RoadIn.LU
+ Start: Road.In.LU
MultiBrush@198:
Template: 198
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@198reverse:
Template: 198
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@199:
Template: 199
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 0,2, 1,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@199reverse:
Template: 199
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 2,0, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@200:
Template: 200
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,1, 1,1, 1,2
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@200reverse:
Template: 200
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 2,1, 2,0, 1,0, 0,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@201:
Template: 201
Segment:
- End: RoadIn.RD
+ End: Road.In.RD
Inner: Road
Points: 0,0, 0,1, 0,2, 1,2
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@201reverse:
Template: 201
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: RoadOut.LU
+ Start: Road.Out.LU
MultiBrush@203:
Template: 203
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 0,2, 1,2, 2,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@203reverse:
Template: 203
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 2,1, 1,1, 1,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@204:
Template: 204
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,1, 0,2
- Start: RoadOut.RD
+ Start: Road.Out.RD
MultiBrush@204reverse:
Template: 204
Segment:
- End: RoadIn.LU
+ End: Road.In.LU
Inner: Road
Points: 1,2, 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@206:
Template: 206
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@206reverse:
Template: 206
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@207:
Template: 207
Segment:
- End: RoadOut.RU
+ End: Road.Out.RU
Inner: Road
Points: 1,3, 2,3, 2,2, 3,2, 3,1
- Start: RoadIn.RU
+ Start: Road.In.RU
MultiBrush@207reverse:
Template: 207
Segment:
- End: RoadOut.LD
+ End: Road.Out.LD
Inner: Road
Points: 2,0, 1,0, 1,1, 0,1, 0,2
- Start: RoadIn.LD
+ Start: Road.In.LD
MultiBrush@208:
Template: 208
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@208reverse:
Template: 208
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@209:
Template: 209
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 2,2, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@209reverse:
Template: 209
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 0,0, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@210:
Template: 210
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@210reverse:
Template: 210
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 2,0, 1,0, 0,0, 0,1
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@211:
Template: 211
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,2, 2,2, 2,1, 2,0
- Start: RoadOut.RU
+ Start: Road.Out.RU
MultiBrush@211reverse:
Template: 211
Segment:
- End: RoadIn.LD
+ End: Road.In.LD
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@213:
Template: 213
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 0,2, 1,2, 2,2, 2,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@213reverse:
Template: 213
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 1,1, 0,1
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@214:
Template: 214
Segment:
- End: RoadIn.RU
+ End: Road.In.RU
Inner: Road
Points: 1,2, 1,1, 2,1
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@214reverse:
Template: 214
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 1,0, 0,0, 0,1, 0,2
- Start: RoadOut.LD
+ Start: Road.Out.LD
MultiBrush@227:
Template: 227
Segment:
- End: Road.D
+ End: Road.Main.D
Inner: Road
Points: 0,0, 0,1
- Start: Road.D
+ Start: Road.Main.D
MultiBrush@227reverse:
Template: 227
Segment:
- End: Road.U
+ End: Road.Main.U
Inner: Road
Points: 1,1, 1,0
- Start: Road.U
+ Start: Road.Main.U
MultiBrush@228:
Template: 228
Segment:
- End: Road.R
+ End: Road.Main.R
Inner: Road
Points: 0,1, 1,1
- Start: Road.R
+ Start: Road.Main.R
MultiBrush@228reverse:
Template: 228
Segment:
- End: Road.L
+ End: Road.Main.L
Inner: Road
Points: 1,0, 0,0
- Start: Road.L
+ Start: Road.Main.L
MultiBrush@401:
Template: 401
Segment: