Add limestone cavern map builder

This commit is contained in:
Timothy Warren 2022-01-10 09:57:59 -05:00
parent 902f71f57c
commit 5c34390bc9
4 changed files with 119 additions and 1 deletions

View File

@ -4,6 +4,7 @@ use super::{Map, TileType};
pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let (glyph, mut fg, mut bg) = match map.depth {
3 => get_limestone_cavern_glyph(idx, map),
2 => get_forest_glyph(idx, map),
_ => get_tile_glyph_default(idx, map),
};
@ -20,6 +21,27 @@ pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
(glyph, fg, bg)
}
fn get_limestone_cavern_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let bg = RGB::from_f32(0., 0., 0.);
let (glyph, fg) = match map.tiles[idx] {
TileType::Wall => (to_cp437('▒'), RGB::from_f32(0.7, 0.7, 0.7)),
TileType::Bridge => (to_cp437('.'), RGB::named(rltk::CHOCOLATE)),
TileType::Road => (to_cp437('≡'), RGB::named(rltk::YELLOW)),
TileType::Grass => (to_cp437('"'), RGB::named(rltk::GREEN)),
TileType::ShallowWater => (to_cp437('░'), RGB::named(rltk::CYAN)),
TileType::DeepWater => (to_cp437('▓'), RGB::named(rltk::BLUE)),
TileType::Gravel => (to_cp437(';'), RGB::from_f32(0.5, 0.5, 0.5)),
TileType::DownStairs => (to_cp437('>'), RGB::from_f32(0., 1.0, 1.0)),
TileType::UpStairs => (to_cp437('<'), RGB::from_f32(0., 1.0, 1.0)),
TileType::Stalactite => (to_cp437('╨'), RGB::from_f32(0.5, 0.5, 0.5)),
TileType::Stalagmite => (to_cp437('╥'), RGB::from_f32(0.5, 0.5, 0.5)),
_ => (to_cp437('░'), RGB::from_f32(0.4, 0.4, 0.4)),
};
(glyph, fg, bg)
}
fn get_forest_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let bg = RGB::from_f32(0., 0., 0.);
@ -58,6 +80,8 @@ fn get_tile_glyph_default(idx: usize, map: &Map) -> (rltk::FontCharType, RGB, RG
TileType::DeepWater => (to_cp437('~'), RGB::named(rltk::NAVY_BLUE)),
TileType::Gravel => (to_cp437(';'), RGB::named(rltk::GRAY)),
TileType::UpStairs => (to_cp437('<'), RGB::from_f32(0., 1.0, 1.0)),
TileType::Stalactite => (to_cp437('╨'), RGB::from_f32(0.5, 0.5, 0.5)),
TileType::Stalagmite => (to_cp437('╥'), RGB::from_f32(0.5, 0.5, 0.5)),
};
if map.bloodstains.contains(&idx) {

View File

@ -13,6 +13,8 @@ pub enum TileType {
Bridge,
Gravel,
UpStairs,
Stalactite,
Stalagmite,
}
pub fn tile_walkable(tt: TileType) -> bool {
@ -31,7 +33,10 @@ pub fn tile_walkable(tt: TileType) -> bool {
}
pub fn tile_opaque(tt: TileType) -> bool {
matches!(tt, TileType::Wall)
matches!(
tt,
TileType::Wall | TileType::Stalactite | TileType::Stalagmite
)
}
pub fn tile_cost(tt: TileType) -> f32 {

View File

@ -9,6 +9,7 @@ mod dla;
mod door_placement;
mod drunkard;
mod forest;
mod limestone_cavern;
mod maze;
mod prefab_builder;
mod room_based_spawner;
@ -41,6 +42,7 @@ use dla::DLABuilder;
use door_placement::DoorPlacement;
use drunkard::DrunkardsWalkBuilder;
use forest::forest_builder;
use limestone_cavern::limestone_cavern_builder;
use maze::MazeBuilder;
use prefab_builder::PrefabBuilder;
use room_based_spawner::RoomBasedSpawner;
@ -345,6 +347,7 @@ pub fn level_builder(
match new_depth {
1 => town_builder(new_depth, rng, width, height),
2 => forest_builder(new_depth, rng, width, height),
3 => limestone_cavern_builder(new_depth, rng, width, height),
_ => random_builder(new_depth, rng, width, height),
}
}

View File

@ -0,0 +1,86 @@
use ::rltk::RandomNumberGenerator;
use super::{
AreaStartingPosition, BuilderChain, BuilderMap, CullUnreachable, DistantExit,
DrunkardsWalkBuilder, MetaMapBuilder, VoronoiSpawning, XStart, YStart,
};
use crate::map::{self, TileType};
pub fn limestone_cavern_builder(
new_depth: i32,
_rng: &mut RandomNumberGenerator,
width: i32,
height: i32,
) -> BuilderChain {
let mut chain = BuilderChain::new(new_depth, width, height, "Limestone Caverns");
chain
.start_with(DrunkardsWalkBuilder::winding_passages())
.with(AreaStartingPosition::new(XStart::Center, YStart::Center))
.with(CullUnreachable::new())
.with(AreaStartingPosition::new(XStart::Left, YStart::Center))
.with(VoronoiSpawning::new())
.with(DistantExit::new())
.with(CaveDecorator::new());
chain
}
pub struct CaveDecorator {}
impl MetaMapBuilder for CaveDecorator {
fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
self.build(rng, build_data);
}
}
impl CaveDecorator {
#[allow(dead_code)]
pub fn new() -> Box<CaveDecorator> {
Box::new(CaveDecorator {})
}
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
let old_map = build_data.map.clone();
for (idx, tt) in build_data.map.tiles.iter_mut().enumerate() {
// Gravel Spawning
if *tt == TileType::Floor && rng.roll_dice(1, 6) == 1 {
*tt = TileType::Gravel;
} else if *tt == TileType::Floor && rng.roll_dice(1, 10) == 1 {
// Spawn passable pools
*tt = TileType::ShallowWater;
} else if *tt == TileType::Wall {
// Spawn deep pools and stalactites
let mut neighbors = 0;
let x = idx as i32 % old_map.width;
let y = idx as i32 / old_map.width;
if x > 0 && old_map.tiles[idx - 1] == TileType::Wall {
neighbors += 1;
}
if x < old_map.width - 2 && old_map.tiles[idx + 1] == TileType::Wall {
neighbors += 1
}
if y > 0 && old_map.tiles[idx - old_map.width as usize] == TileType::Wall {
neighbors += 1
}
if y < old_map.height - 2
&& old_map.tiles[idx + old_map.width as usize] == TileType::Wall
{
neighbors += 1
}
if neighbors == 2 {
*tt = TileType::DeepWater;
} else if neighbors == 1 {
*tt = match rng.roll_dice(1, 4) {
1 => TileType::Stalactite,
2 => TileType::Stalagmite,
_ => *tt,
}
}
}
}
build_data.take_snapshot();
}
}