diff --git a/src/main.rs b/src/main.rs index 26746ee..e7415cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,6 +77,7 @@ pub enum RunState { }, SaveGame, NextLevel, + PreviousLevel, ShowRemoveItem, GameOver, MagicMapReveal { @@ -345,6 +346,11 @@ impl GameState for State { self.goto_next_level(); newrunstate = RunState::PreRun; } + RunState::PreviousLevel => { + self.goto_previous_level(); + self.mapgen_next_state = Some(RunState::PreRun); + newrunstate = RunState::MapGeneration; + } RunState::MagicMapReveal { row } => { let mut map = self.ecs.fetch_mut::(); for x in 0..map.width { @@ -429,6 +435,29 @@ impl State { gamelog.append("You descend to the next level."); } + fn goto_previous_level(&mut self) { + // Delete entities that aren't the palyer or their equipment + let to_delete = self.entities_to_remove_on_level_change(); + for target in to_delete { + self.ecs + .delete_entity(target) + .expect("failed to delete entity"); + } + + // Build a new map and place the player + #[allow(unused_assignments)] + let current_depth; + { + let worldmap_resource = self.ecs.fetch::(); + current_depth = worldmap_resource.depth; + } + self.generate_world_map(current_depth - 1); + + // Notify the player + let mut gamelog = self.ecs.fetch_mut::(); + gamelog.append("You ascend to the previous level."); + } + fn game_over_cleanup(&mut self) { // Delete everything let mut to_delete = Vec::new(); diff --git a/src/player.rs b/src/player.rs index 539ebfa..b3def79 100644 --- a/src/player.rs +++ b/src/player.rs @@ -119,6 +119,22 @@ pub fn try_next_level(ecs: &mut World) -> bool { } } +pub fn try_previous_level(ecs: &mut World) -> bool { + let player_pos = ecs.fetch::(); + let map = ecs.fetch::(); + let player_idx = map.xy_idx(player_pos.x, player_pos.y); + + if map.tiles[player_idx] == TileType::UpStairs { + true + } else { + let mut gamelog = ecs.fetch_mut::(); + gamelog + .entries + .push("There is no way up from here.".to_string()); + false + } +} + fn get_item(ecs: &mut World) { let player_pos = ecs.fetch::(); let player_entity = ecs.fetch::(); @@ -316,6 +332,11 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { return RunState::NextLevel; } } + VirtualKeyCode::Comma => { + if try_previous_level(&mut gs.ecs) { + return RunState::PreviousLevel; + } + } // Item management VirtualKeyCode::G => get_item(&mut gs.ecs),