diff --git a/pytiled_parser/tileset.py b/pytiled_parser/tileset.py index dcb2ee2..9d22ec5 100644 --- a/pytiled_parser/tileset.py +++ b/pytiled_parser/tileset.py @@ -46,6 +46,27 @@ class Frame(NamedTuple): duration: int +@attr.s(auto_attribs=True, kw_only=True) +class Transformations: + """Transformations Object. + + This is used to store what transformations may be performed on Tiles + within a tileset. (This is primarily used with wang sets, however could + be used for any means a game wants really.) + + Args: + hflip: Allow horizontal flip? + vflip: Allow vertical flip? + rotate: Allow rotation? + prefer_untransformed: Should untransformed tiles be preferred? + """ + + hflip: Optional[bool] = None + vflip: Optional[bool] = None + rotate: Optional[bool] = None + prefer_untransformed: Optional[bool] = None + + @attr.s(auto_attribs=True, kw_only=True) class Tile: # FIXME: args @@ -121,6 +142,8 @@ class Tileset: image_width: Optional[int] = None image_height: Optional[int] = None + transformations: Optional[Transformations] = None + firstgid: Optional[int] = None background_color: Optional[Color] = None tile_offset: Optional[OrderedPair] = None @@ -145,6 +168,15 @@ class RawTileOffset(TypedDict): y: int +class RawTransformations(TypedDict): + """ The keys and their types that appear in a Transformations JSON Object.""" + + hflip: bool + vflip: bool + rotate: bool + preferuntransformed: bool + + class RawTile(TypedDict): """ The keys and their types that appear in a Tile JSON Object.""" @@ -189,7 +221,7 @@ class RawTileSet(TypedDict): tiles: List[RawTile] tilewidth: int transparentcolor: str - type: str + transformations: RawTransformations version: Union[str, float] wangsets: List[RawWangSet] @@ -262,6 +294,24 @@ def _cast_tile(raw_tile: RawTile, external_path: Optional[Path] = None) -> Tile: return tile +def _cast_transformations(raw_transformations: RawTransformations) -> Transformations: + """Cast the raw_transformations to a Transformations object. + + Args: + raw_transformations: RawTransformations to be casted to a Transformations + + Returns: + Transformations: The Transformations created from the raw_transformations + """ + + return Transformations( + hflip=raw_transformations["hflip"], + vflip=raw_transformations["vflip"], + rotate=raw_transformations["rotate"], + prefer_untransformed=raw_transformations["preferuntransformed"], + ) + + def _cast_grid(raw_grid: RawGrid) -> Grid: """Cast the raw_grid to a Grid object. @@ -356,4 +406,7 @@ def cast(raw_tileset: RawTileSet, external_path: Optional[Path] = None) -> Tiles wangsets.append(cast_wangset(raw_wangset)) tileset.wang_sets = wangsets + if raw_tileset.get("transformations") is not None: + tileset.transformations = _cast_transformations(raw_tileset["transformations"]) + return tileset diff --git a/tests/test_data/tilesets/image_transformations/expected.py b/tests/test_data/tilesets/image_transformations/expected.py new file mode 100644 index 0000000..d683947 --- /dev/null +++ b/tests/test_data/tilesets/image_transformations/expected.py @@ -0,0 +1,25 @@ +from pathlib import Path + +from pytiled_parser import tileset + +EXPECTED = tileset.Tileset( + columns=8, + image=Path("../../images/tmw_desert_spacing.png"), + image_height=199, + image_width=265, + margin=1, + spacing=1, + name="tile_set_image", + tile_count=48, + tiled_version="1.6.0", + tile_height=32, + tile_width=32, + transformations=tileset.Transformations( + hflip=True, + vflip=False, + prefer_untransformed=False, + rotate=False, + ), + version="1.6", + type="tileset", +) diff --git a/tests/test_data/tilesets/image_transformations/tileset.json b/tests/test_data/tilesets/image_transformations/tileset.json new file mode 100644 index 0000000..134873c --- /dev/null +++ b/tests/test_data/tilesets/image_transformations/tileset.json @@ -0,0 +1,21 @@ +{ "columns":8, + "image":"..\/..\/images\/tmw_desert_spacing.png", + "imageheight":199, + "imagewidth":265, + "margin":1, + "name":"tile_set_image", + "spacing":1, + "tilecount":48, + "tiledversion":"1.6.0", + "tileheight":32, + "tilewidth":32, + "transformations": + { + "hflip":true, + "preferuntransformed":false, + "rotate":false, + "vflip":false + }, + "type":"tileset", + "version":"1.6" +} \ No newline at end of file diff --git a/tests/test_tileset.py b/tests/test_tileset.py index f8a83a1..bca29bd 100644 --- a/tests/test_tileset.py +++ b/tests/test_tileset.py @@ -20,6 +20,7 @@ ALL_TILESET_DIRS = [ TILE_SETS / "image_properties", TILE_SETS / "image_transparent_color", TILE_SETS / "image_tile_offset", + TILE_SETS / "image_transformations", TILE_SETS / "individual_images", TILE_SETS / "terrain", ]