From 170741fe959d30ee43ce689fd5fbae725cc1dae4 Mon Sep 17 00:00:00 2001 From: troido Date: Thu, 5 Mar 2020 12:50:25 +0100 Subject: equipent now kinda works --- src/components/equipment.rs | 164 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/components/equipment.rs (limited to 'src/components/equipment.rs') diff --git a/src/components/equipment.rs b/src/components/equipment.rs new file mode 100644 index 0000000..1d86e95 --- /dev/null +++ b/src/components/equipment.rs @@ -0,0 +1,164 @@ + +use std::collections::HashMap; +use serde_json::{json, Value}; +use specs::{ + Component, + HashMapStorage +}; + + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Slot { + Hand, + Body +} + +impl Slot { + pub fn from_str(txt: &str) -> Option { + match txt { + "hand" => Some(Self::Hand), + "body" => Some(Self::Body), + _ => None + } + } + pub fn to_string(&self) -> String { + match self { + Self::Hand => "hand", + Self::Body => "body" + }.to_string() + } +} + + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Stat { + Strength, + Defence +} + +impl Stat { + pub fn from_str(txt: &str) -> Option { + match txt { + "strength" => Some(Self::Strength), + "defence" => Some(Self::Defence), + _ => None + } + } + pub fn to_string(&self) -> String { + match self { + Self::Strength => "strength", + Self::Defence => "defence" + }.to_string() + } +} + + +#[derive(Debug, Clone, PartialEq)] +pub struct Equippable { + pub slot: Slot, + pub stats: HashMap +} + +impl Equippable { + pub fn from_json(val: &Value) -> Option { + Some(Equippable{ + slot: Slot::from_str(val.get("slot")?.as_str()?)?, + stats: val + .get("stats")? + .as_object()? + .into_iter() + .map(|(k, v)| + Some((Stat::from_str(k.as_str())?, v.as_i64()?)) + ) + .collect::>>()? + }) + } + pub fn to_json(&self) -> Value { + json!({ + "slot": self.slot.to_string(), + "stats": self.stats.iter().map(|(k, v)| (k.to_string(), *v)).collect::>() + }) + } +} + + + +#[derive(Component, Debug, Clone)] +#[storage(HashMapStorage)] +pub struct Equipment { + pub equipment: HashMap> +} + +impl Equipment { + pub fn get_bonus(&self, stat: Stat) -> i64 { + let mut bonus = 0; + for v in self.equipment.values() { + if let Some(equippable) = v { + if let Some(s) = equippable.stats.get(&stat) { + bonus += s; + } + } + } + bonus + } + pub fn all_bonuses(&self) -> HashMap { + let mut bonuses: HashMap = HashMap::new(); + for v in self.equipment.values() { + if let Some(equippable) = v { + for (stat, s) in equippable.stats.iter(){ + let current: i64 = *bonuses.entry(*stat).or_insert(0); + bonuses.insert(*stat, current + s); + } + } + } + bonuses + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::hashmap; + + + #[test] + fn slots() { + assert_eq!(Slot::from_str("hand"), Some(Slot::Hand)); + assert_eq!(Slot::from_str("body"), Some(Slot::Body)); + assert_eq!(Slot::from_str("hands"), None); + assert_eq!(Slot::from_str("head"), None); + } + + #[test] + fn stats() { + assert_eq!(Stat::from_str("strength"), Some(Stat::Strength)); + assert_eq!(Stat::from_str("defence"), Some(Stat::Defence)); + assert_eq!(Stat::from_str("hand"), None); + assert_eq!(Stat::from_str("body"), None); + assert_eq!(Stat::from_str("attack"), None); + } + + #[test] + fn equippable_from_json() { + assert_eq!( + Equippable::from_json(&json!({"slot": "hand", "stats": {"strength": 10}})), + Some(Equippable {slot: Slot::Hand, stats: hashmap!(Stat::Strength => 10)}) + ); + } + + + #[test] + fn bonus_value() { + assert_eq!( + Equipment{equipment: hashmap!( + Slot::Hand => Some(Equippable{ + slot: Slot::Hand, + stats: hashmap!(Stat::Strength => 15) + }), + Slot::Body => None + )}.get_bonus(Stat::Strength), + 15 + ); + } +} -- cgit