Update random spawning, and create next dungeon level
This commit is contained in:
parent
2df20956bb
commit
3b62fd9c20
@ -9,6 +9,7 @@ mod distant_exit;
|
|||||||
mod dla;
|
mod dla;
|
||||||
mod door_placement;
|
mod door_placement;
|
||||||
mod drunkard;
|
mod drunkard;
|
||||||
|
mod dwarf_fort;
|
||||||
mod forest;
|
mod forest;
|
||||||
mod limestone_cavern;
|
mod limestone_cavern;
|
||||||
mod maze;
|
mod maze;
|
||||||
@ -43,6 +44,7 @@ use distant_exit::DistantExit;
|
|||||||
use dla::DLABuilder;
|
use dla::DLABuilder;
|
||||||
use door_placement::DoorPlacement;
|
use door_placement::DoorPlacement;
|
||||||
use drunkard::DrunkardsWalkBuilder;
|
use drunkard::DrunkardsWalkBuilder;
|
||||||
|
use dwarf_fort::*;
|
||||||
use forest::forest_builder;
|
use forest::forest_builder;
|
||||||
use limestone_cavern::{
|
use limestone_cavern::{
|
||||||
limestone_cavern_builder, limestone_deep_cavern_builder, limestone_transition_builder,
|
limestone_cavern_builder, limestone_deep_cavern_builder, limestone_transition_builder,
|
||||||
@ -354,6 +356,7 @@ pub fn level_builder(
|
|||||||
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),
|
5 => limestone_transition_builder(new_depth, rng, width, height),
|
||||||
|
6 => dwarf_fort_builder(new_depth, rng, width, height),
|
||||||
_ => random_builder(new_depth, rng, width, height),
|
_ => random_builder(new_depth, rng, width, height),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
69
src/map_builders/dwarf_fort.rs
Normal file
69
src/map_builders/dwarf_fort.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
use ::rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
AreaEndingPosition, AreaStartingPosition, BspCorridors, BspDungeonBuilder, BuilderChain,
|
||||||
|
BuilderMap, CorridorSpawner, CullUnreachable, DLABuilder, DistantExit, MetaMapBuilder,
|
||||||
|
RoomDrawer, RoomSort, RoomSorter, VoronoiSpawning, XEnd, XStart, YEnd, YStart,
|
||||||
|
};
|
||||||
|
use crate::TileType;
|
||||||
|
|
||||||
|
pub fn dwarf_fort_builder(
|
||||||
|
new_depth: i32,
|
||||||
|
_rng: &mut RandomNumberGenerator,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
) -> BuilderChain {
|
||||||
|
let mut chain = BuilderChain::new(new_depth, width, height, "Dwarven Fortress");
|
||||||
|
chain
|
||||||
|
.start_with(BspDungeonBuilder::new())
|
||||||
|
.with(RoomSorter::new(RoomSort::Central))
|
||||||
|
.with(RoomDrawer::new())
|
||||||
|
.with(BspCorridors::new())
|
||||||
|
.with(CorridorSpawner::new())
|
||||||
|
.with(DragonsLair::new())
|
||||||
|
.with(AreaStartingPosition::new(XStart::Left, YStart::Top))
|
||||||
|
.with(CullUnreachable::new())
|
||||||
|
.with(AreaEndingPosition::new(XEnd::Right, YEnd::Bottom))
|
||||||
|
.with(VoronoiSpawning::new())
|
||||||
|
.with(DistantExit::new());
|
||||||
|
|
||||||
|
chain
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DragonsLair {}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for DragonsLair {
|
||||||
|
fn build_map(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.build(rng, build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DragonsLair {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn new() -> Box<DragonsLair> {
|
||||||
|
Box::new(DragonsLair {})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
build_data.map.depth = 7;
|
||||||
|
build_data.take_snapshot();
|
||||||
|
|
||||||
|
let mut builder = BuilderChain::new(6, build_data.width, build_data.height, "New Map");
|
||||||
|
builder.start_with(DLABuilder::insectoid());
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Merge the maps
|
||||||
|
for (idx, tt) in build_data.map.tiles.iter_mut().enumerate() {
|
||||||
|
if *tt == TileType::Wall && builder.build_data.map.tiles[idx] == TileType::Floor {
|
||||||
|
*tt = TileType::Floor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build_data.take_snapshot();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
use ::rltk::RandomNumberGenerator;
|
use ::rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
|
use crate::raws::{spawn_type_by_name, RawMaster, SpawnTableType};
|
||||||
|
|
||||||
pub struct RandomEntry {
|
pub struct RandomEntry {
|
||||||
name: String,
|
name: String,
|
||||||
weight: i32,
|
weight: i32,
|
||||||
@ -14,6 +16,41 @@ impl RandomEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct MasterTable {
|
||||||
|
items: RandomTable,
|
||||||
|
mobs: RandomTable,
|
||||||
|
props: RandomTable,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MasterTable {
|
||||||
|
pub fn new() -> MasterTable {
|
||||||
|
MasterTable {
|
||||||
|
items: RandomTable::new(),
|
||||||
|
mobs: RandomTable::new(),
|
||||||
|
props: RandomTable::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add<S: ToString>(&mut self, name: S, weight: i32, raws: &RawMaster) {
|
||||||
|
match spawn_type_by_name(raws, &name.to_string()) {
|
||||||
|
SpawnTableType::Item => self.items.add(name, weight),
|
||||||
|
SpawnTableType::Mob => self.mobs.add(name, weight),
|
||||||
|
SpawnTableType::Prop => self.props.add(name, weight),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn roll(&self, rng: &mut RandomNumberGenerator) -> String {
|
||||||
|
let roll = rng.roll_dice(1, 4);
|
||||||
|
match roll {
|
||||||
|
1 => self.items.roll(rng),
|
||||||
|
2 => self.props.roll(rng),
|
||||||
|
3 => self.mobs.roll(rng),
|
||||||
|
_ => "None".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RandomTable {
|
pub struct RandomTable {
|
||||||
entries: Vec<RandomEntry>,
|
entries: Vec<RandomEntry>,
|
||||||
@ -28,13 +65,11 @@ impl RandomTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add<S: ToString>(mut self, name: S, weight: i32) -> Self {
|
pub fn add<S: ToString>(&mut self, name: S, weight: i32) {
|
||||||
if weight > 0 {
|
if weight > 0 {
|
||||||
self.total_weight += weight;
|
self.total_weight += weight;
|
||||||
self.entries.push(RandomEntry::new(name, weight));
|
self.entries.push(RandomEntry::new(name, weight));
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roll(&self, rng: &mut RandomNumberGenerator) -> String {
|
pub fn roll(&self, rng: &mut RandomNumberGenerator) -> String {
|
||||||
|
@ -8,7 +8,7 @@ use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
|||||||
use crate::components::*;
|
use crate::components::*;
|
||||||
use crate::gamesystem::{mana_at_level, npc_hp};
|
use crate::gamesystem::{mana_at_level, npc_hp};
|
||||||
use crate::map::MasterDungeonMap;
|
use crate::map::MasterDungeonMap;
|
||||||
use crate::random_table::RandomTable;
|
use crate::random_table::{MasterTable, RandomTable};
|
||||||
use crate::raws::{Raws, Reaction, RAWS};
|
use crate::raws::{Raws, Reaction, RAWS};
|
||||||
|
|
||||||
pub fn parse_dice_string(dice: &str) -> (i32, i32, i32) {
|
pub fn parse_dice_string(dice: &str) -> (i32, i32, i32) {
|
||||||
@ -755,6 +755,22 @@ pub fn spawn_named_entity(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum SpawnTableType {
|
||||||
|
Item,
|
||||||
|
Mob,
|
||||||
|
Prop,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_type_by_name(raws: &RawMaster, key: &str) -> SpawnTableType {
|
||||||
|
if raws.item_index.contains_key(key) {
|
||||||
|
SpawnTableType::Item
|
||||||
|
} else if raws.mob_index.contains_key(key) {
|
||||||
|
SpawnTableType::Mob
|
||||||
|
} else {
|
||||||
|
SpawnTableType::Prop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn_named_spell(raws: &RawMaster, ecs: &mut World, key: &str) -> Option<Entity> {
|
pub fn spawn_named_spell(raws: &RawMaster, ecs: &mut World, key: &str) -> Option<Entity> {
|
||||||
if raws.spell_index.contains_key(key) {
|
if raws.spell_index.contains_key(key) {
|
||||||
let spell_template = &raws.raws.spells[raws.spell_index[key]];
|
let spell_template = &raws.raws.spells[raws.spell_index[key]];
|
||||||
@ -775,7 +791,7 @@ pub fn spawn_named_spell(raws: &RawMaster, ecs: &mut World, key: &str) -> Option
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_spawn_table_for_depth(raws: &RawMaster, depth: i32) -> RandomTable {
|
pub fn get_spawn_table_for_depth(raws: &RawMaster, depth: i32) -> MasterTable {
|
||||||
use super::SpawnTableEntry;
|
use super::SpawnTableEntry;
|
||||||
|
|
||||||
let available_options: Vec<&SpawnTableEntry> = raws
|
let available_options: Vec<&SpawnTableEntry> = raws
|
||||||
@ -785,13 +801,13 @@ pub fn get_spawn_table_for_depth(raws: &RawMaster, depth: i32) -> RandomTable {
|
|||||||
.filter(|a| depth >= a.min_depth && depth <= a.max_depth)
|
.filter(|a| depth >= a.min_depth && depth <= a.max_depth)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut rt = RandomTable::new();
|
let mut rt = MasterTable::new();
|
||||||
for e in available_options.iter() {
|
for e in available_options.iter() {
|
||||||
let mut weight = e.weight;
|
let mut weight = e.weight;
|
||||||
if e.add_map_depth_to_weight.is_some() {
|
if e.add_map_depth_to_weight.is_some() {
|
||||||
weight += depth;
|
weight += depth;
|
||||||
}
|
}
|
||||||
rt = rt.add(e.name.clone(), weight);
|
rt.add(e.name.clone(), weight, raws);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt
|
rt
|
||||||
@ -806,7 +822,7 @@ pub fn get_item_drop(
|
|||||||
let mut rt = RandomTable::new();
|
let mut rt = RandomTable::new();
|
||||||
let available_options = &raws.raws.loot_tables[raws.loot_index[table]];
|
let available_options = &raws.raws.loot_tables[raws.loot_index[table]];
|
||||||
for item in available_options.drops.iter() {
|
for item in available_options.drops.iter() {
|
||||||
rt = rt.add(item.name.clone(), item.weight);
|
rt.add(item.name.clone(), item.weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(rt.roll(rng));
|
return Some(rt.roll(rng));
|
||||||
|
@ -5,7 +5,7 @@ use ::specs::prelude::*;
|
|||||||
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||||
|
|
||||||
use crate::components::*;
|
use crate::components::*;
|
||||||
use crate::random_table::RandomTable;
|
use crate::random_table::MasterTable;
|
||||||
use crate::raws::{
|
use crate::raws::{
|
||||||
get_spawn_table_for_depth, spawn_all_spells, spawn_named_entity, SpawnType, RAWS,
|
get_spawn_table_for_depth, spawn_all_spells, spawn_named_entity, SpawnType, RAWS,
|
||||||
};
|
};
|
||||||
@ -70,7 +70,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||||||
|
|
||||||
const MAX_MONSTERS: i32 = 4;
|
const MAX_MONSTERS: i32 = 4;
|
||||||
|
|
||||||
fn room_table(map_depth: i32) -> RandomTable {
|
fn room_table(map_depth: i32) -> MasterTable {
|
||||||
get_spawn_table_for_depth(&RAWS.lock().unwrap(), map_depth)
|
get_spawn_table_for_depth(&RAWS.lock().unwrap(), map_depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ use crate::visibility_system::VisibilitySystem;
|
|||||||
use crate::{ai, camera, damage_system, effects, saveload_system, spawner};
|
use crate::{ai, camera, damage_system, effects, saveload_system, spawner};
|
||||||
|
|
||||||
/// Whether to show a visual representation of map generation
|
/// Whether to show a visual representation of map generation
|
||||||
pub const SHOW_MAPGEN_VISUALIZER: bool = false;
|
pub const SHOW_MAPGEN_VISUALIZER: bool = true;
|
||||||
|
|
||||||
/// The main actions possible with a vendor
|
/// The main actions possible with a vendor
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
Loading…
Reference in New Issue
Block a user