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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* 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::{
    object::Object,
    parsers::{parse_color, parse_data, parse_path, parse_property},
    Color, TiledValue,
};
use serde::Deserialize;
use std::collections::HashMap;
use std::path::PathBuf;

#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct TileLayer {
    /// Array of chunks (optional, generally infinite maps)
    pub chunks: Option<Vec<Chunk>>,
    /// Data consists of the global ID's of tiles making up this
    /// layer of the map
    #[serde(deserialize_with = "parse_data", default)]
    pub data: Vec<u32>,
    /// Row count. Same as map height for fixed-size maps.
    pub height: u32,
    /// Column count. Same as map width for fixed-size maps.
    pub width: u32,
}

#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct ObjectGroup {
    /// `TopDown` (default) or `Index`
    #[serde(rename(deserialize = "draworder"), default)]
    pub draw_order: DrawOrder,
    /// The array of `Object` in this layer
    #[serde(default)]
    pub objects: Vec<Object>,
}

/// Contains a file path to an image plus a mix colour
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct ImageLayer {
    /// Image used by this layer
    #[serde(deserialize_with = "parse_path", default)]
    pub image: PathBuf,
    #[serde(
        rename(deserialize = "transparentcolor"),
        deserialize_with = "parse_color",
        default
    )]
    /// Defaults to 0,0,0,0 (rgba)
    pub transparent_color: Color,
}

/// Used to group layers if required
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct Group {
    pub layers: Vec<Layer>,
}

/// Contains the data for this variant of layer
///
/// # Example
///
/// ``` no-run
/// match &layer_type {
///     LayerType::TileLayer(tiles) => {
///         //do_something(tiles);
///     }
///     LayerType::Group { layers } => {
///         &mut render_layers(layers);
///     }
///     LayerType::ImageLayer(image) => {
///         //do_something_else(image);
///     }
///     LayerType::ObjectGroup(objects) => {
///         //and_another_thing(objects);
///     }
/// }
/// ```
#[derive(Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all(deserialize = "lowercase"), tag = "type")]
pub enum LayerType {
    TileLayer(TileLayer),
    ObjectGroup(ObjectGroup),
    ImageLayer(ImageLayer),
    Group { layers: Vec<Layer> },
}

/// A map can contain any number of layers.
///
/// Layers have sub-types such as (enum) `LayerType::TileLayer(TileLayer)`
/// which contains the data for that sub-type.
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct Layer {
    pub name: String,
    /// Horizontal layer offset in pixels (default: 0)
    #[serde(rename(deserialize = "offsetx"), default)]
    pub offset_x: f32,
    /// Vertical layer offset in pixels (default: 0)
    #[serde(rename(deserialize = "offsety"), default)]
    pub offset_y: f32,
    /// Value between 0 and 1
    pub opacity: f32,
    #[serde(deserialize_with = "parse_property", default)]
    pub properties: HashMap<String, TiledValue>,
    #[serde(flatten)]
    /// The `LayerType` object also contains the data relating to the type
    pub layer_type: LayerType,
    /// Horizontal layer offset in tiles. Always 0.
    pub x: i32,
    /// Vertical layer offset in tiles. Always 0.
    pub y: i32,
}

/// Chunks are used to store the tile layer data for infinite maps
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Chunk {
    /// Array of unsigned int (GIDs) or base64-encoded data
    #[serde(deserialize_with = "parse_data", default)]
    pub data: Vec<u32>,
    pub height: u32,
    pub width: u32,
    pub x: i32,
    pub y: i32,
}

/// Can be `TopDown` (default) or `Index`. Applies to `ObjectGroup` only.
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all(deserialize = "lowercase"))]
pub enum DrawOrder {
    TopDown,
    Index,
}

impl Default for DrawOrder {
    fn default() -> Self {
        DrawOrder::TopDown
    }
}