1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use crate::{
    layer::ObjectGroup,
    parsers::{parse_color, parse_path, parse_property},
    wangs::WangSet,
    Color, TiledValue, Vec2,
};
use serde::Deserialize;
use std::collections::HashMap;
use std::path::PathBuf;

/// A tileset that associates information with each tile.
///
/// A tileset associates information with each tile such as
/// image path or terrain type, may include a tiles array property.
/// Each tile in the `tiles` member has a local id property which
/// specifies the local ID within the tileset.
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct TileSet {
    /// The number of tile columns in the tileset. Eg; dividing the
    /// associated image in to columns where each column is the width
    /// of the tile.
    pub columns: u32,
    /// GID corresponding to the first tile in the set
    #[serde(rename(deserialize = "firstgid"))]
    pub first_gid: u32,
    /// Path to the image used for tiles in this set
    #[serde(deserialize_with = "parse_path")]
    pub image: PathBuf,
    #[serde(rename(deserialize = "imagewidth"))]
    pub image_width: u32,
    #[serde(rename(deserialize = "imageheight"))]
    pub image_height: u32,
    /// Buffer between image edge and first tile in pixels
    pub margin: u32,
    /// Spacing between adjacent tiles in image in pixels
    pub spacing: u32,
    pub name: String,
    #[serde(deserialize_with = "parse_property", default)]
    pub properties: HashMap<String, TiledValue>,
    pub terrains: Option<Vec<Terrain>>,
    /// The tile count + the first GID enable finding the tile location
    /// on the image
    #[serde(rename(deserialize = "tilecount"))]
    pub tile_count: u32,
    #[serde(rename(deserialize = "tileheight"))]
    pub tile_height: u32,
    #[serde(rename(deserialize = "tilewidth"))]
    pub tile_width: u32,
    /// used to specify an offset in pixels, to be applied
    /// when drawing a tile from this tileset
    #[serde(rename(deserialize = "tileoffset"))]
    pub tile_offset: Option<Vec2<i32>>,
    /// Holds *extra* information for tiles such as terrain or animation
    pub tiles: Option<Vec<Tile>>,
    #[serde(
        rename(deserialize = "transparentcolor"),
        deserialize_with = "parse_color",
        default
    )]
    /// Defaults to 0,0,0,0 (rgba)
    pub transparent_color: Color,
    #[serde(rename(deserialize = "wangsets"))]
    pub wang_sets: Option<Vec<WangSet>>,
}

#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct Tile {
    pub animation: Option<Vec<Frame>>,
    /// Unlike the ID used in the `TileLayer`, this ID is
    /// local to the `TileSet` only and so starts at 0 (the
    /// tile layer ID starts a 1 for tiles with 0 being no-tile).
    pub id: u32,
    /// Image representing this tile if it uses a separate image
    pub image: Option<String>,
    /// Width of the tile image in pixels
    #[serde(rename(deserialize = "imagewidth"), default)]
    pub image_width: u32,
    /// Height of the tile image in pixels
    #[serde(rename(deserialize = "imageheight"), default)]
    pub image_height: u32,
    #[serde(rename(deserialize = "objectgroup"))]
    pub object_group: Option<ObjectGroup>,
    #[serde(deserialize_with = "parse_property", default)]
    pub properties: HashMap<String, TiledValue>,
    /// The order of indices is: top-left, top-right, bottom-left, bottom-right
    ///
    /// Each entry is the index number in to the Terrain array to get the
    /// specific terrain type for this tile.
    pub terrain: Option<[i8; 4]>,
    /// An optional string for describing a type
    #[serde(rename(deserialize = "type"))]
    pub tile_type: Option<String>,
}

#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Frame {
    /// Frame duration in milliseconds
    pub duration: u32,
    /// Local tile ID representing this frame
    #[serde(rename(deserialize = "tileid"))]
    pub tile_id: u32,
}

#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all(deserialize = "lowercase"))]
pub enum Orientation {
    Orthogonal,
    Isometric,
}

#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Terrain {
    pub name: String,
    pub tile: u32,
}