use super::*;
use bevy_reflect::TypeUuid;
#[derive(TypeUuid)]
#[uuid = "387665bd-394f-4c83-8869-dbf135aaa6a4"]
pub struct Map {
pub properties: HashMap<String, Property>,
pub tilesets: Vec<Arc<Tileset>>,
pub layers: Vec<Layer>,
pub width: u32,
pub height: u32,
pub tile_type: TileType,
pub background: [u8; 4],
}
pub struct Objects<'a> {
l: &'a [Layer],
i: usize,
z: f32,
sub: Option<Box<Objects<'a>>>,
}
impl Map {
pub fn get_tileset(&self, gid: u32) -> Option<Arc<Tileset>> {
for tileset in self.tilesets.iter().rev() {
if gid >= tileset.first_gid {
return Some(tileset.clone());
}
}
None
}
pub fn get_tile(&self, gid: u32) -> Option<&Tile> {
for tileset in self.tilesets.iter().rev() {
if gid >= tileset.first_gid {
let id = gid - tileset.first_gid;
return if let Some(&Some(ref tile)) = tileset.tiles.get(id as usize) {
Some(&tile)
} else {
None
};
}
}
None
}
pub fn objects(&self) -> Objects {
Objects {
l: self.layers.as_slice(),
i: 0,
z: 0.0,
sub: None,
}
}
}
impl<'a> Iterator for Objects<'a> {
type Item = (f32, &'a Object);
fn next(&mut self) -> Option<(f32, &'a Object)> {
if let Some(sub) = self.sub.as_mut().and_then(|s| s.next()) {
return Some(sub);
} else if self.sub.is_some() {
self.z = self.sub.take().unwrap().z + 1.0;
self.sub = None;
}
if !self.l.is_empty() {
match &self.l[0] {
Layer::Group { layers, .. } => {
self.sub = Some(Box::new(Objects {
l: layers.as_slice(),
i: 0,
z: self.z,
sub: None,
}));
}
Layer::ObjectLayer { objects, .. } => {
if self.i < objects.len() {
self.i += 1;
return Some((self.z, &objects[self.i - 1]));
}
}
_ => {}
}
self.l = &self.l[1..];
self.i = 0;
self.z += 1.0;
return self.next();
}
None
}
}