Add XML docs for entire model

This commit is contained in:
Daniel Cronqvist 2024-08-20 23:23:40 +02:00
parent 608e77927a
commit 0d19127fb7
42 changed files with 1023 additions and 75 deletions

View file

@ -1,7 +1,7 @@
test: test:
dotnet test src/DotTiled.sln dotnet test src/DotTiled.sln
docs-serve: docs-build docs-serve:
docfx docs/docfx.json --serve docfx docs/docfx.json --serve
docs-build: docs-build:

View file

@ -4,19 +4,19 @@ namespace DotTiled.Tests;
public static partial class DotTiledAssert public static partial class DotTiledAssert
{ {
internal static void AssertObject(Model.Layers.Objects.Object expected, Model.Layers.Objects.Object actual) internal static void AssertObject(Model.Object expected, Model.Object actual)
{ {
// Attributes // Attributes
AssertEqual(expected.ID, actual.ID, nameof(Model.Layers.Objects.Object.ID)); AssertEqual(expected.ID, actual.ID, nameof(Model.Object.ID));
AssertEqual(expected.Name, actual.Name, nameof(Model.Layers.Objects.Object.Name)); AssertEqual(expected.Name, actual.Name, nameof(Model.Object.Name));
AssertEqual(expected.Type, actual.Type, nameof(Model.Layers.Objects.Object.Type)); AssertEqual(expected.Type, actual.Type, nameof(Model.Object.Type));
AssertEqual(expected.X, actual.X, nameof(Model.Layers.Objects.Object.X)); AssertEqual(expected.X, actual.X, nameof(Model.Object.X));
AssertEqual(expected.Y, actual.Y, nameof(Model.Layers.Objects.Object.Y)); AssertEqual(expected.Y, actual.Y, nameof(Model.Object.Y));
AssertEqual(expected.Width, actual.Width, nameof(Model.Layers.Objects.Object.Width)); AssertEqual(expected.Width, actual.Width, nameof(Model.Object.Width));
AssertEqual(expected.Height, actual.Height, nameof(Model.Layers.Objects.Object.Height)); AssertEqual(expected.Height, actual.Height, nameof(Model.Object.Height));
AssertEqual(expected.Rotation, actual.Rotation, nameof(Model.Layers.Objects.Object.Rotation)); AssertEqual(expected.Rotation, actual.Rotation, nameof(Model.Object.Rotation));
AssertEqual(expected.Visible, actual.Visible, nameof(Model.Layers.Objects.Object.Visible)); AssertEqual(expected.Visible, actual.Visible, nameof(Model.Object.Visible));
AssertEqual(expected.Template, actual.Template, nameof(Model.Layers.Objects.Object.Template)); AssertEqual(expected.Template, actual.Template, nameof(Model.Object.Template));
AssertProperties(expected.Properties, actual.Properties); AssertProperties(expected.Properties, actual.Properties);

View file

@ -2,20 +2,65 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Base class for all layer types in a map.
/// To check the type of a layer, <see href="https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching">use C# pattern matching</see>,
/// or some other mechanism to determine the type of the layer at runtime.
/// </summary>
public abstract class BaseLayer public abstract class BaseLayer
{ {
// Attributes /// <summary>
/// Unique ID of the layer. Each layer that is added to a map gets a unique ID. Even if a layer is deleted, no layer ever gets the same ID.
/// </summary>
public required uint ID { get; set; } public required uint ID { get; set; }
/// <summary>
/// The name of the layer.
/// </summary>
public string Name { get; set; } = ""; public string Name { get; set; } = "";
/// <summary>
/// The class of the layer.
/// </summary>
public string Class { get; set; } = ""; public string Class { get; set; } = "";
/// <summary>
/// The opacity of the layer as a value from 0 (fully transparent) to 1 (fully opaque).
/// </summary>
public float Opacity { get; set; } = 1.0f; public float Opacity { get; set; } = 1.0f;
/// <summary>
/// Whether the layer is shown (true) or hidden (false).
/// </summary>
public bool Visible { get; set; } = true; public bool Visible { get; set; } = true;
/// <summary>
/// A tint color that is multiplied with any tiles drawn by this layer.
/// </summary>
public Color? TintColor { get; set; } public Color? TintColor { get; set; }
/// <summary>
/// Horizontal offset for this layer in pixels.
/// </summary>
public float OffsetX { get; set; } = 0.0f; public float OffsetX { get; set; } = 0.0f;
/// <summary>
/// Vertical offset for this layer in pixels.
/// </summary>
public float OffsetY { get; set; } = 0.0f; public float OffsetY { get; set; } = 0.0f;
/// <summary>
/// Horizontal parallax factor for this layer.
/// </summary>
public float ParallaxX { get; set; } = 1.0f; public float ParallaxX { get; set; } = 1.0f;
/// <summary>
/// Vertical parallax factor for this layer.
/// </summary>
public float ParallaxY { get; set; } = 1.0f; public float ParallaxY { get; set; } = 1.0f;
// At most one of /// <summary>
/// Layer properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
} }

View file

@ -2,50 +2,143 @@ using System;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Specifies the encoding used to encode the tile layer data.
/// </summary>
public enum DataEncoding public enum DataEncoding
{ {
/// <summary>
/// The data is stored as comma-separated values.
/// </summary>
Csv, Csv,
/// <summary>
/// The data is stored as base64-encoded binary data.
/// </summary>
Base64 Base64
} }
/// <summary>
/// Specifies the compression algorithm used to compress the tile layer data.
/// </summary>
public enum DataCompression public enum DataCompression
{ {
/// <summary>
/// GZip compression.
/// </summary>
GZip, GZip,
/// <summary>
/// ZLib compression.
/// </summary>
ZLib, ZLib,
/// <summary>
/// ZStandard compression. Currently not supported by DotTiled and will throw an exception if encountered.
/// </summary>
ZStd ZStd
} }
/// <summary>
/// The flipping flags for a tile. These can be used to check how a tile is flipped or rotated. Uses the
/// <see href="https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-flagsattribute">FlagsAttribute, for which there is plenty of documentation.</see>
/// </summary>
[Flags] [Flags]
public enum FlippingFlags : uint public enum FlippingFlags : uint
{ {
/// <summary>
/// No flipping.
/// </summary>
None = 0, None = 0,
/// <summary>
/// The tile is flipped horizontally.
/// </summary>
FlippedHorizontally = 0x80000000u, FlippedHorizontally = 0x80000000u,
/// <summary>
/// The tile is flipped vertically.
/// </summary>
FlippedVertically = 0x40000000u, FlippedVertically = 0x40000000u,
/// <summary>
/// The tile is flipped diagonally.
/// </summary>
FlippedDiagonally = 0x20000000u, FlippedDiagonally = 0x20000000u,
/// <summary>
/// In hexagonal maps, the tile is rotated 120 degrees clockwise.
/// </summary>
RotatedHexagonal120 = 0x10000000u RotatedHexagonal120 = 0x10000000u
} }
/// <summary>
/// Represents part of a tile layer of a map that is infinite.
/// </summary>
public class Chunk public class Chunk
{ {
// Attributes /// <summary>
/// The X coordinate of the chunk in tiles.
/// </summary>
public required int X { get; set; } public required int X { get; set; }
/// <summary>
/// The Y coordinate of the chunk in tiles.
/// </summary>
public required int Y { get; set; } public required int Y { get; set; }
/// <summary>
/// The width of the chunk in tiles.
/// </summary>
public required uint Width { get; set; } public required uint Width { get; set; }
/// <summary>
/// The height of the chunk in tiles.
/// </summary>
public required uint Height { get; set; } public required uint Height { get; set; }
// Data /// <summary>
/// The parsed chunk data, as a list of tile GIDs.
/// To get an actual tile ID, you map it to a local tile ID using the correct tileset. Please refer to
/// <see href="https://doc.mapeditor.org/en/stable/reference/global-tile-ids/#mapping-a-gid-to-a-local-tile-id">the documentation on how to do this</see>.
/// </summary>
public required uint[] GlobalTileIDs { get; set; } public required uint[] GlobalTileIDs { get; set; }
/// <summary>
/// The parsed flipping flags for each tile in the chunk. Appear in the same order as the tiles in the layer in <see cref="GlobalTileIDs"/>.
/// </summary>
public required FlippingFlags[] FlippingFlags { get; set; } public required FlippingFlags[] FlippingFlags { get; set; }
} }
/// <summary>
/// Represents the data of a tile layer.
/// </summary>
public class Data public class Data
{ {
// Attributes /// <summary>
/// The encoding used to encode the tile layer data.
/// </summary>
public DataEncoding? Encoding { get; set; } public DataEncoding? Encoding { get; set; }
/// <summary>
/// The compression method used to compress the tile layer data.
/// </summary>
public DataCompression? Compression { get; set; } public DataCompression? Compression { get; set; }
// Data /// <summary>
/// The parsed tile layer data, as a list of tile GIDs.
/// To get an actual tile ID, you map it to a local tile ID using the correct tileset. Please refer to
/// <see href="https://doc.mapeditor.org/en/stable/reference/global-tile-ids/#mapping-a-gid-to-a-local-tile-id">the documentation on how to do this</see>.
/// </summary>
public uint[]? GlobalTileIDs { get; set; } public uint[]? GlobalTileIDs { get; set; }
/// <summary>
/// The parsed flipping flags for each tile in the layer. Appear in the same order as the tiles in the layer in <see cref="GlobalTileIDs"/>.
/// </summary>
public FlippingFlags[]? FlippingFlags { get; set; } public FlippingFlags[]? FlippingFlags { get; set; }
/// <summary>
/// If the map is infinite, it will instead contain a list of chunks.
/// </summary>
public Chunk[]? Chunks { get; set; } public Chunk[]? Chunks { get; set; }
} }

View file

@ -2,10 +2,13 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a group of layers, to form a hierarchy.
/// </summary>
public class Group : BaseLayer public class Group : BaseLayer
{ {
// Uses same attributes as BaseLayer /// <summary>
/// The contained sub-layers in the group.
// Any number of /// </summary>
public List<BaseLayer> Layers { get; set; } = []; public List<BaseLayer> Layers { get; set; } = [];
} }

View file

@ -1,13 +1,32 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents an image layer in a map.
/// </summary>
public class ImageLayer : BaseLayer public class ImageLayer : BaseLayer
{ {
// Attributes /// <summary>
/// The X position of the image layer in pixels.
/// </summary>
public uint X { get; set; } = 0; public uint X { get; set; } = 0;
/// <summary>
/// The Y position of the image layer in pixels.
/// </summary>
public uint Y { get; set; } = 0; public uint Y { get; set; } = 0;
/// <summary>
/// Whether the image drawn by this layer is repeated along the X axis.
/// </summary>
public bool RepeatX { get; set; } = false; public bool RepeatX { get; set; } = false;
/// <summary>
/// Whether the image drawn by this layer is repeated along the Y axis.
/// </summary>
public bool RepeatY { get; set; } = false; public bool RepeatY { get; set; } = false;
// At most one of /// <summary>
/// The image to be drawn by this image layer.
/// </summary>
public Image? Image { get; set; } public Image? Image { get; set; }
} }

View file

@ -2,22 +2,59 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents the order in which objects can be drawn.
/// </summary>
public enum DrawOrder public enum DrawOrder
{ {
/// <summary>
/// Objects are drawn sorted by their Y coordinate.
/// </summary>
TopDown, TopDown,
/// <summary>
/// Objects are drawn in the order of appearance in the object layer.
/// </summary>
Index Index
} }
/// <summary>
/// Represents an object layer in a map. In Tiled documentation, it is often called an "object group".
/// </summary>
public class ObjectLayer : BaseLayer public class ObjectLayer : BaseLayer
{ {
// Attributes /// <summary>
/// The X coordinate of the object layer in tiles.
/// </summary>
public uint X { get; set; } = 0; public uint X { get; set; } = 0;
/// <summary>
/// The Y coordinate of the object layer in tiles.
/// </summary>
public uint Y { get; set; } = 0; public uint Y { get; set; } = 0;
/// <summary>
/// The width of the object layer in tiles. Meaningless.
/// </summary>
public uint? Width { get; set; } public uint? Width { get; set; }
/// <summary>
/// The height of the object layer in tiles. Meaningless.
/// </summary>
public uint? Height { get; set; } public uint? Height { get; set; }
/// <summary>
/// A color that is multiplied with any tile objects drawn by this layer.
/// </summary>
public Color? Color { get; set; } public Color? Color { get; set; }
/// <summary>
/// Whether the objects are drawn according to the order of appearance (<see cref="DrawOrder.Index"/>) or sorted by their Y coordinate (<see cref="DrawOrder.TopDown"/>).
/// </summary>
public DrawOrder DrawOrder { get; set; } = DrawOrder.TopDown; public DrawOrder DrawOrder { get; set; } = DrawOrder.TopDown;
// Elements /// <summary>
/// The objects in the object layer.
/// </summary>
public required List<Object> Objects { get; set; } public required List<Object> Objects { get; set; }
} }

View file

@ -1,3 +1,7 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// An ellipse object in a map. The existing <see cref="Object.X"/>, <see cref="Object.Y"/>, <see cref="Object.Width"/>,
/// and <see cref="Object.Height"/> properties are used to determine the size of the ellipse.
/// </summary>
public class EllipseObject : Object { } public class EllipseObject : Object { }

View file

@ -2,20 +2,63 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Base class for objects in object layers.
/// </summary>
public abstract class Object public abstract class Object
{ {
// Attributes /// <summary>
/// Unique ID of the objects. Each object that is placed on a map gets a unique ID. Even if an object was deleted, no object gets the same ID.
/// </summary>
public uint? ID { get; set; } public uint? ID { get; set; }
/// <summary>
/// The name of the object. An arbitrary string.
/// </summary>
public string Name { get; set; } = ""; public string Name { get; set; } = "";
/// <summary>
/// The class of the object. An arbitrary string.
/// </summary>
public string Type { get; set; } = ""; public string Type { get; set; } = "";
/// <summary>
/// The X coordinate of the object in pixels.
/// </summary>
public float X { get; set; } = 0f; public float X { get; set; } = 0f;
/// <summary>
/// The Y coordinate of the object in pixels.
/// </summary>
public float Y { get; set; } = 0f; public float Y { get; set; } = 0f;
/// <summary>
/// The width of the object in pixels.
/// </summary>
public float Width { get; set; } = 0f; public float Width { get; set; } = 0f;
/// <summary>
/// The height of the object in pixels.
/// </summary>
public float Height { get; set; } = 0f; public float Height { get; set; } = 0f;
/// <summary>
/// The rotation of the object in degrees clockwise around (X, Y).
/// </summary>
public float Rotation { get; set; } = 0f; public float Rotation { get; set; } = 0f;
/// <summary>
/// Whether the object is shown (true) or hidden (false).
/// </summary>
public bool Visible { get; set; } = true; public bool Visible { get; set; } = true;
/// <summary>
/// A reference to a template file.
/// </summary>
public string? Template { get; set; } public string? Template { get; set; }
// Elements /// <summary>
/// Object properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
} }

View file

@ -1,3 +1,7 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A point object in a map. The existing <see cref="Object.X"/> and <see cref="Object.Y"/> properties are used to
/// determine the position of the point.
/// </summary>
public class PointObject : Object { } public class PointObject : Object { }

View file

@ -3,8 +3,15 @@ using System.Numerics;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A polygon object in a map. The existing <see cref="Object.X"/> and <see cref="Object.Y"/> properties are used as
/// the origin of the polygon.
/// </summary>
public class PolygonObject : Object public class PolygonObject : Object
{ {
// Attributes /// <summary>
/// The points that make up the polygon.
/// <see cref="Object.X"/> and <see cref="Object.Y"/> are used as the origin of the polygon.
/// </summary>
public required List<Vector2> Points { get; set; } public required List<Vector2> Points { get; set; }
} }

View file

@ -3,8 +3,14 @@ using System.Numerics;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A polyline object in a map. The existing <see cref="Object.X"/> and <see cref="Object.Y"/> properties are used as
/// the origin of the polyline.
/// </summary>
public class PolylineObject : Object public class PolylineObject : Object
{ {
// Attributes /// <summary>
/// The points that make up the polyline. <see cref="Object.X"/> and <see cref="Object.Y"/> are used as the origin of the polyline.
/// </summary>
public required List<Vector2> Points { get; set; } public required List<Vector2> Points { get; set; }
} }

View file

@ -1,3 +1,7 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A rectangle object in a map. The existing <see cref="Object.X"/>, <see cref="Object.Y"/>, <see cref="Object.Width"/>,
/// and <see cref="Object.Height"/> properties are used to determine the size of the rectangle.
/// </summary>
public class RectangleObject : Object { } public class RectangleObject : Object { }

View file

@ -2,36 +2,115 @@ using System.Globalization;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// The horizontal alignment of text.
/// </summary>
public enum TextHorizontalAlignment public enum TextHorizontalAlignment
{ {
/// <summary>
/// The text is aligned to the left.
/// </summary>
Left, Left,
/// <summary>
/// The text is aligned to the center.
/// </summary>
Center, Center,
/// <summary>
/// The text is aligned to the right.
/// </summary>
Right, Right,
/// <summary>
/// The text is justified.
/// </summary>
Justify Justify
} }
/// <summary>
/// The vertical alignment of text.
/// </summary>
public enum TextVerticalAlignment public enum TextVerticalAlignment
{ {
/// <summary>
/// The text is aligned to the top.
/// </summary>
Top, Top,
/// <summary>
/// The text is aligned to the center.
/// </summary>
Center, Center,
/// <summary>
/// The text is aligned to the bottom.
/// </summary>
Bottom Bottom
} }
/// <summary>
/// A text object in a map.
/// </summary>
public class TextObject : Object public class TextObject : Object
{ {
// Attributes /// <summary>
/// The font family used for the text.
/// </summary>
public string FontFamily { get; set; } = "sans-serif"; public string FontFamily { get; set; } = "sans-serif";
/// <summary>
/// The size of the font in pixels.
/// </summary>
public int PixelSize { get; set; } = 16; public int PixelSize { get; set; } = 16;
/// <summary>
/// Whether word wrapping is enabled.
/// </summary>
public bool Wrap { get; set; } = false; public bool Wrap { get; set; } = false;
/// <summary>
/// The color of the text.
/// </summary>
public Color Color { get; set; } = Color.Parse("#000000", CultureInfo.InvariantCulture); public Color Color { get; set; } = Color.Parse("#000000", CultureInfo.InvariantCulture);
/// <summary>
/// Whether the text is bold.
/// </summary>
public bool Bold { get; set; } = false; public bool Bold { get; set; } = false;
/// <summary>
/// Whether the text is italic.
/// </summary>
public bool Italic { get; set; } = false; public bool Italic { get; set; } = false;
/// <summary>
/// Whether a line should be drawn below the text.
/// </summary>
public bool Underline { get; set; } = false; public bool Underline { get; set; } = false;
/// <summary>
/// Whether a line should be drawn through the text.
/// </summary>
public bool Strikeout { get; set; } = false; public bool Strikeout { get; set; } = false;
/// <summary>
/// Whether kerning should be used while rendering the text.
/// </summary>
public bool Kerning { get; set; } = true; public bool Kerning { get; set; } = true;
/// <summary>
/// The horizontal alignment of the text.
/// </summary>
public TextHorizontalAlignment HorizontalAlignment { get; set; } = TextHorizontalAlignment.Left; public TextHorizontalAlignment HorizontalAlignment { get; set; } = TextHorizontalAlignment.Left;
/// <summary>
/// The vertical alignment of the text.
/// </summary>
public TextVerticalAlignment VerticalAlignment { get; set; } = TextVerticalAlignment.Top; public TextVerticalAlignment VerticalAlignment { get; set; } = TextVerticalAlignment.Top;
// Elements /// <summary>
/// The text to be displayed.
/// </summary>
public string Text { get; set; } = ""; public string Text { get; set; } = "";
} }

View file

@ -1,6 +1,12 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A tile object in a map.
/// </summary>
public class TileObject : Object public class TileObject : Object
{ {
/// <summary>
/// A reference to a tile.
/// </summary>
public uint GID { get; set; } public uint GID { get; set; }
} }

View file

@ -1,13 +1,32 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a tile layer in a map.
/// </summary>
public class TileLayer : BaseLayer public class TileLayer : BaseLayer
{ {
// Attributes /// <summary>
/// The X coordinate of the layer in tiles.
/// </summary>
public uint X { get; set; } = 0; public uint X { get; set; } = 0;
/// <summary>
/// The Y coordinate of the layer in tiles.
/// </summary>
public uint Y { get; set; } = 0; public uint Y { get; set; } = 0;
/// <summary>
/// The width of the layer in tiles. Always the same as the map width for fixed-size maps.
/// </summary>
public required uint Width { get; set; } public required uint Width { get; set; }
/// <summary>
/// The height of the layer in tiles. Always the same as the map height for fixed-size maps.
/// </summary>
public required uint Height { get; set; } public required uint Height { get; set; }
// At most one of /// <summary>
/// The tile layer data.
/// </summary>
public Data? Data { get; set; } public Data? Data { get; set; }
} }

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a boolean property.
/// </summary>
public class BoolProperty : IProperty public class BoolProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.Bool; public PropertyType Type => PropertyType.Bool;
/// <summary>
/// The boolean value of the property.
/// </summary>
public required bool Value { get; set; } public required bool Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new BoolProperty public IProperty Clone() => new BoolProperty
{ {
Name = Name, Name = Name,

View file

@ -3,13 +3,29 @@ using System.Linq;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a class property.
/// </summary>
public class ClassProperty : IProperty public class ClassProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
public PropertyType Type => Model.Properties.PropertyType.Class;
/// <inheritdoc/>
public PropertyType Type => Model.PropertyType.Class;
/// <summary>
/// The type of the class property. This will be the name of a custom defined
/// type in Tiled.
/// </summary>
public required string PropertyType { get; set; } public required string PropertyType { get; set; }
/// <summary>
/// The properties of the class property.
/// </summary>
public required Dictionary<string, IProperty> Properties { get; set; } public required Dictionary<string, IProperty> Properties { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new ClassProperty public IProperty Clone() => new ClassProperty
{ {
Name = Name, Name = Name,

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a color property.
/// </summary>
public class ColorProperty : IProperty public class ColorProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.Color; public PropertyType Type => PropertyType.Color;
/// <summary>
/// The color value of the property.
/// </summary>
public required Color Value { get; set; } public required Color Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new ColorProperty public IProperty Clone() => new ColorProperty
{ {
Name = Name, Name = Name,

View file

@ -3,25 +3,87 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents the types of objects that can use a custom class.
/// Uses the <see href="https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-flagsattribute">FlagsAttribute, for which there is plenty of documentation.</see>
/// </summary>
[Flags] [Flags]
public enum CustomClassUseAs public enum CustomClassUseAs
{ {
/// <summary>
/// Any property on any kind of object.
/// </summary>
Property, Property,
/// <summary>
/// A map.
/// </summary>
Map, Map,
/// <summary>
/// A layer.
/// </summary>
Layer, Layer,
/// <summary>
/// An object.
/// </summary>
Object, Object,
/// <summary>
/// A tile.
/// </summary>
Tile, Tile,
/// <summary>
/// A tileset.
/// </summary>
Tileset, Tileset,
/// <summary>
/// A Wang color.
/// </summary>
WangColor, WangColor,
/// <summary>
/// A Wangset.
/// </summary>
Wangset, Wangset,
/// <summary>
/// A project.
/// </summary>
Project, Project,
/// <summary>
/// All types.
/// </summary>
All = Property | Map | Layer | Object | Tile | Tileset | WangColor | Wangset | Project All = Property | Map | Layer | Object | Tile | Tileset | WangColor | Wangset | Project
} }
/// <summary>
/// Represents a custom class definition in Tiled. Refer to the
/// <see href="https://doc.mapeditor.org/en/stable/manual/custom-properties/#custom-types">documentation of custom types to understand how they work</see>.
/// </summary>
public class CustomClassDefinition : CustomTypeDefinition public class CustomClassDefinition : CustomTypeDefinition
{ {
/// <summary>
/// The color of the custom class inside the Tiled editor.
/// </summary>
public Color? Color { get; set; } public Color? Color { get; set; }
/// <summary>
/// Whether the custom class should be drawn with a fill color.
/// </summary>
public bool DrawFill { get; set; } public bool DrawFill { get; set; }
/// <summary>
/// What the custom class can be used as, or rather, what types of objects can use it.
/// </summary>
public CustomClassUseAs UseAs { get; set; } public CustomClassUseAs UseAs { get; set; }
/// <summary>
/// The members of the custom class, with their names, types and default values.
/// </summary>
public List<IProperty> Members { get; set; } = []; public List<IProperty> Members { get; set; } = [];
} }

View file

@ -2,15 +2,40 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents the storage type of a custom enum.
/// </summary>
public enum CustomEnumStorageType public enum CustomEnumStorageType
{ {
/// <summary>
/// The backing value is an integer.
/// </summary>
Int, Int,
/// <summary>
/// The backing value is a string.
/// </summary>
String String
} }
/// <summary>
/// Represents a custom enum definition in Tiled. Refer to the
/// <see href="https://doc.mapeditor.org/en/stable/manual/custom-properties/#custom-types">documentation of custom types to understand how they work</see>.
/// </summary>
public class CustomEnumDefinition : CustomTypeDefinition public class CustomEnumDefinition : CustomTypeDefinition
{ {
/// <summary>
/// The storage type of the custom enum.
/// </summary>
public CustomEnumStorageType StorageType { get; set; } public CustomEnumStorageType StorageType { get; set; }
/// <summary>
/// The values of the custom enum.
/// </summary>
public List<string> Values { get; set; } = []; public List<string> Values { get; set; } = [];
/// <summary>
/// Whether the value should be treated as flags.
/// </summary>
public bool ValueAsFlags { get; set; } public bool ValueAsFlags { get; set; }
} }

View file

@ -1,7 +1,17 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Base class for custom type definitions.
/// </summary>
public abstract class CustomTypeDefinition public abstract class CustomTypeDefinition
{ {
/// <summary>
/// The ID of the custom type.
/// </summary>
public uint ID { get; set; } public uint ID { get; set; }
/// <summary>
/// The name of the custom type.
/// </summary>
public string Name { get; set; } = ""; public string Name { get; set; } = "";
} }

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a file property.
/// </summary>
public class FileProperty : IProperty public class FileProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.File; public PropertyType Type => PropertyType.File;
/// <summary>
/// The value of the property.
/// </summary>
public required string Value { get; set; } public required string Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new FileProperty public IProperty Clone() => new FileProperty
{ {
Name = Name, Name = Name,

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a float property.
/// </summary>
public class FloatProperty : IProperty public class FloatProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.Float; public PropertyType Type => PropertyType.Float;
/// <summary>
/// The float value of the property.
/// </summary>
public required float Value { get; set; } public required float Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new FloatProperty public IProperty Clone() => new FloatProperty
{ {
Name = Name, Name = Name,

View file

@ -1,9 +1,24 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Interface for properties that can be attached to objects, tiles, tilesets, maps etc.
/// </summary>
public interface IProperty public interface IProperty
{ {
/// <summary>
/// The name of the property.
/// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// The type of the property.
/// </summary>
public PropertyType Type { get; } public PropertyType Type { get; }
/// <summary>
/// Clones the property, only used for copying properties when performing overriding
/// with templates.
/// </summary>
/// <returns>An identical, but non-reference-equal, instance of the same property.</returns>
IProperty Clone(); IProperty Clone();
} }

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents an integer property.
/// </summary>
public class IntProperty : IProperty public class IntProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.Int; public PropertyType Type => PropertyType.Int;
/// <summary>
/// The integer value of the property.
/// </summary>
public required int Value { get; set; } public required int Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new IntProperty public IProperty Clone() => new IntProperty
{ {
Name = Name, Name = Name,

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents an object property.
/// </summary>
public class ObjectProperty : IProperty public class ObjectProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.Object; public PropertyType Type => PropertyType.Object;
/// <summary>
/// The object identifier referenced by the property.
/// </summary>
public required uint Value { get; set; } public required uint Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new ObjectProperty public IProperty Clone() => new ObjectProperty
{ {
Name = Name, Name = Name,

View file

@ -1,13 +1,47 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents the type of a property.
/// </summary>
public enum PropertyType public enum PropertyType
{ {
/// <summary>
/// A string property.
/// </summary>
String, String,
/// <summary>
/// An integer property.
/// </summary>
Int, Int,
/// <summary>
/// A float property.
/// </summary>
Float, Float,
/// <summary>
/// A boolean property.
/// </summary>
Bool, Bool,
/// <summary>
/// A color property.
/// </summary>
Color, Color,
/// <summary>
/// A file property.
/// </summary>
File, File,
/// <summary>
/// An object property.
/// </summary>
Object, Object,
/// <summary>
/// A class property.
/// </summary>
Class Class
} }

View file

@ -1,11 +1,22 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a string property.
/// </summary>
public class StringProperty : IProperty public class StringProperty : IProperty
{ {
/// <inheritdoc/>
public required string Name { get; set; } public required string Name { get; set; }
/// <inheritdoc/>
public PropertyType Type => PropertyType.String; public PropertyType Type => PropertyType.String;
/// <summary>
/// The string value of the property.
/// </summary>
public required string Value { get; set; } public required string Value { get; set; }
/// <inheritdoc/>
public IProperty Clone() => new StringProperty public IProperty Clone() => new StringProperty
{ {
Name = Name, Name = Name,

View file

@ -1,8 +1,17 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// A single frame of an animated tile.
/// </summary>
public class Frame public class Frame
{ {
// Attributes /// <summary>
/// The local tile ID within the parent tileset.
/// </summary>
public required uint TileID { get; set; } public required uint TileID { get; set; }
/// <summary>
/// How long (in milliseconds) this frame should be displayed before advancing to the next frame.
/// </summary>
public required uint Duration { get; set; } public required uint Duration { get; set; }
} }

View file

@ -1,15 +1,38 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Orientation of the grid for the tiles in this tileset.
/// </summary>
public enum GridOrientation public enum GridOrientation
{ {
/// <summary>
/// The grid is orthogonal.
/// </summary>
Orthogonal, Orthogonal,
/// <summary>
/// The grid is isometric.
/// </summary>
Isometric Isometric
} }
/// <summary>
/// Used to specify how tile overlays for terrain and collision information are rendered in isometric maps.
/// </summary>
public class Grid public class Grid
{ {
// Attributes /// <summary>
/// Orientation of the grid for the tiles in this tileset.
/// </summary>
public GridOrientation Orientation { get; set; } = GridOrientation.Orthogonal; public GridOrientation Orientation { get; set; } = GridOrientation.Orthogonal;
/// <summary>
/// Width of a grid cell.
/// </summary>
public required uint Width { get; set; } public required uint Width { get; set; }
/// <summary>
/// Height of a grid cell.
/// </summary>
public required uint Height { get; set; } public required uint Height { get; set; }
} }

View file

@ -1,19 +1,58 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// The format of an image.
/// </summary>
public enum ImageFormat public enum ImageFormat
{ {
/// <summary>
/// Portable Network Graphics.
/// </summary>
Png, Png,
/// <summary>
/// Graphics Interchange Format.
/// </summary>
Gif, Gif,
/// <summary>
/// Joint Photographic Experts Group.
/// </summary>
Jpg, Jpg,
/// <summary>
/// Windows Bitmap.
/// </summary>
Bmp Bmp
} }
/// <summary>
/// Represents an image that is used by a tileset.
/// </summary>
public class Image public class Image
{ {
// Attributes /// <summary>
/// The format of the image.
/// </summary>
public ImageFormat? Format { get; set; } public ImageFormat? Format { get; set; }
/// <summary>
/// The reference to the image file.
/// </summary>
public string? Source { get; set; } public string? Source { get; set; }
/// <summary>
/// Defines a specific color that is treated as transparent.
/// </summary>
public Color? TransparentColor { get; set; } public Color? TransparentColor { get; set; }
/// <summary>
/// The image width in pixels, used for tile index correction when the image changes.
/// </summary>
public uint? Width { get; set; } public uint? Width { get; set; }
/// <summary>
/// The image height in pixels, used for tile index correction when the image changes.
/// </summary>
public uint? Height { get; set; } public uint? Height { get; set; }
} }

View file

@ -2,20 +2,64 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a single tile in a tileset, when using a collection of images to represent the tileset.
/// <see href="https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tile">Tiled documentation for Tileset tiles</see>
/// </summary>
public class Tile public class Tile
{ {
// Attributes /// <summary>
/// The local tile ID within its tileset.
/// </summary>
public required uint ID { get; set; } public required uint ID { get; set; }
/// <summary>
/// The class of the tile. Is inherited by tile objects
/// </summary>
public string Type { get; set; } = ""; public string Type { get; set; } = "";
/// <summary>
/// A percentage indicating the probability that this tile is chosen when it competes with others while editing with the terrain tool.
/// </summary>
public float Probability { get; set; } = 0f; public float Probability { get; set; } = 0f;
/// <summary>
/// The X position of the sub-rectangle representing this tile within the tileset image.
/// </summary>
public uint X { get; set; } = 0; public uint X { get; set; } = 0;
/// <summary>
/// The Y position of the sub-rectangle representing this tile within the tileset image.
/// </summary>
public uint Y { get; set; } = 0; public uint Y { get; set; } = 0;
/// <summary>
/// The width of the sub-rectangle representing this tile within the tileset image.
/// </summary>
public required uint Width { get; set; } public required uint Width { get; set; }
/// <summary>
/// The height of the sub-rectangle representing this tile within the tileset image.
/// </summary>
public required uint Height { get; set; } public required uint Height { get; set; }
// Elements /// <summary>
/// Tile properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
/// <summary>
/// The image representing this tile. Only used for tilesets that composed of a collection of images.
/// </summary>
public Image? Image { get; set; } public Image? Image { get; set; }
/// <summary>
/// Unclear what this is for.
/// </summary>
public ObjectLayer? ObjectLayer { get; set; } public ObjectLayer? ObjectLayer { get; set; }
/// <summary>
/// The animation frames for this tile.
/// </summary>
public List<Frame>? Animation { get; set; } public List<Frame>? Animation { get; set; }
} }

View file

@ -1,8 +1,17 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Is used to specify an offset in pixels in tilesets, to be applied when drawing a tile from the related tileset.
/// </summary>
public class TileOffset public class TileOffset
{ {
// Attributes /// <summary>
/// The horizontal offset in pixels.
/// </summary>
public float X { get; set; } = 0f; public float X { get; set; } = 0f;
/// <summary>
/// The vertical offset in pixels.
/// </summary>
public float Y { get; set; } = 0f; public float Y { get; set; } = 0f;
} }

View file

@ -2,60 +2,208 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// The alignment of tile objects.
/// </summary>
public enum ObjectAlignment public enum ObjectAlignment
{ {
/// <summary>
/// The alignment is unspecified. Tile objects will use <see cref="BottomLeft"/> in orthogonal maps, and <see cref="Bottom"/> in isometric maps.
/// </summary>
Unspecified, Unspecified,
/// <summary>
/// The tile object is aligned to the top left of the tile.
/// </summary>
TopLeft, TopLeft,
/// <summary>
/// The tile object is aligned to the top of the tile.
/// </summary>
Top, Top,
/// <summary>
/// The tile object is aligned to the top right of the tile.
/// </summary>
TopRight, TopRight,
/// <summary>
/// The tile object is aligned to the left of the tile.
/// </summary>
Left, Left,
/// <summary>
/// The tile object is aligned to the center of the tile.
/// </summary>
Center, Center,
/// <summary>
/// The tile object is aligned to the right of the tile.
/// </summary>
Right, Right,
/// <summary>
/// The tile object is aligned to the bottom left of the tile.
/// </summary>
BottomLeft, BottomLeft,
/// <summary>
/// The tile object is aligned to the bottom of the tile.
/// </summary>
Bottom, Bottom,
/// <summary>
/// The tile object is aligned to the bottom right of the tile.
/// </summary>
BottomRight BottomRight
} }
/// <summary>
/// The size to use when rendering tiles from a tileset on a tile layer.
/// </summary>
public enum TileRenderSize public enum TileRenderSize
{ {
/// <summary>
/// The tile is drawn at the size of the tile in the tileset.
/// </summary>
Tile, Tile,
/// <summary>
/// The tile is drawn at the tile grid size of the map.
/// </summary>
Grid Grid
} }
/// <summary>
/// Determines how a tile is rendered in a tile set.
/// </summary>
public enum FillMode public enum FillMode
{ {
/// <summary>
/// The tile is stretched to fill the tile size, possibly distorting the tile.
/// </summary>
Stretch, Stretch,
/// <summary>
/// The tile's aspect ratio is preserved, and it is scaled to fit within the tile size.
/// </summary>
PreserveAspectFit PreserveAspectFit
} }
/// <summary>
/// A tileset is a collection of tiles that can be used in a tile layer, or by tile objects.
/// </summary>
public class Tileset public class Tileset
{ {
// Attributes /// <summary>
/// The TMX format version. Is incremented to match minor Tiled releases.
/// </summary>
public string? Version { get; set; } public string? Version { get; set; }
/// <summary>
/// The Tiled version used to save the file in case it was loaded from an external tileset file.
/// </summary>
public string? TiledVersion { get; set; } public string? TiledVersion { get; set; }
/// <summary>
/// The first global tile ID of this tileset (this global ID maps to the first tile in this tileset).
/// </summary>
public uint? FirstGID { get; set; } public uint? FirstGID { get; set; }
/// <summary>
/// If this tileset is stored in an external TSX (Tile Set XML) file, this attribute refers to that file.
/// </summary>
public string? Source { get; set; } public string? Source { get; set; }
/// <summary>
/// The name of this tileset.
/// </summary>
public string? Name { get; set; } public string? Name { get; set; }
/// <summary>
/// The class of this tileset.
/// </summary>
public string Class { get; set; } = ""; public string Class { get; set; } = "";
/// <summary>
/// The width of the tiles in this tileset, which should be at least 1 (non-zero) except in the case of image collection tilesets (in which case it stores the maximum tile width).
/// </summary>
public uint? TileWidth { get; set; } public uint? TileWidth { get; set; }
/// <summary>
/// The height of the tiles in this tileset, which should be at least 1 (non-zero) except in the case of image collection tilesets (in which case it stores the maximum tile height).
/// </summary>
public uint? TileHeight { get; set; } public uint? TileHeight { get; set; }
/// <summary>
/// The spacing in pixels between the tiles in this tileset (applies to the tileset image). Irrelevant for image collection tilesets.
/// </summary>
public float? Spacing { get; set; } = 0f; public float? Spacing { get; set; } = 0f;
/// <summary>
/// The margin around the tiles in this tileset (applies to the tileset image). Irrelevant for image collection tilesets.
/// </summary>
public float? Margin { get; set; } = 0f; public float? Margin { get; set; } = 0f;
/// <summary>
/// The number of tiles in this tileset.
/// </summary>
public uint? TileCount { get; set; } public uint? TileCount { get; set; }
/// <summary>
/// The number of tile columns in the tileset.
/// </summary>
public uint? Columns { get; set; } public uint? Columns { get; set; }
/// <summary>
/// Controls the aligntment for tile objects.
/// </summary>
public ObjectAlignment ObjectAlignment { get; set; } = ObjectAlignment.Unspecified; public ObjectAlignment ObjectAlignment { get; set; } = ObjectAlignment.Unspecified;
/// <summary>
/// The size to use when rendering tiles from thie tileset on a tile layer. When set to <see cref="TileRenderSize.Grid"/>, the tile is drawn at the tile grid size of the map.
/// </summary>
public TileRenderSize RenderSize { get; set; } = TileRenderSize.Tile; public TileRenderSize RenderSize { get; set; } = TileRenderSize.Tile;
/// <summary>
/// The fill mode to use when rendering tiles from this tileset.
/// </summary>
public FillMode FillMode { get; set; } = FillMode.Stretch; public FillMode FillMode { get; set; } = FillMode.Stretch;
// At most one of /// <summary>
/// If the tileset is based on a single image, which is cut into tiles based on the given attributes of the tileset, then this is that image.
/// </summary>
public Image? Image { get; set; } public Image? Image { get; set; }
/// <summary>
/// This is used to specify an offset in pixels, to be applied when drawing a tile from the related tileset. When not present, no offset is applied.
/// </summary>
public TileOffset? TileOffset { get; set; } public TileOffset? TileOffset { get; set; }
/// <summary>
/// Ths is only used in case of isometric orientation, and determines how tile overlays for terrain and collision information are rendered.
/// </summary>
public Grid? Grid { get; set; } public Grid? Grid { get; set; }
/// <summary>
/// Tileset properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
// public List<Terrain>? TerrainTypes { get; set; } TODO: Implement Terrain -> Wangset conversion during deserialization // public List<Terrain>? TerrainTypes { get; set; } TODO: Implement Terrain -> Wangset conversion during deserialization
/// <summary>
/// Contains the list of Wang sets defined for this tileset.
/// </summary>
public List<Wangset>? Wangsets { get; set; } public List<Wangset>? Wangsets { get; set; }
/// <summary>
/// Used to describe which transformations can be applied to the tiles (e.g. to extend a Wang set by transforming existing tiles).
/// </summary>
public Transformations? Transformations { get; set; } public Transformations? Transformations { get; set; }
// Any number of /// <summary>
/// If this tileset is based on a collection of images, then this list of tiles will contain the individual images that make up the tileset.
/// </summary>
public List<Tile> Tiles { get; set; } = []; public List<Tile> Tiles { get; set; } = [];
} }

View file

@ -1,10 +1,27 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents which transformations can be applied to a tile in a tileset.
/// </summary>
public class Transformations public class Transformations
{ {
// Attributes /// <summary>
/// Whether the file in this can set be flipped horizontally.
/// </summary>
public bool HFlip { get; set; } = false; public bool HFlip { get; set; } = false;
/// <summary>
/// Whether the file in this can set be flipped vertically.
/// </summary>
public bool VFlip { get; set; } = false; public bool VFlip { get; set; } = false;
/// <summary>
/// Whether the file in this set can be rotated in 90 degree increments.
/// </summary>
public bool Rotate { get; set; } = false; public bool Rotate { get; set; } = false;
/// <summary>
/// Whether untransformed tiles remain preferred, otherwise transformed tiles are used to produce more vartiations.
/// </summary>
public bool PreferUntransformed { get; set; } = false; public bool PreferUntransformed { get; set; } = false;
} }

View file

@ -2,15 +2,38 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a Wang color in a Wang set.
/// </summary>
public class WangColor public class WangColor
{ {
// Attributes /// <summary>
/// The name of this color.
/// </summary>
public required string Name { get; set; } public required string Name { get; set; }
/// <summary>
/// The class of the Wang color.
/// </summary>
public string Class { get; set; } = ""; public string Class { get; set; } = "";
/// <summary>
/// The color of the Wang color.
/// </summary>
public required Color Color { get; set; } public required Color Color { get; set; }
/// <summary>
/// The tile ID of the tile representing this color.
/// </summary>
public required int Tile { get; set; } public required int Tile { get; set; }
/// <summary>
/// The relative probability that this color is chosen over others in case of multiple options.
/// </summary>
public float Probability { get; set; } = 0f; public float Probability { get; set; } = 0f;
// Elements /// <summary>
/// The Wang color properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
} }

View file

@ -1,8 +1,17 @@
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Represents a Wang tile in a Wang set.
/// </summary>
public class WangTile public class WangTile
{ {
// Attributes /// <summary>
/// The tile ID associated with this Wang tile.
/// </summary>
public required uint TileID { get; set; } public required uint TileID { get; set; }
/// <summary>
/// The Wang ID of this Wang tile.
/// </summary>
public required byte[] WangID { get; set; } public required byte[] WangID { get; set; }
} }

View file

@ -2,20 +2,39 @@ using System.Collections.Generic;
namespace DotTiled.Model; namespace DotTiled.Model;
/// <summary>
/// Defines a list of colors and any number of Wang tiles using these colors.
/// </summary>
public class Wangset public class Wangset
{ {
// Attributes /// <summary>
/// The name of the Wang set.
/// </summary>
public required string Name { get; set; } public required string Name { get; set; }
/// <summary>
/// The class of the Wang set.
/// </summary>
public string Class { get; set; } = ""; public string Class { get; set; } = "";
/// <summary>
/// The tile ID of the tile representing the Wang set.
/// </summary>
public required int Tile { get; set; } public required int Tile { get; set; }
// Elements /// <summary>
// At most one of /// The Wang set properties.
/// </summary>
public Dictionary<string, IProperty>? Properties { get; set; } public Dictionary<string, IProperty>? Properties { get; set; }
// Up to 254 Wang colors // Up to 254 Wang colors
/// <summary>
/// The Wang colors in the Wang set.
/// </summary>
public List<WangColor>? WangColors { get; set; } = []; public List<WangColor>? WangColors { get; set; } = [];
// Any number of /// <summary>
/// The Wang tiles in the Wang set.
/// </summary>
public List<WangTile> WangTiles { get; set; } = []; public List<WangTile> WangTiles { get; set; } = [];
} }

View file

@ -38,7 +38,7 @@ internal partial class Tmj
_ => throw new JsonException($"Unknown draw order '{s}'.") _ => throw new JsonException($"Unknown draw order '{s}'.")
}, DrawOrder.TopDown); }, DrawOrder.TopDown);
var objects = element.GetOptionalPropertyCustom<List<Model.Layers.Objects.Object>>("objects", e => e.GetValueAsList<Model.Layers.Objects.Object>(el => ReadObject(el, externalTemplateResolver, customTypeDefinitions)), []); var objects = element.GetOptionalPropertyCustom<List<Model.Object>>("objects", e => e.GetValueAsList<Model.Object>(el => ReadObject(el, externalTemplateResolver, customTypeDefinitions)), []);
return new ObjectLayer return new ObjectLayer
{ {
@ -63,7 +63,7 @@ internal partial class Tmj
}; };
} }
internal static Model.Layers.Objects.Object ReadObject( internal static Model.Object ReadObject(
JsonElement element, JsonElement element,
Func<string, Template> externalTemplateResolver, Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions) IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)

View file

@ -17,7 +17,7 @@ internal partial class Tmj
{ {
var type = element.GetRequiredProperty<string>("type"); var type = element.GetRequiredProperty<string>("type");
var tileset = element.GetOptionalPropertyCustom<Tileset?>("tileset", el => ReadTileset(el, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions), null); var tileset = element.GetOptionalPropertyCustom<Tileset?>("tileset", el => ReadTileset(el, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions), null);
var @object = element.GetRequiredPropertyCustom<Model.Layers.Objects.Object>("object", el => ReadObject(el, externalTemplateResolver, customTypeDefinitions)); var @object = element.GetRequiredPropertyCustom<Model.Object>("object", el => ReadObject(el, externalTemplateResolver, customTypeDefinitions));
return new Template return new Template
{ {

View file

@ -40,7 +40,7 @@ internal partial class Tmx
// Elements // Elements
Dictionary<string, IProperty>? properties = null; Dictionary<string, IProperty>? properties = null;
List<Model.Layers.Objects.Object> objects = []; List<Model.Object> objects = [];
reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch
{ {
@ -72,14 +72,14 @@ internal partial class Tmx
}; };
} }
internal static Model.Layers.Objects.Object ReadObject( internal static Model.Object ReadObject(
XmlReader reader, XmlReader reader,
Func<string, Template> externalTemplateResolver, Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions) IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var template = reader.GetOptionalAttribute("template"); var template = reader.GetOptionalAttribute("template");
Model.Layers.Objects.Object? obj = null; Model.Object? obj = null;
if (template is not null) if (template is not null)
obj = externalTemplateResolver(template).Object; obj = externalTemplateResolver(template).Object;
@ -107,7 +107,7 @@ internal partial class Tmx
var visible = reader.GetOptionalAttributeParseable<bool>("visible") ?? visibleDefault; var visible = reader.GetOptionalAttributeParseable<bool>("visible") ?? visibleDefault;
// Elements // Elements
Model.Layers.Objects.Object? foundObject = null; Model.Object? foundObject = null;
int propertiesCounter = 0; int propertiesCounter = 0;
Dictionary<string, IProperty>? properties = propertiesDefault; Dictionary<string, IProperty>? properties = propertiesDefault;
@ -145,7 +145,7 @@ internal partial class Tmx
return OverrideObject(obj, foundObject); return OverrideObject(obj, foundObject);
} }
internal static Model.Layers.Objects.Object OverrideObject(Model.Layers.Objects.Object? obj, Model.Layers.Objects.Object foundObject) internal static Model.Object OverrideObject(Model.Object? obj, Model.Object foundObject)
{ {
if (obj is null) if (obj is null)
return foundObject; return foundObject;
@ -316,7 +316,7 @@ internal partial class Tmx
Tileset? tileset = null; Tileset? tileset = null;
// Should contain exactly one of // Should contain exactly one of
Model.Layers.Objects.Object? obj = null; Model.Object? obj = null;
reader.ProcessChildren("template", (r, elementName) => elementName switch reader.ProcessChildren("template", (r, elementName) => elementName switch
{ {