From 7e4953f096fbddba72afea7f299024aca263056b Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Sat, 15 Jul 2023 11:01:50 +0100 Subject: [PATCH 1/2] map builder module --- src/main.rs | 29 ++++---- src/map.rs | 120 +++++---------------------------- src/map_builders/common.rs | 29 ++++++++ src/map_builders/mod.rs | 15 +++++ src/map_builders/simple_map.rs | 77 +++++++++++++++++++++ 5 files changed, 156 insertions(+), 114 deletions(-) create mode 100644 src/map_builders/common.rs create mode 100644 src/map_builders/mod.rs create mode 100644 src/map_builders/simple_map.rs diff --git a/src/main.rs b/src/main.rs index a1435c9..05bd033 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ mod rect; pub use rect::Rect; mod gamelog; mod gui; +pub mod map_builders; mod saveload_system; mod spawner; mod visibility_system; @@ -143,11 +144,14 @@ impl State { // Build new map let worldmap; let current_depth; + let player_start; { let mut worldmap_resource = self.ecs.write_resource::(); current_depth = worldmap_resource.depth; let mut rng = self.ecs.write_resource::(); - *worldmap_resource = Map::new_map_rooms_and_corridors(&mut rng, current_depth + 1); + let (newmap, start) = map_builders::build_random_map(&mut rng, current_depth + 1); + *worldmap_resource = newmap; + player_start = start; worldmap = worldmap_resource.clone(); } @@ -157,15 +161,14 @@ impl State { } // Place the player and update resources - let (player_x, player_y) = worldmap.rooms[0].centre(); let mut player_position = self.ecs.write_resource::(); - *player_position = Point::new(player_x, player_y); + *player_position = Point::new(player_start.x, player_start.y); let mut position_components = self.ecs.write_storage::(); let player_entity = self.ecs.fetch::(); let player_pos_comp = position_components.get_mut(*player_entity); if let Some(player_pos_comp) = player_pos_comp { - player_pos_comp.x = player_x; - player_pos_comp.y = player_y; + player_pos_comp.x = player_start.x; + player_pos_comp.y = player_start.y; } // Dirtify viewshed @@ -196,10 +199,13 @@ impl State { // Build a new map and place the player let worldmap; + let player_start; { let mut worldmap_resource = self.ecs.write_resource::(); let mut rng = self.ecs.write_resource::(); - *worldmap_resource = Map::new_map_rooms_and_corridors(&mut rng, 1); + let (newmap, start) = map_builders::build_random_map(&mut rng, 1); + *worldmap_resource = newmap; + player_start = start; worldmap = worldmap_resource.clone(); } @@ -209,7 +215,7 @@ impl State { } // Place the player and update resources - let (player_x, player_y) = worldmap.rooms[0].centre(); + let (player_x, player_y) = (player_start.x, player_start.y); let player_entity = spawner::player(&mut self.ecs, player_x, player_y, "Player".to_string()); let mut player_position = self.ecs.write_resource::(); *player_position = Point::new(player_x, player_y); @@ -524,23 +530,22 @@ fn main() -> rltk::BError { gs.ecs.register::(); gs.ecs.insert(SimpleMarkerAllocator::::new()); - // Create RNG. + // Create seed. let mut rng = rltk::RandomNumberGenerator::new(); // Use seed to generate the map. - let map = Map::new_map_rooms_and_corridors(&mut rng, 1); + let (map, player_start) = map_builders::build_random_map(&mut rng, 1); // Insert seed into the ECS. gs.ecs.insert(rng); - let (player_x, player_y) = map.rooms[0].centre(); let player_name = "wanderer".to_string(); - let player_entity = spawner::player(&mut gs.ecs, player_x, player_y, player_name); + let player_entity = spawner::player(&mut gs.ecs, player_start.x, player_start.y, player_name); for room in map.rooms.iter().skip(1) { spawner::spawn_room(&mut gs.ecs, room, 1); } gs.ecs.insert(map); - gs.ecs.insert(Point::new(player_x, player_y)); + gs.ecs.insert(Point::new(player_start.x, player_start.y)); gs.ecs.insert(player_entity); gamelog::setup_log(); diff --git a/src/map.rs b/src/map.rs index 038e768..a0aec24 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,8 +1,7 @@ use super::Rect; -use rltk::{Algorithm2D, BaseMap, Point, RandomNumberGenerator, Rltk, RGB}; +use rltk::{Algorithm2D, BaseMap, Point, Rltk, RGB}; use serde::{Deserialize, Serialize}; use specs::prelude::*; -use std::cmp::{max, min}; use std::collections::HashSet; use std::ops::{Add, Mul}; @@ -15,7 +14,6 @@ pub enum TileType { pub const MAPWIDTH: usize = 80; pub const MAPHEIGHT: usize = 43; -const MAX_OFFSET: u8 = 32; pub const MAPCOUNT: usize = MAPHEIGHT * MAPWIDTH; #[derive(Default, Serialize, Deserialize, Clone)] @@ -45,30 +43,23 @@ impl Map { (y as usize) * (self.width as usize) + (x as usize) } - fn apply_room_to_map(&mut self, room: &Rect) { - for y in room.y1 + 1..=room.y2 { - for x in room.x1 + 1..=room.x2 { - let idx = self.xy_idx(x, y); - self.tiles[idx] = TileType::Floor; - } - } - } - - fn apply_horizontal_tunnel(&mut self, x1: i32, x2: i32, y: i32) { - for x in min(x1, x2)..=max(x1, x2) { - let idx = self.xy_idx(x, y); - if idx > 0 && idx < (self.width as usize) * (self.height as usize) { - self.tiles[idx as usize] = TileType::Floor; - } - } - } - - fn apply_vertical_tunnel(&mut self, y1: i32, y2: i32, x: i32) { - for y in min(y1, y2)..=max(y1, y2) { - let idx = self.xy_idx(x, y); - if idx > 0 && idx < (self.width as usize) * (self.height as usize) { - self.tiles[idx as usize] = TileType::Floor; - } + pub fn new(new_depth: i32) -> Map { + Map { + tiles: vec![TileType::Wall; MAPCOUNT], + rooms: Vec::new(), + width: MAPWIDTH as i32, + height: MAPHEIGHT as i32, + revealed_tiles: vec![false; MAPCOUNT], + visible_tiles: vec![false; MAPCOUNT], + lit_tiles: vec![true; MAPCOUNT], // NYI: Light sources. Once those exist, we can set this to false. + telepath_tiles: vec![false; MAPCOUNT], + red_offset: vec![0; MAPCOUNT], + green_offset: vec![0; MAPCOUNT], + blue_offset: vec![0; MAPCOUNT], + blocked: vec![false; MAPCOUNT], + depth: new_depth, + bloodstains: HashSet::new(), + tile_content: vec![Vec::new(); MAPCOUNT], } } @@ -92,81 +83,6 @@ impl Map { content.clear(); } } - - /// Makes a procgen map out of rooms and corridors, and returns the rooms and the map. - pub fn new_map_rooms_and_corridors(rng: &mut RandomNumberGenerator, new_depth: i32) -> Map { - let mut map = Map { - tiles: vec![TileType::Wall; MAPCOUNT], - rooms: Vec::new(), - width: MAPWIDTH as i32, - height: MAPHEIGHT as i32, - revealed_tiles: vec![false; MAPCOUNT], - visible_tiles: vec![false; MAPCOUNT], - lit_tiles: vec![true; MAPCOUNT], // NYI: Light sources. Once those exist, we can set this to false. - telepath_tiles: vec![false; MAPCOUNT], - red_offset: vec![0; MAPCOUNT], - green_offset: vec![0; MAPCOUNT], - blue_offset: vec![0; MAPCOUNT], - blocked: vec![false; MAPCOUNT], - depth: new_depth, - bloodstains: HashSet::new(), - tile_content: vec![Vec::new(); MAPCOUNT], - }; - - const MAX_ROOMS: i32 = 30; - const MIN_SIZE: i32 = 6; - const MAX_SIZE: i32 = 10; - - for idx in 0..map.red_offset.len() { - let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.red_offset[idx] = roll as u8; - } - for idx in 0..map.green_offset.len() { - let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.green_offset[idx] = roll as u8; - } - for idx in 0..map.blue_offset.len() { - let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.blue_offset[idx] = roll as u8; - } - - for _i in 0..MAX_ROOMS { - let w = rng.range(MIN_SIZE, MAX_SIZE); - let h = rng.range(MIN_SIZE, MAX_SIZE); - let x = rng.roll_dice(1, map.width - w - 1) - 1; - let y = rng.roll_dice(1, map.height - h - 1) - 1; - let new_room = Rect::new(x, y, w, h); - let mut ok = true; - for other_room in map.rooms.iter() { - if new_room.intersect(other_room) { - ok = false; - } - } - if ok { - map.apply_room_to_map(&new_room); - - if !map.rooms.is_empty() { - let (new_x, new_y) = new_room.centre(); - let (prev_x, prev_y) = map.rooms[map.rooms.len() - 1].centre(); - if rng.range(0, 2) == 1 { - map.apply_horizontal_tunnel(prev_x, new_x, prev_y); - map.apply_vertical_tunnel(prev_y, new_y, new_x); - } else { - map.apply_vertical_tunnel(prev_y, new_y, prev_x); - map.apply_horizontal_tunnel(prev_x, new_x, new_y); - } - } - - map.rooms.push(new_room); - } - } - - let stairs_position = map.rooms[map.rooms.len() - 1].centre(); - let stairs_idx = map.xy_idx(stairs_position.0, stairs_position.1); - map.tiles[stairs_idx] = TileType::DownStair; - - map - } } impl Algorithm2D for Map { diff --git a/src/map_builders/common.rs b/src/map_builders/common.rs new file mode 100644 index 0000000..b3d314b --- /dev/null +++ b/src/map_builders/common.rs @@ -0,0 +1,29 @@ +use super::{Map, Rect, TileType}; +use std::cmp::{max, min}; + +pub fn apply_room_to_map(map: &mut Map, room: &Rect) { + for y in room.y1 + 1..=room.y2 { + for x in room.x1 + 1..=room.x2 { + let idx = map.xy_idx(x, y); + map.tiles[idx] = TileType::Floor; + } + } +} + +pub fn apply_horizontal_tunnel(map: &mut Map, x1: i32, x2: i32, y: i32) { + for x in min(x1, x2)..=max(x1, x2) { + let idx = map.xy_idx(x, y); + if idx > 0 && idx < (map.width as usize) * (map.height as usize) { + map.tiles[idx as usize] = TileType::Floor; + } + } +} + +pub fn apply_vertical_tunnel(map: &mut Map, y1: i32, y2: i32, x: i32) { + for y in min(y1, y2)..=max(y1, y2) { + let idx = map.xy_idx(x, y); + if idx > 0 && idx < (map.width as usize) * (map.height as usize) { + map.tiles[idx as usize] = TileType::Floor; + } + } +} diff --git a/src/map_builders/mod.rs b/src/map_builders/mod.rs new file mode 100644 index 0000000..5bf7e33 --- /dev/null +++ b/src/map_builders/mod.rs @@ -0,0 +1,15 @@ +use super::{spawner, Map, Position, Rect, TileType}; +mod simple_map; +use simple_map::SimpleMapBuilder; +mod common; +use common::*; +use rltk::RandomNumberGenerator; +use specs::prelude::*; + +trait MapBuilder { + fn build(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position); +} + +pub fn build_random_map(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position) { + SimpleMapBuilder::build(rng, new_depth) +} diff --git a/src/map_builders/simple_map.rs b/src/map_builders/simple_map.rs new file mode 100644 index 0000000..76a9258 --- /dev/null +++ b/src/map_builders/simple_map.rs @@ -0,0 +1,77 @@ +use super::{ + apply_horizontal_tunnel, apply_room_to_map, apply_vertical_tunnel, spawner, Map, MapBuilder, Position, Rect, + TileType, +}; +use rltk::RandomNumberGenerator; +use specs::prelude::*; + +pub struct SimpleMapBuilder {} + +impl MapBuilder for SimpleMapBuilder { + fn build(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position) { + let mut map = Map::new(new_depth); + let player_pos = SimpleMapBuilder::rooms_and_corridors(rng, &mut map); + + return (map, player_pos); + } +} + +impl SimpleMapBuilder { + fn rooms_and_corridors(rng: &mut RandomNumberGenerator, map: &mut Map) -> Position { + const MAX_ROOMS: i32 = 30; + const MIN_SIZE: i32 = 6; + const MAX_SIZE: i32 = 10; + const MAX_OFFSET: u8 = 32; + + for idx in 0..map.red_offset.len() { + let roll = rng.roll_dice(1, MAX_OFFSET as i32); + map.red_offset[idx] = roll as u8; + } + for idx in 0..map.green_offset.len() { + let roll = rng.roll_dice(1, MAX_OFFSET as i32); + map.green_offset[idx] = roll as u8; + } + for idx in 0..map.blue_offset.len() { + let roll = rng.roll_dice(1, MAX_OFFSET as i32); + map.blue_offset[idx] = roll as u8; + } + + for _i in 0..MAX_ROOMS { + let w = rng.range(MIN_SIZE, MAX_SIZE); + let h = rng.range(MIN_SIZE, MAX_SIZE); + let x = rng.roll_dice(1, map.width - w - 1) - 1; + let y = rng.roll_dice(1, map.height - h - 1) - 1; + let new_room = Rect::new(x, y, w, h); + let mut ok = true; + for other_room in map.rooms.iter() { + if new_room.intersect(other_room) { + ok = false + } + } + if ok { + apply_room_to_map(map, &new_room); + + if !map.rooms.is_empty() { + let (new_x, new_y) = new_room.centre(); + let (prev_x, prev_y) = map.rooms[map.rooms.len() - 1].centre(); + if rng.range(0, 2) == 1 { + apply_horizontal_tunnel(map, prev_x, new_x, prev_y); + apply_vertical_tunnel(map, prev_y, new_y, new_x); + } else { + apply_vertical_tunnel(map, prev_y, new_y, prev_x); + apply_horizontal_tunnel(map, prev_x, new_x, new_y); + } + } + + map.rooms.push(new_room); + } + } + + let stairs_position = map.rooms[map.rooms.len() - 1].centre(); + let stairs_idx = map.xy_idx(stairs_position.0, stairs_position.1); + map.tiles[stairs_idx] = TileType::DownStair; + + let start_pos = map.rooms[0].centre(); + return Position { x: start_pos.0, y: start_pos.1 }; + } +} From 325c5af52feae8f2a9a3dae0dbf56c6584488095 Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Sat, 15 Jul 2023 12:27:50 +0100 Subject: [PATCH 2/2] enforces api usage --- src/main.rs | 37 +++++++--------- src/map.rs | 3 -- src/map_builders/mod.rs | 11 +++-- src/map_builders/simple_map.rs | 81 ++++++++++++++++++++++------------ 4 files changed, 77 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index 05bd033..829f514 100644 --- a/src/main.rs +++ b/src/main.rs @@ -142,23 +142,21 @@ impl State { } // Build new map - let worldmap; + let mut builder; let current_depth; let player_start; { let mut worldmap_resource = self.ecs.write_resource::(); current_depth = worldmap_resource.depth; let mut rng = self.ecs.write_resource::(); - let (newmap, start) = map_builders::build_random_map(&mut rng, current_depth + 1); - *worldmap_resource = newmap; - player_start = start; - worldmap = worldmap_resource.clone(); + builder = map_builders::random_builder(current_depth + 1); + builder.build_map(&mut rng); + *worldmap_resource = builder.get_map(); + player_start = builder.get_starting_pos(); } // Spawn things in rooms - for room in worldmap.rooms.iter().skip(1) { - spawner::spawn_room(&mut self.ecs, room, current_depth + 1); - } + builder.spawn_entities(&mut self.ecs); // Place the player and update resources let mut player_position = self.ecs.write_resource::(); @@ -198,21 +196,19 @@ impl State { } // Build a new map and place the player - let worldmap; + let mut builder; let player_start; { let mut worldmap_resource = self.ecs.write_resource::(); let mut rng = self.ecs.write_resource::(); - let (newmap, start) = map_builders::build_random_map(&mut rng, 1); - *worldmap_resource = newmap; - player_start = start; - worldmap = worldmap_resource.clone(); + builder = map_builders::random_builder(1); + builder.build_map(&mut rng); + *worldmap_resource = builder.get_map(); + player_start = builder.get_starting_pos(); } // Spawn bad guys - for room in worldmap.rooms.iter().skip(1) { - spawner::spawn_room(&mut self.ecs, room, 1); - } + builder.spawn_entities(&mut self.ecs); // Place the player and update resources let (player_x, player_y) = (player_start.x, player_start.y); @@ -533,16 +529,17 @@ fn main() -> rltk::BError { // Create seed. let mut rng = rltk::RandomNumberGenerator::new(); // Use seed to generate the map. - let (map, player_start) = map_builders::build_random_map(&mut rng, 1); + let mut builder = map_builders::random_builder(1); + builder.build_map(&mut rng); + let player_start = builder.get_starting_pos(); + let map = builder.get_map(); // Insert seed into the ECS. gs.ecs.insert(rng); let player_name = "wanderer".to_string(); let player_entity = spawner::player(&mut gs.ecs, player_start.x, player_start.y, player_name); - for room in map.rooms.iter().skip(1) { - spawner::spawn_room(&mut gs.ecs, room, 1); - } + builder.spawn_entities(&mut gs.ecs); gs.ecs.insert(map); gs.ecs.insert(Point::new(player_start.x, player_start.y)); diff --git a/src/map.rs b/src/map.rs index a0aec24..31d528a 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,4 +1,3 @@ -use super::Rect; use rltk::{Algorithm2D, BaseMap, Point, Rltk, RGB}; use serde::{Deserialize, Serialize}; use specs::prelude::*; @@ -19,7 +18,6 @@ pub const MAPCOUNT: usize = MAPHEIGHT * MAPWIDTH; #[derive(Default, Serialize, Deserialize, Clone)] pub struct Map { pub tiles: Vec, - pub rooms: Vec, pub width: i32, pub height: i32, pub revealed_tiles: Vec, @@ -46,7 +44,6 @@ impl Map { pub fn new(new_depth: i32) -> Map { Map { tiles: vec![TileType::Wall; MAPCOUNT], - rooms: Vec::new(), width: MAPWIDTH as i32, height: MAPHEIGHT as i32, revealed_tiles: vec![false; MAPCOUNT], diff --git a/src/map_builders/mod.rs b/src/map_builders/mod.rs index 5bf7e33..03653f2 100644 --- a/src/map_builders/mod.rs +++ b/src/map_builders/mod.rs @@ -6,10 +6,13 @@ use common::*; use rltk::RandomNumberGenerator; use specs::prelude::*; -trait MapBuilder { - fn build(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position); +pub trait MapBuilder { + fn build_map(&mut self, rng: &mut RandomNumberGenerator); + fn spawn_entities(&mut self, ecs: &mut World); + fn get_map(&mut self) -> Map; + fn get_starting_pos(&mut self) -> Position; } -pub fn build_random_map(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position) { - SimpleMapBuilder::build(rng, new_depth) +pub fn random_builder(new_depth: i32) -> Box { + return Box::new(SimpleMapBuilder::new(new_depth)); } diff --git a/src/map_builders/simple_map.rs b/src/map_builders/simple_map.rs index 76a9258..2151e52 100644 --- a/src/map_builders/simple_map.rs +++ b/src/map_builders/simple_map.rs @@ -5,73 +5,98 @@ use super::{ use rltk::RandomNumberGenerator; use specs::prelude::*; -pub struct SimpleMapBuilder {} +pub struct SimpleMapBuilder { + map: Map, + starting_position: Position, + depth: i32, + rooms: Vec, +} impl MapBuilder for SimpleMapBuilder { - fn build(rng: &mut RandomNumberGenerator, new_depth: i32) -> (Map, Position) { - let mut map = Map::new(new_depth); - let player_pos = SimpleMapBuilder::rooms_and_corridors(rng, &mut map); + fn get_map(&mut self) -> Map { + return self.map.clone(); + } - return (map, player_pos); + fn get_starting_pos(&mut self) -> Position { + return self.starting_position.clone(); + } + + fn build_map(&mut self, rng: &mut RandomNumberGenerator) { + return self.rooms_and_corridors(rng); + } + + fn spawn_entities(&mut self, ecs: &mut World) { + for room in self.rooms.iter().skip(1) { + return spawner::spawn_room(ecs, room, self.depth); + } } } impl SimpleMapBuilder { - fn rooms_and_corridors(rng: &mut RandomNumberGenerator, map: &mut Map) -> Position { + pub fn new(new_depth: i32) -> SimpleMapBuilder { + SimpleMapBuilder { + map: Map::new(new_depth), + starting_position: Position { x: 0, y: 0 }, + depth: new_depth, + rooms: Vec::new(), + } + } + + fn rooms_and_corridors(&mut self, rng: &mut RandomNumberGenerator) { const MAX_ROOMS: i32 = 30; const MIN_SIZE: i32 = 6; const MAX_SIZE: i32 = 10; const MAX_OFFSET: u8 = 32; - for idx in 0..map.red_offset.len() { + for idx in 0..self.map.red_offset.len() { let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.red_offset[idx] = roll as u8; + self.map.red_offset[idx] = roll as u8; } - for idx in 0..map.green_offset.len() { + for idx in 0..self.map.green_offset.len() { let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.green_offset[idx] = roll as u8; + self.map.green_offset[idx] = roll as u8; } - for idx in 0..map.blue_offset.len() { + for idx in 0..self.map.blue_offset.len() { let roll = rng.roll_dice(1, MAX_OFFSET as i32); - map.blue_offset[idx] = roll as u8; + self.map.blue_offset[idx] = roll as u8; } for _i in 0..MAX_ROOMS { let w = rng.range(MIN_SIZE, MAX_SIZE); let h = rng.range(MIN_SIZE, MAX_SIZE); - let x = rng.roll_dice(1, map.width - w - 1) - 1; - let y = rng.roll_dice(1, map.height - h - 1) - 1; + let x = rng.roll_dice(1, self.map.width - w - 1) - 1; + let y = rng.roll_dice(1, self.map.height - h - 1) - 1; let new_room = Rect::new(x, y, w, h); let mut ok = true; - for other_room in map.rooms.iter() { + for other_room in self.rooms.iter() { if new_room.intersect(other_room) { ok = false } } if ok { - apply_room_to_map(map, &new_room); + apply_room_to_map(&mut self.map, &new_room); - if !map.rooms.is_empty() { + if !self.rooms.is_empty() { let (new_x, new_y) = new_room.centre(); - let (prev_x, prev_y) = map.rooms[map.rooms.len() - 1].centre(); + let (prev_x, prev_y) = self.rooms[self.rooms.len() - 1].centre(); if rng.range(0, 2) == 1 { - apply_horizontal_tunnel(map, prev_x, new_x, prev_y); - apply_vertical_tunnel(map, prev_y, new_y, new_x); + apply_horizontal_tunnel(&mut self.map, prev_x, new_x, prev_y); + apply_vertical_tunnel(&mut self.map, prev_y, new_y, new_x); } else { - apply_vertical_tunnel(map, prev_y, new_y, prev_x); - apply_horizontal_tunnel(map, prev_x, new_x, new_y); + apply_vertical_tunnel(&mut self.map, prev_y, new_y, prev_x); + apply_horizontal_tunnel(&mut self.map, prev_x, new_x, new_y); } } - map.rooms.push(new_room); + self.rooms.push(new_room); } } - let stairs_position = map.rooms[map.rooms.len() - 1].centre(); - let stairs_idx = map.xy_idx(stairs_position.0, stairs_position.1); - map.tiles[stairs_idx] = TileType::DownStair; + let stairs_position = self.rooms[self.rooms.len() - 1].centre(); + let stairs_idx = self.map.xy_idx(stairs_position.0, stairs_position.1); + self.map.tiles[stairs_idx] = TileType::DownStair; - let start_pos = map.rooms[0].centre(); - return Position { x: start_pos.0, y: start_pos.1 }; + let start_pos = self.rooms[0].centre(); + self.starting_position = Position { x: start_pos.0, y: start_pos.1 }; } }