aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2019-11-21 19:23:03 +0000
committerGuillaume Pasquet <dev@etenil.net>2019-11-21 19:23:03 +0000
commitb53947f191ad6ffc9b72890abb916a44f581c0c3 (patch)
tree951d424561ecf98d70c0468827b4b09f83b317f8
parent75a049c911c7fe23a1dbf7c708af3476c2e050cb (diff)
parent6bc22fb1e6ced5ef313baa1f9905d427a377c3ba (diff)
Merge branch 'master' of github.com:Etenil/roguerust
-rw-r--r--src/entities.rs27
-rw-r--r--src/state.rs12
-rw-r--r--src/tiling.rs87
-rw-r--r--src/world.rs77
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",
+ )
+ ));
}
}
}