diff options
author | Guillaume Pasquet <dev@etenil.net> | 2019-11-20 14:29:21 +0000 |
---|---|---|
committer | Guillaume Pasquet <dev@etenil.net> | 2019-11-20 14:29:21 +0000 |
commit | 15ccde4be6585865d01d9a620778dbcf5d8d998d (patch) | |
tree | 62f87126d9f9295ef363984d349e2e6aaa5f5c50 | |
parent | bd87cf7569ace13eb2351fb5fc1a58f01f83f343 (diff) |
Go up and down the stairs!
-rw-r--r-- | src/main.rs | 37 | ||||
-rw-r--r-- | src/state.rs | 114 | ||||
-rw-r--r-- | src/world.rs | 8 |
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 { |