diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 005bc82..d2d3316 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -38,6 +38,7 @@ public static partial class TestData ["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty()], ["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty()], ["Serialization/TestData/Map/map_external_tileset_multi/map-external-tileset-multi", (string f) => TestData.MapExternalTilesetMulti(f), Array.Empty()], + ["Serialization/TestData/Map/map_external_tileset_wangset/map-external-tileset-wangset", (string f) => TestData.MapExternalTilesetWangset(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs new file mode 100644 index 0000000..9aaa7d7 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs @@ -0,0 +1,92 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapExternalTilesetWangset(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 24, + TileHeight = 24, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "tileset", + TileWidth = 24, + TileHeight = 24, + TileCount = 48, + Columns = 10, + Source = $"wangset-tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Transformations = new Transformations + { + HFlip = true, + VFlip = true, + Rotate = false, + PreferUntransformed = false + }, + Grid = new Grid + { + Orientation = GridOrientation.Orthogonal, + Width = 32, + Height = 32 + }, + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 2, 2, 12, 11, 0, + 1, 12, 1, 11, 0, + 2, 1, 0, 1, 0, + 12, 11, 12, 2, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.FlippedHorizontally, FlippingFlags.None, FlippingFlags.FlippedHorizontally, FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.FlippedVertically, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically | FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically | FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj new file mode 100644 index 0000000..cea9ad6 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj @@ -0,0 +1,36 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[2147483650, 2, 2147483660, 2147483659, 0, + 1073741825, 12, 1, 3221225483, 0, + 2, 1, 0, 3221225473, 0, + 12, 11, 12, 2147483650, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":24, + "tilesets":[ + { + "firstgid":1, + "source":"wangset-tileset.tsj" + }], + "tilewidth":24, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx new file mode 100644 index 0000000..656fddb --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx @@ -0,0 +1,13 @@ + + + + + +2147483650,2,2147483660,2147483659,0, +1073741825,12,1,3221225483,0, +2,1,0,3221225473,0, +12,11,12,2147483650,0, +0,0,0,0,0 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png new file mode 100644 index 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png differ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj new file mode 100644 index 0000000..511641a --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj @@ -0,0 +1,69 @@ +{ "columns":10, + "grid": + { + "height":32, + "orientation":"orthogonal", + "width":32 + }, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":48, + "tiledversion":"1.11.0", + "tileheight":24, + "tilewidth":24, + "transformations": + { + "hflip":true, + "preferuntransformed":false, + "rotate":false, + "vflip":true + }, + "type":"tileset", + "version":"1.10", + "wangsets":[ + { + "colors":[ + { + "color":"#ff0000", + "name":"Water", + "probability":1, + "tile":0 + }, + { + "color":"#00ff00", + "name":"Grass", + "probability":1, + "tile":-1 + }, + { + "color":"#0000ff", + "name":"Stone", + "probability":1, + "tile":29 + }], + "name":"test-terrain", + "tile":-1, + "type":"mixed", + "wangtiles":[ + { + "tileid":0, + "wangid":[1, 1, 0, 0, 0, 1, 1, 1] + }, + { + "tileid":1, + "wangid":[1, 1, 1, 1, 0, 0, 0, 1] + }, + { + "tileid":10, + "wangid":[0, 0, 0, 1, 1, 1, 1, 1] + }, + { + "tileid":11, + "wangid":[0, 1, 1, 1, 1, 1, 0, 0] + }] + }] +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx new file mode 100644 index 0000000..d2b8666 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/DotTiled/Model/Tileset/WangColor.cs b/DotTiled/Model/Tileset/WangColor.cs index e278bb9..9ac751c 100644 --- a/DotTiled/Model/Tileset/WangColor.cs +++ b/DotTiled/Model/Tileset/WangColor.cs @@ -8,7 +8,7 @@ public class WangColor public required string Name { get; set; } public string Class { get; set; } = ""; public required Color Color { get; set; } - public required uint Tile { get; set; } + public required int Tile { get; set; } public float Probability { get; set; } = 0f; // Elements diff --git a/DotTiled/Model/Tileset/Wangset.cs b/DotTiled/Model/Tileset/Wangset.cs index 8d4d1a5..61f8496 100644 --- a/DotTiled/Model/Tileset/Wangset.cs +++ b/DotTiled/Model/Tileset/Wangset.cs @@ -7,7 +7,7 @@ public class Wangset // Attributes public required string Name { get; set; } public string Class { get; set; } = ""; - public required uint Tile { get; set; } + public required int Tile { get; set; } // Elements // At most one of diff --git a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs index 6eefdb7..d455b42 100644 --- a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs +++ b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs @@ -64,7 +64,8 @@ internal partial class Tmj var transparentColor = element.GetOptionalPropertyParseable("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null); var type = element.GetOptionalProperty("type", null); var version = element.GetOptionalProperty("version", null); - //var wangsets = element.GetOptionalPropertyCustom?>("wangsets", ReadWangSets, null); + var transformations = element.GetOptionalPropertyCustom("transformations", ReadTransformations, null); + var wangsets = element.GetOptionalPropertyCustom?>("wangsets", el => el.GetValueAsList(e => ReadWangset(e, customTypeDefinitions)), null); if (source is not null) { @@ -108,7 +109,24 @@ internal partial class Tmj Tiles = tiles, TileWidth = tileWidth, Version = version, - //Wangsets = wangsets + Wangsets = wangsets, + Transformations = transformations + }; + } + + internal static Transformations ReadTransformations(JsonElement element) + { + var hFlip = element.GetOptionalProperty("hflip", false); + var vFlip = element.GetOptionalProperty("vflip", false); + var rotate = element.GetOptionalProperty("rotate", false); + var preferUntransformed = element.GetOptionalProperty("preferuntransformed", false); + + return new Transformations + { + HFlip = hFlip, + VFlip = vFlip, + Rotate = rotate, + PreferUntransformed = preferUntransformed }; } @@ -208,7 +226,7 @@ internal partial class Tmj var colors = element.GetOptionalPropertyCustom>("colors", e => e.GetValueAsList(el => ReadWangColor(el, customTypeDefinitions)), []); var name = element.GetRequiredProperty("name"); var properties = element.GetOptionalPropertyCustom?>("properties", e => ReadProperties(e, customTypeDefinitions), null); - var tile = element.GetOptionalProperty("tile", 0); + var tile = element.GetOptionalProperty("tile", 0); var type = element.GetOptionalProperty("type", ""); var wangTiles = element.GetOptionalPropertyCustom>("wangtiles", e => e.GetValueAsList(ReadWangTile), []); @@ -232,7 +250,7 @@ internal partial class Tmj var name = element.GetRequiredProperty("name"); var probability = element.GetOptionalProperty("probability", 1.0f); var properties = element.GetOptionalPropertyCustom?>("properties", e => ReadProperties(e, customTypeDefinitions), null); - var tile = element.GetOptionalProperty("tile", 0); + var tile = element.GetOptionalProperty("tile", 0); return new WangColor { diff --git a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs index 9f576bb..1912df2 100644 --- a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs +++ b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs @@ -193,10 +193,10 @@ internal partial class Tmx internal static Transformations ReadTransformations(XmlReader reader) { // Attributes - var hFlip = reader.GetOptionalAttributeParseable("hflip") ?? false; - var vFlip = reader.GetOptionalAttributeParseable("vflip") ?? false; - var rotate = reader.GetOptionalAttributeParseable("rotate") ?? false; - var preferUntransformed = reader.GetOptionalAttributeParseable("preferuntransformed") ?? false; + var hFlip = (reader.GetOptionalAttributeParseable("hflip") ?? 0) == 1; + var vFlip = (reader.GetOptionalAttributeParseable("vflip") ?? 0) == 1; + var rotate = (reader.GetOptionalAttributeParseable("rotate") ?? 0) == 1; + var preferUntransformed = (reader.GetOptionalAttributeParseable("preferuntransformed") ?? 0) == 1; reader.ReadStartElement("transformations"); return new Transformations { HFlip = hFlip, VFlip = vFlip, Rotate = rotate, PreferUntransformed = preferUntransformed }; @@ -266,7 +266,7 @@ internal partial class Tmx // Attributes var name = reader.GetRequiredAttribute("name"); var @class = reader.GetOptionalAttribute("class") ?? ""; - var tile = reader.GetRequiredAttributeParseable("tile"); + var tile = reader.GetRequiredAttributeParseable("tile"); // Elements Dictionary? properties = null; @@ -303,7 +303,7 @@ internal partial class Tmx var name = reader.GetRequiredAttribute("name"); var @class = reader.GetOptionalAttribute("class") ?? ""; var color = reader.GetRequiredAttributeParseable("color"); - var tile = reader.GetRequiredAttributeParseable("tile"); + var tile = reader.GetRequiredAttributeParseable("tile"); var probability = reader.GetOptionalAttributeParseable("probability") ?? 0f; // Elements @@ -339,6 +339,8 @@ internal partial class Tmx return indices; }); + reader.ReadStartElement("wangtile"); + return new WangTile { TileID = tileID,