Better object template loading

This commit is contained in:
Darren Eberly
2021-12-21 21:50:32 -05:00
parent 22d7631bfb
commit 923149c0a4
4 changed files with 65 additions and 26 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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