Implement map builder for level 5
This commit is contained in:
parent
e71c391f3a
commit
9e85abb29b
@ -5,6 +5,14 @@ use crate::colors;
|
|||||||
|
|
||||||
pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
|
pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
|
||||||
let (glyph, mut fg, mut bg) = match map.depth {
|
let (glyph, mut fg, mut bg) = match map.depth {
|
||||||
|
5 => {
|
||||||
|
let x = idx as i32 % map.width;
|
||||||
|
if x < map.width / 2 {
|
||||||
|
get_limestone_cavern_glyph(idx, map)
|
||||||
|
} else {
|
||||||
|
get_tile_glyph_default(idx, map)
|
||||||
|
}
|
||||||
|
}
|
||||||
3 | 4 => get_limestone_cavern_glyph(idx, map),
|
3 | 4 => get_limestone_cavern_glyph(idx, map),
|
||||||
2 => get_forest_glyph(idx, map),
|
2 => get_forest_glyph(idx, map),
|
||||||
_ => get_tile_glyph_default(idx, map),
|
_ => get_tile_glyph_default(idx, map),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mod area_ending_point;
|
||||||
mod area_starting_points;
|
mod area_starting_points;
|
||||||
mod bsp_dungeon;
|
mod bsp_dungeon;
|
||||||
mod bsp_interior;
|
mod bsp_interior;
|
||||||
@ -32,6 +33,7 @@ mod waveform_collapse;
|
|||||||
|
|
||||||
use ::rltk::RandomNumberGenerator;
|
use ::rltk::RandomNumberGenerator;
|
||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
use area_ending_point::{AreaEndingPosition, XEnd, YEnd};
|
||||||
use area_starting_points::{AreaStartingPosition, XStart, YStart};
|
use area_starting_points::{AreaStartingPosition, XStart, YStart};
|
||||||
use bsp_dungeon::BspDungeonBuilder;
|
use bsp_dungeon::BspDungeonBuilder;
|
||||||
use bsp_interior::BspInteriorBuilder;
|
use bsp_interior::BspInteriorBuilder;
|
||||||
@ -42,7 +44,9 @@ use dla::DLABuilder;
|
|||||||
use door_placement::DoorPlacement;
|
use door_placement::DoorPlacement;
|
||||||
use drunkard::DrunkardsWalkBuilder;
|
use drunkard::DrunkardsWalkBuilder;
|
||||||
use forest::forest_builder;
|
use forest::forest_builder;
|
||||||
use limestone_cavern::{limestone_cavern_builder, limestone_deep_cavern_builder};
|
use limestone_cavern::{
|
||||||
|
limestone_cavern_builder, limestone_deep_cavern_builder, limestone_transition_builder,
|
||||||
|
};
|
||||||
use maze::MazeBuilder;
|
use maze::MazeBuilder;
|
||||||
use prefab_builder::PrefabBuilder;
|
use prefab_builder::PrefabBuilder;
|
||||||
use room_based_spawner::RoomBasedSpawner;
|
use room_based_spawner::RoomBasedSpawner;
|
||||||
@ -349,6 +353,7 @@ pub fn level_builder(
|
|||||||
2 => forest_builder(new_depth, rng, width, height),
|
2 => forest_builder(new_depth, rng, width, height),
|
||||||
3 => limestone_cavern_builder(new_depth, rng, width, height),
|
3 => limestone_cavern_builder(new_depth, rng, width, height),
|
||||||
4 => limestone_deep_cavern_builder(new_depth, rng, width, height),
|
4 => limestone_deep_cavern_builder(new_depth, rng, width, height),
|
||||||
|
5 => limestone_transition_builder(new_depth, rng, width, height),
|
||||||
_ => random_builder(new_depth, rng, width, height),
|
_ => random_builder(new_depth, rng, width, height),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
src/map_builders/area_ending_point.rs
Normal file
73
src/map_builders/area_ending_point.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use ::rltk::{DistanceAlg, Point, RandomNumberGenerator};
|
||||||
|
|
||||||
|
use super::{BuilderMap, MetaMapBuilder};
|
||||||
|
use crate::{map, Map, TileType};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum XEnd {
|
||||||
|
Left,
|
||||||
|
Center,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum YEnd {
|
||||||
|
Top,
|
||||||
|
Center,
|
||||||
|
Bottom,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AreaEndingPosition {
|
||||||
|
x: XEnd,
|
||||||
|
y: YEnd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for AreaEndingPosition {
|
||||||
|
fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.build(rng, build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AreaEndingPosition {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new(x: XEnd, y: YEnd) -> Box<AreaEndingPosition> {
|
||||||
|
Box::new(AreaEndingPosition { x, y })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(&mut self, _rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
let seed_x = match self.x {
|
||||||
|
XEnd::Left => 1,
|
||||||
|
XEnd::Center => build_data.map.width / 2,
|
||||||
|
XEnd::Right => build_data.map.width - 2,
|
||||||
|
};
|
||||||
|
let seed_y = match self.y {
|
||||||
|
YEnd::Top => 1,
|
||||||
|
YEnd::Center => build_data.map.height / 2,
|
||||||
|
YEnd::Bottom => build_data.map.height - 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut available_floors: Vec<(usize, f32)> = Vec::new();
|
||||||
|
for (idx, tiletype) in build_data.map.tiles.iter().enumerate() {
|
||||||
|
if map::tile_walkable(*tiletype) {
|
||||||
|
available_floors.push((
|
||||||
|
idx,
|
||||||
|
DistanceAlg::PythagorasSquared.distance2d(
|
||||||
|
Point::new(
|
||||||
|
idx as i32 % build_data.map.width,
|
||||||
|
idx as i32 / build_data.map.width,
|
||||||
|
),
|
||||||
|
Point::new(seed_x, seed_y),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if available_floors.is_empty() {
|
||||||
|
panic!("No valid floors to start on");
|
||||||
|
}
|
||||||
|
|
||||||
|
available_floors.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap());
|
||||||
|
|
||||||
|
build_data.map.tiles[available_floors[0].0] = TileType::DownStairs;
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
use ::rltk::RandomNumberGenerator;
|
use ::rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AreaStartingPosition, BuilderChain, BuilderMap, CullUnreachable, DistantExit,
|
prefab_builder::prefab_sections, AreaEndingPosition, AreaStartingPosition, BspDungeonBuilder,
|
||||||
DrunkardsWalkBuilder, MetaMapBuilder, VoronoiSpawning, XStart, YStart,
|
BuilderChain, BuilderMap, CellularAutomataBuilder, CullUnreachable, DLABuilder, DistantExit,
|
||||||
|
DrunkardsWalkBuilder, MetaMapBuilder, NearestCorridors, PrefabBuilder, RoomBasedSpawner,
|
||||||
|
RoomDrawer, RoomExploder, RoomSort, RoomSorter, VoronoiSpawning, XEnd, XStart, YEnd, YStart,
|
||||||
};
|
};
|
||||||
use crate::map::TileType;
|
use crate::map::TileType;
|
||||||
use crate::map_builders::dla::DLABuilder;
|
|
||||||
use crate::map_builders::prefab_builder::{prefab_sections, PrefabBuilder};
|
|
||||||
|
|
||||||
pub fn limestone_cavern_builder(
|
pub fn limestone_cavern_builder(
|
||||||
new_depth: i32,
|
new_depth: i32,
|
||||||
@ -45,6 +45,28 @@ pub fn limestone_deep_cavern_builder(
|
|||||||
chain
|
chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn limestone_transition_builder(
|
||||||
|
new_depth: i32,
|
||||||
|
_rng: &mut RandomNumberGenerator,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
) -> BuilderChain {
|
||||||
|
let mut chain = BuilderChain::new(new_depth, width, height, "Dwarf Fort - Upper Reaches");
|
||||||
|
chain
|
||||||
|
.start_with(CellularAutomataBuilder::new())
|
||||||
|
.with(AreaStartingPosition::new(XStart::Center, YStart::Center))
|
||||||
|
.with(CullUnreachable::new())
|
||||||
|
.with(AreaStartingPosition::new(XStart::Left, YStart::Center))
|
||||||
|
.with(VoronoiSpawning::new())
|
||||||
|
.with(CaveDecorator::new())
|
||||||
|
.with(CaveTransition::new())
|
||||||
|
.with(AreaStartingPosition::new(XStart::Left, YStart::Center))
|
||||||
|
.with(CullUnreachable::new())
|
||||||
|
.with(AreaEndingPosition::new(XEnd::Right, YEnd::Center));
|
||||||
|
|
||||||
|
chain
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CaveDecorator {}
|
pub struct CaveDecorator {}
|
||||||
|
|
||||||
impl MetaMapBuilder for CaveDecorator {
|
impl MetaMapBuilder for CaveDecorator {
|
||||||
@ -105,3 +127,64 @@ impl CaveDecorator {
|
|||||||
build_data.map.outdoors = false;
|
build_data.map.outdoors = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CaveTransition {}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for CaveTransition {
|
||||||
|
fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.build(rng, build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CaveTransition {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new() -> Box<CaveTransition> {
|
||||||
|
Box::new(CaveTransition {})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
build_data.map.depth = 5;
|
||||||
|
build_data.take_snapshot();
|
||||||
|
|
||||||
|
// Build a BSP-based dungeon
|
||||||
|
let mut builder = BuilderChain::new(5, build_data.width, build_data.height, "New Map");
|
||||||
|
builder
|
||||||
|
.start_with(BspDungeonBuilder::new())
|
||||||
|
.with(RoomDrawer::new())
|
||||||
|
.with(RoomSorter::new(RoomSort::RightMost))
|
||||||
|
.with(NearestCorridors::new())
|
||||||
|
.with(RoomExploder::new())
|
||||||
|
.with(RoomBasedSpawner::new());
|
||||||
|
builder.build_map(rng);
|
||||||
|
|
||||||
|
// Add the history to our history
|
||||||
|
for h in builder.build_data.history.iter() {
|
||||||
|
build_data.history.push(h.clone());
|
||||||
|
}
|
||||||
|
build_data.take_snapshot();
|
||||||
|
|
||||||
|
// Copy the right half of the BSP map into our map
|
||||||
|
for x in build_data.map.width / 2..build_data.map.width {
|
||||||
|
for y in 0..build_data.map.height {
|
||||||
|
let idx = build_data.map.xy_idx(x, y);
|
||||||
|
build_data.map.tiles[idx] = builder.build_data.map.tiles[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build_data.take_snapshot();
|
||||||
|
|
||||||
|
// Keep Voronoi spawn data from the left half of the map
|
||||||
|
let w = build_data.map.width;
|
||||||
|
build_data.spawn_list.retain(|s| {
|
||||||
|
let x = s.0 as i32 / w;
|
||||||
|
x < w / 2
|
||||||
|
});
|
||||||
|
|
||||||
|
// Keep room spawn data from the right half of the map
|
||||||
|
for s in builder.build_data.spawn_list.iter() {
|
||||||
|
let x = s.0 as i32 / w;
|
||||||
|
if x < w / 2 {
|
||||||
|
build_data.spawn_list.push(s.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user