diff options
author | Guillaume Pasquet <dev@etenil.net> | 2019-11-21 19:23:03 +0000 |
---|---|---|
committer | Guillaume Pasquet <dev@etenil.net> | 2019-11-21 19:23:03 +0000 |
commit | b53947f191ad6ffc9b72890abb916a44f581c0c3 (patch) | |
tree | 951d424561ecf98d70c0468827b4b09f83b317f8 | |
parent | 75a049c911c7fe23a1dbf7c708af3476c2e050cb (diff) | |
parent | 6bc22fb1e6ced5ef313baa1f9905d427a377c3ba (diff) |
Merge branch 'master' of github.com:Etenil/roguerust
-rw-r--r-- | src/entities.rs | 27 | ||||
-rw-r--r-- | src/state.rs | 12 | ||||
-rw-r--r-- | src/tiling.rs | 87 | ||||
-rw-r--r-- | src/world.rs | 77 |
4 files changed, 122 insertions, 81 deletions
diff --git a/src/entities.rs b/src/entities.rs index 79f482b..b3cdf34 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -1,6 +1,6 @@ use std::cmp;
-use crate::tiling::TileType;
+use crate::tiling::{Tile, TileType};
use crate::world::{apply_movement, Movement, Point};
pub trait Entity {
@@ -9,7 +9,7 @@ pub trait Entity { /// Initial placement of the entity
fn place(&mut self, location: Point);
/// Get the tiletype for the entity
- fn tiletype(&self) -> &TileType;
+ fn tile(&self) -> &Tile;
/// Get the entity's current location
fn location(&self) -> &Point;
/// Get the entity's previous location (before it moved)
@@ -38,14 +38,15 @@ pub struct Character { dodge: i32,
luck: i32,
xp: i32,
- tile_type: TileType,
+ tile: Tile,
}
pub trait Enemy {
- fn new(class: String, health: i32, attack: i32, dodge: i32, luck: i32, location: Point)
+ fn new(class: String, health: i32, attack: i32, dodge: i32, luck: i32,
+ location: Point, tile_str: &'static str)
-> Self;
- fn set_tile_type(&mut self, tile_type: TileType);
+ fn set_tile(&mut self, tile: Tile);
}
pub trait Player {
@@ -71,8 +72,8 @@ impl Entity for Character { )
}
- fn tiletype(&self) -> &TileType {
- &self.tile_type
+ fn tile(&self) -> &Tile {
+ &self.tile
}
fn location(&self) -> &Point {
@@ -112,6 +113,7 @@ impl Enemy for Character { dodge: i32,
luck: i32,
location: Point,
+ tile_str: &'static str,
) -> Character {
Character {
name: class.clone(),
@@ -125,13 +127,13 @@ impl Enemy for Character { xp: 0,
location,
previous_location: location,
- tile_type: TileType::Character,
+ tile: Tile::from(TileType::Character(tile_str)),
dirty: false,
}
}
- fn set_tile_type(&mut self, tile_type: TileType) {
- self.tile_type = tile_type
+ fn set_tile(&mut self, tile: Tile) {
+ self.tile = tile
}
}
@@ -156,7 +158,10 @@ impl Player for Character { level: 0,
location: (0, 0),
previous_location: (0, 0),
- tile_type: TileType::Player,
+ tile: Tile::new(
+ TileType::Player,
+ true, // player is visible by default
+ ),
dirty: false,
}
}
diff --git a/src/state.rs b/src/state.rs index 6e76aee..9939226 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,7 +3,7 @@ use crossterm::{queue, Output}; use std::io::{stdout, Write}; use crate::entities::{Character, Entity, Player}; -use crate::tiling::{tile_to_str, TileGrid, TileType}; +use crate::tiling::{tile_to_str, Tile, TileGrid, TileType}; use crate::world::{apply_movement, Dungeon, Generatable, Level, Movement}; pub struct State { @@ -59,7 +59,7 @@ impl State { MoveTo(dirt.0 as u16, dirt.1 as u16), Output(tile_to_str(background)), MoveTo(entity.location().0 as u16, entity.location().1 as u16), - Output(tile_to_str(entity.tiletype())) + Output(tile_to_str(entity.tile())) ) .unwrap(); sout.flush().unwrap(); @@ -112,8 +112,8 @@ impl State { &self.dungeon.levels[self.level] } - fn can_step_on(tile: &TileType) -> bool { - match tile { + fn can_step_on(tile: &Tile) -> bool { + match tile.get_type() { TileType::Floor => true, TileType::StairsDown => true, TileType::StairsUp => true, @@ -146,7 +146,7 @@ impl State { } let loc = self.player.location(); - match grid.block_at(loc.0, loc.1) { + match grid.block_at(loc.0, loc.1).get_type() { TileType::StairsDown => { self.switch_level(self.level + 1); self.render_level(); @@ -167,7 +167,7 @@ impl State { } let loc = self.player.location(); - match grid.block_at(loc.0, loc.1) { + match grid.block_at(loc.0, loc.1).get_type() { TileType::StairsUp => { self.switch_level(self.level - 1); self.render_level(); diff --git a/src/tiling.rs b/src/tiling.rs index f1630d6..c79d6ef 100644 --- a/src/tiling.rs +++ b/src/tiling.rs @@ -1,5 +1,45 @@ +use std::convert::From; + +#[derive(Clone)] +pub enum TileType { + Empty, + Wall, + Floor, + StairsUp, + StairsDown, + Character(&'static str), + Player, +} + +#[derive(Clone)] +pub struct Tile { + tile_type: TileType, + visible: bool, +} + +impl Tile { + pub fn new(tile_type: TileType, visible: bool) -> Self { + Tile { tile_type, visible } + } + + pub fn get_type(&self) -> &TileType { + &self.tile_type + } +} + +impl From<TileType> for Tile { + fn from(tile_type: TileType) -> Self { + Tile { + tile_type, + visible: true, // <--- TODO: this set the default beaviour + // - true: all tiles of world and entities will be drawn + // - false: only draw tiles visible for the player + } + } +} + pub struct TileGrid { - grid: Vec<Vec<TileType>>, + grid: Vec<Vec<Tile>>, xsize: usize, ysize: usize, } @@ -15,7 +55,7 @@ impl TileGrid { for _ in 0..ysize { let mut subvec = Vec::with_capacity(xsize); for _ in 0..xsize { - subvec.push(TileType::Empty); + subvec.push(Tile::new(TileType::Empty, true)); } grid.grid.push(subvec); } @@ -23,27 +63,27 @@ impl TileGrid { grid } - pub fn set_tile(&mut self, x: usize, y: usize, tile: TileType) { + pub fn set_tile(&mut self, x: usize, y: usize, tile: Tile) { self.grid[y][x] = tile; } /// Sets a tile if nothing lies underneath it. - pub fn set_empty_tile(&mut self, x: usize, y: usize, tile: TileType) { + pub fn set_empty_tile(&mut self, x: usize, y: usize, tile: Tile) { self.set_tile( x, y, - match self.grid[y][x] { + match self.grid[y][x].tile_type { TileType::Empty => tile, _ => self.grid[y][x].clone(), }, ) } - pub fn raw_data(&self) -> &Vec<Vec<TileType>> { + pub fn raw_data(&self) -> &Vec<Vec<Tile>> { &self.grid } - pub fn block_at(&self, x: usize, y: usize) -> &TileType { + pub fn block_at(&self, x: usize, y: usize) -> &Tile { &self.grid[y + 1][x] } @@ -56,29 +96,22 @@ impl TileGrid { } } -pub fn tile_to_str(tile: &TileType) -> &str { - match tile { - TileType::Floor => ".", - TileType::Wall => "#", - TileType::Empty => " ", - TileType::StairsDown => ">", - TileType::StairsUp => "<", - TileType::Player => "@", - _ => "?", +pub fn tile_to_str(tile: &Tile) -> &str { + if tile.visible { + match tile.tile_type { + TileType::Floor => ".", + TileType::Wall => "#", + TileType::Empty => " ", + TileType::StairsDown => ">", + TileType::StairsUp => "<", + TileType::Player => "@", + TileType::Character(t) => t, + } + } else { + " " } } pub trait Tileable { fn tile(&self, grid: &mut TileGrid) -> Result<(), String>; } - -#[derive(Clone)] -pub enum TileType { - Empty, - Wall, - Floor, - StairsUp, - StairsDown, - Character, - Player, -} diff --git a/src/world.rs b/src/world.rs index 37eb8a3..507e6b8 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,5 +1,5 @@ use crate::entities::{Character, Enemy, Entity}; -use crate::tiling::{TileGrid, TileType, Tileable}; +use crate::tiling::{Tile, TileGrid, TileType, Tileable}; use rand::Rng; use std::cmp::{min, PartialEq}; use std::fmt; @@ -59,19 +59,19 @@ impl Tileable for Room { // Set the walls for x in self.start.0..=endx { - grid.set_empty_tile(x, self.start.1, TileType::Wall); - grid.set_empty_tile(x, endy, TileType::Wall); + grid.set_empty_tile(x, self.start.1, Tile::from(TileType::Wall)); + grid.set_empty_tile(x, endy, Tile::from(TileType::Wall)); } for y in self.start.1..endy { - grid.set_empty_tile(self.start.0, y, TileType::Wall); - grid.set_empty_tile(endx, y, TileType::Wall); + grid.set_empty_tile(self.start.0, y, Tile::from(TileType::Wall)); + grid.set_empty_tile(endx, y, Tile::from(TileType::Wall)); } // Fill the room for x in (self.start.0 + 1)..endx { for y in (self.start.1 + 1)..endy { - grid.set_tile(x, y, TileType::Floor); + grid.set_tile(x, y, Tile::from(TileType::Floor)); } } @@ -176,34 +176,34 @@ impl Corridor { 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, TileType::Wall); - grid.set_tile(x, y, TileType::Floor); - grid.set_empty_tile(x + 1, y, TileType::Wall); + grid.set_empty_tile(x - 1, y, Tile::from(TileType::Wall)); + grid.set_tile(x, y, Tile::from(TileType::Floor)); + grid.set_empty_tile(x + 1, y, Tile::from(TileType::Wall)); } // Wall ends - grid.set_empty_tile(x - 1, self.start.1, TileType::Wall); - grid.set_empty_tile(x, self.start.1, TileType::Wall); - grid.set_empty_tile(x + 1, self.start.1, TileType::Wall); - grid.set_empty_tile(x - 1, endy, TileType::Wall); - grid.set_empty_tile(x, endy, TileType::Wall); - grid.set_empty_tile(x + 1, endy, TileType::Wall); + grid.set_empty_tile(x - 1, self.start.1, Tile::from(TileType::Wall)); + grid.set_empty_tile(x, self.start.1, Tile::from(TileType::Wall)); + grid.set_empty_tile(x + 1, self.start.1, Tile::from(TileType::Wall)); + 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)); } 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, TileType::Wall); - grid.set_tile(x, y, TileType::Floor); - grid.set_empty_tile(x, y + 1, TileType::Wall); + grid.set_empty_tile(x, y - 1, Tile::from(TileType::Wall)); + grid.set_tile(x, y, Tile::from(TileType::Floor)); + grid.set_empty_tile(x, y + 1, Tile::from(TileType::Wall)); } // Wall ends - grid.set_empty_tile(self.start.0, y - 1, TileType::Wall); - grid.set_empty_tile(self.start.0, y, TileType::Wall); - grid.set_empty_tile(self.start.0, y + 1, TileType::Wall); - grid.set_empty_tile(endx, y - 1, TileType::Wall); - grid.set_empty_tile(endx, y, TileType::Wall); - grid.set_empty_tile(endx, y + 1, TileType::Wall); + grid.set_empty_tile(self.start.0, y - 1, Tile::from(TileType::Wall)); + grid.set_empty_tile(self.start.0, y, Tile::from(TileType::Wall)); + grid.set_empty_tile(self.start.0, y + 1, Tile::from(TileType::Wall)); + 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)); } } @@ -310,8 +310,8 @@ impl Level { corridor.tile(&mut grid)?; } - grid.set_tile(self.entrance.0, self.entrance.1, TileType::StairsUp); - grid.set_tile(self.exit.0, self.exit.1, TileType::StairsDown); + grid.set_tile(self.entrance.0, self.entrance.1, Tile::from(TileType::StairsUp)); + grid.set_tile(self.exit.0, self.exit.1, Tile::from(TileType::StairsDown)); Ok(grid) } @@ -426,17 +426,20 @@ impl Generatable for Level { let room = &self.rooms[rng.gen_range(0, self.rooms.len() - 1)]; // Create the enemy - self.entities.push(Box::<Character>::new(Enemy::new( - String::from("snake"), - 2 * self.depth as i32, - (2.0 * self.depth as f32 * 0.6).round() as i32, - (20.0 * self.depth as f32 * 0.2).max(80.0).round() as i32, - 0, - ( - room.start.0 + rng.gen_range(0, room.width), - room.start.1 + rng.gen_range(0, room.height), - ), - ))); + self.entities.push(Box::<Character>::new( + Enemy::new( + String::from("snake"), + 2 * self.depth as i32, + (2.0 * self.depth as f32 * 0.6).round() as i32, + (20.0 * self.depth as f32 * 0.2).max(80.0).round() as i32, + 0, + ( + room.start.0 + rng.gen_range(0, room.width), + room.start.1 + rng.gen_range(0, room.height), + ), + "s", + ) + )); } } } |