From 1ffab0381abdea1fab49e66fcc65dab3ed4f60cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 3 Sep 2024 15:34:15 +0200 Subject: [PATCH] Fixed template instance size and position overrides (#311) Template instances of rectangle, ellipse and text objects can override the width and height of the template object. This is now taken into account when reading out the attributes and when inheriting the shape from the template. Template instances of point objects are now also correctly storing the instance position in the Point shape, instead of the position of the template object. Added a small test for the resized templated object case. Closes #310 --- CHANGELOG.md | 4 +++ assets/tiled_object_template.tmx | 3 +- src/objects.rs | 57 +++++++++++++++++++++++++++++--- tests/lib.rs | 8 +++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7df560d..591a71d6 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 940809e8..b6b8416a 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 05d0b984..dcf130fc 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 4b41ccb8..f190049f 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!(