rm room_accretion for now
This commit is contained in:
parent
c73f9a5458
commit
30697a98bb
3 changed files with 1 additions and 534 deletions
|
|
@ -1,8 +1,6 @@
|
||||||
use super::{ spawner, Map, Position, Rect, TileType };
|
use super::{ spawner, Map, Position, Rect, TileType };
|
||||||
use bracket_lib::prelude::*;
|
use bracket_lib::prelude::*;
|
||||||
|
|
||||||
mod room_accretion;
|
|
||||||
use room_accretion::RoomAccretionBuilder;
|
|
||||||
mod bsp_dungeon;
|
mod bsp_dungeon;
|
||||||
use bsp_dungeon::BspDungeonBuilder;
|
use bsp_dungeon::BspDungeonBuilder;
|
||||||
mod bsp_interior;
|
mod bsp_interior;
|
||||||
|
|
@ -447,7 +445,7 @@ pub fn level_builder(
|
||||||
initial_player_level: i32
|
initial_player_level: i32
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
match id {
|
match id {
|
||||||
ID_OVERMAP => room_accretion(),
|
ID_OVERMAP => overmap_builder(),
|
||||||
ID_TOWN => town_builder(id, rng, width, height, 0, initial_player_level),
|
ID_TOWN => town_builder(id, rng, width, height, 0, initial_player_level),
|
||||||
ID_TOWN2 => forest_builder(id, rng, width, height, 1, initial_player_level),
|
ID_TOWN2 => forest_builder(id, rng, width, height, 1, initial_player_level),
|
||||||
ID_TOWN3 =>
|
ID_TOWN3 =>
|
||||||
|
|
@ -492,10 +490,3 @@ pub fn level_builder(
|
||||||
fn diff(branch_id: i32, lvl_id: i32) -> i32 {
|
fn diff(branch_id: i32, lvl_id: i32) -> i32 {
|
||||||
return lvl_id - branch_id;
|
return lvl_id - branch_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn room_accretion() -> BuilderChain {
|
|
||||||
let mut builder = BuilderChain::new(false, 110, 64, 64, 0, "room_accretion", "accretion", 0, 1);
|
|
||||||
builder.start_with(RoomAccretionBuilder::new());
|
|
||||||
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
|
||||||
builder
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use bracket_lib::prelude::*;
|
|
||||||
|
|
||||||
pub const HEIGHT: usize = 64;
|
|
||||||
pub const WIDTH: usize = 64;
|
|
||||||
pub const HALLWAY_CHANCE: f32 = 0.5;
|
|
||||||
pub const VERTICAL_CORRIDOR_MIN_LENGTH: i32 = 2;
|
|
||||||
pub const VERTICAL_CORRIDOR_MAX_LENGTH: i32 = 9;
|
|
||||||
pub const HORIZONTAL_CORRIDOR_MIN_LENGTH: i32 = 5;
|
|
||||||
pub const HORIZONTAL_CORRIDOR_MAX_LENGTH: i32 = 15;
|
|
||||||
|
|
||||||
pub enum Operator {
|
|
||||||
LessThan,
|
|
||||||
GreaterThan,
|
|
||||||
LessThanEqualTo,
|
|
||||||
GreaterThanEqualTo,
|
|
||||||
EqualTo,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Operator {
|
|
||||||
pub fn eval(&self, a: i32, b: i32) -> bool {
|
|
||||||
match self {
|
|
||||||
Operator::LessThan => a < b,
|
|
||||||
Operator::GreaterThan => a > b,
|
|
||||||
Operator::LessThanEqualTo => a <= b,
|
|
||||||
Operator::GreaterThanEqualTo => a >= b,
|
|
||||||
Operator::EqualTo => a == b,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn string(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Operator::LessThan => "<",
|
|
||||||
Operator::GreaterThan => ">",
|
|
||||||
Operator::LessThanEqualTo => "<=",
|
|
||||||
Operator::GreaterThanEqualTo => ">=",
|
|
||||||
Operator::EqualTo => "==",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CellRules {
|
|
||||||
pub adjacent_type: i32,
|
|
||||||
pub into: i32,
|
|
||||||
pub operator: Operator,
|
|
||||||
pub n: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CellRules {
|
|
||||||
const fn new(adjacent_type: i32, into: i32, operator: Operator, n: i32) -> CellRules {
|
|
||||||
CellRules {
|
|
||||||
adjacent_type,
|
|
||||||
into,
|
|
||||||
operator,
|
|
||||||
n,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref CA: Vec<Vec<CellRules>> = vec![
|
|
||||||
vec![CellRules::new(1, 1, Operator::GreaterThanEqualTo, 4)],
|
|
||||||
vec![
|
|
||||||
CellRules::new(0, 0, Operator::GreaterThanEqualTo, 5),
|
|
||||||
CellRules::new(1, 0, Operator::LessThan, 2)
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
||||||
pub enum Direction {
|
|
||||||
NoDir = -1,
|
|
||||||
North = 0,
|
|
||||||
East = 1,
|
|
||||||
South = 2,
|
|
||||||
West = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Direction {
|
|
||||||
pub fn transform(&self) -> Point {
|
|
||||||
match self {
|
|
||||||
Direction::NoDir => unreachable!("Direction::NoDir should never be transformed"),
|
|
||||||
Direction::North => Point::new(0, -1),
|
|
||||||
Direction::East => Point::new(1, 0),
|
|
||||||
Direction::South => Point::new(0, 1),
|
|
||||||
Direction::West => Point::new(-1, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn opposite_dir(&self) -> Direction {
|
|
||||||
match self {
|
|
||||||
Direction::NoDir => unreachable!("Direction::NoDir has no opposite."),
|
|
||||||
Direction::North => Direction::South,
|
|
||||||
Direction::East => Direction::West,
|
|
||||||
Direction::South => Direction::North,
|
|
||||||
Direction::West => Direction::East,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DirectionIterator {
|
|
||||||
current: Direction,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DirectionIterator {
|
|
||||||
pub fn new() -> DirectionIterator {
|
|
||||||
DirectionIterator {
|
|
||||||
current: Direction::North,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for DirectionIterator {
|
|
||||||
type Item = Direction;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
use Direction::*;
|
|
||||||
let next_direction = match self.current {
|
|
||||||
North => East,
|
|
||||||
East => South,
|
|
||||||
South => West,
|
|
||||||
West => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
NoDir => unreachable!("Direction::NoDir should never be iterated over."),
|
|
||||||
};
|
|
||||||
self.current = next_direction;
|
|
||||||
Some(next_direction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,397 +0,0 @@
|
||||||
use super::{ BuilderMap, Map, InitialMapBuilder, TileType, Point };
|
|
||||||
use bracket_lib::prelude::*;
|
|
||||||
|
|
||||||
mod consts;
|
|
||||||
use consts::*;
|
|
||||||
|
|
||||||
/// Room Accretion map builder.
|
|
||||||
pub struct RoomAccretionBuilder {}
|
|
||||||
|
|
||||||
impl InitialMapBuilder for RoomAccretionBuilder {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
|
||||||
self.build(rng, build_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RoomAccretionBuilder {
|
|
||||||
/// Constructor for Room Accretion.
|
|
||||||
pub fn new() -> Box<RoomAccretionBuilder> {
|
|
||||||
Box::new(RoomAccretionBuilder {})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
|
||||||
accrete_rooms(rng, build_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn grid_with_dimensions(h: usize, w: usize, value: i32) -> Vec<Vec<i32>> {
|
|
||||||
vec![vec![value; w]; h]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn in_bounds(row: i32, col: i32, build_data: &BuilderMap) -> bool {
|
|
||||||
row > 0 && row < build_data.height && col > 0 && col < build_data.width
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_continuous_shape_on_grid(
|
|
||||||
room: &Vec<Vec<i32>>,
|
|
||||||
top_offset: usize,
|
|
||||||
left_offset: usize,
|
|
||||||
grid: &mut Vec<Vec<i32>>
|
|
||||||
) {
|
|
||||||
for row in 0..room.len() {
|
|
||||||
for col in 0..room[0].len() {
|
|
||||||
if room[row][col] != 0 {
|
|
||||||
let target_row = row + top_offset;
|
|
||||||
let target_col = col + left_offset;
|
|
||||||
if target_row < grid.len() && target_col < grid[0].len() {
|
|
||||||
grid[target_row][target_col] = room[row][col];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Coordinate {
|
|
||||||
pub location: Point,
|
|
||||||
pub value: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_individual_coordinates_on_grid(coordinates: &Vec<Coordinate>, grid: &mut Vec<Vec<i32>>) {
|
|
||||||
for c in coordinates {
|
|
||||||
let x = c.location.x as usize;
|
|
||||||
let y = c.location.y as usize;
|
|
||||||
if y < grid.len() && x < grid[0].len() {
|
|
||||||
grid[y][x] = c.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cell_neighbours(
|
|
||||||
cells: &Vec<Vec<i32>>,
|
|
||||||
row: usize,
|
|
||||||
col: usize,
|
|
||||||
h: usize,
|
|
||||||
w: usize
|
|
||||||
) -> Vec<i32> {
|
|
||||||
let mut neighbours = Vec::new();
|
|
||||||
for x in row.saturating_sub(1)..=std::cmp::min(row + 1, h - 1) {
|
|
||||||
for y in col.saturating_sub(1)..=std::cmp::min(col + 1, w - 1) {
|
|
||||||
if x != row || y != col {
|
|
||||||
neighbours.push(cells[x][y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console::log(&format!("neighbours: {:?}", neighbours));
|
|
||||||
neighbours
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_ca_room(rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) -> Vec<Vec<i32>> {
|
|
||||||
let width = rng.range(5, 12);
|
|
||||||
let height = rng.range(5, 12);
|
|
||||||
let mut cells = grid_with_dimensions(height, width, 0);
|
|
||||||
cells = cells
|
|
||||||
.into_iter()
|
|
||||||
.map(|row| {
|
|
||||||
row.into_iter()
|
|
||||||
.map(|_| if rng.roll_dice(1, 2) == 1 { 1 } else { 0 })
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let transform_cell = |state: i32, neighbours: &Vec<i32>| -> i32 {
|
|
||||||
let rules: &[CellRules] = &CA[state as usize];
|
|
||||||
let mut new_state = state;
|
|
||||||
for rule in rules {
|
|
||||||
let n_neighbours = neighbours
|
|
||||||
.iter()
|
|
||||||
.filter(|&&neighbour| neighbour == rule.adjacent_type)
|
|
||||||
.count();
|
|
||||||
if rule.operator.eval(n_neighbours as i32, rule.n) {
|
|
||||||
new_state = rule.into;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_state
|
|
||||||
};
|
|
||||||
|
|
||||||
for _ in 0..5 {
|
|
||||||
let mut new_cells = vec![vec![0; width]; height];
|
|
||||||
for row in 0..height {
|
|
||||||
for col in 0..width {
|
|
||||||
let neighbours = get_cell_neighbours(&cells, row, col, height, width);
|
|
||||||
let new_state = transform_cell(cells[row][col], &neighbours);
|
|
||||||
new_cells[row][col] = new_state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cells = new_cells;
|
|
||||||
}
|
|
||||||
// TODO: Floodfill to keep largest contiguous blob
|
|
||||||
cells
|
|
||||||
}
|
|
||||||
|
|
||||||
fn room_fits_at(
|
|
||||||
hyperspace: Vec<Vec<i32>>,
|
|
||||||
top_offset: usize,
|
|
||||||
left_offset: usize,
|
|
||||||
build_data: &BuilderMap
|
|
||||||
) -> bool {
|
|
||||||
let mut x_dungeon: usize;
|
|
||||||
let mut y_dungeon: usize;
|
|
||||||
for y in 0..HEIGHT {
|
|
||||||
for x in 0..WIDTH {
|
|
||||||
if hyperspace[y][x] != 2 {
|
|
||||||
y_dungeon = y + top_offset;
|
|
||||||
x_dungeon = x + left_offset;
|
|
||||||
for i in y_dungeon.saturating_sub(1)..=std::cmp::min(y_dungeon + 1, WIDTH - 1) {
|
|
||||||
for j in x_dungeon.saturating_sub(1)..=std::cmp::min(
|
|
||||||
x_dungeon + 1,
|
|
||||||
HEIGHT - 1
|
|
||||||
) {
|
|
||||||
let pt = build_data.map.xy_idx(i as i32, j as i32);
|
|
||||||
if
|
|
||||||
!in_bounds(i as i32, j as i32, &build_data) ||
|
|
||||||
!(build_data.map.tiles[pt] == TileType::Wall) ||
|
|
||||||
build_data.spawn_list.contains(&(pt, "door".to_string()))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn direction_of_door(
|
|
||||||
grid: &Vec<Vec<i32>>,
|
|
||||||
row: usize,
|
|
||||||
col: usize,
|
|
||||||
build_data: &BuilderMap
|
|
||||||
) -> Direction {
|
|
||||||
if grid[row][col] != 0 {
|
|
||||||
return Direction::NoDir;
|
|
||||||
}
|
|
||||||
let mut solution = Direction::NoDir;
|
|
||||||
let mut dir_iter = DirectionIterator::new();
|
|
||||||
for dir in &mut dir_iter {
|
|
||||||
let new_col = (col as i32) + dir.transform().x;
|
|
||||||
let new_row = (row as i32) + dir.transform().y;
|
|
||||||
let opp_col = (col as i32) - dir.transform().x;
|
|
||||||
let opp_row = (row as i32) - dir.transform().y;
|
|
||||||
if
|
|
||||||
in_bounds(new_row, new_col, &build_data) &&
|
|
||||||
in_bounds(opp_row, opp_col, &build_data) &&
|
|
||||||
grid[opp_row as usize][opp_col as usize] != 0
|
|
||||||
{
|
|
||||||
solution = dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return solution;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
||||||
pub struct DoorSite {
|
|
||||||
pub x: i32,
|
|
||||||
pub y: i32,
|
|
||||||
pub dir: Direction,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn choose_random_door_site(
|
|
||||||
room: Vec<Vec<i32>>,
|
|
||||||
rng: &mut RandomNumberGenerator,
|
|
||||||
build_data: &BuilderMap
|
|
||||||
) -> Vec<Option<DoorSite>> {
|
|
||||||
let mut grid = grid_with_dimensions(HEIGHT, WIDTH, 0);
|
|
||||||
let mut door_sites: Vec<DoorSite> = Vec::new();
|
|
||||||
const LEFT_OFFSET: usize = ((WIDTH as f32) / 2.0) as usize;
|
|
||||||
const TOP_OFFSET: usize = ((HEIGHT as f32) / 2.0) as usize;
|
|
||||||
draw_continuous_shape_on_grid(&room, TOP_OFFSET, LEFT_OFFSET, &mut grid);
|
|
||||||
for row in 0..HEIGHT {
|
|
||||||
for col in 0..WIDTH {
|
|
||||||
if grid[row][col] == 0 {
|
|
||||||
let door_dir = direction_of_door(&grid, row, col, &build_data);
|
|
||||||
if door_dir == Direction::NoDir {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut door_failed = false;
|
|
||||||
let (mut trace_row, mut trace_col) = (
|
|
||||||
(row as i32) + door_dir.transform().y,
|
|
||||||
(col as i32) + door_dir.transform().x,
|
|
||||||
);
|
|
||||||
let mut i = 0;
|
|
||||||
while i < 10 && in_bounds(trace_row, trace_col, &build_data) && !door_failed {
|
|
||||||
if grid[trace_row as usize][trace_col as usize] != 0 {
|
|
||||||
door_failed = true;
|
|
||||||
}
|
|
||||||
trace_col += door_dir.transform().x;
|
|
||||||
trace_row += door_dir.transform().y;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
if !door_failed {
|
|
||||||
// May need more information here.
|
|
||||||
door_sites.push(DoorSite {
|
|
||||||
x: col as i32,
|
|
||||||
y: row as i32,
|
|
||||||
dir: door_dir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut chosen_doors: Vec<Option<DoorSite>> = vec![None; 4];
|
|
||||||
let mut dir_iter = DirectionIterator::new();
|
|
||||||
for dir in &mut dir_iter {
|
|
||||||
let doors_facing_this_dir: Vec<&DoorSite> = door_sites
|
|
||||||
.iter()
|
|
||||||
.filter(|&door| door.dir == dir)
|
|
||||||
.collect();
|
|
||||||
if !doors_facing_this_dir.is_empty() {
|
|
||||||
let index = rng.range(0, doors_facing_this_dir.len());
|
|
||||||
chosen_doors[dir as usize] = Some(*doors_facing_this_dir[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chosen_doors
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shuffle<T>(list: &mut Vec<T>, rng: &mut RandomNumberGenerator) {
|
|
||||||
let len = list.len();
|
|
||||||
for i in (1..len).rev() {
|
|
||||||
let j = rng.range(0, i + 1);
|
|
||||||
list.swap(i, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clamp<T: Ord>(x: T, min: T, max: T) -> T {
|
|
||||||
if x < min { min } else if x > max { max } else { x }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn attach_hallway_to(
|
|
||||||
door_sites: &mut Vec<Option<DoorSite>>,
|
|
||||||
hyperspace: &mut Vec<Vec<i32>>,
|
|
||||||
rng: &mut RandomNumberGenerator,
|
|
||||||
build_data: &BuilderMap
|
|
||||||
) {
|
|
||||||
let mut directions = vec![Direction::North, Direction::East, Direction::South, Direction::West];
|
|
||||||
shuffle(&mut directions, rng);
|
|
||||||
let mut hallway_dir: Direction = Direction::NoDir;
|
|
||||||
for i in 0..4 {
|
|
||||||
hallway_dir = directions[i];
|
|
||||||
if
|
|
||||||
door_sites[hallway_dir as usize].is_some() &&
|
|
||||||
in_bounds(
|
|
||||||
door_sites[hallway_dir as usize].unwrap().y +
|
|
||||||
hallway_dir.transform().y * VERTICAL_CORRIDOR_MAX_LENGTH,
|
|
||||||
door_sites[hallway_dir as usize].unwrap().x +
|
|
||||||
hallway_dir.transform().x * HORIZONTAL_CORRIDOR_MAX_LENGTH,
|
|
||||||
&build_data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let transform = hallway_dir.transform();
|
|
||||||
let hallway_len: i32 = match hallway_dir {
|
|
||||||
Direction::NoDir => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Direction::North | Direction::South =>
|
|
||||||
rng.range(VERTICAL_CORRIDOR_MIN_LENGTH, VERTICAL_CORRIDOR_MAX_LENGTH + 1),
|
|
||||||
Direction::East | Direction::West =>
|
|
||||||
rng.range(HORIZONTAL_CORRIDOR_MIN_LENGTH, HORIZONTAL_CORRIDOR_MAX_LENGTH + 1),
|
|
||||||
};
|
|
||||||
let mut x = door_sites[hallway_dir as usize].unwrap().x;
|
|
||||||
let mut y = door_sites[hallway_dir as usize].unwrap().y;
|
|
||||||
for _i in 0..hallway_len {
|
|
||||||
if in_bounds(y, x, &build_data) {
|
|
||||||
hyperspace[y as usize][x as usize] = 1; // Dig out corridor.
|
|
||||||
}
|
|
||||||
x += transform.x;
|
|
||||||
y += transform.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
y = clamp(y - transform.y, 0, (HEIGHT as i32) - 1);
|
|
||||||
x = clamp(x - transform.x, 0, (WIDTH as i32) - 1);
|
|
||||||
|
|
||||||
let mut dir_iter = DirectionIterator::new();
|
|
||||||
for dir in &mut dir_iter {
|
|
||||||
if dir != hallway_dir.opposite_dir() {
|
|
||||||
let door_y = y + dir.transform().y;
|
|
||||||
let door_x = x + dir.transform().x;
|
|
||||||
door_sites[dir as usize] = Some(DoorSite {
|
|
||||||
x: door_x,
|
|
||||||
y: door_y,
|
|
||||||
dir,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
door_sites[dir as usize] = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console::log(&format!("door_sites: {:?}", door_sites));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn design_room_in_hyperspace(
|
|
||||||
rng: &mut RandomNumberGenerator,
|
|
||||||
build_data: &mut BuilderMap
|
|
||||||
) -> Vec<Vec<i32>> {
|
|
||||||
// Project onto hyperspace
|
|
||||||
let mut hyperspace = grid_with_dimensions(HEIGHT, WIDTH, 0);
|
|
||||||
let room_type = rng.range(0, 1);
|
|
||||||
let room = match room_type {
|
|
||||||
0 => make_ca_room(rng, build_data),
|
|
||||||
_ => unreachable!("Invalid room type."),
|
|
||||||
};
|
|
||||||
draw_continuous_shape_on_grid(&room, HEIGHT / 2, WIDTH / 2, &mut hyperspace);
|
|
||||||
let mut door_sites = choose_random_door_site(room, rng, &build_data);
|
|
||||||
let roll: f32 = rng.rand();
|
|
||||||
if roll < HALLWAY_CHANCE {
|
|
||||||
attach_hallway_to(&mut door_sites, &mut hyperspace, rng, &build_data);
|
|
||||||
}
|
|
||||||
let coords: Vec<Coordinate> = door_sites
|
|
||||||
.iter()
|
|
||||||
.filter(|&door| door.is_some())
|
|
||||||
.map(|&door| Coordinate {
|
|
||||||
location: Point::new(door.unwrap().x, door.unwrap().y),
|
|
||||||
value: 2,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
draw_individual_coordinates_on_grid(&coords, &mut hyperspace);
|
|
||||||
hyperspace
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_i32_to_tiletype(val: i32, build_data: &mut BuilderMap) -> TileType {
|
|
||||||
match val {
|
|
||||||
0 => TileType::Wall,
|
|
||||||
1 => TileType::Floor,
|
|
||||||
2 => TileType::Floor, // With door.
|
|
||||||
_ => unreachable!("Unknown TileType"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flatten_hyperspace_into_dungeon(
|
|
||||||
hyperspace: Vec<Vec<i32>>,
|
|
||||||
build_data: &mut BuilderMap
|
|
||||||
) -> Vec<TileType> {
|
|
||||||
let flattened_hyperspace: Vec<i32> = hyperspace.into_iter().flatten().collect();
|
|
||||||
flattened_hyperspace
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, cell)| {
|
|
||||||
if cell != 0 {
|
|
||||||
match cell {
|
|
||||||
2 => build_data.spawn_list.push((idx, "door".to_string())),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
map_i32_to_tiletype(cell, build_data)
|
|
||||||
} else {
|
|
||||||
build_data.map.tiles[idx % (build_data.map.width as usize)]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn accrete_rooms(rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
|
||||||
let hyperspace = design_room_in_hyperspace(rng, build_data);
|
|
||||||
build_data.map.tiles = flatten_hyperspace_into_dungeon(hyperspace, build_data);
|
|
||||||
build_data.take_snapshot();
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue