//! The `dungon` crate contains the core functionality for //! interacting with a `Dungeon` and its components. pub mod bsp; pub mod enemy; pub mod entity; pub mod map; pub mod pos; pub use bsp::*; pub use entity::*; pub use map::*; pub use pos::*; use crate::enemy::{Enemy, EnemyType}; /// The `Dungeon` type represents the game state of the /// dungeon crawler. #[derive(Clone, Debug, PartialEq)] pub struct Dungeon { pub floor: Floor, pub player: Player, pub enemies: Vec, } impl Dungeon { /// Creates a new `Dungeon`. /// /// # Examples /// /// ```no_run /// use dungeon::Dungeon; /// /// let dungeon = Dungeon::new(); /// ``` #[must_use] pub fn new() -> Self { Self::from(Floor::generate()) } /// Creates a new `Dungeon` with a provided seed. /// /// # Examples /// /// ```no_run /// use dungeon::Dungeon; /// /// let seed = 234690523482u64; /// let dungeon = Dungeon::new_seeded(seed); /// ``` #[must_use] pub fn new_seeded(seed: u64) -> Self { Self::from(Floor::generate_seeded(seed)) } /// Returns the current position of the camera (viewer) #[must_use] pub fn camera(&self) -> FPos { self.player.entity.fpos } } impl Default for Dungeon { fn default() -> Self { Self::from(Floor::default()) } } impl From for Dungeon { fn from(floor: Floor) -> Self { let player = Player::new(floor.player_start()); // TODO: initalize rest of game state // TODO: How will we randomize enemy type/number per floor? // For now, just create one enemy a few tiles to the right of the player let enemies = vec![Enemy::new( EnemyType::Zombie, Pos::new(player.entity.pos.x() + 4, player.entity.pos.y()) .unwrap_or(const_pos!(1, 1)), )]; Self { floor, player, enemies, } } }