From ad08045e5f32236f806ca5044f9257518b496d24 Mon Sep 17 00:00:00 2001 From: Ashley Newson Date: Sun, 11 May 2025 00:45:48 +0100 Subject: [PATCH] Add path auto-tiling tool to map editor Exposes the TilingPath code used by the map generator as a map editor tool to help automate the process of tiling sequences of templates together. No additional template stitching definitions are added as part of this commit. As such, the tool currently only supports the same auto tiling as the map generator does. This includes: - RA and CnC support. - Beaches, land cliffs, and roads. Support for additional mods and templates can be added in follow-ups by adding the necessary MultiBrush definitions. Related changes included in this commit to support this work include: - Add support for sparse EditorBlits. - Add support for MultiBrush to EditorBlitSource conversion. - Add support for EditorBlitSource previewing. - Adjust the "Road" types used in segmented MultiBrush definitions. --- .../EditorBrushes/EditorBlit.cs | 145 ++++- .../EditorBrushes/EditorTilingPathBrush.cs | 371 +++++++++++++ .../MapGenerator/CellLayerUtils.cs | 30 +- OpenRA.Mods.Common/MapGenerator/Direction.cs | 59 +++ OpenRA.Mods.Common/MapGenerator/MultiBrush.cs | 79 ++- OpenRA.Mods.Common/MapGenerator/TilingPath.cs | 25 +- .../Traits/World/EditorActorPreview.cs | 12 +- .../Traits/World/TerrainRenderer.cs | 11 + .../Traits/World/TilingPathTool.cs | 497 ++++++++++++++++++ OpenRA.Mods.Common/TraitsInterfaces.cs | 1 + .../Logic/Editor/TilingPathToolLogic.cs | 111 ++++ mods/cnc/chrome/editor.yaml | 105 ++++ mods/cnc/fluent/chrome.ftl | 11 + mods/cnc/rules/map-generators.yaml | 2 +- mods/cnc/rules/world.yaml | 4 + mods/cnc/tilesets/desert.yaml | 248 ++++----- mods/cnc/tilesets/snow.yaml | 248 ++++----- mods/cnc/tilesets/temperat.yaml | 248 ++++----- mods/cnc/tilesets/winter.yaml | 248 ++++----- mods/common/chrome/editor.yaml | 108 +++- mods/common/fluent/chrome.ftl | 11 + mods/common/fluent/common.ftl | 6 + mods/ra/fluent/chrome.ftl | 1 - mods/ra/rules/map-generators.yaml | 2 +- mods/ra/rules/world.yaml | 4 + mods/ra/tilesets/desert.yaml | 264 +++++----- mods/ra/tilesets/snow.yaml | 264 +++++----- mods/ra/tilesets/temperat.yaml | 264 +++++----- 28 files changed, 2460 insertions(+), 919 deletions(-) create mode 100644 OpenRA.Mods.Common/EditorBrushes/EditorTilingPathBrush.cs create mode 100644 OpenRA.Mods.Common/Traits/World/TilingPathTool.cs create mode 100644 OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs 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: