From be6d4f86a5902b15e5464f6c596a4989017dea0b Mon Sep 17 00:00:00 2001 From: Guillaume Pasquet Date: Fri, 21 May 2021 13:00:45 +0100 Subject: Add doors. Remove CRLFs --- src/entities.rs | 447 ++++++++++++++++++++++++++++---------------------------- src/tiling.rs | 60 +++----- src/world.rs | 14 ++ 3 files changed, 259 insertions(+), 262 deletions(-) diff --git a/src/entities.rs b/src/entities.rs index 5908092..1be3594 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -1,223 +1,224 @@ -use std::cmp; - -use crate::tiling::{Tile, TileType}; -use crate::world::{apply_movement, Movement, Point}; - -pub trait Entity { - /// Get information about the entity - fn info(&self) -> String; - /// Initial placement of the entity - fn place(&mut self, location: Point); - /// Get the tiletype for the entity - fn tile(&self) -> &Tile; - /// Get the entity's current location - fn location(&self) -> &Point; - /// Get the entity's previous location (before it moved) - fn previous_location(&self) -> &Point; - /// Move the entity to another point - fn move_to(&mut self, location: Point); - /// Move the entity with a movement differential - fn move_by(&mut self, movement: Movement) -> Result<(), String>; - /// Know if the entity needs to be re-rendered - fn is_dirty(&self) -> bool; - /// Declare the entity clean - fn clean(&mut self); - fn visibility(&mut self, visible: bool); - fn is_visible(&self) -> bool; -} - -#[derive(Clone)] -pub struct Character { - pub name: String, - pub class: String, - pub health: i32, - pub level: i32, - location: Point, - previous_location: Point, - dirty: bool, - max_health: i32, - attack: i32, - dodge: i32, - luck: i32, - xp: i32, - tile: Tile, -} - -pub trait Enemy { - fn new( - class: String, - health: i32, - attack: i32, - dodge: i32, - luck: i32, - location: Point, - tile_str: &'static str, - ) -> Self; - - fn set_tile(&mut self, tile: Tile); -} - -pub trait Player { - fn new(name: String, class: String, health: i32, attack: i32, dodge: i32, luck: i32) -> Self; - fn damage(&mut self, damage_amount: i32); - fn heal(&mut self, heal_amount: i32); - fn attack(&self) -> i32; - fn dodge(&self) -> i32; - fn stats(&self) -> String; -} - -impl Entity for Character { - fn place(&mut self, location: Point) { - self.location = location; - self.previous_location = location; - self.dirty = true; - } - - fn info(&self) -> String { - format!( - "{} \thp: {} attack: {} dodge: {} luck: {}", - self.class, self.health, self.attack, self.dodge, self.luck - ) - } - - fn tile(&self) -> &Tile { - &self.tile - } - - fn location(&self) -> &Point { - &self.location - } - - fn previous_location(&self) -> &Point { - &self.previous_location - } - - fn move_to(&mut self, location: Point) { - self.previous_location = self.location; - self.location = location; - self.dirty = true; - } - - fn move_by(&mut self, movement: Movement) -> Result<(), String> { - self.previous_location = self.location; - self.location = apply_movement(self.location, movement)?; - Ok(()) - } - - fn is_dirty(&self) -> bool { - self.dirty - } - - fn clean(&mut self) { - self.dirty = false; - } - - fn visibility(&mut self, visible: bool) { - if visible != self.is_visible() { - self.dirty = true; - } - self.tile.visibility(visible) - } - - fn is_visible(&self) -> bool { - self.tile.is_visible() - } -} - -impl Enemy for Character { - fn new( - class: String, - health: i32, - attack: i32, - dodge: i32, - luck: i32, - location: Point, - tile_str: &'static str, - ) -> Character { - Character { - name: class.clone(), - class: class.clone(), - max_health: health, - health, - attack, - dodge, - luck, - level: 0, - xp: 0, - location, - previous_location: location, - tile: Tile::from(TileType::Character(tile_str)), - dirty: false, - } - } - - fn set_tile(&mut self, tile: Tile) { - self.tile = tile - } -} - -impl Player for Character { - fn new( - name: String, - class: String, - health: i32, - attack: i32, - dodge: i32, - luck: i32, - ) -> Character { - Character { - name, - class, - max_health: health, - health, - attack, - dodge, - luck, - xp: 0, - level: 0, - location: (0, 0), - previous_location: (0, 0), - tile: Tile::new( - TileType::Player, - true, // player is visible by default - false, - true - ), - dirty: false, - } - } - - fn damage(&mut self, damage_amount: i32) { - self.health = cmp::max(0, self.health - damage_amount); - self.xp += 2; - } - - fn heal(&mut self, heal_amount: i32) { - if (self.health) <= self.max_health { - self.health = cmp::min(self.health + heal_amount, self.max_health); - self.xp += 1; - } - } - - fn attack(&self) -> i32 { - self.xp + self.attack + self.luck / 2 - } - - fn dodge(&self) -> i32 { - self.xp + self.dodge + self.luck / 2 - } - - fn stats(&self) -> String { - format!( - "{}({}) - hp: {}/{} attack: {} dodge: {} luck: {} experience: {}", - self.name, - self.class, - self.health, - self.max_health, - self.attack, - self.dodge, - self.luck, - self.xp - ) - } -} +use std::cmp; + +use crate::tiling::{Tile, TileType}; +use crate::world::{apply_movement, Movement, Point}; + +pub trait Entity { + /// Get information about the entity + fn info(&self) -> String; + /// Initial placement of the entity + fn place(&mut self, location: Point); + /// Get the tiletype for the entity + fn tile(&self) -> &Tile; + /// Get the entity's current location + fn location(&self) -> &Point; + /// Get the entity's previous location (before it moved) + fn previous_location(&self) -> &Point; + /// Move the entity to another point + fn move_to(&mut self, location: Point); + /// Move the entity with a movement differential + fn move_by(&mut self, movement: Movement) -> Result<(), String>; + /// Know if the entity needs to be re-rendered + fn is_dirty(&self) -> bool; + /// Declare the entity clean + fn clean(&mut self); + fn visibility(&mut self, visible: bool); + fn is_visible(&self) -> bool; +} + +#[derive(Clone)] +pub struct Character { + pub name: String, + pub class: String, + pub health: i32, + pub level: i32, + location: Point, + previous_location: Point, + dirty: bool, + max_health: i32, + attack: i32, + dodge: i32, + luck: i32, + xp: i32, + tile: Tile, +} + +pub trait Enemy { + fn new( + class: String, + health: i32, + attack: i32, + dodge: i32, + luck: i32, + location: Point, + tile_str: &'static str, + ) -> Self; + + fn set_tile(&mut self, tile: Tile); +} + +pub trait Player { + fn new(name: String, class: String, health: i32, attack: i32, dodge: i32, luck: i32) -> Self; + fn damage(&mut self, damage_amount: i32); + fn heal(&mut self, heal_amount: i32); + fn attack(&self) -> i32; + fn dodge(&self) -> i32; + fn stats(&self) -> String; +} + +impl Entity for Character { + fn place(&mut self, location: Point) { + self.location = location; + self.previous_location = location; + self.dirty = true; + } + + fn info(&self) -> String { + format!( + "{} \thp: {} attack: {} dodge: {} luck: {}", + self.class, self.health, self.attack, self.dodge, self.luck + ) + } + + fn tile(&self) -> &Tile { + &self.tile + } + + fn location(&self) -> &Point { + &self.location + } + + fn previous_location(&self) -> &Point { + &self.previous_location + } + + fn move_to(&mut self, location: Point) { + self.previous_location = self.location; + self.location = location; + self.dirty = true; + } + + fn move_by(&mut self, movement: Movement) -> Result<(), String> { + self.previous_location = self.location; + self.location = apply_movement(self.location, movement)?; + Ok(()) + } + + fn is_dirty(&self) -> bool { + self.dirty + } + + fn clean(&mut self) { + self.dirty = false; + } + + fn visibility(&mut self, visible: bool) { + if visible != self.is_visible() { + self.dirty = true; + } + self.tile.visibility(visible) + } + + fn is_visible(&self) -> bool { + self.tile.is_visible() + } +} + +impl Enemy for Character { + fn new( + class: String, + health: i32, + attack: i32, + dodge: i32, + luck: i32, + location: Point, + tile_str: &'static str, + ) -> Character { + Character { + name: class.clone(), + class: class.clone(), + max_health: health, + health, + attack, + dodge, + luck, + level: 0, + xp: 0, + location, + previous_location: location, + tile: Tile::from(TileType::Character(tile_str)), + dirty: false, + } + } + + fn set_tile(&mut self, tile: Tile) { + self.tile = tile + } +} + +impl Player for Character { + fn new( + name: String, + class: String, + health: i32, + attack: i32, + dodge: i32, + luck: i32, + ) -> Character { + Character { + name, + class, + max_health: health, + health, + attack, + dodge, + luck, + xp: 0, + level: 0, + location: (0, 0), + previous_location: (0, 0), + tile: Tile::new( + TileType::Player, + true, // player is visible by default + false, + true, + false + ), + dirty: false, + } + } + + fn damage(&mut self, damage_amount: i32) { + self.health = cmp::max(0, self.health - damage_amount); + self.xp += 2; + } + + fn heal(&mut self, heal_amount: i32) { + if (self.health) <= self.max_health { + self.health = cmp::min(self.health + heal_amount, self.max_health); + self.xp += 1; + } + } + + fn attack(&self) -> i32 { + self.xp + self.attack + self.luck / 2 + } + + fn dodge(&self) -> i32 { + self.xp + self.dodge + self.luck / 2 + } + + fn stats(&self) -> String { + format!( + "{}({}) - hp: {}/{} attack: {} dodge: {} luck: {} experience: {}", + self.name, + self.class, + self.health, + self.max_health, + self.attack, + self.dodge, + self.luck, + self.xp + ) + } +} diff --git a/src/tiling.rs b/src/tiling.rs index 06aa037..e21c02a 100644 --- a/src/tiling.rs +++ b/src/tiling.rs @@ -1,4 +1,3 @@ -use log::debug; use std::convert::From; #[derive(Copy, Clone, Debug)] @@ -10,6 +9,7 @@ pub enum TileType { StairsDown, Character(&'static str), Player, + Door, } #[derive(Clone, Debug)] @@ -18,15 +18,17 @@ pub struct Tile { visible: bool, opaque: bool, lit: bool, + open: bool, } impl Tile { - pub fn new(tile_type: TileType, visible: bool, opaque: bool, lit: bool) -> Self { + pub fn new(tile_type: TileType, visible: bool, opaque: bool, open: bool, lit: bool) -> Self { Tile { tile_type, visible, opaque, lit, + open, } } @@ -57,6 +59,18 @@ impl Tile { pub fn opacity(&mut self, opaque: bool) { self.opaque = opaque } + + pub fn is_open(&self) -> bool { + self.open + } + + pub fn open(&mut self) { + self.open = true; + } + + pub fn clos(&mut self) { + self.open = false; + } } impl From for Tile { @@ -72,6 +86,7 @@ impl From for Tile { _ => false, }, lit: false, + open: false, } } } @@ -183,6 +198,10 @@ pub fn tile_to_str(tile: &Tile) -> &str { TileType::StairsUp => "<", TileType::Player => "@", TileType::Character(t) => t, + TileType::Door => match tile.is_open() { + true => "'", + false => "+", + }, } } else { " " @@ -193,43 +212,6 @@ pub trait Tileable { fn tile(&self, grid: &mut TileGrid) -> Result<(), String>; } -// fn circle(center: &(usize, usize), radius: usize) -> Vec<(usize, usize)> { -// let mut x: i32 = radius as i32; -// let mut y: i32 = 0; -// let mut err: i32 = 0; - -// let signs: [i32; 2] = [-1, 1]; -// let mut points: Vec<(usize, usize)> = vec![]; - -// while x >= y { -// for xsign in signs.iter() { -// for ysign in signs.iter() { -// points.push(( -// (center.0 as i32 + xsign * x).max(0) as usize, -// (center.1 as i32 + ysign * y).max(0) as usize, -// )); -// points.push(( -// (center.0 as i32 + xsign * y).max(0) as usize, -// (center.1 as i32 + ysign * x).max(0) as usize, -// )); -// } -// } - -// if err <= 0 { -// y += 1; -// err += 2 * y + 1; -// } - -// if err > 0 { -// x -= 1; -// err -= 2 * x + 1; -// } -// } -// points.sort(); -// points.dedup(); -// points -// } - #[cfg(test)] mod tests { use super::*; diff --git a/src/world.rs b/src/world.rs index c577680..6d0c097 100644 --- a/src/world.rs +++ b/src/world.rs @@ -175,6 +175,7 @@ impl Corridor { fn tile_vertical(&self, grid: &mut TileGrid) { let x = self.start.0; let endy = self.start.1 + self.length; + for y in self.start.1..endy { grid.set_empty_tile(x - 1, y, Tile::from(TileType::Wall)); grid.set_tile(x, y, Tile::from(TileType::Floor)); @@ -187,11 +188,18 @@ impl Corridor { grid.set_empty_tile(x - 1, endy, Tile::from(TileType::Wall)); grid.set_empty_tile(x, endy, Tile::from(TileType::Wall)); grid.set_empty_tile(x + 1, endy, Tile::from(TileType::Wall)); + + // Have a door at the start? + let mut rng = rand::thread_rng(); + if rng.gen_bool(0.5) { + grid.set_tile(self.start.0, self.start.1, Tile::from(TileType::Door)); + } } fn tile_horizontal(&self, grid: &mut TileGrid) { let y = self.start.1; let endx = self.start.0 + self.length; + for x in self.start.0..endx { grid.set_empty_tile(x, y - 1, Tile::from(TileType::Wall)); grid.set_tile(x, y, Tile::from(TileType::Floor)); @@ -204,6 +212,12 @@ impl Corridor { grid.set_empty_tile(endx, y - 1, Tile::from(TileType::Wall)); grid.set_empty_tile(endx, y, Tile::from(TileType::Wall)); grid.set_empty_tile(endx, y + 1, Tile::from(TileType::Wall)); + + // Have a door at the start? + let mut rng = rand::thread_rng(); + if rng.gen_bool(0.5) { + grid.set_tile(self.start.0, self.start.1, Tile::from(TileType::Door)); + } } } -- cgit v1.2.3