diff --git a/pytiled_parser/tileset.py b/pytiled_parser/tileset.py index 516d4c6..f94bea4 100644 --- a/pytiled_parser/tileset.py +++ b/pytiled_parser/tileset.py @@ -1,6 +1,6 @@ # pylint: disable=too-few-public-methods from pathlib import Path -from typing import Dict, List, NamedTuple, Optional +from typing import Dict, List, NamedTuple, Optional, Union import attr from typing_extensions import TypedDict @@ -9,6 +9,8 @@ from . import layer from . import properties as properties_ from .common_types import Color, OrderedPair from .util import parse_color +from .wang_set import RawWangSet, WangSet +from .wang_set import cast as cast_wangset class Grid(NamedTuple): @@ -150,7 +152,7 @@ class Tileset: type: Optional[str] = None tiled_version: Optional[str] = None - version: Optional[float] = None + version: Optional[str] = None image: Optional[Path] = None image_width: Optional[int] = None @@ -164,6 +166,7 @@ class Tileset: properties: Optional[properties_.Properties] = None terrain_types: Optional[List[Terrain]] = None tiles: Optional[Dict[int, Tile]] = None + wang_sets: Optional[List[WangSet]] = None class RawFrame(TypedDict): @@ -235,7 +238,8 @@ class RawTileSet(TypedDict): tilewidth: int transparentcolor: str type: str - version: float + version: Union[str, float] + wangsets: List[RawWangSet] def _cast_frame(raw_frame: RawFrame) -> Frame: @@ -361,6 +365,7 @@ def cast(raw_tileset: RawTileSet, external_path: Optional[Path] = None) -> Tiles Args: raw_tileset: Raw Tileset to be cast. + external_path: The path to the tileset if it is not an embedded one. Returns: TileSet: a properly typed TileSet. @@ -380,7 +385,10 @@ def cast(raw_tileset: RawTileSet, external_path: Optional[Path] = None) -> Tiles tileset.type = raw_tileset["type"] if raw_tileset.get("version") is not None: - tileset.version = raw_tileset["version"] + if isinstance(raw_tileset["version"], float): + tileset.version = str(raw_tileset["version"]) + else: + tileset.version = raw_tileset["version"] if raw_tileset.get("tiledversion") is not None: tileset.tiled_version = raw_tileset["tiledversion"] @@ -429,4 +437,10 @@ def cast(raw_tileset: RawTileSet, external_path: Optional[Path] = None) -> Tiles tiles[raw_tile["id"]] = _cast_tile(raw_tile, external_path=external_path) tileset.tiles = tiles + if raw_tileset.get("wangsets") is not None: + wangsets = [] + for raw_wangset in raw_tileset["wangsets"]: + wangsets.append(cast_wangset(raw_wangset)) + tileset.wang_sets = wangsets + return tileset diff --git a/pytiled_parser/wang_set.py b/pytiled_parser/wang_set.py index 04ef559..498e6dd 100644 --- a/pytiled_parser/wang_set.py +++ b/pytiled_parser/wang_set.py @@ -1,36 +1,37 @@ -from typing import List, NamedTuple, Optional +from typing import List, Optional import attr from typing_extensions import TypedDict from . import properties as properties_ -from .common_types import Color, OrderedPair +from .common_types import Color +from .util import parse_color -class WangTile(NamedTuple): +@attr.s(auto_attribs=True) +class WangTile: - id: int - dflip: bool = False - hflip: bool = False - vflip: bool = False - wang_ids: List[int] = [] + tile_id: int + wang_id: List[int] -class WangColor(NamedTuple): +@attr.s(auto_attribs=True) +class WangColor: color: Color name: str probability: float tile: int + properties: Optional[properties_.Properties] = None -class WangSet(NamedTuple): +@attr.s(auto_attribs=True) +class WangSet: - cornercolors: List[WangColor] - edgecolors: List[WangColor] name: str tile: int wang_tiles: List[WangTile] + wang_colors: List[WangColor] properties: Optional[properties_.Properties] = None @@ -38,9 +39,6 @@ class RawWangTile(TypedDict): """ The keys and their types that appear in a Wang Tile JSON Object.""" tileid: int - dflip: bool - hflip: bool - vflip: bool wangid: List[int] @@ -51,7 +49,79 @@ class RawWangColor(TypedDict): name: str probability: float tile: int + properties: List[properties_.RawProperty] class RawWangSet(TypedDict): """ The keys and their types that appear in a Wang Set JSON Object.""" + + colors: List[RawWangColor] + name: str + properties: List[properties_.RawProperty] + tile: int + wangtiles: List[RawWangTile] + + +def _cast_wang_tile(raw_wang_tile: RawWangTile) -> WangTile: + """Cast the raw wang tile into a pytiled_parser type + + Args: + raw_wang_tile: RawWangTile to be cast. + + Returns: + WangTile: A properly typed WangTile. + """ + return WangTile(tile_id=raw_wang_tile["tileid"], wang_id=raw_wang_tile["wangid"]) + + +def _cast_wang_color(raw_wang_color: RawWangColor) -> WangColor: + """Cast the raw wang color into a pytiled_parser type + + Args: + raw_wang_color: RawWangColor to be cast. + + Returns: + WangColor: A properly typed WangColor. + """ + wang_color = WangColor( + name=raw_wang_color["name"], + color=parse_color(raw_wang_color["color"]), + tile=raw_wang_color["tile"], + probability=raw_wang_color["probability"], + ) + + if raw_wang_color.get("properties") is not None: + wang_color.properties = properties_.cast(raw_wang_color["properties"]) + + return wang_color + + +def cast(raw_wangset: RawWangSet) -> WangSet: + """Cast the raw wangset into a pytiled_parser type + + Args: + raw_wangset: Raw Wangset to be cast. + + Returns: + WangSet: A properly typed WangSet. + """ + + colors = [] + for raw_wang_color in raw_wangset["colors"]: + colors.append(_cast_wang_color(raw_wang_color)) + + tiles = [] + for raw_wang_tile in raw_wangset["wangtiles"]: + tiles.append(_cast_wang_tile(raw_wang_tile)) + + wangset = WangSet( + name=raw_wangset["name"], + tile=raw_wangset["tile"], + wang_colors=colors, + wang_tiles=tiles, + ) + + if raw_wangset.get("properties") is not None: + wangset.properties = properties_.cast(raw_wangset["properties"]) + + return wangset