From c1222294d0719747d780ad4e2f6d17cad2f8eca1 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 23 Dec 2021 13:07:50 -0500 Subject: [PATCH] Move the spawn table to raws --- src/raws.rs | 3 ++ src/raws/rawmaster.rs | 58 +++++++++++++++++++++++++++++++-- src/raws/spawn_table_structs.rs | 12 +++++++ src/spawner.rs | 17 ++-------- 4 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 src/raws/spawn_table_structs.rs diff --git a/src/raws.rs b/src/raws.rs index 8adab0f..f567cc3 100644 --- a/src/raws.rs +++ b/src/raws.rs @@ -2,6 +2,7 @@ mod item_structs; mod mob_structs; mod prop_structs; mod rawmaster; +mod spawn_table_structs; use std::sync::Mutex; @@ -10,12 +11,14 @@ use mob_structs::*; use prop_structs::*; pub use rawmaster::*; use serde::Deserialize; +use spawn_table_structs::*; #[derive(Deserialize, Debug)] pub struct Raws { pub items: Vec, pub mobs: Vec, pub props: Vec, + pub spawn_table: Vec, } rltk::embedded_resource!(RAW_FILE, "../raws/spawns.json"); diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index ceb50df..a925595 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -1,8 +1,9 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use specs::prelude::*; use crate::components::*; +use crate::random_table::RandomTable; use crate::raws::Raws; pub enum SpawnType { @@ -23,6 +24,7 @@ impl RawMaster { items: Vec::new(), mobs: Vec::new(), props: Vec::new(), + spawn_table: Vec::new(), }, item_index: HashMap::new(), mob_index: HashMap::new(), @@ -33,15 +35,45 @@ impl RawMaster { pub fn load(&mut self, raws: Raws) { self.raws = raws; self.item_index = HashMap::new(); - + let mut used_names: HashSet = HashSet::new(); for (i, item) in self.raws.items.iter().enumerate() { + if used_names.contains(&item.name) { + rltk::console::log(format!( + "WARNING - duplicate item name in raws [{}]", + item.name + )); + } self.item_index.insert(item.name.clone(), i); + used_names.insert(item.name.clone()); } for (i, mob) in self.raws.mobs.iter().enumerate() { + if used_names.contains(&mob.name) { + rltk::console::log(format!( + "WARNING - duplicate mob name in raws [{}]", + mob.name + )); + } self.mob_index.insert(mob.name.clone(), i); + used_names.insert(mob.name.clone()); } for (i, prop) in self.raws.props.iter().enumerate() { + if used_names.contains(&prop.name) { + rltk::console::log(format!( + "WARNING - duplicate prop name in raws [{}]", + prop.name + )); + } self.prop_index.insert(prop.name.clone(), i); + used_names.insert(prop.name.clone()); + } + + for spawn in self.raws.spawn_table.iter() { + if !used_names.contains(&spawn.name) { + rltk::console::log(format!( + "WARNING - Spawn tables references unspecified entity {}", + spawn.name + )); + } } } } @@ -280,3 +312,25 @@ pub fn spawn_named_entity( None } + +pub fn get_spawn_table_for_depth(raws: &RawMaster, depth: i32) -> RandomTable { + use super::SpawnTableEntry; + + let available_options: Vec<&SpawnTableEntry> = raws + .raws + .spawn_table + .iter() + .filter(|a| depth >= a.min_depth && depth <= a.max_depth) + .collect(); + + let mut rt = RandomTable::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 +} diff --git a/src/raws/spawn_table_structs.rs b/src/raws/spawn_table_structs.rs new file mode 100644 index 0000000..88f89e2 --- /dev/null +++ b/src/raws/spawn_table_structs.rs @@ -0,0 +1,12 @@ +use serde::Deserialize; + +use super::Renderable; + +#[derive(Deserialize, Debug)] +pub struct SpawnTableEntry { + pub name: String, + pub weight: i32, + pub min_depth: i32, + pub max_depth: i32, + pub add_map_depth_to_weight: Option, +} diff --git a/src/spawner.rs b/src/spawner.rs index 826460d..67f329e 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -6,7 +6,7 @@ use specs::saveload::{MarkedBuilder, SimpleMarker}; use crate::components::*; use crate::random_table::RandomTable; -use crate::raws::{spawn_named_entity, SpawnType, RAWS}; +use crate::raws::{get_spawn_table_for_depth, spawn_named_entity, SpawnType, RAWS}; use crate::{Map, Rect, TileType}; /// Spawns the player and returns their entity object @@ -42,20 +42,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 { - RandomTable::new() - .add("Goblin", 10) - .add("Orc", 1 + map_depth) - .add("Health Potion", 7) - .add("Fireball Scroll", 2 + map_depth) - .add("Confusion Scroll", 2 + map_depth) - .add("Magic Missile Scroll", 4) - .add("Dagger", 3) - .add("Shield", 3) - .add("Longsword", map_depth - 1) - .add("Tower Shield", map_depth - 1) - .add("Rations", 10) - .add("Magic Mapping Scroll", 2) - .add("Bear Trap", 2) + get_spawn_table_for_depth(&RAWS.lock().unwrap(), map_depth) } /// fills a room with stuff!