rust-rl/src/map_builders/area_starting_points.rs

85 lines
2.3 KiB
Rust

use super::{ BuilderMap, MetaMapBuilder, Position };
use rltk::RandomNumberGenerator;
#[allow(dead_code)]
pub enum XStart {
LEFT,
CENTRE,
RIGHT,
}
#[allow(dead_code)]
pub enum YStart {
TOP,
CENTRE,
BOTTOM,
}
pub struct AreaStartingPosition {
x: XStart,
y: YStart,
}
impl MetaMapBuilder for AreaStartingPosition {
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
self.build(rng, build_data);
}
}
impl AreaStartingPosition {
#[allow(dead_code)]
pub fn new(x: XStart, y: YStart) -> Box<AreaStartingPosition> {
Box::new(AreaStartingPosition { x, y })
}
fn build(&mut self, _rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
let seed_x;
let seed_y;
match self.x {
XStart::LEFT => {
seed_x = 1;
}
XStart::CENTRE => {
seed_x = build_data.map.width / 2;
}
XStart::RIGHT => {
seed_x = build_data.map.width - 2;
}
}
match self.y {
YStart::TOP => {
seed_y = 1;
}
YStart::CENTRE => {
seed_y = build_data.map.height / 2;
}
YStart::BOTTOM => {
seed_y = build_data.map.height - 2;
}
}
let mut available_floors: Vec<(usize, f32)> = Vec::new();
for (idx, tiletype) in build_data.map.tiles.iter().enumerate() {
if crate::tile_walkable(*tiletype) {
available_floors.push((
idx,
rltk::DistanceAlg::PythagorasSquared.distance2d(
rltk::Point::new((idx as i32) % build_data.map.width, (idx as i32) / build_data.map.width),
rltk::Point::new(seed_x, seed_y)
),
));
}
}
if available_floors.is_empty() {
panic!("No valid floors to start on");
}
available_floors.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap());
let start_x = (available_floors[0].0 as i32) % build_data.map.width;
let start_y = (available_floors[0].0 as i32) / build_data.map.width;
build_data.starting_position = Some(Position { x: start_x, y: start_y });
}
}