atomises rooms and corridors
- room sorter - rounding room corners - dogleg and bsp corridors - room exploder
This commit is contained in:
parent
b7b2061228
commit
2ceb20a822
9 changed files with 411 additions and 59 deletions
|
|
@ -50,14 +50,14 @@ pub fn delete_the_dead(ecs: &mut World) {
|
|||
.append("The")
|
||||
.npc_name(&victim_name.name)
|
||||
.colour(rltk::WHITE)
|
||||
.append("was destroyed!")
|
||||
.append("is destroyed!")
|
||||
.log();
|
||||
} else {
|
||||
gamelog::Logger::new()
|
||||
.append("The")
|
||||
.npc_name(&victim_name.name)
|
||||
.colour(rltk::WHITE)
|
||||
.append("died!")
|
||||
.append("dies!")
|
||||
.log();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,20 +42,6 @@ impl BspDungeonBuilder {
|
|||
n_rooms += 1;
|
||||
}
|
||||
|
||||
// Now we sort the rooms
|
||||
rooms.sort_by(|a, b| a.x1.cmp(&b.x1));
|
||||
|
||||
// Now we want corridors
|
||||
for i in 0..rooms.len() - 1 {
|
||||
let room = rooms[i];
|
||||
let next_room = rooms[i + 1];
|
||||
let start_x = room.x1 + (rng.roll_dice(1, i32::abs(room.x1 - room.x2)) - 1);
|
||||
let start_y = room.y1 + (rng.roll_dice(1, i32::abs(room.y1 - room.y2)) - 1);
|
||||
let end_x = next_room.x1 + (rng.roll_dice(1, i32::abs(next_room.x1 - next_room.x2)) - 1);
|
||||
let end_y = next_room.y1 + (rng.roll_dice(1, i32::abs(next_room.y1 - next_room.y2)) - 1);
|
||||
draw_corridor(&mut build_data.map, start_x, start_y, end_x, end_y);
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
build_data.rooms = Some(rooms);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use drunkard::DrunkardsWalkBuilder;
|
|||
mod maze;
|
||||
use maze::MazeBuilder;
|
||||
mod simple_map;
|
||||
use simple_map::SimpleMapBuilder;
|
||||
mod voronoi;
|
||||
use voronoi::VoronoiBuilder;
|
||||
mod prefab_builder;
|
||||
|
|
@ -35,6 +36,16 @@ use common::*;
|
|||
use specs::prelude::*;
|
||||
use voronoi_spawning::VoronoiSpawning;
|
||||
use wfc::WaveFunctionCollapseBuilder;
|
||||
mod room_exploder;
|
||||
use room_exploder::RoomExploder;
|
||||
mod room_corner_rounding;
|
||||
use room_corner_rounding::RoomCornerRounder;
|
||||
mod rooms_corridors_dogleg;
|
||||
use rooms_corridors_dogleg::DoglegCorridors;
|
||||
mod rooms_corridors_bsp;
|
||||
use rooms_corridors_bsp::BspCorridors;
|
||||
mod room_sorter;
|
||||
use room_sorter::{RoomSort, RoomSorter};
|
||||
|
||||
// Shared data to be passed around build chain
|
||||
pub struct BuilderMap {
|
||||
|
|
@ -119,38 +130,139 @@ pub trait MetaMapBuilder {
|
|||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap);
|
||||
}
|
||||
|
||||
fn random_initial_builder(rng: &mut rltk::RandomNumberGenerator) -> (Box<dyn InitialMapBuilder>, bool) {
|
||||
let builder = rng.roll_dice(1, 17);
|
||||
let result: (Box<dyn InitialMapBuilder>, bool);
|
||||
match builder {
|
||||
1 => result = (BspDungeonBuilder::new(), true),
|
||||
2 => result = (BspInteriorBuilder::new(), true),
|
||||
3 => result = (CellularAutomataBuilder::new(), false),
|
||||
4 => result = (DrunkardsWalkBuilder::open_area(), false),
|
||||
5 => result = (DrunkardsWalkBuilder::open_halls(), false),
|
||||
6 => result = (DrunkardsWalkBuilder::winding_passages(), false),
|
||||
7 => result = (DrunkardsWalkBuilder::fat_passages(), false),
|
||||
8 => result = (DrunkardsWalkBuilder::fearful_symmetry(), false),
|
||||
9 => result = (MazeBuilder::new(), false),
|
||||
10 => result = (DLABuilder::walk_inwards(), false),
|
||||
11 => result = (DLABuilder::walk_outwards(), false),
|
||||
12 => result = (DLABuilder::central_attractor(), false),
|
||||
13 => result = (DLABuilder::insectoid(), false),
|
||||
14 => result = (VoronoiBuilder::pythagoras(), false),
|
||||
15 => result = (VoronoiBuilder::manhattan(), false),
|
||||
16 => result = (PrefabBuilder::constant(prefab_builder::prefab_levels::WFC_POPULATED), false),
|
||||
_ => result = (simple_map::SimpleMapBuilder::new(), true),
|
||||
fn random_start_position(rng: &mut rltk::RandomNumberGenerator) -> (XStart, YStart) {
|
||||
let x;
|
||||
let xroll = rng.roll_dice(1, 3);
|
||||
match xroll {
|
||||
1 => x = XStart::LEFT,
|
||||
2 => x = XStart::CENTRE,
|
||||
_ => x = XStart::RIGHT,
|
||||
}
|
||||
result
|
||||
|
||||
let y;
|
||||
let yroll = rng.roll_dice(1, 3);
|
||||
match yroll {
|
||||
1 => y = YStart::BOTTOM,
|
||||
2 => y = YStart::CENTRE,
|
||||
_ => y = YStart::TOP,
|
||||
}
|
||||
|
||||
(x, y)
|
||||
}
|
||||
|
||||
fn random_room_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut BuilderChain) {
|
||||
let build_roll = rng.roll_dice(1, 3);
|
||||
// Start with a room builder.
|
||||
match build_roll {
|
||||
1 => builder.start_with(SimpleMapBuilder::new()),
|
||||
2 => builder.start_with(BspDungeonBuilder::new()),
|
||||
_ => builder.start_with(BspInteriorBuilder::new()),
|
||||
}
|
||||
|
||||
// BspInterior makes its own doorways. If we're not using that one,
|
||||
// select a sorting method, a type of corridor, and modifiers.
|
||||
if build_roll != 3 {
|
||||
// Sort by one of the 5 available algorithms
|
||||
let sort_roll = rng.roll_dice(1, 5);
|
||||
match sort_roll {
|
||||
1 => builder.with(RoomSorter::new(RoomSort::LEFTMOST)),
|
||||
2 => builder.with(RoomSorter::new(RoomSort::RIGHTMOST)),
|
||||
3 => builder.with(RoomSorter::new(RoomSort::TOPMOST)),
|
||||
4 => builder.with(RoomSorter::new(RoomSort::BOTTOMMOST)),
|
||||
_ => builder.with(RoomSorter::new(RoomSort::CENTRAL)),
|
||||
}
|
||||
|
||||
let corridor_roll = rng.roll_dice(1, 2);
|
||||
match corridor_roll {
|
||||
1 => builder.with(DoglegCorridors::new()),
|
||||
_ => builder.with(BspCorridors::new()),
|
||||
}
|
||||
|
||||
let modifier_roll = rng.roll_dice(1, 6);
|
||||
match modifier_roll {
|
||||
1 => builder.with(RoomExploder::new()),
|
||||
2 => builder.with(RoomCornerRounder::new()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a starting position, in a room or elsewhere.
|
||||
let start_roll = rng.roll_dice(1, 2);
|
||||
match start_roll {
|
||||
1 => builder.with(RoomBasedStartingPosition::new()),
|
||||
_ => {
|
||||
let (start_x, start_y) = random_start_position(rng);
|
||||
builder.with(AreaStartingPosition::new(start_x, start_y));
|
||||
}
|
||||
}
|
||||
|
||||
// Decide where to put the exit - in a room or far away, anywhere.
|
||||
let exit_roll = rng.roll_dice(1, 2);
|
||||
match exit_roll {
|
||||
1 => builder.with(RoomBasedStairs::new()),
|
||||
_ => builder.with(DistantExit::new()),
|
||||
}
|
||||
|
||||
// Decide whether to spawn entities only in rooms, or with voronoi noise.
|
||||
let spawn_roll = rng.roll_dice(1, 2);
|
||||
match spawn_roll {
|
||||
1 => builder.with(RoomBasedSpawner::new()),
|
||||
_ => builder.with(VoronoiSpawning::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn random_shape_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut BuilderChain) {
|
||||
// Pick an initial builder
|
||||
let builder_roll = rng.roll_dice(1, 16);
|
||||
match builder_roll {
|
||||
1 => builder.start_with(CellularAutomataBuilder::new()),
|
||||
2 => builder.start_with(DrunkardsWalkBuilder::open_area()),
|
||||
3 => builder.start_with(DrunkardsWalkBuilder::open_halls()),
|
||||
4 => builder.start_with(DrunkardsWalkBuilder::winding_passages()),
|
||||
5 => builder.start_with(DrunkardsWalkBuilder::fat_passages()),
|
||||
6 => builder.start_with(DrunkardsWalkBuilder::fearful_symmetry()),
|
||||
7 => builder.start_with(MazeBuilder::new()),
|
||||
8 => builder.start_with(DLABuilder::walk_inwards()),
|
||||
9 => builder.start_with(DLABuilder::walk_outwards()),
|
||||
10 => builder.start_with(DLABuilder::central_attractor()),
|
||||
11 => builder.start_with(DLABuilder::insectoid()),
|
||||
12 => builder.start_with(VoronoiBuilder::pythagoras()),
|
||||
13 => builder.start_with(VoronoiBuilder::manhattan()),
|
||||
_ => builder.start_with(PrefabBuilder::constant(prefab_builder::prefab_levels::WFC_POPULATED)),
|
||||
}
|
||||
|
||||
// 'Select' the centre by placing a starting position, and cull everywhere unreachable.
|
||||
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
||||
builder.with(CullUnreachable::new());
|
||||
|
||||
// Now set the start to a random spot in our remaining area.
|
||||
let (start_x, start_y) = random_start_position(rng);
|
||||
builder.with(AreaStartingPosition::new(start_x, start_y));
|
||||
|
||||
// Place the exit and spawn mobs
|
||||
builder.with(VoronoiSpawning::new());
|
||||
builder.with(DistantExit::new());
|
||||
}
|
||||
|
||||
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator) -> BuilderChain {
|
||||
let mut builder = BuilderChain::new(new_depth);
|
||||
builder.start_with(simple_map::SimpleMapBuilder::new());
|
||||
builder.with(DLABuilder::heavy_erosion());
|
||||
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
||||
builder.with(CullUnreachable::new());
|
||||
builder.with(VoronoiSpawning::new());
|
||||
builder.with(DistantExit::new());
|
||||
let type_roll = rng.roll_dice(1, 2);
|
||||
match type_roll {
|
||||
1 => random_room_builder(rng, &mut builder),
|
||||
_ => random_shape_builder(rng, &mut builder),
|
||||
}
|
||||
|
||||
/* WFC needs some fixes.
|
||||
if rng.roll_dice(1, 3) == 1 {
|
||||
builder.with(WaveFunctionCollapseBuilder::new());
|
||||
}
|
||||
*/
|
||||
|
||||
if rng.roll_dice(1, 20) == 1 {
|
||||
builder.with(PrefabBuilder::sectional(prefab_builder::prefab_sections::UNDERGROUND_FORT));
|
||||
}
|
||||
|
||||
builder.with(PrefabBuilder::vaults());
|
||||
|
||||
builder
|
||||
}
|
||||
|
|
|
|||
57
src/map_builders/room_corner_rounding.rs
Normal file
57
src/map_builders/room_corner_rounding.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
use super::{BuilderMap, MetaMapBuilder, Rect, TileType};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct RoomCornerRounder {}
|
||||
|
||||
impl MetaMapBuilder for RoomCornerRounder {
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.build(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl RoomCornerRounder {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<RoomCornerRounder> {
|
||||
return Box::new(RoomCornerRounder {});
|
||||
}
|
||||
|
||||
fn fill_if_corner(&mut self, x: i32, y: i32, build_data: &mut BuilderMap) {
|
||||
let w = build_data.map.width;
|
||||
let h = build_data.map.height;
|
||||
let idx = build_data.map.xy_idx(x, y);
|
||||
let mut neighbour_walls = 0;
|
||||
if x > 0 && build_data.map.tiles[idx - 1] == TileType::Wall {
|
||||
neighbour_walls += 1;
|
||||
}
|
||||
if y > 0 && build_data.map.tiles[idx - w as usize] == TileType::Wall {
|
||||
neighbour_walls += 1;
|
||||
}
|
||||
if x < w - 2 && build_data.map.tiles[idx + 1] == TileType::Wall {
|
||||
neighbour_walls += 1;
|
||||
}
|
||||
if y < h - 2 && build_data.map.tiles[idx + w as usize] == TileType::Wall {
|
||||
neighbour_walls += 1;
|
||||
}
|
||||
if neighbour_walls == 2 {
|
||||
build_data.map.tiles[idx] = TileType::Wall;
|
||||
}
|
||||
}
|
||||
|
||||
fn build(&mut self, _rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
let rooms: Vec<Rect>;
|
||||
if let Some(rooms_builder) = &build_data.rooms {
|
||||
rooms = rooms_builder.clone();
|
||||
} else {
|
||||
panic!("RoomCornerRounding requires a builder with rooms.");
|
||||
}
|
||||
|
||||
for room in rooms.iter() {
|
||||
self.fill_if_corner(room.x1 + 1, room.y1 + 1, build_data);
|
||||
self.fill_if_corner(room.x2, room.y1 + 1, build_data);
|
||||
self.fill_if_corner(room.x1 + 1, room.y2, build_data);
|
||||
self.fill_if_corner(room.x2, room.y2, build_data);
|
||||
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/map_builders/room_exploder.rs
Normal file
82
src/map_builders/room_exploder.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
use super::{paint, BuilderMap, MetaMapBuilder, Rect, Symmetry, TileType};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct RoomExploder {}
|
||||
|
||||
impl MetaMapBuilder for RoomExploder {
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.build(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl RoomExploder {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<RoomExploder> {
|
||||
return Box::new(RoomExploder {});
|
||||
}
|
||||
|
||||
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
let rooms: Vec<Rect>;
|
||||
if let Some(rooms_builder) = &build_data.rooms {
|
||||
rooms = rooms_builder.clone();
|
||||
} else {
|
||||
panic!("RoomExploder requires a builder with rooms.");
|
||||
}
|
||||
for room in rooms.iter() {
|
||||
let start = room.centre();
|
||||
let n_diggers = rng.roll_dice(1, 20) - 5;
|
||||
if n_diggers > 0 {
|
||||
for _i in 0..n_diggers {
|
||||
let mut drunk_x = start.0;
|
||||
let mut drunk_y = start.1;
|
||||
let mut drunk_life = 20;
|
||||
let mut did_something = false;
|
||||
|
||||
while drunk_life > 0 {
|
||||
let drunk_idx = build_data.map.xy_idx(drunk_x, drunk_y);
|
||||
if build_data.map.tiles[drunk_idx] == TileType::Wall {
|
||||
did_something = true;
|
||||
}
|
||||
paint(&mut build_data.map, Symmetry::None, 1, drunk_x, drunk_y);
|
||||
build_data.map.tiles[drunk_idx] = TileType::DownStair;
|
||||
|
||||
let stagger_direction = rng.roll_dice(1, 4);
|
||||
match stagger_direction {
|
||||
1 => {
|
||||
if drunk_x > 2 {
|
||||
drunk_x -= 1;
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
if drunk_x < build_data.map.width - 2 {
|
||||
drunk_x += 1;
|
||||
}
|
||||
}
|
||||
3 => {
|
||||
if drunk_y > 2 {
|
||||
drunk_y -= 1;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if drunk_y < build_data.map.height - 2 {
|
||||
drunk_y += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drunk_life -= 1;
|
||||
}
|
||||
if did_something {
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
|
||||
for t in build_data.map.tiles.iter_mut() {
|
||||
if *t == TileType::DownStair {
|
||||
*t = TileType::Floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/map_builders/room_sorter.rs
Normal file
47
src/map_builders/room_sorter.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use super::{BuilderMap, MetaMapBuilder, Rect};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub enum RoomSort {
|
||||
LEFTMOST,
|
||||
RIGHTMOST,
|
||||
TOPMOST,
|
||||
BOTTOMMOST,
|
||||
CENTRAL,
|
||||
}
|
||||
|
||||
pub struct RoomSorter {
|
||||
sort_by: RoomSort,
|
||||
}
|
||||
|
||||
impl MetaMapBuilder for RoomSorter {
|
||||
#[allow(dead_code)]
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.sorter(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl RoomSorter {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(sort_by: RoomSort) -> Box<RoomSorter> {
|
||||
return Box::new(RoomSorter { sort_by });
|
||||
}
|
||||
|
||||
fn sorter(&mut self, _rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
match self.sort_by {
|
||||
RoomSort::LEFTMOST => build_data.rooms.as_mut().unwrap().sort_by(|a, b| a.x1.cmp(&b.x1)),
|
||||
RoomSort::RIGHTMOST => build_data.rooms.as_mut().unwrap().sort_by(|a, b| b.x2.cmp(&a.x2)),
|
||||
RoomSort::TOPMOST => build_data.rooms.as_mut().unwrap().sort_by(|a, b| a.y1.cmp(&b.y1)),
|
||||
RoomSort::BOTTOMMOST => build_data.rooms.as_mut().unwrap().sort_by(|a, b| b.y2.cmp(&a.y2)),
|
||||
RoomSort::CENTRAL => {
|
||||
let map_centre = rltk::Point::new(build_data.map.width / 2, build_data.map.height / 2);
|
||||
build_data.rooms.as_mut().unwrap().sort_by(|a: &Rect, b: &Rect| {
|
||||
let a_centre_pt = rltk::Point::new(a.centre().0, a.centre().1);
|
||||
let b_centre_pt = rltk::Point::new(b.centre().0, b.centre().1);
|
||||
let distance_a = rltk::DistanceAlg::Pythagoras.distance2d(a_centre_pt, map_centre);
|
||||
let distance_b = rltk::DistanceAlg::Pythagoras.distance2d(b_centre_pt, map_centre);
|
||||
return distance_a.partial_cmp(&distance_b).unwrap();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/map_builders/rooms_corridors_bsp.rs
Normal file
38
src/map_builders/rooms_corridors_bsp.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use super::{draw_corridor, BuilderMap, MetaMapBuilder, Rect};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct BspCorridors {}
|
||||
|
||||
impl MetaMapBuilder for BspCorridors {
|
||||
#[allow(dead_code)]
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.corridors(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl BspCorridors {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<BspCorridors> {
|
||||
Box::new(BspCorridors {})
|
||||
}
|
||||
|
||||
fn corridors(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
let rooms: Vec<Rect>;
|
||||
if let Some(rooms_builder) = &build_data.rooms {
|
||||
rooms = rooms_builder.clone();
|
||||
} else {
|
||||
panic!("BSP Corridors require a builder with room structures");
|
||||
}
|
||||
|
||||
for i in 0..rooms.len() - 1 {
|
||||
let room = rooms[i];
|
||||
let next_room = rooms[i + 1];
|
||||
let start_x = room.x1 + (rng.roll_dice(1, i32::abs(room.x1 - room.x2)) - 1);
|
||||
let start_y = room.y1 + (rng.roll_dice(1, i32::abs(room.y1 - room.y2)) - 1);
|
||||
let end_x = next_room.x1 + (rng.roll_dice(1, i32::abs(next_room.x1 - next_room.x2)) - 1);
|
||||
let end_y = next_room.y1 + (rng.roll_dice(1, i32::abs(next_room.y1 - next_room.y2)) - 1);
|
||||
draw_corridor(&mut build_data.map, start_x, start_y, end_x, end_y);
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/map_builders/rooms_corridors_dogleg.rs
Normal file
42
src/map_builders/rooms_corridors_dogleg.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use super::{apply_horizontal_tunnel, apply_vertical_tunnel, BuilderMap, MetaMapBuilder, Rect};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct DoglegCorridors {}
|
||||
|
||||
impl MetaMapBuilder for DoglegCorridors {
|
||||
#[allow(dead_code)]
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.corridors(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl DoglegCorridors {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<DoglegCorridors> {
|
||||
Box::new(DoglegCorridors {})
|
||||
}
|
||||
|
||||
fn corridors(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
let rooms: Vec<Rect>;
|
||||
if let Some(rooms_builder) = &build_data.rooms {
|
||||
rooms = rooms_builder.clone();
|
||||
} else {
|
||||
panic!("DoglegCorridors require a builder with rooms.");
|
||||
}
|
||||
|
||||
for (i, room) in rooms.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let (new_x, new_y) = room.centre();
|
||||
let (prev_x, prev_y) = rooms[i as usize - 1].centre();
|
||||
if rng.range(0, 2) == 1 {
|
||||
apply_horizontal_tunnel(&mut build_data.map, prev_x, new_x, prev_y);
|
||||
apply_vertical_tunnel(&mut build_data.map, prev_y, new_y, new_x);
|
||||
} else {
|
||||
apply_vertical_tunnel(&mut build_data.map, prev_y, new_y, prev_x);
|
||||
apply_horizontal_tunnel(&mut build_data.map, prev_x, new_x, new_y);
|
||||
}
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use super::{apply_horizontal_tunnel, apply_room_to_map, apply_vertical_tunnel, BuilderMap, InitialMapBuilder, Rect};
|
||||
use super::{apply_room_to_map, apply_vertical_tunnel, BuilderMap, InitialMapBuilder, Rect};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
pub struct SimpleMapBuilder {}
|
||||
|
|
@ -6,7 +6,7 @@ pub struct SimpleMapBuilder {}
|
|||
impl InitialMapBuilder for SimpleMapBuilder {
|
||||
#[allow(dead_code)]
|
||||
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
self.rooms_and_corridors(rng, build_data);
|
||||
self.build_rooms(rng, build_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ impl SimpleMapBuilder {
|
|||
Box::new(SimpleMapBuilder {})
|
||||
}
|
||||
|
||||
fn rooms_and_corridors(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
fn build_rooms(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||
const MAX_ROOMS: i32 = 30;
|
||||
const MIN_SIZE: i32 = 6;
|
||||
const MAX_SIZE: i32 = 10;
|
||||
|
|
@ -38,18 +38,6 @@ impl SimpleMapBuilder {
|
|||
apply_room_to_map(&mut build_data.map, &new_room);
|
||||
build_data.take_snapshot();
|
||||
|
||||
if !rooms.is_empty() {
|
||||
let (new_x, new_y) = new_room.centre();
|
||||
let (prev_x, prev_y) = rooms[rooms.len() - 1].centre();
|
||||
if rng.range(0, 2) == 1 {
|
||||
apply_horizontal_tunnel(&mut build_data.map, prev_x, new_x, prev_y);
|
||||
apply_vertical_tunnel(&mut build_data.map, prev_y, new_y, new_x);
|
||||
} else {
|
||||
apply_vertical_tunnel(&mut build_data.map, prev_y, new_y, prev_x);
|
||||
apply_horizontal_tunnel(&mut build_data.map, prev_x, new_x, new_y);
|
||||
}
|
||||
}
|
||||
|
||||
rooms.push(new_room);
|
||||
build_data.take_snapshot();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue