mirror of
https://github.com/OMGeeky/pytiled_parser.git
synced 2025-12-26 17:02:28 +01:00
Add support for pre-1.0 Tiled JSON formats
While attempting to parse Starbound dungeons in Tiled JSON format, I encountered a number of parse errors. These errors appear to be due to pre-1.0 differences in the Tiled JSON map and tileset formats. As far as I can tell, most Starbound dungeon files were created and/or last edited with Tiled 0.15.2. * Map object `properties` were dictionaries rather than lists, with the key being the property name and the value always a string. * Tileset `tiles` were dictionaries rather than lists, with the key being the tile id (integer cast as a string) and the value being a dictionary containing the remainder of the tile definition. * Some map and tileset properties did not exist, or were optional. This patch introduces minimal changes to the code to allow the Starbound files to be parsed. There may be other legacy quirks, but these are the only ones I've noticed in these files.
This commit is contained in:
@@ -27,7 +27,7 @@ def parse(raw_properties: List[RawProperty]) -> Properties:
|
||||
"""Parse a list of `RawProperty` objects into `Properties`.
|
||||
|
||||
Args:
|
||||
raw_properties: The list of `RawProperty` objects to parse.
|
||||
raw_properties: The list or dict of `RawProperty` objects to parse. The dict type is supported for parsing legacy Tiled dungeon files.
|
||||
|
||||
Returns:
|
||||
Properties: The parsed `Property` objects.
|
||||
@@ -36,13 +36,17 @@ def parse(raw_properties: List[RawProperty]) -> Properties:
|
||||
final: Properties = {}
|
||||
value: Property
|
||||
|
||||
for raw_property in raw_properties:
|
||||
if raw_property["type"] == "file":
|
||||
value = Path(cast(str, raw_property["value"]))
|
||||
elif raw_property["type"] == "color":
|
||||
value = parse_color(cast(str, raw_property["value"]))
|
||||
else:
|
||||
value = raw_property["value"]
|
||||
final[raw_property["name"]] = value
|
||||
if isinstance(raw_properties, dict):
|
||||
for name, value in raw_properties.items():
|
||||
final[name] = value
|
||||
else:
|
||||
for raw_property in raw_properties:
|
||||
if raw_property["type"] == "file":
|
||||
value = Path(cast(str, raw_property["value"]))
|
||||
elif raw_property["type"] == "color":
|
||||
value = parse_color(cast(str, raw_property["value"]))
|
||||
else:
|
||||
value = raw_property["value"]
|
||||
final[raw_property["name"]] = value
|
||||
|
||||
return final
|
||||
|
||||
@@ -112,14 +112,14 @@ def parse(file: Path) -> TiledMap:
|
||||
# `map` is a built-in function
|
||||
map_ = TiledMap(
|
||||
map_file=file,
|
||||
infinite=raw_tiled_map["infinite"],
|
||||
infinite=raw_tiled_map.get("infinite", False),
|
||||
layers=[parse_layer(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_layer_id=raw_tiled_map.get("nextlayerid"),
|
||||
next_object_id=raw_tiled_map["nextobjectid"],
|
||||
orientation=raw_tiled_map["orientation"],
|
||||
render_order=raw_tiled_map["renderorder"],
|
||||
tiled_version=raw_tiled_map["tiledversion"],
|
||||
tiled_version=raw_tiled_map.get("tiledversion", ""),
|
||||
tile_size=Size(raw_tiled_map["tilewidth"], raw_tiled_map["tileheight"]),
|
||||
tilesets=tilesets,
|
||||
version=version,
|
||||
|
||||
@@ -249,7 +249,7 @@ def parse(
|
||||
tile_count=raw_tileset["tilecount"],
|
||||
tile_width=raw_tileset["tilewidth"],
|
||||
tile_height=raw_tileset["tileheight"],
|
||||
columns=raw_tileset["columns"],
|
||||
columns=raw_tileset.get("columns", 1),
|
||||
spacing=raw_tileset["spacing"],
|
||||
margin=raw_tileset["margin"],
|
||||
firstgid=firstgid,
|
||||
@@ -304,8 +304,18 @@ def parse(
|
||||
|
||||
if raw_tileset.get("tiles") is not None:
|
||||
tiles = {}
|
||||
for raw_tile in raw_tileset["tiles"]:
|
||||
tiles[raw_tile["id"]] = _parse_tile(raw_tile, external_path=external_path)
|
||||
if isinstance(raw_tileset["tiles"], dict):
|
||||
for raw_tile_id, raw_tile in raw_tileset["tiles"].items():
|
||||
assert raw_tile.get("id") is None
|
||||
raw_tile["id"] = int(raw_tile_id)
|
||||
tiles[raw_tile["id"]] = _parse_tile(
|
||||
raw_tile, external_path=external_path
|
||||
)
|
||||
else:
|
||||
for raw_tile in raw_tileset["tiles"]:
|
||||
tiles[raw_tile["id"]] = _parse_tile(
|
||||
raw_tile, external_path=external_path
|
||||
)
|
||||
tileset.tiles = tiles
|
||||
|
||||
if raw_tileset.get("wangsets") is not None:
|
||||
|
||||
Reference in New Issue
Block a user