2020-09-12 12:44:37 +00:00
|
|
|
use wasm_bindgen::prelude::*;
|
2020-09-15 06:45:40 +00:00
|
|
|
use web_sys;
|
2020-09-13 11:26:36 +00:00
|
|
|
use rand::prelude::*;
|
2020-10-18 19:40:40 +00:00
|
|
|
use mapgen::{Map, MapBuilder, TileType, geometry::Point};
|
2020-09-23 08:31:13 +00:00
|
|
|
use mapgen::filter::*;
|
2020-09-12 12:44:37 +00:00
|
|
|
|
|
|
|
|
2020-09-14 09:46:48 +00:00
|
|
|
#[wasm_bindgen]
|
|
|
|
#[repr(u8)]
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
|
|
pub enum Cell {
|
|
|
|
Floor = 0,
|
|
|
|
Wall = 1,
|
|
|
|
}
|
|
|
|
|
2020-09-13 11:26:36 +00:00
|
|
|
#[wasm_bindgen]
|
|
|
|
pub struct World {
|
2020-09-13 12:43:59 +00:00
|
|
|
width: u32,
|
|
|
|
height: u32,
|
2020-09-14 09:46:48 +00:00
|
|
|
tiles: Vec<Cell>,
|
2020-10-18 19:40:40 +00:00
|
|
|
map: Map,
|
2020-09-13 11:26:36 +00:00
|
|
|
}
|
|
|
|
|
2020-10-18 19:40:40 +00:00
|
|
|
#[wasm_bindgen]
|
|
|
|
pub struct Position {
|
|
|
|
col: usize,
|
|
|
|
row: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-13 11:26:36 +00:00
|
|
|
#[wasm_bindgen]
|
|
|
|
impl World {
|
2020-10-17 10:19:01 +00:00
|
|
|
|
2020-10-18 19:40:40 +00:00
|
|
|
fn new(width: u32, height: u32, map: Map) -> World {
|
2020-10-17 10:19:01 +00:00
|
|
|
let tiles = (0..map.tiles.len())
|
|
|
|
.map(|i| if map.tiles[i] == TileType::Floor {Cell::Floor} else {Cell::Wall})
|
|
|
|
.collect();
|
2020-10-18 19:40:40 +00:00
|
|
|
World { width, height, tiles, map }
|
2020-10-17 10:19:01 +00:00
|
|
|
}
|
2020-09-15 06:45:40 +00:00
|
|
|
|
2020-09-14 09:46:48 +00:00
|
|
|
pub fn new_cellular_automata(width: u32, height: u32, seed: u32) -> World {
|
2020-09-15 06:45:40 +00:00
|
|
|
World::print_map_info(format!("Cellular Automata with the seed: {}", seed));
|
2020-09-14 09:46:48 +00:00
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
2020-10-19 19:39:30 +00:00
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
2020-09-23 08:31:13 +00:00
|
|
|
.with(NoiseGenerator::uniform())
|
2020-09-22 18:54:19 +00:00
|
|
|
.with(CellularAutomata::new())
|
2020-09-13 11:26:36 +00:00
|
|
|
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
|
|
|
|
.with(CullUnreachable::new())
|
|
|
|
.with(DistantExit::new())
|
2020-09-25 13:09:08 +00:00
|
|
|
.build_with_rng(&mut rng);
|
2020-10-18 19:40:40 +00:00
|
|
|
World::new(width, height, map)
|
2020-09-14 18:29:36 +00:00
|
|
|
}
|
|
|
|
|
2020-09-15 06:45:40 +00:00
|
|
|
pub fn new_simple_rooms(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
World::print_map_info(format!("Simple Rooms with the seed: {}", seed));
|
2020-09-14 18:29:36 +00:00
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
2020-10-19 19:39:30 +00:00
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
2020-09-22 18:54:19 +00:00
|
|
|
.with(SimpleRooms::new())
|
2020-09-14 20:54:39 +00:00
|
|
|
.with(NearestCorridors::new())
|
2020-10-22 20:35:06 +00:00
|
|
|
.with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP))
|
|
|
|
.with(DistantExit::new())
|
|
|
|
.build_with_rng(&mut rng);
|
|
|
|
World::new(width, height, map)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_bsp_rooms(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
World::print_map_info(format!("BSP Rooms with the seed: {}", seed));
|
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
|
|
|
.with(BspRooms::new())
|
|
|
|
.with(NearestCorridors::new())
|
|
|
|
.with(AreaStartingPosition::new(XStart::LEFT, YStart::BOTTOM))
|
2020-10-18 19:40:40 +00:00
|
|
|
.with(DistantExit::new())
|
2020-09-25 13:09:08 +00:00
|
|
|
.build_with_rng(&mut rng);
|
2020-10-18 19:40:40 +00:00
|
|
|
World::new(width, height, map)
|
2020-09-13 11:26:36 +00:00
|
|
|
}
|
2020-09-12 12:44:37 +00:00
|
|
|
|
2020-09-15 20:33:18 +00:00
|
|
|
pub fn new_bsp_interior(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
World::print_map_info(format!("BSP Interior with the seed: {}", seed));
|
2020-09-15 14:23:47 +00:00
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
2020-10-19 19:39:30 +00:00
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
2020-09-22 18:54:19 +00:00
|
|
|
.with(BspInterior::new())
|
2020-10-18 19:40:40 +00:00
|
|
|
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
|
|
|
|
.with(CullUnreachable::new())
|
|
|
|
.with(DistantExit::new())
|
2020-09-25 13:09:08 +00:00
|
|
|
.build_with_rng(&mut rng);
|
2020-10-18 19:40:40 +00:00
|
|
|
World::new(width, height, map)
|
2020-09-15 14:23:47 +00:00
|
|
|
}
|
|
|
|
|
2020-09-16 09:42:59 +00:00
|
|
|
pub fn new_drunkard(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
World::print_map_info(format!("Drunkard with the seed: {}", seed));
|
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
2020-10-19 19:39:30 +00:00
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
2020-09-22 18:54:19 +00:00
|
|
|
.with(DrunkardsWalk::open_halls())
|
2020-10-22 20:35:06 +00:00
|
|
|
.with(AreaStartingPosition::new(XStart::RIGHT, YStart::BOTTOM))
|
2020-10-16 06:13:43 +00:00
|
|
|
.with(CullUnreachable::new())
|
2020-10-18 19:40:40 +00:00
|
|
|
.with(DistantExit::new())
|
2020-09-25 13:09:08 +00:00
|
|
|
.build_with_rng(&mut rng);
|
2020-10-18 19:40:40 +00:00
|
|
|
World::new(width, height, map)
|
2020-09-16 09:42:59 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 08:04:33 +00:00
|
|
|
pub fn new_maze(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
World::print_map_info(format!("Maze with the seed: {}", seed));
|
|
|
|
let mut rng = StdRng::seed_from_u64(seed as u64);
|
|
|
|
let map = MapBuilder::new(width as usize, height as usize)
|
|
|
|
.with(MazeBuilder::new())
|
|
|
|
.with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP))
|
|
|
|
.with(DistantExit::new())
|
|
|
|
.build_with_rng(&mut rng);
|
|
|
|
World::new(width, height, map)
|
|
|
|
}
|
|
|
|
|
2020-09-15 06:45:40 +00:00
|
|
|
pub fn new_random(width: u32, height: u32, seed: u32) -> World {
|
|
|
|
let mut rng = rand::thread_rng();
|
2020-09-15 14:23:47 +00:00
|
|
|
let px = rng.gen::<f32>();
|
2020-11-03 08:04:33 +00:00
|
|
|
if px < 1.0/6.0 {
|
2020-09-15 06:45:40 +00:00
|
|
|
World::new_cellular_automata(width, height, seed)
|
2020-11-03 08:04:33 +00:00
|
|
|
} else if px < 2.0/6.0 {
|
2020-09-15 06:45:40 +00:00
|
|
|
World::new_simple_rooms(width, height, seed)
|
2020-11-03 08:04:33 +00:00
|
|
|
} else if px < 3.0/6.0 {
|
2020-09-16 09:42:59 +00:00
|
|
|
World::new_drunkard(width, height, seed)
|
2020-11-03 08:04:33 +00:00
|
|
|
} else if px < 4.0/6.0 {
|
|
|
|
World::new_bsp_rooms(width, height, seed)
|
|
|
|
} else if px < 5.0/6.0 {
|
2020-10-22 20:35:06 +00:00
|
|
|
World::new_bsp_rooms(width, height, seed)
|
2020-09-15 14:23:47 +00:00
|
|
|
} else {
|
2020-11-03 08:04:33 +00:00
|
|
|
World::new_maze(width, height, seed)
|
2020-09-15 06:45:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-13 11:26:36 +00:00
|
|
|
pub fn width(&self) -> u32 {
|
2020-09-13 12:43:59 +00:00
|
|
|
self.width
|
2020-09-13 11:26:36 +00:00
|
|
|
}
|
2020-09-12 12:44:37 +00:00
|
|
|
|
2020-09-13 11:26:36 +00:00
|
|
|
pub fn height(&self) -> u32 {
|
2020-09-13 12:43:59 +00:00
|
|
|
self.height
|
|
|
|
}
|
|
|
|
|
2020-09-14 09:46:48 +00:00
|
|
|
pub fn tiles(&self) -> *const Cell {
|
2020-09-13 12:43:59 +00:00
|
|
|
self.tiles.as_ptr()
|
2020-09-13 11:26:36 +00:00
|
|
|
}
|
2020-09-15 06:45:40 +00:00
|
|
|
|
2020-10-18 19:40:40 +00:00
|
|
|
pub fn player_pos(&self) -> Position {
|
|
|
|
let p = self.map.starting_point.unwrap_or(Point::new(0, 0));
|
|
|
|
Position { col: p.x, row: p.y }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn exit_pos(&self) -> Position {
|
|
|
|
let p = self.map.exit_point.unwrap_or(Point::new(0, 0));
|
|
|
|
Position { col: p.x, row: p.y }
|
|
|
|
}
|
|
|
|
|
2020-09-15 06:45:40 +00:00
|
|
|
fn print_map_info(info: String) {
|
|
|
|
let window = web_sys::window().expect("no global `window` exists");
|
|
|
|
let document = window.document().expect("should have a document on window");
|
|
|
|
let div = document.get_element_by_id("map-info").expect("Need div with id: map-info");
|
|
|
|
div.set_inner_html(&info);
|
|
|
|
}
|
2020-10-18 19:40:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[wasm_bindgen]
|
|
|
|
impl Position {
|
|
|
|
pub fn new(col: usize, row: usize) -> Position {
|
|
|
|
Position { col, row }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn col(&self) -> usize {
|
|
|
|
self.col
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn row(&self) -> usize {
|
|
|
|
self.row
|
|
|
|
}
|
2020-09-14 09:46:48 +00:00
|
|
|
}
|