use std::sync::Arc;
use crate::prelude::*;
use bevy::prelude::*;
use bevy_ecs_tilemap::prelude::{HexCoordSystem, IsoCoordSystem};
pub fn get_layer_from_map(map: &tiled::Map, layer_id: u32) -> Option<tiled::Layer<'_>> {
map.get_layer(layer_id as usize)
}
pub fn get_tileset_from_map(map: &tiled::Map, tileset_id: u32) -> Option<&Arc<tiled::Tileset>> {
for (id, tileset) in map.tilesets().iter().enumerate() {
if id == tileset_id as usize {
return Some(tileset);
}
}
None
}
pub fn get_tile_from_map(
map: &tiled::Map,
tileset_id: u32,
tile_id: tiled::TileId,
) -> Option<tiled::Tile<'_>> {
get_tileset_from_map(map, tileset_id).and_then(|t| t.get_tile(tile_id))
}
pub fn get_object_from_map(map: &tiled::Map, object_id: u32) -> Option<tiled::Object<'_>> {
for layer in map.layers() {
let obj = layer
.as_object_layer()
.and_then(|l| l.objects().find(|o| o.id() == object_id));
if obj.is_some() {
return obj;
}
}
None
}
pub fn tilemap_type_from_map(map: &tiled::Map) -> TilemapType {
match map.orientation {
tiled::Orientation::Orthogonal => TilemapType::Square,
tiled::Orientation::Hexagonal => match map.stagger_axis {
tiled::StaggerAxis::X if map.stagger_index == tiled::StaggerIndex::Even => {
TilemapType::Hexagon(HexCoordSystem::ColumnOdd)
}
tiled::StaggerAxis::X if map.stagger_index == tiled::StaggerIndex::Odd => {
TilemapType::Hexagon(HexCoordSystem::ColumnEven)
}
tiled::StaggerAxis::Y if map.stagger_index == tiled::StaggerIndex::Even => {
TilemapType::Hexagon(HexCoordSystem::RowOdd)
}
tiled::StaggerAxis::Y if map.stagger_index == tiled::StaggerIndex::Odd => {
TilemapType::Hexagon(HexCoordSystem::RowEven)
}
_ => unreachable!(),
},
tiled::Orientation::Isometric => TilemapType::Isometric(IsoCoordSystem::Diamond),
tiled::Orientation::Staggered => {
panic!("Isometric (Staggered) map is not supported");
}
}
}
pub fn grid_size_from_map(map: &tiled::Map) -> TilemapGridSize {
TilemapGridSize {
x: map.tile_width as f32,
y: map.tile_height as f32,
}
}
pub fn tile_size(tile: &tiled::Tile) -> TilemapTileSize {
match &tile.image {
Some(image) => TilemapTileSize::new(image.width as f32, image.height as f32),
None => TilemapTileSize::new(
tile.tileset().tile_width as f32,
tile.tileset().tile_height as f32,
),
}
}
pub(crate) fn iso_projection(
coords: Vec2,
tilemap_size: &TilemapSize,
grid_size: &TilemapGridSize,
) -> Vec2 {
let fract = Vec2 {
x: coords.x / grid_size.y,
y: coords.y / grid_size.y,
};
let origin_x = tilemap_size.y as f32 * grid_size.x / 2.;
Vec2 {
x: (fract.x - fract.y) * grid_size.x / 2. + origin_x,
y: (fract.x + fract.y) * grid_size.y / 2.,
}
}