Skip to content

Commit 4bdd1d0

Browse files
authored
Merge pull request #38 from Beefy-Swain/development
Merge development for v1.5.0
2 parents fa86a9f + e31d634 commit 4bdd1d0

File tree

93 files changed

+1880
-2484
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+1880
-2484
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Tiled Session file from using a project file
2+
*.tiled-session
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
## [1.5.0] - 2021-05-16
10+
11+
This release contains several new features. As of this release pytiled-parser supports 100% of Tiled's feature-set as of Tiled 1.6.
12+
13+
As of version 1.5.0 of pytiled-parser, we are supporting a minimum version of Tiled 1.5. Many features will still work with older versions, but we cannot guarantee functionality with those versions.
14+
15+
### Additions
16+
17+
- Added support for object template files
18+
- Added `World` object to support loading Tiled `.world` files.
19+
- Full support for Wang Sets/Terrains
20+
21+
### Changes
22+
23+
- The `version` attribute of `TiledMap` and `TileSet` is now a string with Tiled major/minor version. For example `"1.6"`. It used to be a float like `1.6`. This is due to Tiled changing that on their side. pytiled-parser will still load in the value regardless if it is a number or string in the JSON, but it will be converted to a string within pytiled-parser if it comes in as a float.
24+
925
## [1.4.0] - 2021-04-25
1026

1127
- Fixes issues with image loading for external tilesets. Previously, if an external tileset was in a different directory than the map file, image paths for the tileset would be incorrect. This was due to all images being given relative paths to the map file, regardless of if they were for an external tileset. This has been solved by giving absolute paths for images from external tilesets. Relative paths for embedded tilesets is still fine as the tileset is part of the map file.

pytiled_parser/layer.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,9 @@ def _cast_tile_layer(raw_layer: RawLayer) -> TileLayer:
402402
return tile_layer
403403

404404

405-
def _cast_object_layer(raw_layer: RawLayer) -> ObjectLayer:
405+
def _cast_object_layer(
406+
raw_layer: RawLayer, parent_dir: Optional[Path] = None
407+
) -> ObjectLayer:
406408
"""Cast the raw_layer to an ObjectLayer.
407409
408410
Args:
@@ -413,7 +415,7 @@ def _cast_object_layer(raw_layer: RawLayer) -> ObjectLayer:
413415

414416
tiled_objects = []
415417
for tiled_object_ in raw_layer["objects"]:
416-
tiled_objects.append(tiled_object.cast(tiled_object_))
418+
tiled_objects.append(tiled_object.cast(tiled_object_, parent_dir))
417419

418420
return ObjectLayer(
419421
tiled_objects=tiled_objects,
@@ -441,7 +443,9 @@ def _cast_image_layer(raw_layer: RawLayer) -> ImageLayer:
441443
return image_layer
442444

443445

444-
def _cast_group_layer(raw_layer: RawLayer) -> LayerGroup:
446+
def _cast_group_layer(
447+
raw_layer: RawLayer, parent_dir: Optional[Path] = None
448+
) -> LayerGroup:
445449
"""Cast the raw_layer to a LayerGroup.
446450
447451
Args:
@@ -454,7 +458,7 @@ def _cast_group_layer(raw_layer: RawLayer) -> LayerGroup:
454458
layers = []
455459

456460
for layer in raw_layer["layers"]:
457-
layers.append(cast(layer))
461+
layers.append(cast(layer, parent_dir))
458462

459463
return LayerGroup(layers=layers, **_get_common_attributes(raw_layer).__dict__)
460464

@@ -477,7 +481,7 @@ def _get_caster(type_: str) -> Callable[[RawLayer], Layer]:
477481
return casters[type_]
478482

479483

480-
def cast(raw_layer: RawLayer) -> Layer:
484+
def cast(raw_layer: RawLayer, parent_dir: Optional[Path] = None) -> Layer:
481485
"""Cast a raw Tiled layer into a pytiled_parser type.
482486
483487
This function will determine the type of layer and cast accordingly.
@@ -490,4 +494,10 @@ def cast(raw_layer: RawLayer) -> Layer:
490494
"""
491495
caster = _get_caster(raw_layer["type"])
492496

