Mapping merge driver: continued (#2803)

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
20kdc
2021-02-06 22:56:40 +00:00
committed by GitHub
parent 5cbb3f1222
commit 2f01d7899f
14 changed files with 1026 additions and 0 deletions

1
.gitattributes vendored
View File

@@ -34,6 +34,7 @@
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
Resources/Maps/**.yml merge=mapping-merge-driver
###############################################################################
# behavior for image files

4
.gitignore vendored
View File

@@ -284,3 +284,7 @@ BuildFiles/Windows/Godot/*
# Windows image file caches
Thumbs.db
ehthumbs.db
# Merge driver stuff
Content.Tools/test/out.yml

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="9.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RobustToolbox\Robust.Shared\Robust.Shared.csproj" />
</ItemGroup>
</Project>

83
Content.Tools/Map.cs Normal file
View File

@@ -0,0 +1,83 @@
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using YamlDotNet.Core;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Tools
{
public class Map
{
public Map(string path)
{
Path = path;
using var reader = new StreamReader(path);
var stream = new YamlStream();
stream.Load(reader);
Root = stream.Documents[0].RootNode;
TilemapNode = (YamlMappingNode) Root["tilemap"];
GridsNode = (YamlSequenceNode) Root["grids"];
_entitiesNode = (YamlSequenceNode) Root["entities"];
foreach (var entity in _entitiesNode)
{
var uid = uint.Parse(entity["uid"].AsString());
if (uid >= NextAvailableEntityId)
NextAvailableEntityId = uid + 1;
Entities[uid] = (YamlMappingNode) entity;
}
}
// Core
public string Path { get; }
public YamlNode Root { get; }
// Useful
public YamlMappingNode TilemapNode { get; }
public YamlSequenceNode GridsNode { get; }
// Entities lookup
private YamlSequenceNode _entitiesNode { get; }
public Dictionary<uint, YamlMappingNode> Entities { get; } = new Dictionary<uint, YamlMappingNode>();
public uint MaxId => Entities.Max(entry => entry.Key);
public uint NextAvailableEntityId { get; set; }
// ----
public void Save(string fileName)
{
// Update entities node
_entitiesNode.Children.Clear();
foreach (var kvp in Entities)
_entitiesNode.Add(kvp.Value);
using var writer = new StreamWriter(fileName);
var document = new YamlDocument(Root);
var stream = new YamlStream(document);
var emitter = new Emitter(writer);
var fixer = new TypeTagPreserver(emitter);
stream.Save(fixer, false);
writer.Flush();
}
public void Save()
{
Save(Path);
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using YamlDotNet.Core;
using YamlDotNet.RepresentationModel;
namespace Content.Tools
{
internal static class MappingMergeDriver
{
/// %A: Our file
/// %O: Origin (common, base) file
/// %B: Other file
/// %P: Actual filename of the resulting file
public static void Main(string[] args)
{
var ours = new Map(args[0]);
var based = new Map(args[1]); // On what?
var other = new Map(args[2]);
if ((ours.GridsNode.Children.Count != 1) || (based.GridsNode.Children.Count != 1) || (other.GridsNode.Children.Count != 1))
{
Console.WriteLine("one or more files had an amount of grids not equal to 1");
Environment.Exit(1);
}
if (!(new Merger(ours, based, other).Merge()))
{
Console.WriteLine("unable to merge!");
Environment.Exit(1);
}
ours.Save();
Environment.Exit(0);
}
}
}

356
Content.Tools/Merger.cs Normal file
View File

@@ -0,0 +1,356 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using YamlDotNet.Core;
using YamlDotNet.RepresentationModel;
namespace Content.Tools
{
public class Merger
{
public Map MapOurs { get; }
public Map MapBased { get; }
public Map MapOther { get; }
public Dictionary<uint, uint> TileMapFromOtherToOurs { get; } = new Dictionary<uint, uint>();
public Dictionary<uint, uint> TileMapFromBasedToOurs { get; } = new Dictionary<uint, uint>();
public Dictionary<uint, uint> EntityMapFromOtherToOurs { get; } = new Dictionary<uint, uint>();
public List<uint> EntityListDirectMerge { get; } = new List<uint>();
private const int ExpectedChunkSize = 16 * 16 * 4;
public Merger(Map ours, Map based, Map other)
{
MapOurs = ours;
MapBased = based;
MapOther = other;
}
public bool Merge()
{
PlanTileMapping(TileMapFromOtherToOurs, MapOther);
PlanTileMapping(TileMapFromBasedToOurs, MapBased);
MergeTiles();
PlanEntityMapping();
return MergeEntities();
}
// -- Tiles --
public void PlanTileMapping(Dictionary<uint, uint> relativeOtherToOurs, Map relativeOther)
{
var mapping = new Dictionary<string, uint>();
uint nextAvailable = 0;
foreach (var kvp in MapOurs.TilemapNode)
{
var k = uint.Parse(kvp.Key.ToString());
var v = kvp.Value.ToString();
mapping[v] = k;
if (k >= nextAvailable)
nextAvailable = k + 1;
}
foreach (var kvp in relativeOther.TilemapNode)
{
var k = uint.Parse(kvp.Key.ToString());
var v = kvp.Value.ToString();
if (mapping.ContainsKey(v))
{
relativeOtherToOurs[k] = mapping[v];
}
else
{
MapOurs.TilemapNode.Add(nextAvailable.ToString(CultureInfo.InvariantCulture), v);
relativeOtherToOurs[k] = nextAvailable++;
}
}
}
public void MergeTiles()
{
var a = MapOurs.GridsNode.Children[0];
var b = MapBased.GridsNode.Children[0];
var c = MapOther.GridsNode.Children[0];
var aChunks = a["chunks"];
var bChunks = b["chunks"];
var cChunks = c["chunks"];
MergeTileChunks((YamlSequenceNode) aChunks, (YamlSequenceNode) bChunks, (YamlSequenceNode) cChunks);
}
public void MergeTileChunks(YamlSequenceNode aChunks, YamlSequenceNode bChunks, YamlSequenceNode cChunks)
{
var aMap = ConvertTileChunks(aChunks);
var bMap = ConvertTileChunks(bChunks);
var cMap = ConvertTileChunks(cChunks);
var xMap = new HashSet<string>();
foreach (var kvp in aMap)
xMap.Add(kvp.Key);
// don't include b because that would mess with chunk deletion
foreach (var kvp in cMap)
xMap.Add(kvp.Key);
foreach (var ind in xMap)
{
using var a = new MemoryStream(GetChunkBytes(aMap, ind));
using var b = new MemoryStream(GetChunkBytes(bMap, ind));
using var c = new MemoryStream(GetChunkBytes(cMap, ind));
using var aR = new BinaryReader(a);
using var bR = new BinaryReader(b);
using var cR = new BinaryReader(c);
var outB = new byte[ExpectedChunkSize];
{
using (var outS = new MemoryStream(outB))
using (var outW = new BinaryWriter(outS))
for (var i = 0; i < ExpectedChunkSize; i += 4)
{
var aI = aR.ReadUInt32();
var bI = MapTileId(bR.ReadUInt32(), TileMapFromBasedToOurs);
var cI = MapTileId(cR.ReadUInt32(), TileMapFromOtherToOurs);
// cI needs translation.
uint result = aI;
if (aI == bI)
{
// If aI == bI then aI did not change anything, so cI always wins
result = cI;
}
else if (bI != cI)
{
// If bI != cI then cI definitely changed something (conflict, but overrides aI)
result = cI;
Console.WriteLine("WARNING: Tile (" + ind + ")[" + i + "] was changed by both branches.");
}
outW.Write(result);
}
}
// Actually output chunk
if (!aMap.ContainsKey(ind))
{
var res = new YamlMappingNode();
res.Children["ind"] = ind;
aMap[ind] = res;
}
aMap[ind].Children["tiles"] = Convert.ToBase64String(outB);
}
}
public uint MapTileId(uint src, Dictionary<uint, uint> mapping)
{
return (src & 0xFFFF0000) | mapping[src & 0xFFFF];
}
public Dictionary<string, YamlMappingNode> ConvertTileChunks(YamlSequenceNode chunks)
{
var map = new Dictionary<string, YamlMappingNode>();
foreach (var chunk in chunks)
map[chunk["ind"].ToString()] = (YamlMappingNode) chunk;
return map;
}
public byte[] GetChunkBytes(Dictionary<string, YamlMappingNode> chunks, string ind)
{
if (!chunks.ContainsKey(ind))
return new byte[ExpectedChunkSize];
return Convert.FromBase64String(chunks[ind]["tiles"].ToString());
}
// -- Entities --
public void PlanEntityMapping()
{
// Ok, so here's how it works:
// 1. Entities that do not exist in "based" are additions.
// 2. Entities that exist in "based" but do not exist in the one map or the other are removals.
// Find modifications and deletions
foreach (var kvp in MapBased.Entities)
{
var deletedByOurs = !MapOurs.Entities.ContainsKey(kvp.Key);
var deletedByOther = !MapOther.Entities.ContainsKey(kvp.Key);
if (deletedByOther && !deletedByOurs)
{
// Delete
MapOurs.Entities.Remove(kvp.Key);
}
else if (!(deletedByOurs || deletedByOther))
{
// Modify
EntityMapFromOtherToOurs[kvp.Key] = kvp.Key;
}
}
// Find additions
foreach (var kvp in MapOther.Entities)
{
if (!MapBased.Entities.ContainsKey(kvp.Key))
{
// New
var newId = MapOurs.NextAvailableEntityId++;
EntityMapFromOtherToOurs[kvp.Key] = newId;
}
}
}
public bool MergeEntities()
{
bool success = true;
foreach (var kvp in EntityMapFromOtherToOurs)
{
// For debug use.
// Console.WriteLine("Entity C/" + kvp.Key + " -> A/" + kvp.Value);
YamlMappingNode oursEnt;
if (MapOurs.Entities.ContainsKey(kvp.Value))
{
oursEnt = MapOurs.Entities[kvp.Value];
if (!MapBased.Entities.TryGetValue(kvp.Value, out var basedEnt))
{
basedEnt = oursEnt;
}
if (!MergeEntityNodes(oursEnt, basedEnt, MapOther.Entities[kvp.Key]))
{
Console.WriteLine("Unable to successfully merge entity C/" + kvp.Key);
success = false;
}
}
else
{
oursEnt = (YamlMappingNode) YamlTools.CopyYamlNodes(MapOther.Entities[kvp.Key]);
if (!MapEntity(oursEnt)) {
Console.WriteLine("Unable to successfully import entity C/" + kvp.Key);
success = false;
} else {
MapOurs.Entities[kvp.Value] = oursEnt;
}
}
oursEnt.Children["uid"] = kvp.Value.ToString(CultureInfo.InvariantCulture);
}
return success;
}
public bool MergeEntityNodes(YamlMappingNode ours, YamlMappingNode based, YamlMappingNode other)
{
// Copy to intermediate
var otherMapped = (YamlMappingNode) YamlTools.CopyYamlNodes(other);
if (!MapEntity(otherMapped))
return false;
// Merge stuff that isn't components
var path = "Entity" + (other["uid"].ToString());
YamlTools.MergeYamlMappings(ours, based, otherMapped, path, new string[] {"components"});
// Components are special
var ourComponents = new Dictionary<string, YamlMappingNode>();
var basedComponents = new Dictionary<string, YamlMappingNode>();
var ourComponentsNode = (YamlSequenceNode) ours["components"];
var basedComponentsNode = (YamlSequenceNode) based["components"];
var otherComponentsNode = (YamlSequenceNode) otherMapped["components"];
foreach (var component in ourComponentsNode)
{
var name = component["type"].ToString();
ourComponents[name] = (YamlMappingNode) component;
}
foreach (var component in basedComponentsNode)
{
var name = component["type"].ToString();
basedComponents[name] = (YamlMappingNode) component;
}
foreach (var otherComponent in otherComponentsNode)
{
var name = otherComponent["type"].ToString();
if (ourComponents.ContainsKey(name))
{
var ourComponent = ourComponents[name];
if (!basedComponents.TryGetValue(name, out var basedComponent))
basedComponent = new YamlMappingNode();
YamlTools.MergeYamlNodes(ourComponent, basedComponent, otherComponent, path + "/components/" + name);
}
else
{
ourComponentsNode.Add(otherComponent);
}
}
return true;
}
public bool MapEntity(YamlMappingNode other)
{
var path = "Entity" + (other["uid"].ToString());
if (other.Children.ContainsKey("components"))
{
var components = (YamlSequenceNode) other["components"];
foreach (var component in components)
{
var type = component["type"].ToString();
if (type == "Transform")
{
if (!MapEntityProperty((YamlMappingNode) component, "parent", path))
return false;
}
else if (type == "ContainerContainer")
{
MapEntityRecursiveAndBadly(component, path);
}
}
}
return true;
}
public bool MapEntityProperty(YamlMappingNode node, string property, string path)
{
if (node.Children.ContainsKey(property)) {
var prop = node[property];
if (prop is YamlScalarNode)
return MapEntityProperty((YamlScalarNode) prop, path + "/" + property);
}
return true;
}
public bool MapEntityProperty(YamlScalarNode node, string path)
{
if (uint.TryParse(node.ToString(), out var uid))
{
if (EntityMapFromOtherToOurs.ContainsKey(uid))
{
node.Value = EntityMapFromOtherToOurs[uid].ToString(CultureInfo.InvariantCulture);
}
else
{
Console.WriteLine($"Error finding UID in MapEntityRecursiveAndBadly {path}. To fix this, the merge driver needs to be improved.");
return false;
}
}
return true;
}
public bool MapEntityRecursiveAndBadly(YamlNode node, string path)
{
switch (node)
{
case YamlSequenceNode subSequence:
var idx = 0;
foreach (var val in subSequence)
if (!MapEntityRecursiveAndBadly(val, path + "/" + (idx++)))
return false;
return true;
case YamlMappingNode subMapping:
foreach (var kvp in subMapping)
if (!MapEntityRecursiveAndBadly(kvp.Key, path))
return false;
foreach (var kvp in subMapping)
if (!MapEntityRecursiveAndBadly(kvp.Value, path + "/" + kvp.Key.ToString()))
return false;
return true;
case YamlScalarNode subScalar:
return MapEntityProperty(subScalar, path);
default:
throw new ArgumentException($"Unrecognized YAML node type: {node.GetType()} at {path}");
}
}
}
}

View File

@@ -0,0 +1,25 @@
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
namespace Content.Tools
{
public class TypeTagPreserver : IEmitter
{
public TypeTagPreserver(IEmitter emitter)
{
Emitter = emitter;
}
private IEmitter Emitter { get; }
public void Emit(ParsingEvent @event)
{
if (@event is MappingStart mapping)
{
@event = new MappingStart(mapping.Anchor, mapping.Tag, false, mapping.Style, mapping.Start, mapping.End);
}
Emitter.Emit(@event);
}
}
}

199
Content.Tools/YamlTools.cs Normal file
View File

@@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using YamlDotNet.Core;
using YamlDotNet.RepresentationModel;
namespace Content.Tools
{
public static class YamlTools
{
public static YamlNode CopyYamlNodes(YamlNode other)
{
switch (other)
{
case YamlSequenceNode subSequence:
YamlSequenceNode tmp1 = new YamlSequenceNode();
MergeYamlSequences((YamlSequenceNode) tmp1, new YamlSequenceNode(), (YamlSequenceNode) other, "");
return tmp1;
case YamlMappingNode subMapping:
YamlMappingNode tmp2 = new YamlMappingNode();
MergeYamlMappings((YamlMappingNode) tmp2, new YamlMappingNode(), (YamlMappingNode) other, "", new string[] {});
return tmp2;
case YamlScalarNode subScalar:
YamlScalarNode tmp3 = new YamlScalarNode();
CopyYamlScalar(tmp3, subScalar);
return tmp3;
default:
throw new ArgumentException($"Unrecognized YAML node type for copy: {other.GetType()}", nameof(other));
}
}
public static bool TriTypeMatch(YamlNode ours, YamlNode based, YamlNode other)
{
var refType = other.GetType();
if (refType != based.GetType())
return false;
if (refType != ours.GetType())
return false;
return true;
}
public static void MergeYamlNodes(YamlNode ours, YamlNode based, YamlNode other, string path)
{
if (!TriTypeMatch(ours, based, other))
throw new ArgumentException($"Node type mismatch at {path}");
switch (other)
{
case YamlSequenceNode subSequence:
MergeYamlSequences((YamlSequenceNode) ours, (YamlSequenceNode) based, (YamlSequenceNode) other, path);
break;
case YamlMappingNode subMapping:
MergeYamlMappings((YamlMappingNode) ours, (YamlMappingNode) based, (YamlMappingNode) other, path, new string[] {});
break;
case YamlScalarNode subScalar:
// Console.WriteLine(path + " - " + ours + " || " + based + " || " + other);
var scalarA = (YamlScalarNode) ours;
var scalarB = (YamlScalarNode) based;
var scalarC = (YamlScalarNode) other;
var aeb = (scalarA.Value == scalarB.Value);
var cneb = (scalarC.Value != scalarB.Value);
if (aeb || cneb)
CopyYamlScalar(scalarA, scalarC);
// Console.WriteLine(path + " . " + ours + " || " + based + " || " + other);
break;
default:
throw new ArgumentException($"Unrecognized YAML node type at {path}: {other.GetType()}", nameof(other));
}
}
public static void MergeYamlSequences(YamlSequenceNode ours, YamlSequenceNode based, YamlSequenceNode other, string path)
{
if ((ours.Children.Count == based.Children.Count) && (other.Children.Count == ours.Children.Count))
{
// this is terrible and doesn't do proper rearrange detection
// but it looks as if vectors might be arrays
// so rearrange detection might break more stuff...
// nope, they aren't, but still good to have
for (var i = 0; i < ours.Children.Count; i++)
MergeYamlNodes(ours.Children[i], based.Children[i], other.Children[i], path + "/" + i);
return;
}
// for now, just copy other -> ours
// I am aware this is terrible
ours.Children.Clear();
foreach (var c in other.Children)
ours.Add(CopyYamlNodes(c));
}
public static void MergeYamlMappings(YamlMappingNode ours, YamlMappingNode based, YamlMappingNode other, string path, string[] ignoreThese)
{
// Deletions/modifications
foreach (var kvp in based)
{
if (ignoreThese.Contains(kvp.Key.ToString()))
continue;
var localPath = path + "/" + kvp.Key.ToString();
var deletedByOurs = !ours.Children.ContainsKey(kvp.Key);
var deletedByOther = !other.Children.ContainsKey(kvp.Key);
if (deletedByOther && (!deletedByOurs))
{
// Delete
ours.Children.Remove(kvp.Key);
}
else if (!(deletedByOurs || deletedByOther))
{
// Modify
var a = ours[kvp.Key];
var b = kvp.Value; // based[kvp.Key]
var c = other[kvp.Key];
if (!TriTypeMatch(a, b, c))
{
Console.WriteLine("Warning: Type mismatch (defaulting to value C) at " + localPath);
ours.Children[kvp.Key] = CopyYamlNodes(c);
}
else
{
MergeYamlNodes(a, b, c, localPath);
}
}
}
// Additions
foreach (var kvp in other)
{
if (ignoreThese.Contains(kvp.Key.ToString()))
continue;
var localPath = path + "/" + kvp.Key.ToString();
if (!based.Children.ContainsKey(kvp.Key))
{
if (ours.Children.ContainsKey(kvp.Key))
{
// Both sides added the same key. Try to merge.
var a = ours[kvp.Key];
var b = based[kvp.Key];
var c = kvp.Value; // other[kvp.Key]
if (!TriTypeMatch(a, b, c))
{
Console.WriteLine("Warning: Type mismatch (defaulting to value C) at " + localPath);
ours.Children[kvp.Key] = CopyYamlNodes(c);
}
else
{
MergeYamlNodes(a, b, c, localPath);
}
}
else
{
// Well that was easy
ours.Children[kvp.Key] = CopyYamlNodes(kvp.Value);
}
}
}
}
// NOTE: This is a heuristic ONLY! And is also not used at the moment because sequence matching isn't in place.
// It could also be massively improved.
public static float YamlNodesHeuristic(YamlNode a, YamlNode b)
{
if (a.GetType() != b.GetType())
return 0.0f;
switch (a)
{
case YamlSequenceNode x:
return YamlSequencesHeuristic((YamlSequenceNode) a, (YamlSequenceNode) b);
case YamlMappingNode y:
return YamlMappingsHeuristic((YamlMappingNode) a, (YamlMappingNode) b);
case YamlScalarNode z:
return (((YamlScalarNode) a).Value == ((YamlScalarNode) b).Value) ? 1.0f : 0.0f;
default:
throw new ArgumentException($"Unrecognized YAML node type: {a.GetType()}", nameof(a));
}
}
public static float YamlSequencesHeuristic(YamlSequenceNode a, YamlSequenceNode b)
{
if (a.Children.Count != b.Children.Count)
return 0.0f;
if (a.Children.Count == 0)
return 1.0f;
var total = 0.0f;
for (var i = 0; i < a.Children.Count; i++)
total += YamlNodesHeuristic(a.Children[i], b.Children[i]);
return total / a.Children.Count;
}
public static float YamlMappingsHeuristic(YamlMappingNode a, YamlMappingNode b)
{
return (a == b) ? 1.0f : 0.0f;
}
public static void CopyYamlScalar(YamlScalarNode dst, YamlScalarNode src)
{
dst.Value = src.Value;
dst.Style = src.Style;
}
}
}

95
Content.Tools/test/0A.yml Normal file
View File

@@ -0,0 +1,95 @@
meta:
format: 2
name: DemoStation
author: Space-Wizards
postmapinit: false
tilemap:
0: space
7: floor_dark
8: floor_elevator_shaft
9: floor_freezer
10: floor_gold
11: floor_green_circuit
12: floor_hydro
13: floor_lino
14: floor_mono
15: floor_reinforced
16: floor_rock_vault
17: floor_showroom
18: floor_snow
19: floor_steel
20: floor_steel_dirty
21: floor_techmaint
22: floor_white
23: floor_wood
24: lattice
25: plating
26: underplating
grids:
- settings:
chunksize: 16
tilesize: 1
snapsize: 1
chunks:
- ind: "-2,-2"
comment: "Ew in A | FQ in B | Fg in C | Fg in Out - SHOULD CAUSE CONFLICT WARNING"
tiles: EwAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABcAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAaAAAAGgAAABMAAAATAAAAEwAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAaAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAVAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAGgAAABMAAAATAAAAEwAAABUAAAAZAAAAFQAAABUAAAAVAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGQAAABUAAAAaAAAAFQAAAA==
- ind: "-1,-1"
tiles: EwAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAWAAAAFgAAABYAAAAWAAAAEwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAAaAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAGgAAABMAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAZAAAAFQAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAAA==
- ind: "-1,0"
tiles: EwAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAWAAAAFgAAABYAAAAWAAAAEwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAAaAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAGgAAABMAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAZAAAAFQAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAAA==
- ind: "0,0"
tiles: FwAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABcAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAaAAAAGgAAABMAAAATAAAAEwAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAaAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAVAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAGgAAABMAAAATAAAAEwAAABUAAAAZAAAAFQAAABUAAAAVAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGQAAABUAAAAaAAAAFQAAAA==
entities:
- uid: 0
type: FakeTestDummy
components:
- parent: 855
pos: -5.5,-1.5
rot: -1.5707963267948966 rad
type: Transform
- type: ContainerContainer
typeChange:
- 0
- 1
- 2
example:
- 0
- 1
- 2
- 3
- 855
- "contributionA"
- uid: 1
type: FakeTestDummy
components:
- parent: 0
pos: -15.5,-14.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 2
type: FakeTestDummy
components:
- parent: 1
pos: -15.5,-14.5
rot: -1.5707963267948966 rad
type: Transform
- type: ThereShouldBeTwoOfTheseInOutputOfMergeTestAAA
- uid: 3
type: AnnoyingPlaceholderOnPurpose
components:
- parent: 0
type: Transform
- uid: 855
components:
- name: Saltern Station
type: MetaData
- parent: null
type: Transform
- index: 0
type: MapGrid
- shapes:
- !type:PhysShapeGrid
grid: 0
type: Physics

86
Content.Tools/test/0B.yml Normal file
View File

@@ -0,0 +1,86 @@
meta:
format: 2
name: DemoStation
author: Space-Wizards
postmapinit: false
tilemap:
0: space
7: floor_dark
8: floor_elevator_shaft
9: floor_freezer
10: floor_gold
11: floor_green_circuit
12: floor_hydro
13: floor_lino
14: floor_mono
15: floor_reinforced
16: floor_rock_vault
17: floor_showroom
18: floor_snow
19: floor_steel
20: floor_steel_dirty
21: floor_techmaint
22: floor_white
23: floor_wood
24: lattice
25: plating
26: underplating
grids:
- settings:
chunksize: 16
tilesize: 1
snapsize: 1
chunks:
- ind: "-2,-2"
comment: "Ew in A | FQ in B | Fg in C | Fg in Out - SHOULD CAUSE CONFLICT WARNING"
tiles: FQAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABcAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAaAAAAGgAAABMAAAATAAAAEwAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAaAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAVAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAGgAAABMAAAATAAAAEwAAABUAAAAZAAAAFQAAABUAAAAVAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGQAAABUAAAAaAAAAFQAAAA==
- ind: "-1,-1"
tiles: FQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAVAAAAFQAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAGgAAABUAAAAaAAAAGgAAABoAAAAZAAAAFQAAABUAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFQAAABUAAAAVAAAAFQAAABUAAAAaAAAAGQAAABUAAAAVAAAAGgAAABYAAAAWAAAAFgAAABoAAAAaAAAAGgAAABUAAAAVAAAAFQAAABUAAAAVAAAAGgAAABkAAAAVAAAAFQAAABoAAAAaAAAAFgAAABoAAAAaAAAAGQAAABkAAAAVAAAAFQAAABUAAAAVAAAAFQAAABoAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAFQAAABUAAAAaAAAAGQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABoAAAAaAAAAGgAAABUAAAAaAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAZAAAAFQAAAA0AAAANAAAADQAAAA0AAAANAAAAGgAAABUAAAAVAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAANAAAADQAAAA0AAAANAAAADQAAABoAAAAVAAAAFQAAABkAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAADQAAAA0AAAANAAAADQAAAA0AAAAaAAAAGgAAABoAAAAZAAAAEwAAAAkAAAAJAAAACQAAAAkAAAAJAAAAGgAAAA0AAAANAAAADQAAAA0AAAANAAAAFwAAABcAAAAXAAAAGgAAABoAAAAJAAAACQAAAAkAAAAJAAAACQAAABoAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAaAAAAGgAAABMAAAAaAAAAGgAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAGgAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAAA==
- ind: "-1,0"
tiles: EwAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAWAAAAFgAAABYAAAAWAAAAEwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAAaAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAGgAAABMAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAZAAAAFQAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAAA==
- ind: "0,-1"
tiles: FgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFgAAABYAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABoAAAAWAAAAFgAAABYAAAAWAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAWAAAAGgAAABoAAAAaAAAAFgAAABYAAAAWAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAZAAAAFQAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFQAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABYAAAAaAAAAGgAAABYAAAAWAAAAGgAAABoAAAAWAAAAFgAAABoAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAXAAAAGgAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFwAAABoAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABoAAAAaAAAAFgAAABcAAAATAAAAEwAAABMAAAATAAAAEwAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAXAAAAEwAAABMAAAATAAAAEwAAABMAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFwAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABoAAAAWAAAAFgAAAA==
- ind: "0,0"
tiles: FwAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABcAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAaAAAAGgAAABMAAAATAAAAEwAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAaAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAVAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAGgAAABMAAAATAAAAEwAAABUAAAAZAAAAFQAAABUAAAAVAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGQAAABUAAAAaAAAAFQAAAA==
entities:
- uid: 0
type: FakeTestDummy
components:
- parent: 855
pos: -15.5,-11.5
rot: -1.5707963267948966 rad
type: Transform
- type: ContainerContainer
typeChange:
- 0
- 1
example:
- 0
- 1
- 3
- 855
- uid: 1
type: FakeTestDummy
components:
- parent: 0
pos: -15.5,-14.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3
type: AnnoyingPlaceholderOnPurpose
components:
- parent: 0
type: Transform
- uid: 855
components:
- name: Saltern Station
type: MetaData
- parent: null
type: Transform
- index: 0
type: MapGrid
- shapes:
- !type:PhysShapeGrid
grid: 0
type: Physics

105
Content.Tools/test/0C.yml Normal file
View File

@@ -0,0 +1,105 @@
meta:
format: 2
name: DemoStation
author: Space-Wizards
postmapinit: false
tilemap:
0: space
1: floor_asteroid_coarse_sand0
2: floor_asteroid_coarse_sand1
3: floor_asteroid_coarse_sand2
4: floor_asteroid_coarse_sand_dug
5: floor_asteroid_sand
6: floor_asteroid_tile
7: floor_dark
8: floor_elevator_shaft
9: floor_freezer
10: floor_gold
11: floor_green_circuit
12: floor_hydro
13: floor_lino
14: floor_mono
15: floor_reinforced
16: floor_rock_vault
17: floor_showroom
18: floor_snow
19: floor_steel
20: floor_steel_dirty
21: floor_techmaint
22: floor_white
23: floor_wood
24: lattice
25: plating
26: underplating
grids:
- settings:
chunksize: 16
tilesize: 1
snapsize: 1
chunks:
- ind: "-2,-2"
comment: "Ew in A | FQ in B | Fg in C | Fg in Out - SHOULD CAUSE CONFLICT WARNING"
tiles: FgAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABcAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAaAAAAGgAAABMAAAATAAAAEwAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAaAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAVAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAGgAAABMAAAATAAAAEwAAABUAAAAZAAAAFQAAABUAAAAVAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGQAAABUAAAAaAAAAFQAAAA==
- ind: "-1,-1"
tiles: FQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAVAAAAFQAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAGgAAABUAAAAaAAAAGgAAABoAAAAZAAAAFQAAABUAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFQAAABUAAAAVAAAAFQAAABUAAAAaAAAAGQAAABUAAAAVAAAAGgAAABYAAAAWAAAAFgAAABoAAAAaAAAAGgAAABUAAAAVAAAAFQAAABUAAAAVAAAAGgAAABkAAAAVAAAAFQAAABoAAAAaAAAAFgAAABoAAAAaAAAAGQAAABkAAAAVAAAAFQAAABUAAAAVAAAAFQAAABoAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAFQAAABUAAAAaAAAAGQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABoAAAAaAAAAGgAAABUAAAAaAAAAGgAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAZAAAAFQAAAA0AAAANAAAADQAAAA0AAAANAAAAGgAAABUAAAAVAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAANAAAADQAAAA0AAAANAAAADQAAABoAAAAVAAAAFQAAABkAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAADQAAAA0AAAANAAAADQAAAA0AAAAaAAAAGgAAABoAAAAZAAAAEwAAAAkAAAAJAAAACQAAAAkAAAAJAAAAGgAAAA0AAAANAAAADQAAAA0AAAANAAAAFwAAABcAAAAXAAAAGgAAABoAAAAJAAAACQAAAAkAAAAJAAAACQAAABoAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAaAAAAGgAAABMAAAAaAAAAGgAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAGgAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAAA==
- ind: "-1,0"
tiles: EwAAABYAAAAWAAAAFgAAABYAAAATAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABoAAAAWAAAAFgAAABYAAAAWAAAAEwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAAaAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAGgAAABMAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABoAAAATAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAEwAAABoAAAAaAAAAEwAAABMAAAAaAAAAGgAAABMAAAAaAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAZAAAAFQAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAEwAAABMAAAATAAAAEwAAABoAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAAA==
- ind: "0,-1"
tiles: FgAAABMAAAATAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAATAAAAEwAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFgAAABYAAAAaAAAAEwAAABMAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABoAAAAWAAAAFgAAABYAAAAWAAAAGgAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABoAAAAWAAAAGgAAABoAAAAaAAAAFgAAABYAAAAWAAAAGgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAZAAAAGgAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGQAAABoAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABkAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAZAAAAFQAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFQAAABoAAAATAAAAEwAAABMAAAAaAAAAGgAAABYAAAAaAAAAGgAAABYAAAAWAAAAGgAAABoAAAAWAAAAFgAAABoAAAAaAAAAEwAAABMAAAATAAAAGgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAXAAAAGgAAABMAAAATAAAAEwAAABoAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFwAAABoAAAATAAAAEwAAABMAAAAaAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABoAAAAaAAAAFgAAABcAAAATAAAAEwAAABMAAAATAAAAEwAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAaAAAAFgAAABYAAAAXAAAAEwAAABMAAAATAAAAEwAAABMAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAGgAAABYAAAAWAAAAFwAAABMAAAATAAAAEwAAABMAAAATAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABoAAAAWAAAAFgAAAA==
entities:
- uid: 0
type: FakeTestDummy
components:
- parent: 855
pos: -15.5,-11.5
rot: -1.5707963267948966 rad
type: Transform
- type: ContainerContainer
typeChange:
something: true
example:
- 0
- 1
- 2
- 3
- 4
- 855
- "contributionC"
- uid: 1
type: FakeTestDummy
components:
- parent: 0
pos: -5.5,-4.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 2
type: FakeTestDummy
components:
- parent: 1
pos: -15.5,-14.5
rot: -1.5707963267948966 rad
type: Transform
- type: ThereShouldBeTwoOfTheseInOutputOfMergeTestBBB
- uid: 3
type: AnnoyingPlaceholderOnPurpose
components:
- parent: 0
type: Transform
- uid: 4
type: ThisShouldHaveParentChangedToFollowUID
components:
- parent: 2
type: Transform
- uid: 855
components:
- name: Saltern Station
type: MetaData
- parent: null
type: Transform
- index: 0
type: MapGrid
- shapes:
- !type:PhysShapeGrid
grid: 0
type: Physics

3
Content.Tools/test/run.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
cp 0A.yml out.yml
../bin/Debug/net5.0/Content.Tools out.yml 0B.yml 0C.yml

View File

@@ -89,6 +89,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX", "RobustToolbox\Xaml
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlX.Runtime", "RobustToolbox\XamlX\src\XamlX.Runtime\XamlX.Runtime.csproj", "{440426C1-8DCA-43F6-967F-94439B8DAF47}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Content.Tools", "Content.Tools\Content.Tools.csproj", "{75AB8F8D-9E56-4B12-85E3-E03A852B31CC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -193,6 +195,10 @@ Global
{440426C1-8DCA-43F6-967F-94439B8DAF47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{440426C1-8DCA-43F6-967F-94439B8DAF47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{440426C1-8DCA-43F6-967F-94439B8DAF47}.Release|Any CPU.Build.0 = Release|Any CPU
{75AB8F8D-9E56-4B12-85E3-E03A852B31CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75AB8F8D-9E56-4B12-85E3-E03A852B31CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75AB8F8D-9E56-4B12-85E3-E03A852B31CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75AB8F8D-9E56-4B12-85E3-E03A852B31CC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

9
Tools/mapping-merge-driver.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
# Add this to .git/config:
# [merge "mapping-merge-driver"]
# name = Merge driver for maps
# driver = Tools/mapping-merge-driver.sh %A %O %B
dotnet run --project ./Content.Tools "$@"