roguelike-game/src/map_builders/door_placement.rs

79 lines
2.7 KiB
Rust
Raw Normal View History

2021-12-17 13:53:14 -05:00
use super::{BuilderMap, MetaMapBuilder};
use crate::rng::roll_dice;
2021-12-17 13:53:14 -05:00
use crate::TileType;
pub struct DoorPlacement {}
impl MetaMapBuilder for DoorPlacement {
#[allow(dead_code)]
fn build_map(&mut self, build_data: &mut BuilderMap) {
self.doors(build_data);
2021-12-17 13:53:14 -05:00
}
}
impl DoorPlacement {
#[allow(dead_code)]
pub fn new() -> Box<DoorPlacement> {
Box::new(DoorPlacement {})
}
fn doors(&mut self, build_data: &mut BuilderMap) {
2021-12-17 13:53:14 -05:00
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
2021-12-17 16:54:36 -05:00
if hall.len() > 2 && self.door_possible(build_data, hall[0]) {
build_data.spawn_list.push((hall[0], "Door".to_string()));
2021-12-17 13:53:14 -05:00
}
}
} 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)
&& roll_dice(1, 3) == 1
{
2021-12-17 13:53:14 -05:00
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;
}
}
2021-12-17 13:53:14 -05:00
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
}
}