diff --git a/src/ai/energy_system.rs b/src/ai/energy_system.rs index f01c612..83fc31d 100644 --- a/src/ai/energy_system.rs +++ b/src/ai/energy_system.rs @@ -1,5 +1,5 @@ use crate::data::entity::*; -use crate::{ Burden, BurdenLevel, Clock, Energy, Name, Position, RunState, TakingTurn }; +use crate::{ Burden, BurdenLevel, Clock, Energy, Name, Position, RunState, Map, TakingTurn }; use rltk::prelude::*; use specs::prelude::*; use crate::config::CONFIG; @@ -12,6 +12,7 @@ const TURN_COST: i32 = NORMAL_SPEED * TURN_COST_MULTIPLIER; impl<'a> System<'a> for EnergySystem { #[allow(clippy::type_complexity)] type SystemData = ( + ReadExpect<'a, Map>, ReadStorage<'a, Clock>, WriteStorage<'a, Energy>, ReadStorage<'a, Burden>, @@ -27,6 +28,7 @@ impl<'a> System<'a> for EnergySystem { fn run(&mut self, data: Self::SystemData) { let ( + map, clock, mut energies, burdens, @@ -62,15 +64,16 @@ impl<'a> System<'a> for EnergySystem { for (entity, energy, pos) in (&entities, &mut energies, &positions).join() { let burden_modifier = if let Some(burden) = burdens.get(entity) { match burden.level { - BurdenLevel::Burdened => 0.75, - BurdenLevel::Strained => 0.5, - BurdenLevel::Overloaded => 0.25, + BurdenLevel::Burdened => SPEED_MOD_BURDENED, + BurdenLevel::Strained => SPEED_MOD_STRAINED, + BurdenLevel::Overloaded => SPEED_MOD_OVERLOADED, } } else { 1.0 }; + let overmap_mod = if map.overmap { SPEED_MOD_OVERMAP_TRAVEL } else { 1.0 }; // Every entity has a POTENTIAL equal to their speed. - let mut energy_potential: i32 = ((energy.speed as f32) * burden_modifier) as i32; + let mut energy_potential: i32 = ((energy.speed as f32) * burden_modifier * overmap_mod) as i32; // Increment current energy by NORMAL_SPEED for every // whole number of NORMAL_SPEEDS in their POTENTIAL. while energy_potential >= NORMAL_SPEED { diff --git a/src/data/entity.rs b/src/data/entity.rs index 929b0d5..46ec1f2 100644 --- a/src/data/entity.rs +++ b/src/data/entity.rs @@ -1,6 +1,10 @@ pub const DEFAULT_VIEWSHED_STANDARD: i32 = 16; // Standard viewshed radius for almost all entities. pub const CARRY_CAPACITY_PER_STRENGTH: i32 = 8; // How much weight can be carried per point of strength. pub const NORMAL_SPEED: i32 = 12; // Normal speed for almost all entities. +pub const SPEED_MOD_BURDENED: f32 = 0.75; +pub const SPEED_MOD_STRAINED: f32 = 0.5; +pub const SPEED_MOD_OVERLOADED: f32 = 0.25; +pub const SPEED_MOD_OVERMAP_TRAVEL: f32 = 0.33; pub const TURN_COST_MULTIPLIER: i32 = 4; // How many ticks for NORMAL_SPEED to get a turn. pub const ATTR_BONUS_0: i32 = 10; // At this value, the attribute bonus is 0. pub const ATTR_NEEDED_PER_POINT: i32 = 2; // How many points +- ATTR_BONUS_0 are needed per +- 1 bonus. diff --git a/src/data/ids.rs b/src/data/ids.rs new file mode 100644 index 0000000..95eac4a --- /dev/null +++ b/src/data/ids.rs @@ -0,0 +1,6 @@ +pub const ID_PREVIOUS_LEVEL: i32 = -5; +pub const ID_NEXT_LEVEL: i32 = -6; + +pub const ID_OVERMAP: i32 = 1; +pub const ID_TOWN: i32 = 10; +pub const ID_TOWN2: i32 = ID_TOWN + 1; diff --git a/src/data/mod.rs b/src/data/mod.rs index 590c92a..e7cc75b 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -3,3 +3,4 @@ pub mod visuals; pub mod messages; pub mod char_create; pub mod events; +pub mod ids; diff --git a/src/data/visuals.rs b/src/data/visuals.rs index efaee3a..21686e8 100644 --- a/src/data/visuals.rs +++ b/src/data/visuals.rs @@ -76,3 +76,9 @@ pub const IMPASSABLE_MOUNTAIN_GLYPH: char = '▲'; // FOREST THEME pub const FOREST_WALL_GLYPH: char = '♣'; + +// Overmap/transition stuff +pub const TO_OVERMAP_GLYPH: char = '<'; +pub const TO_OVERMAP_COLOUR: (u8, u8, u8) = (205, 127, 50); +pub const TO_TOWN_GLYPH: char = 'o'; +pub const TO_TOWN_COLOUR: (u8, u8, u8) = (205, 127, 50); diff --git a/src/main.rs b/src/main.rs index e1762f4..7414dcd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,8 +70,9 @@ pub enum RunState { }, SaveGame, GameOver, - NextLevel, PreviousLevel, + NextLevel, + GoToLevel(i32, Option), HelpScreen, MagicMapReveal { row: i32, @@ -89,12 +90,12 @@ pub struct State { } impl State { - fn generate_world_map(&mut self, new_id: i32, offset: i32) { + fn generate_world_map(&mut self, new_id: i32, offset: i32, from_tile: Option) { // 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, offset); + let map_building_info = map::level_transition(&mut self.ecs, new_id, offset, from_tile); if let Some(history) = map_building_info { self.mapgen_history = history; } else { @@ -171,7 +172,17 @@ impl State { default_move_ai.run_now(&self.ecs); } - fn goto_level(&mut self, offset: i32) { + fn goto_id(&mut self, id: i32, from_tile: Option) { + let current_id; + { + let worldmap_resource = self.ecs.fetch::(); + current_id = worldmap_resource.id; + } + let offset = id - current_id; + self.goto_level(offset, from_tile); + } + + fn goto_level(&mut self, offset: i32, from_tile: Option) { // Build new map + place player let current_id; { @@ -187,7 +198,7 @@ impl State { } // Freeze the current level map::dungeon::freeze_entities(&mut self.ecs); - self.generate_world_map(current_id + offset, offset); + self.generate_world_map(current_id + offset, offset, from_tile); let mapname = self.ecs.fetch::().name.clone(); gamelog::Logger::new().append("You head to").npc_name_n(mapname).period().log(); } @@ -210,7 +221,7 @@ impl State { } // Replace map list self.ecs.insert(map::dungeon::MasterDungeonMap::new()); - self.generate_world_map(1, 0); + self.generate_world_map(1, 0, None); gamelog::setup_log(); gamelog::record_event(EVENT::LEVEL(1)); @@ -299,12 +310,12 @@ impl GameState for State { } gui::CheatMenuResult::NoResponse => {} gui::CheatMenuResult::Ascend => { - self.goto_level(-1); + self.goto_level(-1, Some(TileType::UpStair)); self.mapgen_next_state = Some(RunState::PreRun); new_runstate = RunState::MapGeneration; } gui::CheatMenuResult::Descend => { - self.goto_level(1); + self.goto_level(1, Some(TileType::DownStair)); self.mapgen_next_state = Some(RunState::PreRun); new_runstate = RunState::MapGeneration; } @@ -524,12 +535,17 @@ impl GameState for State { } } RunState::NextLevel => { - self.goto_level(1); + self.goto_level(1, Some(TileType::DownStair)); self.mapgen_next_state = Some(RunState::PreRun); new_runstate = RunState::MapGeneration; } RunState::PreviousLevel => { - self.goto_level(-1); + self.goto_level(-1, Some(TileType::UpStair)); + self.mapgen_next_state = Some(RunState::PreRun); + new_runstate = RunState::MapGeneration; + } + RunState::GoToLevel(id, from_tile) => { + self.goto_id(id, from_tile); self.mapgen_next_state = Some(RunState::PreRun); new_runstate = RunState::MapGeneration; } @@ -734,7 +750,7 @@ fn main() -> rltk::BError { gamelog::setup_log(); gamelog::record_event(EVENT::LEVEL(1)); - gs.generate_world_map(1, 0); + gs.generate_world_map(1, 0, None); rltk::main_loop(context, gs) } diff --git a/src/map/dungeon.rs b/src/map/dungeon.rs index fad2eed..ea707fc 100644 --- a/src/map/dungeon.rs +++ b/src/map/dungeon.rs @@ -5,6 +5,7 @@ use serde::{ Deserialize, Serialize }; use specs::prelude::*; use std::collections::{ HashMap, HashSet }; use crate::data::events::*; +use crate::data::ids::*; #[derive(Default, Serialize, Deserialize, Clone)] pub struct MasterDungeonMap { @@ -188,12 +189,12 @@ fn make_wand_name(rng: &mut RandomNumberGenerator, used_names: &mut HashSet Option> { +pub fn level_transition(ecs: &mut World, new_id: i32, offset: i32, from_tile: Option) -> 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, offset); + transition_to_existing_map(ecs, new_id, offset, from_tile); return None; } else { std::mem::drop(dungeon_master); @@ -201,20 +202,36 @@ pub fn level_transition(ecs: &mut World, new_id: i32, offset: i32) -> Option) { let mut dungeon_master = ecs.write_resource::(); // Unwrapping here panics if new_id isn't present. But this should // never be called without new_id being present by level_transition. let map = dungeon_master.get_map(new_id).unwrap(); let mut worldmap_resource = ecs.write_resource::(); - // Store new state of old map - dungeon_master.store_map(&worldmap_resource); let player_entity = ecs.fetch::(); // Find down stairs, place player + let dest_tile = if from_tile.is_some() { + match from_tile.unwrap() { + TileType::UpStair => TileType::DownStair, + TileType::DownStair => TileType::UpStair, + TileType::ToTown => TileType::ToOvermap, + TileType::ToOvermap => { + match worldmap_resource.id { + ID_TOWN => TileType::ToTown, + _ => panic!("Tried to transition to overmap from somewhere unaccounted for!"), + } + } + _ => if offset < 0 { TileType::DownStair } else { TileType::UpStair } + } + } else if offset < 0 { + TileType::DownStair + } else { + TileType::UpStair + }; + 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 == stair_type { + if *tt == dest_tile { 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::(); @@ -225,6 +242,7 @@ fn transition_to_existing_map(ecs: &mut World, new_id: i32, offset: i32) { } } } + dungeon_master.store_map(&worldmap_resource); *worldmap_resource = map; // Dirtify viewsheds (forces refresh) let mut viewshed_components = ecs.write_storage::(); @@ -248,18 +266,23 @@ fn transition_to_new_map(ecs: &mut World, new_id: i32) -> Vec { let mut builder = map_builders::level_builder(new_id, &mut rng, 100, 50, player_level); builder.build_map(&mut rng); std::mem::drop(rng); - if new_id > 1 { - if let Some(pos) = &builder.build_data.starting_position { - let up_idx = builder.build_data.map.xy_idx(pos.x, pos.y); - builder.build_data.map.tiles[up_idx] = TileType::UpStair; - } - } let mapgen_history = builder.build_data.history.clone(); let player_start; let old_map: Map; { let mut worldmap_resource = ecs.write_resource::(); old_map = worldmap_resource.clone(); + if !old_map.overmap { + if let Some(pos) = &builder.build_data.starting_position { + let up_idx = builder.build_data.map.xy_idx(pos.x, pos.y); + builder.build_data.map.tiles[up_idx] = TileType::UpStair; + } + } else { + if let Some(pos) = &builder.build_data.starting_position { + let down_idx = builder.build_data.map.xy_idx(pos.x, pos.y); + builder.build_data.map.tiles[down_idx] = TileType::ToOvermap; + } + } *worldmap_resource = builder.build_data.map.clone(); // Unwrap so we get a CTD if there's no starting pos. player_start = builder.build_data.starting_position.as_mut().unwrap().clone(); diff --git a/src/map/themes.rs b/src/map/themes.rs index 98d3fea..10e32f1 100644 --- a/src/map/themes.rs +++ b/src/map/themes.rs @@ -1,6 +1,7 @@ use super::{ Map, Point, TileType }; use crate::data::visuals::*; use crate::config::CONFIG; +use crate::data::ids::*; use rltk::prelude::*; use std::ops::{ Add, Mul }; @@ -12,7 +13,7 @@ pub fn get_tile_renderables_for_id( debug: Option ) -> (rltk::FontCharType, RGB, RGB) { let (glyph, mut fg, mut bg, offsets, bg_main_col) = match map.id { - 3 => get_forest_theme_renderables(idx, map, debug), + ID_TOWN2 => get_forest_theme_renderables(idx, map, debug), _ => get_default_theme_renderables(idx, map, debug), }; @@ -87,6 +88,8 @@ pub fn get_default_theme_renderables(idx: usize, map: &Map, debug: Option) TileType::DeepWater => { glyph = rltk::to_cp437(DEEP_WATER_GLYPH); bg = RGB::named(DEEP_WATER_COLOUR); offsets = DEEP_WATER_OFFSETS; } TileType::Bars => { glyph = rltk::to_cp437(BARS_GLYPH); fg = RGB::named(BARS_COLOUR); bg = RGB::named(FLOOR_COLOUR); } TileType::ImpassableMountain => { glyph = rltk::to_cp437(IMPASSABLE_MOUNTAIN_GLYPH); bg = RGB::named(IMPASSABLE_MOUNTAIN_COLOUR); offsets = IMPASSABLE_MOUNTAIN_OFFSETS } + TileType::ToOvermap => { glyph = rltk::to_cp437(TO_OVERMAP_GLYPH); fg = RGB::named(TO_OVERMAP_COLOUR); bg = RGB::named(DEFAULT_BG_COLOUR); bg_main_col = false; } + TileType::ToTown => { glyph = rltk::to_cp437(TO_TOWN_GLYPH); fg = RGB::named(TO_TOWN_COLOUR); bg = RGB::named(DEFAULT_BG_COLOUR); bg_main_col = false; } } return (glyph, fg, bg, offsets, bg_main_col); } diff --git a/src/map/tiletype.rs b/src/map/tiletype.rs index de646b1..45d331a 100644 --- a/src/map/tiletype.rs +++ b/src/map/tiletype.rs @@ -23,23 +23,15 @@ pub enum TileType { // Stairs (changes floor) DownStair, UpStair, + // To/From Overmap - ids are in src/data/ids.rs, are used in try_change_level() in src/player.rs + ToOvermap, + ToTown, } pub fn tile_walkable(tt: TileType) -> bool { match tt { - | TileType::Floor - | TileType::WoodFloor - | TileType::Gravel - | TileType::Road - | TileType::Grass - | TileType::Foliage - | TileType::HeavyFoliage - | TileType::Sand - | TileType::ShallowWater - | TileType::Bridge - | TileType::DownStair - | TileType::UpStair => true, - _ => false, + TileType::ImpassableMountain | TileType::Wall | TileType::DeepWater | TileType::Fence | TileType::Bars => false, + _ => true, } } diff --git a/src/map_builders/mod.rs b/src/map_builders/mod.rs index 20e814d..eaa260f 100644 --- a/src/map_builders/mod.rs +++ b/src/map_builders/mod.rs @@ -36,6 +36,7 @@ use common::*; use specs::prelude::*; use voronoi_spawning::VoronoiSpawning; use super::config::CONFIG; +use super::data::ids::*; //use wfc::WaveFunctionCollapseBuilder; mod room_exploder; use room_exploder::RoomExploder; @@ -318,7 +319,7 @@ fn random_shape_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut Bui } fn overmap_builder() -> BuilderChain { - let mut builder = BuilderChain::new(true, 1, 69, 41, 0, "the world", 1); + let mut builder = BuilderChain::new(true, ID_OVERMAP, 69, 41, 0, "the world", 1); builder.start_with(PrefabBuilder::overmap()); return builder; } @@ -385,9 +386,9 @@ pub fn level_builder( // TODO: With difficulty and ID/depth decoupled, this can be used for branches later. let difficulty = new_id; match new_id { - 1 => overmap_builder(), - 2 => town_builder(new_id, rng, width, height, 0, initial_player_level), - 3 => forest_builder(new_id, rng, width, height, 1, initial_player_level), + ID_OVERMAP => overmap_builder(), + ID_TOWN => town_builder(new_id, rng, width, height, 0, initial_player_level), + ID_TOWN2 => forest_builder(new_id, rng, width, height, 1, initial_player_level), _ => random_builder(new_id, rng, width, height, difficulty, initial_player_level), } } diff --git a/src/map_builders/prefab_builder/mod.rs b/src/map_builders/prefab_builder/mod.rs index 37bd143..8361022 100644 --- a/src/map_builders/prefab_builder/mod.rs +++ b/src/map_builders/prefab_builder/mod.rs @@ -177,6 +177,9 @@ impl PrefabBuilder { '^' => { build_data.map.tiles[idx] = TileType::ImpassableMountain; } + '1' => { + build_data.map.tiles[idx] = TileType::ToTown; + } _ => { rltk::console::log(format!("Unknown glyph '{}' when loading overmap", ch as u8 as char)); } diff --git a/src/map_builders/prefab_builder/overmap b/src/map_builders/prefab_builder/overmap deleted file mode 100644 index 994aa3e..0000000 --- a/src/map_builders/prefab_builder/overmap +++ /dev/null @@ -1,41 +0,0 @@ -~~~~~~~~~.................~~~.......~~~~~~~~~~~~~~~~~~~~~~~~ -~~~~~~~~...........................~~~~~~~~~~~~~~~~~~~~~~~~~ -~~~~~~~............................~~~~~~~~~~~~~~~~~~~~~~~~~ -~~~~....~..........................~~~~~~~~~~~~~.....~~~~~~~ -~~~....~...........................~..~~~~~~~~~~......~~~~~~ -~~~.................~.................~~~~~~~~~........~...~ -~~~.................~....................................... -~~~~........................................................ -~~~~~~...................................................... -~~~~~~..................................~................... -~~~~~........~~.........................~................... -~~~~~......~~~.~............................................ -~~~~.......~~..~...........................................~ -~~~........~...............................................~ -~~~~......~...............................................~~ -~~~~~......................................................~ -~~~~~...~................~.................................. -~~~~~~~~~~~............~~~.................................. -~~~~~~~~~~...........~..~................................... -~~~~~~~~~~~............~.................................... -~~~~~~~~~..............~.................................... -~~~~~~~~.............~~...................................~~ -~~~~~~~..............~.....................................~ -~~~~~......................................................~ -~~~~~.................~~...................................~ -~~~~..................~.~~~................................. -~~~~..............~.......~................................. -~.................~~..................~~.................... -~...............~..~..................~~~................... -..~......~~~~~~~~.....~~~.............~~.................... -..~~.....~~~~~~~~~~...~~~................................... -..~~~~~~~~~~~~~~~~..~~~~~~.................................. -....~~~~~~~~~~~~...~~~~~~~..............~~~~................ -........~~~~~~~~..........~.~....~......~......~.......~.... -~...~...~~~~~~~~...........................................~ -...~~.......~~~~............................................ -...............~............................................ -.................................~.......................... -~~...............................~~.....~................... -~~~..............................~~......................... -~~~......................................~~~.~~~~........... \ No newline at end of file diff --git a/src/map_builders/prefab_builder/prefab_levels.rs b/src/map_builders/prefab_builder/prefab_levels.rs index e0e2139..36ced5e 100644 --- a/src/map_builders/prefab_builder/prefab_levels.rs +++ b/src/map_builders/prefab_builder/prefab_levels.rs @@ -93,7 +93,7 @@ const OVERMAP_TEMPLATE: &str = ^^^^^^^........................≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈.....≈ ^^^^^^^^........@..............≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈ ^^^^^^^^..................≈...≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈...≈≈≈...≈≈≈≈≈≈≈≈.≈≈ -^^^^^^^^^.............>...≈≈....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈≈......≈≈≈≈≈≈≈≈≈ +^^^^^^^^^.............1...≈≈....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈≈......≈≈≈≈≈≈≈≈≈ ^^^^^^^^^........≈≈≈≈...≈≈≈≈....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈..≈≈≈......≈≈≈≈≈≈≈≈≈ ^^^^^^^^^^......≈≈≈≈≈≈≈≈≈≈≈≈≈..≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈ ^^^^^^^^^^.....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈≈ diff --git a/src/map_builders/town.rs b/src/map_builders/town.rs index b633bae..8ebf021 100644 --- a/src/map_builders/town.rs +++ b/src/map_builders/town.rs @@ -61,6 +61,11 @@ impl TownBuilder { self.spawn_dockers(build_data, rng); self.spawn_townsfolk(build_data, rng, &mut available_building_tiles); + build_data.starting_position = Some(Position { + x: build_data.width - 2, + y: wall_gap_y, + }); + build_data.take_snapshot(); } @@ -186,11 +191,6 @@ impl TownBuilder { build_data: &mut BuilderMap, rng: &mut rltk::RandomNumberGenerator ) { - // Place player - build_data.starting_position = Some(Position { - x: building.0 + building.2 / 2, - y: building.1 + building.3 / 2, - }); let player_idx = build_data.map.xy_idx(building.0 + building.2 / 2, building.1 + building.3 / 2); // Place other items diff --git a/src/player.rs b/src/player.rs index 1c71bd7..1c75ca8 100644 --- a/src/player.rs +++ b/src/player.rs @@ -35,6 +35,7 @@ use rltk::{ Point, RandomNumberGenerator, Rltk, VirtualKeyCode }; use specs::prelude::*; use std::cmp::{ max, min }; use crate::data::events::*; +use crate::data::ids::*; pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { let mut positions = ecs.write_storage::(); @@ -529,20 +530,28 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { // id VirtualKeyCode::Period => { if ctx.shift { - if !try_next_level(&mut gs.ecs) { + let (id, from_tile) = try_next_level(&mut gs.ecs); + if from_tile.is_none() { return RunState::AwaitingInput; + } else if id == ID_NEXT_LEVEL { + return RunState::NextLevel; } - return RunState::NextLevel; // > to descend + return RunState::GoToLevel(id, from_tile); } else { return skip_turn(&mut gs.ecs); // (Wait a turn) } } VirtualKeyCode::Comma => { if ctx.shift { - if !try_previous_level(&mut gs.ecs) { + let (id, from_tile) = try_prev_level(&mut gs.ecs); + if from_tile.is_none() { return RunState::AwaitingInput; + } else if id == ID_PREVIOUS_LEVEL { + return RunState::PreviousLevel; } - return RunState::PreviousLevel; // < to ascend + return RunState::GoToLevel(id, from_tile); + } else { + return skip_turn(&mut gs.ecs); // (Wait a turn) } } VirtualKeyCode::Slash => { @@ -591,27 +600,41 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { return RunState::AwaitingInput; } -pub fn try_next_level(ecs: &mut World) -> bool { +fn try_next_level(ecs: &mut World) -> (i32, Option) { 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::DownStair { - return true; - } else { - gamelog::Logger::new().append("You don't see a way down from here.").log(); - return false; + let this_tile = map.tiles[player_idx]; + match this_tile { + TileType::DownStair => { + return (ID_NEXT_LEVEL, Some(this_tile)); + } + TileType::ToTown => { + return (ID_TOWN, Some(this_tile)); + } + _ => { + gamelog::Logger::new().append("You don't see a way down from here.").log(); + return (0, None); + } } } -pub fn try_previous_level(ecs: &mut World) -> bool { +fn try_prev_level(ecs: &mut World) -> (i32, Option) { 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; + let this_tile = map.tiles[player_idx]; + match this_tile { + TileType::UpStair => { + return (ID_PREVIOUS_LEVEL, Some(this_tile)); + } + TileType::ToOvermap => { + return (ID_OVERMAP, Some(this_tile)); + } + _ => { + gamelog::Logger::new().append("You don't see a way out from here.").log(); + return (0, None); + } } }