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 door_placement;
|
||||
mod drunkard;
|
||||
mod dwarf_fort;
|
||||
mod forest;
|
||||
mod limestone_cavern;
|
||||
mod maze;
|
||||
@ -43,6 +44,7 @@ use distant_exit::DistantExit;
|
||||
use dla::DLABuilder;
|
||||
use door_placement::DoorPlacement;
|
||||
use drunkard::DrunkardsWalkBuilder;
|
||||
use dwarf_fort::*;
|
||||
use forest::forest_builder;
|
||||
use limestone_cavern::{
|
||||
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),
|
||||
4 => limestone_deep_cavern_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),
|
||||
}
|
||||
}
|
||||
|
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 crate::raws::{spawn_type_by_name, RawMaster, SpawnTableType};
|
||||
|
||||
pub struct RandomEntry {
|
||||
name: String,
|
||||
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)]
|
||||
pub struct RandomTable {
|
||||
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 {
|
||||
self.total_weight += weight;
|
||||
self.entries.push(RandomEntry::new(name, weight));
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn roll(&self, rng: &mut RandomNumberGenerator) -> String {
|
||||
|
@ -8,7 +8,7 @@ use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
use crate::components::*;
|
||||
use crate::gamesystem::{mana_at_level, npc_hp};
|
||||
use crate::map::MasterDungeonMap;
|
||||
use crate::random_table::RandomTable;
|
||||
use crate::random_table::{MasterTable, RandomTable};
|
||||
use crate::raws::{Raws, Reaction, RAWS};
|
||||
|
||||
pub fn parse_dice_string(dice: &str) -> (i32, i32, i32) {
|
||||
@ -755,6 +755,22 @@ pub fn spawn_named_entity(
|
||||
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> {
|
||||
if raws.spell_index.contains_key(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
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
.collect();
|
||||
|
||||
let mut rt = RandomTable::new();
|
||||
let mut rt = MasterTable::new();
|
||||
for e in available_options.iter() {
|
||||
let mut weight = e.weight;
|
||||
if e.add_map_depth_to_weight.is_some() {
|
||||
weight += depth;
|
||||
}
|
||||
rt = rt.add(e.name.clone(), weight);
|
||||
rt.add(e.name.clone(), weight, raws);
|
||||
}
|
||||
|
||||
rt
|
||||
@ -806,7 +822,7 @@ pub fn get_item_drop(
|
||||
let mut rt = RandomTable::new();
|
||||
let available_options = &raws.raws.loot_tables[raws.loot_index[table]];
|
||||
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));
|
||||
|
@ -5,7 +5,7 @@ use ::specs::prelude::*;
|
||||
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
|
||||
use crate::components::*;
|
||||
use crate::random_table::RandomTable;
|
||||
use crate::random_table::MasterTable;
|
||||
use crate::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;
|
||||
|
||||
fn room_table(map_depth: i32) -> RandomTable {
|
||||
fn room_table(map_depth: i32) -> MasterTable {
|
||||
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};
|
||||
|
||||
/// 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
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
|
Loading…
Reference in New Issue
Block a user