aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Pasquet <dev@etenil.net>2019-11-20 14:29:21 +0000
committerGuillaume Pasquet <dev@etenil.net>2019-11-20 14:29:21 +0000
commit15ccde4be6585865d01d9a620778dbcf5d8d998d (patch)
tree62f87126d9f9295ef363984d349e2e6aaa5f5c50
parentbd87cf7569ace13eb2351fb5fc1a58f01f83f343 (diff)
Go up and down the stairs!
-rw-r--r--src/main.rs37
-rw-r--r--src/state.rs114
-rw-r--r--src/world.rs8
3 files changed, 93 insertions, 66 deletions
diff --git a/src/main.rs b/src/main.rs
index 82c08b6..5acbbef 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,33 +9,16 @@ mod tiling;
mod world;
use crossterm::cursor;
-use crossterm::input::{
- input,
- InputEvent,
- KeyEvent
-};
-use crossterm::screen::{
- EnterAlternateScreen,
- LeaveAlternateScreen,
- RawScreen
-};
-use crossterm::terminal;
use crossterm::execute;
+use crossterm::input::{input, InputEvent, KeyEvent};
+use crossterm::screen::{EnterAlternateScreen, LeaveAlternateScreen, RawScreen};
+use crossterm::terminal;
use entities::Player;
use ignore_result::Ignore;
use state::State;
use std::env;
-use std::io::{
- stdout,
- Write
-};
-use world::{
- Dungeon,
- DOWN,
- LEFT,
- RIGHT,
- UP
-};
+use std::io::{stdout, Write};
+use world::{Dungeon, DOWN, LEFT, RIGHT, UP};
fn player_name() -> String {
match env::var_os("USER") {
@@ -87,6 +70,16 @@ fn main() {
InputEvent::Keyboard(KeyEvent::Up) => state.move_player(UP).ignore(),
InputEvent::Keyboard(KeyEvent::Left) => state.move_player(LEFT).ignore(),
InputEvent::Keyboard(KeyEvent::Right) => state.move_player(RIGHT).ignore(),
+
+ // Stairs
+ InputEvent::Keyboard(KeyEvent::Char('>')) => match state.down_stairs() {
+ Ok(()) => (),
+ Err(info) => state.notify(info),
+ },
+ InputEvent::Keyboard(KeyEvent::Char('<')) => match state.up_stairs() {
+ Ok(()) => (),
+ Err(info) => state.notify(info),
+ },
_ => (),
}
}
diff --git a/src/state.rs b/src/state.rs
index 5f86d3a..6e76aee 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,30 +1,10 @@
use crossterm::cursor::MoveTo;
-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::world::{
- apply_movement,
- Dungeon,
- Generatable,
- Level,
- Movement
-};
+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::world::{apply_movement, Dungeon, Generatable, Level, Movement};
pub struct State {
pub player: Character,
@@ -105,25 +85,29 @@ impl State {
pub fn render_ui(&self) {
let mut sout = stdout();
- queue!(
- sout,
- self.ui_state_position(),
- Output(self.player.stats())
- )
- .unwrap();
+ queue!(sout, self.ui_state_position(), Output(self.player.stats())).unwrap();
sout.flush().unwrap();
}
- pub fn ui_help(&self) {
+ pub fn notify(&self, message: String) {
let mut sout = stdout();
queue!(
sout,
self.ui_notification_position(),
- Output("quit: q, movement{up(k), down(j), left(h), right(l)}")
- ).unwrap();
+ Output(" ".repeat(self.dungeon.xsize())),
+ self.ui_notification_position(),
+ Output(message)
+ )
+ .unwrap();
sout.flush().unwrap();
}
+ pub fn ui_help(&self) {
+ self.notify(String::from(
+ "quit: q, movement{up(k), down(j), left(h), right(l)}",
+ ))
+ }
+
pub fn current_level(&self) -> &Level {
&self.dungeon.levels[self.level]
}
@@ -138,16 +122,58 @@ impl State {
}
pub fn move_player(&mut self, dir: Movement) -> Result<(), String> {
- match &self.grid {
- None => Err(String::from("No level loaded!")),
- Some(grid) => {
- let loc = apply_movement(*self.player.location(), dir)?;
- // Is the new location colliding with anything?
- if !State::can_step_on(grid.block_at(loc.0, loc.1)) {
- return Err(String::from("Can't move entity!"));
- }
- self.player.move_by(dir)
+ let grid = match &self.grid {
+ Some(g) => g,
+ None => return Err(String::from("No level loaded!")),
+ };
+
+ let loc = apply_movement(*self.player.location(), dir)?;
+ // Is the new location colliding with anything?
+ if !State::can_step_on(grid.block_at(loc.0, loc.1)) {
+ return Err(String::from("Can't move entity!"));
+ }
+ self.player.move_by(dir)
+ }
+
+ pub fn down_stairs(&mut self) -> Result<(), String> {
+ let grid = match &self.grid {
+ Some(g) => g,
+ None => return Err(String::from("No level loaded!")),
+ };
+
+ if self.level == self.dungeon.depth() - 1 {
+ return Err(String::from("Already at the bottom level"));
+ }
+
+ let loc = self.player.location();
+ match grid.block_at(loc.0, loc.1) {
+ TileType::StairsDown => {
+ self.switch_level(self.level + 1);
+ self.render_level();
+ Ok(())
+ }
+ _ => Err(String::from("Not on stairs!")),
+ }
+ }
+
+ pub fn up_stairs(&mut self) -> Result<(), String> {
+ let grid = match &self.grid {
+ Some(g) => g,
+ None => return Err(String::from("No level loaded!")),
+ };
+
+ if self.level == 0 {
+ return Err(String::from("Already at the top level"));
+ }
+
+ let loc = self.player.location();
+ match grid.block_at(loc.0, loc.1) {
+ TileType::StairsUp => {
+ self.switch_level(self.level - 1);
+ self.render_level();
+ Ok(())
}
+ _ => Err(String::from("Not on stairs!")),
}
}
}
diff --git a/src/world.rs b/src/world.rs
index 20b510a..a315111 100644
--- a/src/world.rs
+++ b/src/world.rs
@@ -254,9 +254,17 @@ impl Dungeon {
}
}
+ pub fn xsize(&self) -> usize {
+ self.xsize
+ }
+
pub fn ysize(&self) -> usize {
self.ysize
}
+
+ pub fn depth(&self) -> usize {
+ self.depth
+ }
}
impl Generatable for Dungeon {