diff --git a/pytiled_parser/layer.py b/pytiled_parser/layer.py index 58bcc98..ede3375 100644 --- a/pytiled_parser/layer.py +++ b/pytiled_parser/layer.py @@ -402,7 +402,9 @@ def _cast_tile_layer(raw_layer: RawLayer) -> TileLayer: return tile_layer -def _cast_object_layer(raw_layer: RawLayer) -> ObjectLayer: +def _cast_object_layer( + raw_layer: RawLayer, parent_dir: Optional[Path] = None +) -> ObjectLayer: """Cast the raw_layer to an ObjectLayer. Args: @@ -413,7 +415,7 @@ def _cast_object_layer(raw_layer: RawLayer) -> ObjectLayer: tiled_objects = [] for tiled_object_ in raw_layer["objects"]: - tiled_objects.append(tiled_object.cast(tiled_object_)) + tiled_objects.append(tiled_object.cast(tiled_object_, parent_dir)) return ObjectLayer( tiled_objects=tiled_objects, @@ -441,7 +443,9 @@ def _cast_image_layer(raw_layer: RawLayer) -> ImageLayer: return image_layer -def _cast_group_layer(raw_layer: RawLayer) -> LayerGroup: +def _cast_group_layer( + raw_layer: RawLayer, parent_dir: Optional[Path] = None +) -> LayerGroup: """Cast the raw_layer to a LayerGroup. Args: @@ -454,7 +458,7 @@ def _cast_group_layer(raw_layer: RawLayer) -> LayerGroup: layers = [] for layer in raw_layer["layers"]: - layers.append(cast(layer)) + layers.append(cast(layer, parent_dir)) return LayerGroup(layers=layers, **_get_common_attributes(raw_layer).__dict__) @@ -477,7 +481,7 @@ def _get_caster(type_: str) -> Callable[[RawLayer], Layer]: return casters[type_] -def cast(raw_layer: RawLayer) -> Layer: +def cast(raw_layer: RawLayer, parent_dir: Optional[Path] = None) -> Layer: """Cast a raw Tiled layer into a pytiled_parser type. This function will determine the type of layer and cast accordingly. @@ -490,4 +494,10 @@ def cast(raw_layer: RawLayer) -> Layer: """ caster = _get_caster(raw_layer["type"]) - return caster(raw_layer) + if ( + caster.__name__ == "_cast_object_layer" + or caster.__name__ == "_cast_group_layer" + ): + return caster(raw_layer, parent_dir) + else: + return caster(raw_layer) diff --git a/pytiled_parser/template.py b/pytiled_parser/template.py deleted file mode 100644 index c6d58d8..0000000 --- a/pytiled_parser/template.py +++ /dev/null @@ -1,8 +0,0 @@ -# pylint: disable=too-few-public-methods - -import attr - - -@attr.s(auto_attribs=True) -class Template: - """FIXME TODO""" diff --git a/pytiled_parser/tiled_map.py b/pytiled_parser/tiled_map.py index 9c98456..ce8975a 100644 --- a/pytiled_parser/tiled_map.py +++ b/pytiled_parser/tiled_map.py @@ -148,7 +148,7 @@ def parse_map(file: Path) -> TiledMap: map_ = TiledMap( map_file=file, infinite=raw_tiled_map["infinite"], - layers=[layer.cast(layer_) for layer_ in raw_tiled_map["layers"]], + layers=[layer.cast(layer_, parent_dir) for layer_ in raw_tiled_map["layers"]], map_size=Size(raw_tiled_map["width"], raw_tiled_map["height"]), next_layer_id=raw_tiled_map["nextlayerid"], next_object_id=raw_tiled_map["nextobjectid"], diff --git a/pytiled_parser/tiled_object.py b/pytiled_parser/tiled_object.py index f4d95f4..4c4c649 100644 --- a/pytiled_parser/tiled_object.py +++ b/pytiled_parser/tiled_object.py @@ -1,5 +1,6 @@ # pylint: disable=too-few-public-methods - +import json +from pathlib import Path from typing import Callable, Dict, List, Optional, Union import attr @@ -174,6 +175,7 @@ class RawTiledObject(TypedDict): id: int gid: int + template: str x: float y: float width: float @@ -390,7 +392,9 @@ def _get_caster( return _cast_rectangle -def cast(raw_tiled_object: RawTiledObject) -> TiledObject: +def cast( + raw_tiled_object: RawTiledObject, parent_dir: Optional[Path] = None +) -> TiledObject: """Cast the raw tiled object into a pytiled_parser type Args: @@ -399,6 +403,18 @@ def cast(raw_tiled_object: RawTiledObject) -> TiledObject: Returns: TiledObject: a properly typed Tiled object. """ + if raw_tiled_object.get("template"): + if not parent_dir: + raise RuntimeError( + "A parent directory must be specified when using object templates" + ) + template_path = Path(parent_dir / raw_tiled_object["template"]) + with open(template_path) as raw_template_file: + loaded_template = json.load(raw_template_file)["object"] + for key in loaded_template: + if key != "id": + raw_tiled_object[key] = loaded_template[key] # type: ignore + caster = _get_caster(raw_tiled_object) tiled_object = caster(raw_tiled_object)