From aaf3fdcc4289e10e9718bc600993ac0ec0d41c3c Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 23 Dec 2021 12:48:09 -0500 Subject: [PATCH] Spawn all entities via raws, complete Section 5.2 --- raws/spawns.json | 31 ++++++++++++++++++ src/raws.rs | 3 ++ src/raws/prop_structs.rs | 21 +++++++++++++ src/raws/rawmaster.rs | 68 ++++++++++++++++++++++++++++++++++++++++ src/spawner.rs | 44 +++----------------------- 5 files changed, 127 insertions(+), 40 deletions(-) create mode 100644 src/raws/prop_structs.rs diff --git a/raws/spawns.json b/raws/spawns.json index 352ab83..36f1bfe 100644 --- a/raws/spawns.json +++ b/raws/spawns.json @@ -175,5 +175,36 @@ }, "vision_range": 8 } + ], + "props": [ + { + "name": "Bear Trap", + "renderable": { + "glyph": "^", + "fg": "#FF0000", + "bg": "#000000", + "order": 2 + }, + "hidden": true, + "entry_trigger": { + "effects": { + "damage": "6", + "single_activation": "1" + } + } + }, + { + "name": "Door", + "renderable": { + "glyph": "+", + "fg": "#805A46", + "bg": "#000000", + "order": 2 + }, + "hidden": false, + "blocks_tile": true, + "blocks_visibility": true, + "door_open": true + } ] } \ No newline at end of file diff --git a/src/raws.rs b/src/raws.rs index dd3221f..8adab0f 100644 --- a/src/raws.rs +++ b/src/raws.rs @@ -1,11 +1,13 @@ mod item_structs; mod mob_structs; +mod prop_structs; mod rawmaster; use std::sync::Mutex; use item_structs::*; use mob_structs::*; +use prop_structs::*; pub use rawmaster::*; use serde::Deserialize; @@ -13,6 +15,7 @@ use serde::Deserialize; pub struct Raws { pub items: Vec, pub mobs: Vec, + pub props: Vec, } rltk::embedded_resource!(RAW_FILE, "../raws/spawns.json"); diff --git a/src/raws/prop_structs.rs b/src/raws/prop_structs.rs new file mode 100644 index 0000000..54b10ac --- /dev/null +++ b/src/raws/prop_structs.rs @@ -0,0 +1,21 @@ +use std::collections::HashMap; + +use serde::Deserialize; + +use super::Renderable; + +#[derive(Deserialize, Debug)] +pub struct Prop { + pub name: String, + pub renderable: Option, + pub hidden: Option, + pub blocks_tile: Option, + pub blocks_visibility: Option, + pub door_open: Option, + pub entry_trigger: Option, +} + +#[derive(Deserialize, Debug)] +pub struct EntryTrigger { + pub effects: HashMap, +} diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index b7db18c..ceb50df 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -13,6 +13,7 @@ pub struct RawMaster { raws: Raws, item_index: HashMap, mob_index: HashMap, + prop_index: HashMap, } impl RawMaster { @@ -21,9 +22,11 @@ impl RawMaster { raws: Raws { items: Vec::new(), mobs: Vec::new(), + props: Vec::new(), }, item_index: HashMap::new(), mob_index: HashMap::new(), + prop_index: HashMap::new(), } } @@ -37,6 +40,9 @@ impl RawMaster { for (i, mob) in self.raws.mobs.iter().enumerate() { self.mob_index.insert(mob.name.clone(), i); } + for (i, prop) in self.raws.props.iter().enumerate() { + self.prop_index.insert(prop.name.clone(), i); + } } } @@ -198,6 +204,66 @@ pub fn spawn_named_mob( None } +pub fn spawn_named_prop( + raws: &RawMaster, + new_entity: EntityBuilder, + key: &str, + pos: SpawnType, +) -> Option { + if raws.prop_index.contains_key(key) { + let prop_template = &raws.raws.props[raws.prop_index[key]]; + + let mut eb = new_entity; + + // Spawn in the specified location + eb = spawn_position(pos, eb); + + // Renderable + if let Some(renderable) = &prop_template.renderable { + eb = eb.with(get_renderable_component(renderable)); + } + + eb = eb.with(Name::from(&prop_template.name)); + + if let Some(hidden) = prop_template.hidden { + if hidden { + eb = eb.with(Hidden {}) + } + } + if let Some(blocks_tile) = prop_template.blocks_tile { + if blocks_tile { + eb = eb.with(BlocksTile {}) + } + } + if let Some(blocks_visibility) = prop_template.blocks_visibility { + if blocks_visibility { + eb = eb.with(BlocksVisibility {}) + } + } + if let Some(door_open) = prop_template.door_open { + eb = eb.with(Door { open: door_open }); + } + if let Some(entry_trigger) = &prop_template.entry_trigger { + eb = eb.with(EntryTrigger {}); + for effect in entry_trigger.effects.iter() { + match effect.0.as_str() { + "damage" => { + eb = eb.with(InflictsDamage { + damage: effect.1.parse::().unwrap(), + }); + } + "single_activation" => eb = eb.with(SingleActivation {}), + _ => {} + } + } + } + + return Some(eb.build()); + } + + None +} + pub fn spawn_named_entity( raws: &RawMaster, new_entity: EntityBuilder, @@ -208,6 +274,8 @@ pub fn spawn_named_entity( return spawn_named_item(raws, new_entity, key, pos); } else if raws.mob_index.contains_key(key) { return spawn_named_mob(raws, new_entity, key, pos); + } else if raws.prop_index.contains_key(key) { + return spawn_named_prop(raws, new_entity, key, pos); } None diff --git a/src/spawner.rs b/src/spawner.rs index 0892256..826460d 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -143,44 +143,8 @@ pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) { return; } - match spawn.1.as_ref() { - "Bear Trap" => bear_trap(ecs, x, y), - "Door" => door(ecs, x, y), - _ => {} - } -} - -fn bear_trap(ecs: &mut World, x: i32, y: i32) { - ecs.create_entity() - .with(Position { x, y }) - .with(Renderable { - glyph: rltk::to_cp437('^'), - fg: RGB::named(rltk::RED), - bg: RGB::named(rltk::BLACK), - render_order: 2, - }) - .with(Name::from("Bear Trap")) - .with(Hidden {}) - .with(EntryTrigger {}) - .with(InflictsDamage { damage: 6 }) - .with(SingleActivation {}) - .marked::>() - .build(); -} - -fn door(ecs: &mut World, x: i32, y: i32) { - ecs.create_entity() - .with(Position { x, y }) - .with(Renderable { - glyph: rltk::to_cp437('+'), - fg: RGB::named(rltk::CHOCOLATE), - bg: RGB::named(rltk::BLACK), - render_order: 2, - }) - .with(Name::from("Door")) - .with(BlocksTile {}) - .with(BlocksVisibility {}) - .with(Door { open: false }) - .marked::>() - .build(); + rltk::console::log(format!( + "WARNING: We don't know how to spawn [{}]!", + spawn.1 + )); }