diff --git a/src/DotTiled/Layers/Objects/EllipseObject.cs b/src/DotTiled/Layers/Objects/EllipseObject.cs
index 75db631..3ebd55c 100644
--- a/src/DotTiled/Layers/Objects/EllipseObject.cs
+++ b/src/DotTiled/Layers/Objects/EllipseObject.cs
@@ -1,7 +1,25 @@
+using System.Linq;
+
namespace DotTiled;
///
/// An ellipse object in a map. The existing , , ,
/// and properties are used to determine the size of the ellipse.
///
-public class EllipseObject : Object { }
+public class EllipseObject : Object
+{
+ internal override Object Clone() => new EllipseObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ };
+}
diff --git a/src/DotTiled/Layers/Objects/Object.cs b/src/DotTiled/Layers/Objects/Object.cs
index 2484ae8..4015508 100644
--- a/src/DotTiled/Layers/Objects/Object.cs
+++ b/src/DotTiled/Layers/Objects/Object.cs
@@ -64,4 +64,10 @@ public abstract class Object : HasPropertiesBase
///
public override IList GetProperties() => Properties;
+
+ ///
+ /// Creates a deep copy of the object.
+ ///
+ ///
+ internal abstract Object Clone();
}
diff --git a/src/DotTiled/Layers/Objects/PointObject.cs b/src/DotTiled/Layers/Objects/PointObject.cs
index 0c53e1b..43540de 100644
--- a/src/DotTiled/Layers/Objects/PointObject.cs
+++ b/src/DotTiled/Layers/Objects/PointObject.cs
@@ -1,7 +1,25 @@
+using System.Linq;
+
namespace DotTiled;
///
/// A point object in a map. The existing and properties are used to
/// determine the position of the point.
///
-public class PointObject : Object { }
+public class PointObject : Object
+{
+ internal override Object Clone() => new PointObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ };
+}
diff --git a/src/DotTiled/Layers/Objects/PolygonObject.cs b/src/DotTiled/Layers/Objects/PolygonObject.cs
index 2cf3895..afbab41 100644
--- a/src/DotTiled/Layers/Objects/PolygonObject.cs
+++ b/src/DotTiled/Layers/Objects/PolygonObject.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using System.Numerics;
namespace DotTiled;
@@ -14,4 +15,20 @@ public class PolygonObject : Object
/// and are used as the origin of the polygon.
///
public required List Points { get; set; }
+
+ internal override Object Clone() => new PolygonObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ Points = Points.ToList(),
+ };
}
diff --git a/src/DotTiled/Layers/Objects/PolylineObject.cs b/src/DotTiled/Layers/Objects/PolylineObject.cs
index d755521..4ae8270 100644
--- a/src/DotTiled/Layers/Objects/PolylineObject.cs
+++ b/src/DotTiled/Layers/Objects/PolylineObject.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using System.Numerics;
namespace DotTiled;
@@ -13,4 +14,20 @@ public class PolylineObject : Object
/// The points that make up the polyline. and are used as the origin of the polyline.
///
public required List Points { get; set; }
+
+ internal override Object Clone() => new PolylineObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ Points = Points.ToList(),
+ };
}
diff --git a/src/DotTiled/Layers/Objects/RectangleObject.cs b/src/DotTiled/Layers/Objects/RectangleObject.cs
index 8e71ee8..2dfc92a 100644
--- a/src/DotTiled/Layers/Objects/RectangleObject.cs
+++ b/src/DotTiled/Layers/Objects/RectangleObject.cs
@@ -1,7 +1,25 @@
+using System.Linq;
+
namespace DotTiled;
///
/// A rectangle object in a map. The existing , , ,
/// and properties are used to determine the size of the rectangle.
///
-public class RectangleObject : Object { }
+public class RectangleObject : Object
+{
+ internal override Object Clone() => new RectangleObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ };
+}
diff --git a/src/DotTiled/Layers/Objects/TextObject.cs b/src/DotTiled/Layers/Objects/TextObject.cs
index 42b07d0..955242f 100644
--- a/src/DotTiled/Layers/Objects/TextObject.cs
+++ b/src/DotTiled/Layers/Objects/TextObject.cs
@@ -1,4 +1,5 @@
using System.Globalization;
+using System.Linq;
namespace DotTiled;
@@ -113,4 +114,32 @@ public class TextObject : Object
/// The text to be displayed.
///
public string Text { get; set; } = "";
+
+ internal override Object Clone() => new TextObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+
+ FontFamily = FontFamily,
+ PixelSize = PixelSize,
+ Wrap = Wrap,
+ Color = Color,
+ Bold = Bold,
+ Italic = Italic,
+ Underline = Underline,
+ Strikeout = Strikeout,
+ Kerning = Kerning,
+ HorizontalAlignment = HorizontalAlignment,
+ VerticalAlignment = VerticalAlignment,
+ Text = Text,
+ };
}
diff --git a/src/DotTiled/Layers/Objects/TileObject.cs b/src/DotTiled/Layers/Objects/TileObject.cs
index ea23d70..f54a9b9 100644
--- a/src/DotTiled/Layers/Objects/TileObject.cs
+++ b/src/DotTiled/Layers/Objects/TileObject.cs
@@ -1,3 +1,5 @@
+using System.Linq;
+
namespace DotTiled;
///
@@ -14,4 +16,21 @@ public class TileObject : Object
/// The flipping flags for the tile.
///
public FlippingFlags FlippingFlags { get; set; }
+
+ internal override Object Clone() => new TileObject
+ {
+ ID = ID,
+ Name = Name,
+ Type = Type,
+ X = X,
+ Y = Y,
+ Width = Width,
+ Height = Height,
+ Rotation = Rotation,
+ Visible = Visible,
+ Template = Template,
+ Properties = Properties.Select(p => p.Clone()).ToList(),
+ GID = GID,
+ FlippingFlags = FlippingFlags,
+ };
}
diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
index 07b7a62..904321b 100644
--- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
+++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Data.cs
@@ -19,8 +19,7 @@ public abstract partial class TmjReaderBase
internal static Chunk ReadChunk(JsonElement element, Optional compression, DataEncoding encoding)
{
- var data = ReadDataWithoutChunks(element, compression, encoding);
-
+ var data = element.GetRequiredPropertyCustom("data", e => ReadDataWithoutChunks(e, compression, encoding));
var x = element.GetRequiredProperty("x");
var y = element.GetRequiredProperty("y");
var width = element.GetRequiredProperty("width");
diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.ObjectLayer.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.ObjectLayer.cs
index 21e58a0..6eb5f8a 100644
--- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.ObjectLayer.cs
+++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.ObjectLayer.cs
@@ -76,12 +76,13 @@ public abstract partial class TmjReaderBase
List polygonDefault = null;
List polylineDefault = null;
List propertiesDefault = [];
+ Optional gidDefault = Optional.Empty;
var template = element.GetOptionalProperty("template");
if (template.HasValue)
{
var resolvedTemplate = _externalTemplateResolver(template.Value);
- var templObj = resolvedTemplate.Object;
+ var templObj = resolvedTemplate.Object.Clone();
idDefault = templObj.ID;
nameDefault = templObj.Name;
@@ -97,10 +98,11 @@ public abstract partial class TmjReaderBase
pointDefault = templObj is PointObject;
polygonDefault = (templObj is PolygonObject polygonObj) ? polygonObj.Points : null;
polylineDefault = (templObj is PolylineObject polylineObj) ? polylineObj.Points : null;
+ gidDefault = (templObj is TileObject tileObj) ? tileObj.GID : Optional.Empty;
}
var ellipse = element.GetOptionalProperty("ellipse").GetValueOr(ellipseDefault);
- var gid = element.GetOptionalProperty("gid");
+ var gid = element.GetOptionalProperty("gid").GetValueOrOptional(gidDefault);
var height = element.GetOptionalProperty("height").GetValueOr(heightDefault);
var id = element.GetOptionalProperty("id").GetValueOrOptional(idDefault);
var name = element.GetOptionalProperty("name").GetValueOr(nameDefault);
diff --git a/src/DotTiled/Serialization/Tmx/TmxReaderBase.ObjectLayer.cs b/src/DotTiled/Serialization/Tmx/TmxReaderBase.ObjectLayer.cs
index a53cee6..b6fa3dc 100644
--- a/src/DotTiled/Serialization/Tmx/TmxReaderBase.ObjectLayer.cs
+++ b/src/DotTiled/Serialization/Tmx/TmxReaderBase.ObjectLayer.cs
@@ -74,7 +74,7 @@ public abstract partial class TmxReaderBase
var template = _reader.GetOptionalAttribute("template");
DotTiled.Object obj = null;
if (template.HasValue)
- obj = _externalTemplateResolver(template.Value).Object;
+ obj = _externalTemplateResolver(template.Value).Object.Clone();
uint idDefault = obj?.ID.GetValueOr(0) ?? 0;
string nameDefault = obj?.Name ?? "";