493-
return caster(raw_layer)
497+
if (
498+
caster.__name__ == "_cast_object_layer"
499+
or caster.__name__ == "_cast_group_layer"
500+
):
501+
return caster(raw_layer, parent_dir)
502+
else:
503+
return caster(raw_layer)

pytiled_parser/template.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

pytiled_parser/tiled_map.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class TiledMap:
6060
tiled_version: str
6161
tile_size: Size
6262
tilesets: TilesetDict
63-
version: float
63+
version: str
6464

6565
map_file: Optional[Path] = None
6666
background_color: Optional[Color] = None
@@ -102,7 +102,7 @@ class _RawTiledMap(TypedDict):
102102
tilesets: List[_RawTilesetMapping]
103103
tilewidth: int
104104
type: str
105-
version: float
105+
version: Union[str, float]
106106
width: int
107107

108108

@@ -139,11 +139,16 @@ def parse_map(file: Path) -> TiledMap:
139139
raw_tileset = typing_cast(RawTileSet, raw_tileset)
140140
tilesets[raw_tileset["firstgid"]] = tileset.cast(raw_tileset)
141141

142+
if isinstance(raw_tiled_map["version"], float):
143+
version = str(raw_tiled_map["version"])
144+
else:
145+
version = raw_tiled_map["version"]
146+
142147
# `map` is a built-in function
143148
map_ = TiledMap(
144149
map_file=file,
145150
infinite=raw_tiled_map["infinite"],
146-
layers=[layer.cast(layer_) for layer_ in raw_tiled_map["layers"]],
151+
layers=[layer.cast(layer_, parent_dir) for layer_ in raw_tiled_map["layers"]],
147152
map_size=Size(raw_tiled_map["width"], raw_tiled_map["height"]),
148153
next_layer_id=raw_tiled_map["nextlayerid"],
149154
next_object_id=raw_tiled_map["nextobjectid"],
@@ -152,7 +157,7 @@ def parse_map(file: Path) -> TiledMap:
152157
tiled_version=raw_tiled_map["tiledversion"],
153158
tile_size=Size(raw_tiled_map["tilewidth"], raw_tiled_map["tileheight"]),
154159
tilesets=tilesets,
155-
version=raw_tiled_map["version"],
160+
version=version,
156161
)
157162

158163
if raw_tiled_map.get("backgroundcolor") is not None:

pytiled_parser/tiled_object.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# pylint: disable=too-few-public-methods
2-
2+
import json
3+
from pathlib import Path
34
from typing import Callable, Dict, List, Optional, Union
45

56
import attr
@@ -174,6 +175,7 @@ class RawTiledObject(TypedDict):
174175

175176
id: int
176177
gid: int
178+
template: str
177179
x: float
178180
y: float
179181
width: float
@@ -390,7 +392,9 @@ def _get_caster(
390392
return _cast_rectangle
391393

392394

393-
def cast(raw_tiled_object: RawTiledObject) -> TiledObject:
395+
def cast(
396+
raw_tiled_object: RawTiledObject, parent_dir: Optional[Path] = None
397+
) -> TiledObject:
394398
"""Cast the raw tiled object into a pytiled_parser type
395399
396400
Args:
@@ -399,6 +403,18 @@ def cast(raw_tiled_object: RawTiledObject) -> TiledObject:
399403
Returns:
400404
TiledObject: a properly typed Tiled object.
401405
"""
406+
if raw_tiled_object.get("template"):
407+
if not parent_dir:
408+
raise RuntimeError(
409+
"A parent directory must be specified when using object templates"
410+
)
411+
template_path = Path(parent_dir / raw_tiled_object["template"])
412+
with open(template_path) as raw_template_file:
413+
loaded_template = json.load(raw_template_file)["object"]
414+
for key in loaded_template:
415+
if key != "id":
416+
raw_tiled_object[key] = loaded_template[key] # type: ignore
417+
402418
caster = _get_caster(raw_tiled_object)
403419

404420
tiled_object = caster(raw_tiled_object)

0 commit comments

Comments
 (0)