use std::collections::HashMap; use specs::prelude::*; use super::Raws; use crate::components::*; pub enum SpawnType { AtPosition { x: i32, y: i32 }, } pub struct RawMaster { raws: Raws, item_index: HashMap, } impl RawMaster { pub fn empty() -> RawMaster { RawMaster { raws: Raws { items: Vec::new() }, item_index: HashMap::new(), } } pub fn load(&mut self, raws: Raws) { self.raws = raws; self.item_index = HashMap::new(); for (i, item) in self.raws.items.iter().enumerate() { self.item_index.insert(item.name.clone(), i); } } } pub fn spawn_named_item( raws: &RawMaster, new_entity: EntityBuilder, key: &str, pos: SpawnType, ) -> Option { if raws.item_index.contains_key(key) { let item_template = &raws.raws.items[raws.item_index[key]]; let mut eb = new_entity; // Spawn in the specified location match pos { SpawnType::AtPosition { x, y } => { eb = eb.with(Position { x, y }); } } // Renderable if let Some(renderable) = &item_template.renderable { eb = eb.with(Renderable { glyph: rltk::to_cp437(renderable.glyph.chars().next().unwrap()), fg: rltk::RGB::from_hex(&renderable.fg).expect("Invalid RGB"), bg: rltk::RGB::from_hex(&renderable.bg).expect("Invalid RGB"), render_order: renderable.order, }); } eb = eb.with(Name::from(&item_template.name)); eb = eb.with(Item {}); if let Some(consumable) = &item_template.consumable { eb = eb.with(Consumable {}); for effect in consumable.effects.iter() { let effect_name = effect.0.as_str(); match effect_name { "provides_healing" => { eb = eb.with(ProvidesHealing { heal_amount: effect.1.parse::().unwrap(), }) } "ranged" => { eb = eb.with(Ranged { range: effect.1.parse::().unwrap(), }) } "damage" => { eb = eb.with(InflictsDamage { damage: effect.1.parse::().unwrap(), }) } "area_of_effect" => { eb = eb.with(AreaOfEffect { radius: effect.1.parse::().unwrap(), }) } "confusion" => { eb = eb.with(Confusion { turns: effect.1.parse::().unwrap(), }) } "magic_mapping" => eb = eb.with(MagicMapper {}), "food" => eb = eb.with(ProvidesFood {}), _ => { rltk::console::log(format!( "Warning: consumable effect {} not implemented.", effect_name )); } } } } if let Some(weapon) = &item_template.weapon { eb = eb.with(Equippable { slot: EquipmentSlot::Melee, }); eb = eb.with(MeleePowerBonus { power: weapon.power_bonus, }); } if let Some(shield) = &item_template.shield { eb = eb.with(Equippable { slot: EquipmentSlot::Shield, }); eb = eb.with(DefenseBonus { defense: shield.defense_bonus, }); } return Some(eb.build()); } None }