diff --git a/CHANGELOG.md b/CHANGELOG.md index f7df560..591a71d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased (0.12.2)] +### Fixed +- Fixed template instance size and position overrides in `ObjectData::shape`. (#309) + ## [0.12.1] ### Changed - Improved documentation on `Map::layers` and `Map::get_layer`. (#306) diff --git a/assets/tiled_object_template.tmx b/assets/tiled_object_template.tmx index 940809e..b6b8416 100644 --- a/assets/tiled_object_template.tmx +++ b/assets/tiled_object_template.tmx @@ -1,5 +1,5 @@ - + @@ -14,5 +14,6 @@ + diff --git a/src/objects.rs b/src/objects.rs index 05d0b98..dcf130f 100644 --- a/src/objects.rs +++ b/src/objects.rs @@ -229,7 +229,7 @@ impl ObjectData { reader: &mut impl ResourceReader, cache: &mut impl ResourceCache, ) -> Result { - let (id, tile, mut n, mut t, c, w, h, mut v, mut r, template, x, y) = get_attrs!( + let (id, tile, mut n, mut t, c, mut w, mut h, mut v, mut r, template, x, y) = get_attrs!( for v in attrs { Some("id") => id ?= v.parse(), Some("gid") => tile ?= v.parse::(), @@ -275,6 +275,15 @@ impl ObjectData { if let Some(templ_tile) = &obj.tile { tile.get_or_insert_with(|| templ_tile.clone()); } + match &obj.shape { + ObjectShape::Rect { width, height } + | ObjectShape::Ellipse { width, height } + | ObjectShape::Text { width, height, .. } => { + w.get_or_insert(*width); + h.get_or_insert(*height); + } + _ => {} + } Ok(template) }) .transpose()?; @@ -319,11 +328,51 @@ impl ObjectData { }, }); - // Possibly copy properties from the template into the object - // Any that already exist in the object's map don't get copied over if let Some(templ) = template { - shape.get_or_insert(templ.object.shape.clone()); + shape.get_or_insert_with(|| { + // Inherit the shape from the template but use the size and + // position from the object where relevant + match &templ.object.shape { + ObjectShape::Rect { .. } => ObjectShape::Rect { width, height }, + ObjectShape::Ellipse { .. } => ObjectShape::Ellipse { width, height }, + ObjectShape::Point(_, _) => ObjectShape::Point(x, y), + ObjectShape::Text { + font_family, + pixel_size, + wrap, + color, + bold, + italic, + underline, + strikeout, + kerning, + halign, + valign, + text, + width: _, + height: _, + } => ObjectShape::Text { + font_family: font_family.clone(), + pixel_size: pixel_size.clone(), + wrap: wrap.clone(), + color: color.clone(), + bold: bold.clone(), + italic: italic.clone(), + underline: underline.clone(), + strikeout: strikeout.clone(), + kerning: kerning.clone(), + halign: halign.clone(), + valign: valign.clone(), + text: text.clone(), + width, + height, + }, + shape => shape.clone(), + } + }); + // Possibly copy properties from the template into the object + // Any that already exist in the object's map don't get copied over for (k, v) in &templ.object.properties { if !properties.contains_key(k) { properties.insert(k.clone(), v.clone()); diff --git a/tests/lib.rs b/tests/lib.rs index 4b41ccb..f190049 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -439,6 +439,7 @@ fn test_object_template_property() { let object_layer = r.get_layer(1).unwrap().as_object_layer().unwrap(); let object = object_layer.get_object(0).unwrap(); // The templated object let object_nt = object_layer.get_object(1).unwrap(); // The non-templated object + let object_resized = object_layer.get_object(2).unwrap(); // The resized templated object // Test core properties assert_eq!( @@ -450,6 +451,13 @@ fn test_object_template_property() { ); assert_eq!(object.x, 32.0); assert_eq!(object.y, 32.0); + assert_eq!( + object_resized.shape, + ObjectShape::Rect { + width: 64.0, + height: 32.0, + } + ); // Test properties are copied over assert_eq!(