From 2ef1f3e1c8409563ddc4af23e7b97737293a367b Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 16 Dec 2021 14:26:50 -0500 Subject: [PATCH] Make map building random again, completes section 4.15 --- src/map_builders.rs | 179 ++++++++++++++++++++++---------- src/map_builders/bsp_dungeon.rs | 2 +- src/map_builders/dla.rs | 1 + src/map_builders/simple_map.rs | 4 +- 4 files changed, 125 insertions(+), 61 deletions(-) diff --git a/src/map_builders.rs b/src/map_builders.rs index 6b63ee7..e18e173 100644 --- a/src/map_builders.rs +++ b/src/map_builders.rs @@ -159,69 +159,134 @@ pub trait MetaMapBuilder { fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap); } -fn random_initial_builder(rng: &mut RandomNumberGenerator) -> (Box, bool) { - match rng.roll_dice(1, 17) { - 1 => (BspDungeonBuilder::new(), true), - 2 => (BspInteriorBuilder::new(), true), - 3 => (CellularAutomataBuilder::new(), false), - 4 => (DrunkardsWalkBuilder::open_area(), false), - 5 => (DrunkardsWalkBuilder::open_halls(), false), - 6 => (DrunkardsWalkBuilder::winding_passages(), false), - 7 => (DrunkardsWalkBuilder::fat_passages(), false), - 8 => (DrunkardsWalkBuilder::fearful_symmetry(), false), - 9 => (MazeBuilder::new(), false), - 10 => (DLABuilder::walk_inwards(), false), - 11 => (DLABuilder::walk_outwards(), false), - 12 => (DLABuilder::central_attractor(), false), - 13 => (DLABuilder::insectoid(), false), - 14 => (VoronoiCellBuilder::pythagoras(), false), - 15 => (VoronoiCellBuilder::manhattan(), false), - 16 => ( - PrefabBuilder::constant(prefab_builder::prefab_levels::WFC_POPULATED), - false, - ), - _ => (SimpleMapBuilder::new(), true), +fn random_start_position(rng: &mut rltk::RandomNumberGenerator) -> (XStart, YStart) { + let x = match rng.roll_dice(1, 3) { + 1 => XStart::Left, + 2 => XStart::Center, + _ => XStart::Right, + }; + + let y = match rng.roll_dice(1, 3) { + 1 => YStart::Bottom, + 2 => YStart::Center, + _ => YStart::Top, + }; + + (x, y) +} + +fn random_room_builder(rng: &mut RandomNumberGenerator, builder: &mut BuilderChain) { + let build_roll = rng.roll_dice(1, 3); + match build_roll { + 1 => builder.start_with(SimpleMapBuilder::new()), + 2 => builder.start_with(BspDungeonBuilder::new()), + _ => builder.start_with(BspInteriorBuilder::new()), + }; + + // BSP Interior still makes holes in the walls + if build_roll != 3 { + // Sort by one of the 5 available algorithms + let room_sort = match rng.roll_dice(1, 5) { + 1 => RoomSort::LeftMost, + 2 => RoomSort::RightMost, + 3 => RoomSort::TopMost, + 4 => RoomSort::BottomMost, + _ => RoomSort::Central, + }; + builder.with(RoomSorter::new(room_sort)); + + // Pick a corridor type + match rng.roll_dice(1, 2) { + 1 => builder.with(DoglegCorridors::new()), + _ => builder.with(BspCorridors::new()), + }; + + // Add additional modifier + match rng.roll_dice(1, 6) { + 1 => { + builder.with(RoomExploder::new()); + } + 2 => { + builder.with(RoomCornerRounder::new()); + } + _ => {} + }; } + + // Find a starting position + match rng.roll_dice(1, 2) { + 1 => builder.with(RoomBasedStartingPosition::new()), + _ => { + let (start_x, start_y) = random_start_position(rng); + builder.with(AreaStartingPosition::new(start_x, start_y)) + } + }; + + // Find an exit + match rng.roll_dice(1, 2) { + 1 => builder.with(RoomBasedStairs::new()), + _ => builder.with(DistantExit::new()), + }; + + // Spawn stuff + match rng.roll_dice(1, 2) { + 1 => builder.with(RoomBasedSpawner::new()), + _ => builder.with(VoronoiSpawning::new()), + }; +} + +fn random_shape_builder(rng: &mut RandomNumberGenerator, builder: &mut BuilderChain) { + let first_builder: Box = match rng.roll_dice(1, 16) { + 1 => CellularAutomataBuilder::new(), + 2 => DrunkardsWalkBuilder::open_area(), + 3 => DrunkardsWalkBuilder::open_halls(), + 4 => DrunkardsWalkBuilder::winding_passages(), + 5 => DrunkardsWalkBuilder::fat_passages(), + 6 => DrunkardsWalkBuilder::fearful_symmetry(), + 7 => MazeBuilder::new(), + 8 => DLABuilder::walk_inwards(), + 9 => DLABuilder::walk_outwards(), + 10 => DLABuilder::central_attractor(), + 11 => DLABuilder::insectoid(), + 12 => VoronoiCellBuilder::pythagoras(), + 13 => VoronoiCellBuilder::manhattan(), + _ => PrefabBuilder::constant(prefab_builder::prefab_levels::WFC_POPULATED), + }; + + // Set the start to the center and cull + builder + .start_with(first_builder) + .with(AreaStartingPosition::new(XStart::Center, YStart::Center)) + .with(CullUnreachable::new()); + + // Now set the start ot a random starting area + let (start_x, start_y) = random_start_position(rng); + builder.with(AreaStartingPosition::new(start_x, start_y)); + + // Setup an exit and spawn mobs + builder.with(VoronoiSpawning::new()); + builder.with(DistantExit::new()); } pub fn random_builder(new_depth: i32, rng: &mut RandomNumberGenerator) -> BuilderChain { let mut builder = BuilderChain::new(new_depth); - // let (random_starter, has_rooms) = random_initial_builder(rng); - // builder.start_with(random_starter); - // - // if has_rooms { - // builder - // .with(RoomBasedSpawner::new()) - // .with(RoomBasedStairs::new()) - // .with(RoomBasedStartingPosition::new()); - // } else { - // builder - // .with(AreaStartingPosition::new(XStart::Center, YStart::Center)) - // .with(CullUnreachable::new()) - // .with(VoronoiSpawning::new()) - // .with(DistantExit::new()); - // } - // - // if rng.roll_dice(1, 3) == 1 { - // builder.with(WaveformCollapseBuilder::new()); - // } - // - // if rng.roll_dice(1, 20) == 1 { - // builder.with(PrefabBuilder::sectional( - // prefab_builder::prefab_sections::UNDERGROUND_FORT, - // )); - // } - // - // builder.with(PrefabBuilder::vaults()); - builder - .start_with(BspDungeonBuilder::new()) - .with(RoomSorter::new(RoomSort::Central)) - .with(BspCorridors::new()) - .with(AreaStartingPosition::new(XStart::Center, YStart::Center)) - .with(CullUnreachable::new()) - .with(VoronoiSpawning::new()) - .with(DistantExit::new()); + match rng.roll_dice(1, 2) { + 1 => random_room_builder(rng, &mut builder), + _ => random_shape_builder(rng, &mut builder), + }; + + if rng.roll_dice(1, 3) == 1 { + builder.with(WaveformCollapseBuilder::new()); + } + + if rng.roll_dice(1, 20) == 1 { + builder.with(PrefabBuilder::sectional( + prefab_builder::prefab_sections::UNDERGROUND_FORT, + )); + } + + builder.with(PrefabBuilder::vaults()); builder } diff --git a/src/map_builders/bsp_dungeon.rs b/src/map_builders/bsp_dungeon.rs index 2d689c7..023912d 100644 --- a/src/map_builders/bsp_dungeon.rs +++ b/src/map_builders/bsp_dungeon.rs @@ -1,6 +1,6 @@ use rltk::RandomNumberGenerator; -use crate::map_builders::common::{apply_room_to_map, draw_corridor}; +use crate::map_builders::common::apply_room_to_map; use crate::map_builders::{BuilderMap, InitialMapBuilder}; use crate::{Map, Rect, TileType}; diff --git a/src/map_builders/dla.rs b/src/map_builders/dla.rs index ecbba47..4e33b1b 100644 --- a/src/map_builders/dla.rs +++ b/src/map_builders/dla.rs @@ -72,6 +72,7 @@ impl DLABuilder { }) } + #[allow(dead_code)] pub fn heavy_erosion() -> Box { Box::new(DLABuilder { algorithm: DLAAlgorithm::WalkInwards, diff --git a/src/map_builders/simple_map.rs b/src/map_builders/simple_map.rs index ee9e174..c15c029 100644 --- a/src/map_builders/simple_map.rs +++ b/src/map_builders/simple_map.rs @@ -1,8 +1,6 @@ use rltk::RandomNumberGenerator; -use crate::map_builders::common::{ - apply_horizontal_tunnel, apply_room_to_map, apply_vertical_tunnel, -}; +use crate::map_builders::common::apply_room_to_map; use crate::map_builders::{BuilderMap, InitialMapBuilder}; use crate::Rect;