Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for WangSets #226

Merged
merged 9 commits into from
Aug 5, 2022
28 changes: 28 additions & 0 deletions assets/tiled_csv_wangsets.tmx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.5" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="32" tileheight="32" infinite="0" nextlayerid="3" nextobjectid="1">
<tileset firstgid="1" source="tilesheet_wangsets.tsx"/>
<layer id="1" name="Layer 1" width="30" height="20">
<data encoding="csv">
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
</data>
</layer>
</map>
112 changes: 112 additions & 0 deletions assets/tilesheet_wangsets.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.8" tiledversion="1.8.5" name="tilesheet_wangsets" tilewidth="32" tileheight="32" tilecount="84" columns="14">
<image source="tilesheet.png" width="448" height="192"/>
<wangsets>
<wangset name="Void" type="mixed" tile="-1">
<wangcolor name="" color="#ff0000" tile="-1" probability="1"/>
<wangtile tileid="0" wangid="1,1,0,0,0,0,0,1"/>
<wangtile tileid="1" wangid="0,0,0,1,1,1,0,0"/>
<wangtile tileid="14" wangid="0,0,0,0,0,1,1,1"/>
<wangtile tileid="15" wangid="0,1,1,1,0,0,0,0"/>
<wangtile tileid="16" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="17" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="28" wangid="1,1,0,0,0,0,0,1"/>
<wangtile tileid="29" wangid="1,1,0,0,0,0,0,1"/>
<wangtile tileid="56" wangid="1,1,0,0,0,0,0,1"/>
<wangtile tileid="57" wangid="0,0,0,1,1,1,0,0"/>
<wangtile tileid="70" wangid="0,0,0,0,0,1,1,1"/>
<wangtile tileid="71" wangid="0,1,1,1,0,0,0,0"/>
</wangset>
<wangset name="Wall" type="mixed" tile="-1">
<wangcolor name="Light" color="#00ff00" tile="-1" probability="1"/>
<wangcolor name="Dark" color="#006f00" tile="-1" probability="1"/>
<wangtile tileid="4" wangid="2,2,2,2,2,2,2,2"/>
<wangtile tileid="5" wangid="2,2,0,0,0,2,2,2"/>
<wangtile tileid="6" wangid="2,2,0,0,0,0,0,2"/>
<wangtile tileid="7" wangid="2,2,2,2,0,0,0,2"/>
<wangtile tileid="8" wangid="0,0,0,2,0,0,0,0"/>
<wangtile tileid="9" wangid="0,0,0,0,0,2,0,0"/>
<wangtile tileid="10" wangid="2,2,0,2,0,2,2,2"/>
<wangtile tileid="11" wangid="2,2,2,2,0,2,0,2"/>
<wangtile tileid="12" wangid="2,2,0,2,0,2,0,2"/>
<wangtile tileid="13" wangid="0,2,2,2,0,2,0,2"/>
<wangtile tileid="19" wangid="0,0,0,0,0,2,2,2"/>
<wangtile tileid="21" wangid="0,2,2,2,0,0,0,0"/>
<wangtile tileid="22" wangid="0,2,2,0,0,0,0,0"/>
<wangtile tileid="23" wangid="0,0,0,0,0,0,0,2"/>
<wangtile tileid="24" wangid="0,2,0,2,2,2,2,2"/>
<wangtile tileid="25" wangid="0,2,2,2,2,2,0,2"/>
<wangtile tileid="26" wangid="0,2,0,2,0,2,2,2"/>
<wangtile tileid="27" wangid="0,2,0,2,2,2,0,2"/>
<wangtile tileid="31" wangid="0,0,2,2,2,2,2,0"/>
<wangtile tileid="33" wangid="0,0,0,2,2,2,2,2"/>
<wangtile tileid="34" wangid="0,0,0,2,2,2,0,0"/>
<wangtile tileid="35" wangid="0,2,2,2,1,2,0,0"/>
<wangtile tileid="36" wangid="0,0,0,2,0,2,0,0"/>
<wangtile tileid="37" wangid="0,0,0,0,0,2,0,2"/>
<wangtile tileid="38" wangid="0,2,0,0,0,0,0,2"/>
<wangtile tileid="39" wangid="0,2,0,2,0,0,0,0"/>
<wangtile tileid="40" wangid="1,1,0,1,0,1,0,1"/>
<wangtile tileid="41" wangid="0,1,1,1,0,1,0,1"/>
<wangtile tileid="45" wangid="2,2,2,2,2,2,2,2"/>
<wangtile tileid="46" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="47" wangid="1,1,0,0,0,1,1,1"/>
<wangtile tileid="48" wangid="1,1,0,0,0,0,0,1"/>
<wangtile tileid="49" wangid="1,1,1,1,0,0,0,1"/>
<wangtile tileid="50" wangid="0,0,0,1,0,0,0,0"/>
<wangtile tileid="51" wangid="0,0,0,0,0,1,0,0"/>
<wangtile tileid="52" wangid="1,1,0,1,0,1,1,1"/>
<wangtile tileid="53" wangid="1,1,1,1,0,1,0,1"/>
<wangtile tileid="54" wangid="0,1,0,1,0,1,1,1"/>
<wangtile tileid="55" wangid="0,1,0,1,1,1,0,1"/>
<wangtile tileid="59" wangid="0,0,1,1,1,1,1,0"/>
<wangtile tileid="61" wangid="0,0,0,0,0,1,1,1"/>
<wangtile tileid="63" wangid="0,1,1,1,0,0,0,0"/>
<wangtile tileid="64" wangid="0,1,0,0,0,0,0,0"/>
<wangtile tileid="65" wangid="0,0,0,0,0,0,0,1"/>
<wangtile tileid="66" wangid="0,1,0,1,1,1,1,1"/>
<wangtile tileid="67" wangid="0,1,1,1,1,1,0,1"/>
<wangtile tileid="73" wangid="1,1,2,2,2,2,2,1"/>
<wangtile tileid="75" wangid="0,0,0,1,1,1,1,1"/>
<wangtile tileid="76" wangid="0,0,0,1,1,1,0,0"/>
<wangtile tileid="77" wangid="0,1,1,1,1,1,0,0"/>
<wangtile tileid="78" wangid="0,0,0,1,0,1,0,0"/>
<wangtile tileid="79" wangid="0,0,0,0,0,1,0,1"/>
<wangtile tileid="80" wangid="0,1,0,0,0,0,0,1"/>
<wangtile tileid="81" wangid="0,1,0,1,0,0,0,0"/>
</wangset>
<wangset name="Floor" type="mixed" tile="-1">
<wangcolor name="" color="#ff0000" tile="-1" probability="1">
<properties>
<property name="Damage" type="float" value="0"/>
</properties>
</wangcolor>
<wangcolor name="Trap" color="#00ff00" tile="-1" probability="1">
<properties>
<property name="Damage" type="float" value="32.1"/>
</properties>
</wangcolor>
<wangtile tileid="5" wangid="0,0,1,1,1,0,0,0"/>
<wangtile tileid="6" wangid="0,0,1,1,1,1,1,0"/>
<wangtile tileid="7" wangid="0,0,0,0,1,1,1,0"/>
<wangtile tileid="19" wangid="1,1,1,1,1,0,0,0"/>
<wangtile tileid="20" wangid="1,1,1,1,1,1,1,1"/>
<wangtile tileid="21" wangid="1,0,0,0,1,1,1,1"/>
<wangtile tileid="33" wangid="1,1,1,0,0,0,0,0"/>
<wangtile tileid="34" wangid="1,1,1,0,0,0,1,1"/>
<wangtile tileid="35" wangid="1,0,0,0,0,0,1,1"/>
<wangtile tileid="47" wangid="0,0,1,1,1,0,0,0"/>
<wangtile tileid="48" wangid="0,0,1,1,1,1,1,0"/>
<wangtile tileid="49" wangid="0,0,0,0,1,1,1,0"/>
<wangtile tileid="61" wangid="1,1,1,1,1,0,0,0"/>
<wangtile tileid="62" wangid="2,2,2,2,2,2,2,2"/>
<wangtile tileid="63" wangid="1,0,0,0,1,1,1,1"/>
<wangtile tileid="75" wangid="1,1,1,0,0,0,0,0"/>
<wangtile tileid="76" wangid="1,1,1,0,0,0,1,1"/>
<wangtile tileid="77" wangid="1,0,0,0,0,0,1,1"/>
<properties>
<property name="Movement Cost" type="int" value="1"/>
</properties>
</wangset>
</wangsets>
</tileset>
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum Error {
/// Supported types are `string`, `int`, `float`, `bool`, `color`, `file` and `object`.
type_name: String,
},
/// WangId not properly formated. Stores the wrongly parsed String.
InvalidWangIdEncoding(String),
}

/// A result with an error variant of [`crate::Error`].
Expand Down Expand Up @@ -93,6 +95,8 @@ impl fmt::Display for Error {
write!(fmt, "Invalid property value: {}", description),
Error::UnknownPropertyType { type_name } =>
write!(fmt, "Unknown property value type '{}'", type_name),
Error::InvalidWangIdEncoding(s) =>
write!(fmt, "\"{}\" Is not a valid WangId format", s),
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/tileset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use crate::properties::{parse_properties, Properties};
use crate::tile::TileData;
use crate::{util::*, Gid, Tile, TileId};

mod wangset;
pub use wangset::{WangColor, WangId, WangSet, WangTile};

/// A collection of tiles for usage in maps and template objects.
///
/// Also see the [TMX docs](https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tileset).
Expand Down Expand Up @@ -53,6 +56,9 @@ pub struct Tileset {
/// All the tiles present in this tileset, indexed by their local IDs.
tiles: HashMap<TileId, TileData>,

/// All the wangsets present in this tileset
pub wang_sets: Vec<WangSet>,

/// The custom properties of the tileset.
pub properties: Properties,
}
Expand Down Expand Up @@ -235,6 +241,7 @@ impl Tileset {
let mut image = Option::None;
let mut tiles = HashMap::with_capacity(prop.tilecount as usize);
let mut properties = HashMap::new();
let mut wang_sets = Vec::new();

parse_tag!(parser, "tileset", {
"image" => |attrs| {
Expand All @@ -250,6 +257,11 @@ impl Tileset {
tiles.insert(id, tile);
Ok(())
},
"wangset" => |attrs| {
let set = WangSet::new(parser, attrs)?;
wang_sets.push(set);
Ok(())
},
});

// A tileset is considered an image collection tileset if there is no image attribute (because its tiles do).
Expand Down Expand Up @@ -278,6 +290,7 @@ impl Tileset {
tilecount: prop.tilecount,
image,
tiles,
wang_sets,
properties,
})
}
Expand Down
101 changes: 101 additions & 0 deletions src/tileset/wangset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use std::collections::HashMap;

use xml::attribute::OwnedAttribute;

use crate::{
error::Error,
properties::{parse_properties, Properties},
util::{get_attrs, parse_tag, XmlEventResult},
Result, TileId,
};

mod wang_color;
pub use wang_color::WangColor;
mod wang_tile;
pub use wang_tile::{WangId, WangTile};

/// Undocummented WangSet types
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum WangSetType {
Corner,
Edge,
Mixed,
}

impl Default for WangSetType {
fn default() -> Self {
WangSetType::Mixed
}
}

/// Raw data belonging to a WangSet.
#[derive(Debug, PartialEq, Clone)]
pub struct WangSet {
/// The name of the Wang set
pub name: String,
/// Type of wangset
pub wang_type: WangSetType,
/// The tile ID of the tile representing this Wang set.
pub tile: Option<TileId>,
/// A color that can be used to define the corner and/or edge of a Wang tile.
pub wang_colors: Vec<WangColor>,
/// A color that can be used to define the corner and/or edge of a Wang tile.
pub wang_tiles: HashMap<TileId, WangTile>,
/// The custom properties of this tile.
pub properties: Properties,
}

impl WangSet {
/// Reads data from XML parser to create a WangSet.
pub fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
attrs: Vec<OwnedAttribute>,
) -> Result<WangSet> {
// Get common data
let (name, wang_type, tile) = get_attrs!(
for v in attrs {
"name" => name ?= v.parse::<String>(),
"type" => wang_type ?= v.parse::<String>(),
"tile" => tile ?= v.parse::<i64>(),
}
(name, wang_type, tile)
);

let wang_type = match wang_type.as_str() {
"corner" => WangSetType::Corner,
"edge" => WangSetType::Edge,
_ => WangSetType::default(),
};
let tile = if tile >= 0 { Some(tile as u32) } else { None };

// Gather variable data
let mut wang_colors = Vec::new();
let mut wang_tiles = HashMap::new();
let mut properties = HashMap::new();
parse_tag!(parser, "wangset", {
"wangcolor" => |attrs| {
let color = WangColor::new(parser, attrs)?;
wang_colors.push(color);
Ok(())
},
"wangtile" => |attrs| {
let (id, t) = WangTile::new(parser, attrs)?;
wang_tiles.insert(id, t);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
});

Ok(WangSet {
name,
wang_type,
tile,
wang_colors,
wang_tiles,
properties,
})
}
}
63 changes: 63 additions & 0 deletions src/tileset/wangset/wang_color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::collections::HashMap;

use xml::attribute::OwnedAttribute;

use crate::{
error::Error,
properties::{parse_properties, Color, Properties},
util::{get_attrs, parse_tag, XmlEventResult},
Result, TileId,
};

/// Raw data belonging to a tile.
#[derive(Debug, PartialEq, Clone)]
pub struct WangColor {
/// The name of this color.
pub name: String,
#[allow(missing_docs)]
pub color: Color,
/// The tile ID of the tile representing this color.
pub tile: Option<TileId>,
/// The relative probability that this color is chosen over others in case of multiple options. (defaults to 0)
pub probability: f32,
/// The custom properties of this tile.
pub properties: Properties,
}

impl WangColor {
/// Reads data from XML parser to create a WangColor.
pub fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
attrs: Vec<OwnedAttribute>,
) -> Result<WangColor> {
// Get common data
let (name, color, tile, probability) = get_attrs!(
for v in attrs {
"name" => name ?= v.parse::<String>(),
"color" => color ?= v.parse(),
"tile" => tile ?= v.parse::<i64>(),
"probability" => probability ?= v.parse::<f32>(),
}
(name, color, tile, probability)
);

let tile = if tile >= 0 { Some(tile as u32) } else { None };

// Gather variable data
let mut properties = HashMap::new();
parse_tag!(parser, "wangcolor", {
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
});

Ok(WangColor {
name,
color,
tile,
probability,
properties,
})
}
}
Loading