diff --git a/src/level.rs b/src/level.rs index 5c25999..1d3e1e9 100644 --- a/src/level.rs +++ b/src/level.rs @@ -1,22 +1,35 @@ use std::fmt::Display; use pancurses::Window; +use rand::{thread_rng, Rng}; +use specs::prelude::*; -use crate::rooms; +use crate::{ + components::{CharRender, Position}, + rooms, +}; /// The size of a dungeon level, in tiles. pub const LEVEL_SIZE: (usize, usize) = (80, 24); /// A single level of the dungeon. +#[derive(Clone)] pub struct DungeonLevel { /// The tiles at every position in the level. tiles: [[DungeonTile; LEVEL_SIZE.0]; LEVEL_SIZE.1], + /// The locations of the level's exits. + exits: LevelExits, +} + +/// The entrances and exits from a level. +#[derive(Clone)] +pub struct LevelExits { /// The location of each of the up-staircases. - upstairs: Vec<(i32, i32)>, + pub upstairs: Vec<(i32, i32)>, /// The location of each of the down-staircases. - downstairs: Vec<(i32, i32)>, + pub downstairs: Vec<(i32, i32)>, } /// The smallest measurable independent location in the dungeon, @@ -49,26 +62,45 @@ impl DungeonTile { } impl DungeonLevel { - /// Creates a new level in a branch that has the given - /// configuration. - pub fn new() -> Self { - rooms::generate_level(100, &mut rand::thread_rng(), 1, 1) - } - /// Creates a new level with the given set of tiles, upstairs, and /// downstairs. - pub fn from_raw_parts( + pub fn new( tiles: [[DungeonTile; LEVEL_SIZE.0]; LEVEL_SIZE.1], upstairs: Vec<(i32, i32)>, downstairs: Vec<(i32, i32)>, ) -> Self { Self { tiles, - upstairs, - downstairs, + exits: LevelExits { + upstairs, + downstairs, + }, } } + /// Creates a new level and registers it with the given world. + pub fn generate_level(world: &mut World) -> LevelExits { + let level = rooms::generate_level(100, &mut thread_rng(), 1, 1); + world.insert(level.clone()); // inefficient but whatever + + // Spawn some zombies in the world. + for _ in 0..20 { + let (x, y) = ( + thread_rng().gen_range(0..LEVEL_SIZE.0 as _), + thread_rng().gen_range(0..LEVEL_SIZE.1 as _), + ); + if level.tile(x, y).is_navigable() { + world + .create_entity() + .with(Position { x, y }) + .with(CharRender { glyph: 'Z' }) + .build(); + } + } + + level.exits + } + /// Draws a level on the display window. pub fn draw(&self, win: &Window) { for y in 0..LEVEL_SIZE.1 { @@ -130,16 +162,6 @@ impl DungeonLevel { pub fn tile(&self, x: i32, y: i32) -> &DungeonTile { &self.tiles[y as usize][x as usize] } - - /// Gets the list of up-stairs. - pub fn upstairs(&self) -> &[(i32, i32)] { - &self.upstairs - } - - /// Gets the list of down-stairs. - pub fn downstairs(&self) -> &[(i32, i32)] { - &self.downstairs - } } impl Display for DungeonLevel { diff --git a/src/main.rs b/src/main.rs index bc3eeb6..7560ab6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,8 +20,8 @@ fn main() { register_all(&mut world); - let level = DungeonLevel::new(); - let spawn_pos = level.upstairs()[0]; + let level = DungeonLevel::generate_level(&mut world); + let spawn_pos = level.upstairs[0]; world.insert(level); diff --git a/src/rooms.rs b/src/rooms.rs index 5da3da2..f2295bf 100644 --- a/src/rooms.rs +++ b/src/rooms.rs @@ -93,7 +93,7 @@ pub fn generate_level( *slot = value; } - DungeonLevel::from_raw_parts(data, upstairs, downstairs) + DungeonLevel::new(data, upstairs, downstairs) } /// The bounding box of a room.