aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <guillaume@bitimplosion.com>2021-05-21 13:00:45 +0100
committerGuillaume Pasquet <guillaume@bitimplosion.com>2021-05-21 13:00:45 +0100
commitbe6d4f86a5902b15e5464f6c596a4989017dea0b (patch)
tree83b0dadcf101994a26c0000beb35302f249b5e62
parent221ab81a5259acf4d4a0d311a6315979788dc1bf (diff)
Add doors. Remove CRLFsHEADmaster
-rw-r--r--src/entities.rs447
-rw-r--r--src/tiling.rs60
-rw-r--r--src/world.rs14
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<TileType> for Tile {
@@ -72,6 +86,7 @@ impl From<TileType> 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));
+ }
}
}