use glam::Vec3;
use crate::palette::Palette;
use crate::recipe::{DungeonParams, DungeonTheme};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RoomKind {
Entrance,
Normal,
Boss,
Treasure,
}
impl RoomKind {
pub fn name(self) -> &'static str {
match self {
RoomKind::Entrance => "entrance",
RoomKind::Normal => "normal",
RoomKind::Boss => "boss",
RoomKind::Treasure => "treasure",
}
}
}
#[derive(Clone, Debug)]
pub struct Room {
pub id: usize,
pub kind: RoomKind,
pub min: Vec3,
pub max: Vec3,
}
impl Room {
pub fn center(&self) -> Vec3 {
(self.min + self.max) * 0.5
}
pub fn center_i(&self) -> Vec3 {
let c = self.center();
Vec3::new(c.x.round(), 0.0, c.z.round())
}
}
#[derive(Clone, Debug)]
pub struct Corridor {
pub a: usize,
pub b: usize,
pub path: Vec<Vec3>,
}
#[derive(Clone, Debug)]
pub struct Door {
pub room: usize,
pub corridor: usize,
pub pos: Vec3,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SpawnKind {
Player,
Enemy,
Loot,
Boss,
}
impl SpawnKind {
pub fn name(self) -> &'static str {
match self {
SpawnKind::Player => "player",
SpawnKind::Enemy => "enemy",
SpawnKind::Loot => "loot",
SpawnKind::Boss => "boss",
}
}
}
#[derive(Clone, Debug)]
pub struct SpawnPoint {
pub kind: SpawnKind,
pub pos: Vec3,
}
pub struct DungeonModel {
pub p: DungeonParams,
pub pal: Palette,
pub rooms: Vec<Room>,
pub corridors: Vec<Corridor>,
pub doors: Vec<Door>,
pub spawns: Vec<SpawnPoint>,
pub bounds: (Vec3, Vec3),
}
impl DungeonModel {
pub fn new(p: &DungeonParams, pal: &Palette) -> Result<Self, String> {
let mut p = p.clone();
p.rooms = p.rooms.map(|r| r.clamp(1, 60));
p.loops = p.loops.clamp(0.0, 1.0);
p.density = p.density.clamp(0.0, 1.0);
p.detail = p.detail.clamp(0.5, 2.0);
let pal = crate::palette::by_name(pal.name);
super::layout::build(p, pal)
}
pub fn ceiling(theme: DungeonTheme) -> f32 {
match theme {
DungeonTheme::Crypt => 4.0,
DungeonTheme::Cavern => 6.0,
DungeonTheme::Sewer => 4.0,
DungeonTheme::Mine => 4.0,
DungeonTheme::Temple => 6.0,
DungeonTheme::Fortress => 5.0,
}
}
}