diff --git a/pytiled_parser/parsers/json/tiled_object.py b/pytiled_parser/parsers/json/tiled_object.py index e537637..2acc4b3 100644 --- a/pytiled_parser/parsers/json/tiled_object.py +++ b/pytiled_parser/parsers/json/tiled_object.py @@ -1,6 +1,7 @@ """Object parsing for the JSON Map Format. """ import json +import xml.etree.ElementTree as etree from pathlib import Path from typing import Any, Callable, Dict, List, Optional @@ -19,7 +20,7 @@ from pytiled_parser.tiled_object import ( Tile, TiledObject, ) -from pytiled_parser.util import parse_color +from pytiled_parser.util import load_object_template, parse_color class RawText(TypedDict): @@ -300,20 +301,19 @@ def parse( "A parent directory must be specified when using object templates." ) template_path = Path(parent_dir / raw_object["template"]) - with open(template_path) as raw_template_file: - template = json.load(raw_template_file) - if "tileset" in template: - tileset_path = Path( - template_path.parent / template["tileset"]["source"] - ) - with open(tileset_path) as raw_tileset_file: - new_tileset = json.load(raw_tileset_file) - new_tileset_path = tileset_path.parent + template, new_tileset, new_tileset_path = load_object_template(template_path) + if isinstance(template, dict): loaded_template = template["object"] for key in loaded_template: if key != "id": raw_object[key] = loaded_template[key] # type: ignore + elif isinstance(template, etree.Element): + # load the XML object into the JSON object + raise NotImplementedError( + "Loading TMX object templates inside a JSON map is currently not supported, " + "but will be in a future release." + ) if raw_object.get("gid"): return _parse_tile(raw_object, new_tileset, new_tileset_path) diff --git a/pytiled_parser/parsers/tmx/tiled_map.py b/pytiled_parser/parsers/tmx/tiled_map.py index 4ecb5ed..f12c6e2 100644 --- a/pytiled_parser/parsers/tmx/tiled_map.py +++ b/pytiled_parser/parsers/tmx/tiled_map.py @@ -94,6 +94,7 @@ def parse(file: Path) -> TiledMap: break if not already_loaded: + print("here") highest_firstgid = max(map_.tilesets.keys()) last_tileset_count = map_.tilesets[highest_firstgid].tile_count new_firstgid = highest_firstgid + last_tileset_count diff --git a/pytiled_parser/parsers/tmx/tiled_object.py b/pytiled_parser/parsers/tmx/tiled_object.py index 9d272ea..ceb4e08 100644 --- a/pytiled_parser/parsers/tmx/tiled_object.py +++ b/pytiled_parser/parsers/tmx/tiled_object.py @@ -1,3 +1,4 @@ +import json import xml.etree.ElementTree as etree from pathlib import Path from typing import Callable, Optional @@ -14,7 +15,7 @@ from pytiled_parser.tiled_object import ( Tile, TiledObject, ) -from pytiled_parser.util import parse_color +from pytiled_parser.util import load_object_template, parse_color def _parse_common(raw_object: etree.Element) -> TiledObject: @@ -264,18 +265,9 @@ def parse(raw_object: etree.Element, parent_dir: Optional[Path] = None) -> Tiled "A parent directory must be specified when using object templates." ) template_path = Path(parent_dir / raw_object.attrib["template"]) - with open(template_path) as template_file: - template = etree.parse(template_file).getroot() - - tileset_element = template.find("./tileset") - if tileset_element: - tileset_path = Path( - template_path.parent / tileset_element.attrib["source"] - ) - with open(tileset_path) as tileset_file: - new_tileset = etree.parse(tileset_file).getroot() - new_tileset_path = tileset_path.parent + template, new_tileset, new_tileset_path = load_object_template(template_path) + if isinstance(template, etree.Element): new_object = template.find("./object") if new_object is not None: if raw_object.attrib.get("id") is not None: @@ -288,11 +280,14 @@ def parse(raw_object: etree.Element, parent_dir: Optional[Path] = None) -> Tiled new_object.attrib["y"] = raw_object.attrib["y"] raw_object = new_object - - if raw_object.attrib.get("gid"): - return _parse_tile(raw_object, new_tileset, new_tileset_path) + elif isinstance(template, dict): + # load the JSON object into the XML object + raise NotImplementedError( + "Loading JSON object templates inside a TMX map is currently not supported, " + "but will be in a future release." + ) if raw_object.attrib.get("gid"): - return _parse_tile(raw_object) + return _parse_tile(raw_object, new_tileset, new_tileset_path) return _get_parser(raw_object)(raw_object) diff --git a/pytiled_parser/util.py b/pytiled_parser/util.py index 07fd955..f8bb18b 100644 --- a/pytiled_parser/util.py +++ b/pytiled_parser/util.py @@ -1,5 +1,8 @@ """Utility Functions for PyTiled""" +import json +import xml.etree.ElementTree as etree from pathlib import Path +from typing import Any from pytiled_parser.common_types import Color @@ -37,3 +40,43 @@ def check_format(file_path: Path) -> str: return "tmx" else: return "json" + + +def load_object_template(file_path: Path) -> Any: + template_format = check_format(file_path) + + new_tileset = None + new_tileset_path = None + + if template_format == "tmx": + with open(file_path) as template_file: + template = etree.parse(template_file).getroot() + + tileset_element = template.find("./tileset") + if tileset_element is not None: + tileset_path = Path(file_path.parent / tileset_element.attrib["source"]) + new_tileset = load_object_tileset(tileset_path) + new_tileset_path = tileset_path.parent + elif template_format == "json": + with open(file_path) as template_file: + template = json.load(template_file) + if "tileset" in template: + tileset_path = Path(file_path.parent / template["tileset"]["source"]) # type: ignore + new_tileset = load_object_tileset(tileset_path) + new_tileset_path = tileset_path.parent + + return (template, new_tileset, new_tileset_path) + + +def load_object_tileset(file_path: Path) -> Any: + tileset_format = check_format(file_path) + + new_tileset = None + + with open(file_path) as tileset_file: + if tileset_format == "tmx": + new_tileset = etree.parse(tileset_file).getroot() + elif tileset_format == "json": + new_tileset = json.load(tileset_file) + + return new_tileset