diff --git a/src/main.rs b/src/main.rs index 96cd1b1..36924af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,6 +62,7 @@ pub enum RunState { SaveGame, GameOver, NextLevel, + PreviousLevel, HelpScreen, MagicMapReveal { row: i32, cursed: bool }, MapGeneration, @@ -76,12 +77,12 @@ pub struct State { } impl State { - fn generate_world_map(&mut self, new_id: i32) { + fn generate_world_map(&mut self, new_id: i32, offset: i32) { // Visualisation stuff self.mapgen_index = 0; self.mapgen_timer = 0.0; self.mapgen_history.clear(); - let map_building_info = map::level_transition(&mut self.ecs, new_id); + let map_building_info = map::level_transition(&mut self.ecs, new_id, offset); if let Some(history) = map_building_info { self.mapgen_history = history; } @@ -178,7 +179,7 @@ impl State { return to_delete; } - fn goto_next_level(&mut self) { + fn goto_level(&mut self, offset: i32) { // Delete entities that aren't player/player's equipment let to_delete = self.entities_to_remove_on_level_change(); for target in to_delete { @@ -192,21 +193,9 @@ impl State { current_id = worldmap_resource.id; } gamelog::record_event("descended", 1); - self.generate_world_map(current_id + 1); - - // Notify player, restore health up to a point. - let player_entity = self.ecs.fetch::(); - gamelog::Logger::new() - .append("Taking a short rest, you manage to") - .colour((0, 255, 0)) - .append_n("recover some of your strength") - .period() - .log(); - let mut pools = self.ecs.write_storage::(); - let stats = pools.get_mut(*player_entity); - if let Some(stats) = stats { - stats.hit_points.current = i32::max(stats.hit_points.current, stats.hit_points.max / 2); - } + self.generate_world_map(current_id + offset, offset); + let mapname = self.ecs.fetch::().name.clone(); + gamelog::Logger::new().append("You head to").npc_name_n(mapname).period().log(); } fn game_over_cleanup(&mut self) { @@ -227,7 +216,7 @@ impl State { } // Replace map list self.ecs.insert(map::dungeon::MasterDungeonMap::new()); - self.generate_world_map(1); + self.generate_world_map(1, 0); gamelog::setup_log(); gamelog::record_event("player_level", 1); @@ -408,7 +397,12 @@ impl GameState for State { } } RunState::NextLevel => { - self.goto_next_level(); + self.goto_level(1); + self.mapgen_next_state = Some(RunState::PreRun); + new_runstate = RunState::MapGeneration; + } + RunState::PreviousLevel => { + self.goto_level(-1); self.mapgen_next_state = Some(RunState::PreRun); new_runstate = RunState::MapGeneration; } @@ -589,7 +583,7 @@ fn main() -> rltk::BError { gamelog::setup_log(); gamelog::record_event("player_level", 1); - gs.generate_world_map(1); + gs.generate_world_map(1, 0); rltk::main_loop(context, gs) } diff --git a/src/map/dungeon.rs b/src/map/dungeon.rs index e46e1a8..fd3e6d5 100644 --- a/src/map/dungeon.rs +++ b/src/map/dungeon.rs @@ -31,12 +31,12 @@ impl MasterDungeonMap { } } -pub fn level_transition(ecs: &mut World, new_id: i32) -> Option> { +pub fn level_transition(ecs: &mut World, new_id: i32, offset: i32) -> Option> { // Obtain master let dungeon_master = ecs.read_resource::(); if dungeon_master.get_map(new_id).is_some() { std::mem::drop(dungeon_master); - transition_to_existing_map(ecs, new_id); + transition_to_existing_map(ecs, new_id, offset); return None; } else { std::mem::drop(dungeon_master); @@ -44,7 +44,7 @@ pub fn level_transition(ecs: &mut World, new_id: i32) -> Option> { } } -fn transition_to_existing_map(ecs: &mut World, new_id: i32) { +fn transition_to_existing_map(ecs: &mut World, new_id: i32, offset: i32) { let dungeon_master = ecs.read_resource::(); // Unwrapping here panics if new_id isn't present. But this should // never be called without new_id being present by level_transition. @@ -53,8 +53,9 @@ fn transition_to_existing_map(ecs: &mut World, new_id: i32) { let player_entity = ecs.fetch::(); // Find down stairs, place player let w = map.width; + let stair_type = if offset < 0 { TileType::DownStair } else { TileType::UpStair }; for (idx, tt) in map.tiles.iter().enumerate() { - if *tt == TileType::DownStair { + if *tt == stair_type { let mut player_position = ecs.write_resource::(); *player_position = Point::new(idx as i32 % w, idx as i32 / w); let mut position_components = ecs.write_storage::(); diff --git a/src/map_builders/forest.rs b/src/map_builders/forest.rs index caa80e4..e83bfe7 100644 --- a/src/map_builders/forest.rs +++ b/src/map_builders/forest.rs @@ -12,7 +12,7 @@ pub fn forest_builder( difficulty: i32, initial_player_level: i32, ) -> BuilderChain { - let mut chain = BuilderChain::new(new_id, width, height, difficulty, "Into the Woods", initial_player_level); + let mut chain = BuilderChain::new(new_id, width, height, difficulty, "the woods", initial_player_level); chain.start_with(CellularAutomataBuilder::new()); chain.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE)); chain.with(CullUnreachable::new()); diff --git a/src/map_builders/mod.rs b/src/map_builders/mod.rs index be118ba..fba91f0 100644 --- a/src/map_builders/mod.rs +++ b/src/map_builders/mod.rs @@ -308,7 +308,7 @@ pub fn random_builder( initial_player_level: i32, ) -> BuilderChain { rltk::console::log(format!("DEBUGINFO: Building random (ID:{}, DIFF:{})", new_id, difficulty)); - let mut builder = BuilderChain::new(new_id, width, height, difficulty, "", initial_player_level); + let mut builder = BuilderChain::new(new_id, width, height, difficulty, "the dungeon", initial_player_level); let type_roll = rng.roll_dice(1, 2); let mut want_doors = true; match type_roll { diff --git a/src/map_builders/town.rs b/src/map_builders/town.rs index d6af07c..c5ab5cb 100644 --- a/src/map_builders/town.rs +++ b/src/map_builders/town.rs @@ -10,7 +10,7 @@ pub fn town_builder( initial_player_level: i32, ) -> BuilderChain { rltk::console::log(format!("DEBUGINFO: Building town (ID:{}, DIFF:{})", new_id, difficulty)); - let mut chain = BuilderChain::new(new_id, width, height, difficulty, "", initial_player_level); + let mut chain = BuilderChain::new(new_id, width, height, difficulty, "the town", initial_player_level); chain.start_with(TownBuilder::new()); return chain; diff --git a/src/player.rs b/src/player.rs index b46e4fd..25fc53e 100644 --- a/src/player.rs +++ b/src/player.rs @@ -457,6 +457,14 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { result = skip_turn(&mut gs.ecs); // (Wait a turn) } } + VirtualKeyCode::Comma => { + if ctx.shift { + if !try_previous_level(&mut gs.ecs) { + return RunState::AwaitingInput; + } + return RunState::PreviousLevel; // < to ascend + } + } VirtualKeyCode::Slash => { if ctx.shift { return RunState::HelpScreen; @@ -496,7 +504,19 @@ pub fn try_next_level(ecs: &mut World) -> bool { if map.tiles[player_idx] == TileType::DownStair { return true; } else { - gamelog::Logger::new().append("You don't see a way down.").log(); + gamelog::Logger::new().append("You don't see a way down from here.").log(); + return false; + } +} + +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::UpStair { + return true; + } else { + gamelog::Logger::new().append("You don't see a way up from here.").log(); return false; } }