use ::rltk::RandomNumberGenerator; use super::{BuilderMap, MetaMapBuilder}; use crate::TileType; pub struct DoorPlacement {} impl MetaMapBuilder for DoorPlacement { #[allow(dead_code)] fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) { self.doors(rng, build_data); } } impl DoorPlacement { #[allow(dead_code)] pub fn new() -> Box { Box::new(DoorPlacement {}) } fn doors(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) { if let Some(halls_original) = &build_data.corridors { let halls = halls_original.clone(); for hall in halls.iter() { // We aren't interested in tiny corridors if hall.len() > 2 && self.door_possible(build_data, hall[0]) { build_data.spawn_list.push((hall[0], "Door".to_string())); } } } else { // There are no corridors - scan for possible places let tiles = build_data.map.tiles.clone(); for (i, tile) in tiles.iter().enumerate() { if *tile == TileType::Floor && self.door_possible(build_data, i) && rng.roll_dice(1, 3) == 1 { build_data.spawn_list.push((i, "Door".to_string())); } } } } fn door_possible(&self, build_data: &mut BuilderMap, idx: usize) -> bool { // Check that there isn't already something in this tile for spawn in build_data.spawn_list.iter() { if spawn.0 == idx { return false; } } let width = build_data.map.width as usize; let height = build_data.map.height as usize; let x = idx % width; let y = idx / width; // Check for east-west door possibility if build_data.map.tiles[idx] == TileType::Floor && (x > 1 && build_data.map.tiles[idx - 1] == TileType::Floor) && (x < width - 2 && build_data.map.tiles[idx + 1] == TileType::Floor) && (y > 1 && build_data.map.tiles[idx - width] == TileType::Wall) && (y < height - 2 && build_data.map.tiles[idx + width] == TileType::Wall) { return true; } // Check for north-south door possibility if build_data.map.tiles[idx] == TileType::Floor && (x > 1 && build_data.map.tiles[idx - 1] == TileType::Wall) && (x < width - 2 && build_data.map.tiles[idx + 1] == TileType::Wall) && (y > 1 && build_data.map.tiles[idx - width] == TileType::Floor) && (y < height - 2 && build_data.map.tiles[idx + width] == TileType::Floor) { return true; } false } }