use skill::{Skill}; use spec::{Spec}; use cryp::{Colours}; #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] pub enum Item { // colours Blue, Green, Red, // base skills Attack, Block, Stun, Buff, Debuff, // specs // Base Damage, Life, Speed, // Lifes Upgrades GreenLifeI, RedLifeI, BlueLifeI, GRLI, GBLI, RBLI, // Damage Upgrades RedDamageI, BlueDamageI, GreenDamageI, GRDI, GBDI, RBDI, // Speed Upgrades RedSpeedI, BlueSpeedI, GreenSpeedI, GRSpeedI, GBSpeedI, RBSpeedI, Amplify, Banish, Blast, Chaos, Clutch, Corrupt, Curse, Decay, Hostility, Haste, Heal, Hex, Impurity, Invert, Parry, Purge, Purify, Reflect, Recharge, Ruin, Scatter, Silence, Slay, Sleep, Snare, Strangle, Strike, StrikeII, StrikeIII, Siphon, Taunt, Throw, Triage, TestTouch, TestStun, TestBlock, TestParry, TestSiphon, } pub enum ItemEffect { Skill, Spec, } impl Item { pub fn colours(&self, count: &mut Colours) { let combos = get_combos(); let combo = combos.iter().find(|c| c.item == *self); match combo { Some(c) => c.units.iter().for_each(|unit| match unit { Item::Red => count.red += 1, Item::Blue => count.blue += 1, Item::Green => count.green += 1, _ => { let mut combo_count = Colours::new(); unit.colours(&mut combo_count); count.red += combo_count.red; count.blue += combo_count.blue; count.green += combo_count.green; } }), None => (), } } pub fn cost(&self) -> u16 { match self { Item::Red => 1, Item::Green => 1, Item::Blue => 1, Item::Attack => 2, Item::Block => 2, Item::Buff => 2, Item::Debuff => 2, Item::Stun => 2, Item::Damage => 3, Item::Life => 3, Item::Speed => 3, _ => { let combos = get_combos(); let combo = combos.iter().find(|c| c.item == *self) .unwrap_or_else(|| panic!("unable to find components for {:?}", self)); return combo.units.iter().fold(0, |acc, c| acc + c.cost()); }, } } pub fn speed(&self) -> u8 { match self { Item::Red => 3, Item::Green => 2, Item::Blue => 1, Item::Attack => 1, Item::Stun => 2, Item::Block => 3, Item::Buff => 4, Item::Debuff => 4, _ => { let combos = get_combos(); let combo = combos.iter().find(|c| c.item == *self) .unwrap_or_else(|| panic!("unable to find components for {:?}", self)); return combo.units.iter().fold(0, |acc, c| acc + c.speed()); }, } } pub fn effect(&self) -> Option { if let Some(_skill) = self.into_skill() { return Some(ItemEffect::Skill); } if let Some(_spec) = self.into_spec() { return Some(ItemEffect::Spec); } return None; } pub fn into_skill(&self) -> Option { match self { Item::Attack => Some(Skill::Attack), Item::Amplify => Some(Skill::Amplify), Item::Banish => Some(Skill::Banish), Item::Blast => Some(Skill::Blast), Item::Block => Some(Skill::Block), Item::Chaos => Some(Skill::Chaos), Item::Curse => Some(Skill::Curse), Item::Debuff => Some(Skill::Debuff), Item::Decay => Some(Skill::Decay), Item::Haste => Some(Skill::Haste), Item::Heal => Some(Skill::Heal), Item::Hex => Some(Skill::Hex), Item::Hostility => Some(Skill::Hostility), Item::Impurity => Some(Skill::Impurity), Item::Invert => Some(Skill::Invert), Item::Parry => Some(Skill::Parry), Item::Purge => Some(Skill::Purge), Item::Purify => Some(Skill::Purify), Item::Recharge => Some(Skill::Recharge), Item::Reflect => Some(Skill::Reflect), Item::Ruin => Some(Skill::Ruin), Item::Scatter => Some(Skill::Scatter), Item::Silence => Some(Skill::Silence), Item::Slay => Some(Skill::Slay), Item::Sleep => Some(Skill::Sleep), Item::Siphon => Some(Skill::Siphon), Item::Snare => Some(Skill::Snare), Item::Strangle => Some(Skill::Strangle), Item::Stun => Some(Skill::Stun), Item::Strike => Some(Skill::Strike), Item::StrikeII => Some(Skill::StrikeII), Item::StrikeIII => Some(Skill::StrikeIII), Item::Clutch => Some(Skill::Clutch), Item::Taunt => Some(Skill::Taunt), Item::Throw => Some(Skill::Throw), Item::Corrupt => Some(Skill::Corrupt), Item::Triage => Some(Skill::Triage), _ => None, } } pub fn into_spec(&self) -> Option { match *self { Item::Speed => Some(Spec::Speed), Item::RedSpeedI => Some(Spec::RedSpeedI), Item::BlueSpeedI => Some(Spec::BlueSpeedI), Item::GreenSpeedI => Some(Spec::GreenSpeedI), Item::GRSpeedI => Some(Spec::GRSpeedI), Item::GBSpeedI => Some(Spec::GBSpeedI), Item::RBSpeedI => Some(Spec::RBSpeedI), Item::Damage => Some(Spec::Damage), Item::RedDamageI => Some(Spec::RedDamageI), Item::BlueDamageI => Some(Spec::BlueDamageI), Item::GreenDamageI => Some(Spec::GreenDamageI), Item::GRDI => Some(Spec::GRDI), Item::GBDI => Some(Spec::GBDI), Item::RBDI => Some(Spec::RBDI), Item::Life => Some(Spec::Life), Item::GRLI => Some(Spec::GRLI), Item::GBLI => Some(Spec::GBLI), Item::RBLI => Some(Spec::RBLI), Item::GreenLifeI => Some(Spec::GreenLifeI), Item::RedLifeI => Some(Spec::RedLifeI), Item::BlueLifeI => Some(Spec::BlueLifeI), _ => None, } } pub fn into_description(&self) -> String { match self { // colours Item::Blue => format!("Combine with skills and specs to create upgraded items. \n Deterrents and destruction."), Item::Green => format!("Combine with skills and specs to create upgraded items.\n Protection and trickery."), Item::Red => format!("Combine with skills and specs to create upgraded items. \n Speed and chaos."), // base skills Item::Attack => format!("Deal {:?}% RedDamage", self.into_skill().unwrap().multiplier()), Item::Block => format!("description"), Item::Stun => format!("description"), Item::Buff => format!("description"), Item::Debuff => format!("description"), // specs // Base Item::Damage => format!("description"), Item::Life => format!("description"), Item::Speed => format!("description"), // Lifes Upgrades Item::GreenLifeI => format!("description"), Item::RedLifeI => format!("description"), Item::BlueLifeI => format!("description"), Item::GRLI => format!("description"), Item::GBLI => format!("description"), Item::RBLI => format!("description"), // Damage Upgrades Item::RedDamageI => format!("description"), Item::BlueDamageI => format!("description"), Item::GreenDamageI => format!("description"), Item::GRDI => format!("description"), Item::GBDI => format!("description"), Item::RBDI => format!("description"), // Speed Upgrades Item::RedSpeedI => format!("description"), Item::BlueSpeedI => format!("description"), Item::GreenSpeedI => format!("description"), Item::GRSpeedI => format!("description"), Item::GBSpeedI => format!("description"), Item::RBSpeedI => format!("description"), Item::Amplify => format!("description"), Item::Banish => format!("description"), Item::Blast => format!("description"), Item::Chaos => format!("description"), Item::Clutch => format!("description"), Item::Corrupt => format!("description"), Item::Curse => format!("description"), Item::Decay => format!("description"), Item::Hostility => format!("description"), Item::Haste => format!("description"), Item::Heal => format!("description"), Item::Hex => format!("description"), Item::Impurity => format!("description"), Item::Invert => format!("description"), Item::Parry => format!("description"), Item::Purge => format!("description"), Item::Purify => format!( "Remove debuffs and heal for {:?}% GreenDamage per debuff removed.", self.into_skill().unwrap().multiplier()), Item::Reflect => format!("description"), Item::Recharge => format!("description"), Item::Ruin => format!("description"), Item::Scatter => format!("description"), Item::Silence => format!("description"), Item::Slay => format!("description"), Item::Sleep => format!("description"), Item::Snare => format!("description"), Item::Strangle => format!("description"), Item::Strike => format!("description"), Item::StrikeII => format!("description"), Item::StrikeIII => format!("description"), Item::Siphon => format!("description"), Item::Taunt => format!("description"), Item::Throw => format!("description"), Item::Triage => format!("description"), _ => format!("..."), } } } impl From for Item { fn from(skill: Skill) -> Item { match skill { Skill::Amplify => Item::Amplify, Skill::Attack => Item::Attack, Skill::Banish => Item::Banish, Skill::Blast => Item::Blast, Skill::Block => Item::Block, Skill::Chaos => Item::Chaos, Skill::Curse => Item::Curse, Skill::Clutch => Item::Clutch, Skill::Decay => Item::Decay, Skill::Debuff => Item::Debuff, Skill::Haste => Item::Haste, Skill::Hostility => Item::Hostility, Skill::Heal => Item::Heal, Skill::Hex => Item::Hex, Skill::Impurity => Item::Impurity, Skill::Invert => Item::Invert, Skill::Parry => Item::Parry, Skill::Purge => Item::Purge, Skill::Purify => Item::Purify, Skill::Recharge => Item::Recharge, Skill::Reflect => Item::Reflect, Skill::Ruin => Item::Ruin, Skill::Scatter => Item::Scatter, Skill::Silence => Item::Silence, Skill::Siphon => Item::Siphon, Skill::Slay => Item::Slay, Skill::Sleep => Item::Sleep, Skill::Snare => Item::Snare, Skill::Strangle => Item::Strangle, Skill::Strike => Item::Strike, Skill::StrikeII => Item::StrikeII, Skill::StrikeIII => Item::StrikeIII, Skill::Stun => Item::Stun, Skill::Taunt => Item::Taunt, Skill::Throw => Item::Throw, Skill::Triage => Item::Triage, Skill::Corrupt => Item::Corrupt, Skill::TestTouch => Item::TestTouch, Skill::TestStun => Item::TestStun, Skill::TestBlock => Item::TestBlock, Skill::TestParry => Item::TestParry, Skill::TestSiphon => Item::TestSiphon, _ => panic!("{:?} not implemented as a item", skill), } } } impl From for Item { fn from(spec: Spec) -> Item { match spec { Spec::Speed => Item::Speed, Spec::RedSpeedI => Item::RedSpeedI, Spec::BlueSpeedI => Item::BlueSpeedI, Spec::GreenSpeedI => Item::GreenSpeedI, Spec::GRSpeedI => Item::GRSpeedI, Spec::GBSpeedI => Item::GBSpeedI, Spec::RBSpeedI => Item::RBSpeedI, Spec::Damage => Item::Damage, Spec::RedDamageI => Item::RedDamageI, Spec::BlueDamageI => Item::BlueDamageI, Spec::GreenDamageI => Item::GreenDamageI, Spec::GRDI => Item::GRDI, Spec::GBDI => Item::GBDI, Spec::RBDI => Item::RBDI, Spec::Life => Item::Life, Spec::GRLI => Item::GRLI, Spec::GBLI => Item::GBLI, Spec::RBLI => Item::RBLI, Spec::GreenLifeI => Item::GreenLifeI, Spec::RedLifeI => Item::RedLifeI, Spec::BlueLifeI => Item::BlueLifeI, // _ => panic!("{:?} not implemented as a item", spec), } } } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Combo { pub item: Item, pub units: Vec, } pub fn get_combos() -> Vec { let mut combinations = vec![ Combo { units: vec![Item::Buff, Item::Red, Item::Red], item: Item::Taunt }, Combo { units: vec![Item::Buff, Item::Green, Item::Green], item: Item::Triage }, Combo { units: vec![Item::Buff, Item::Blue, Item::Blue], item: Item::Scatter }, //To be impl Combo { units: vec![Item::Buff, Item::Red, Item::Green], item: Item::Haste }, Combo { units: vec![Item::Buff, Item::Green, Item::Blue], item: Item::Impurity }, Combo { units: vec![Item::Buff, Item::Red, Item::Blue], item: Item::Amplify }, // Some flavour Combo { units: vec![Item::Debuff, Item::Red, Item::Red], item: Item::Snare }, Combo { units: vec![Item::Debuff, Item::Green, Item::Green], item: Item::Purge }, // Needs flavour Combo { units: vec![Item::Debuff, Item::Blue, Item::Blue], item: Item::Silence }, Combo { units: vec![Item::Debuff, Item::Red, Item::Green], item: Item::Curse }, // To be reworked Combo { units: vec![Item::Debuff, Item::Green, Item::Blue], item: Item::Decay }, Combo { units: vec![Item::Debuff, Item::Red, Item::Blue], item: Item::Invert }, Combo { units: vec![Item::Block, Item::Red, Item::Red], item: Item::Parry }, // Add red recharge Combo { units: vec![Item::Block, Item::Green, Item::Green], item: Item::Purify }, Combo { units: vec![Item::Block, Item::Blue, Item::Blue], item: Item::Corrupt }, Combo { units: vec![Item::Block, Item::Red, Item::Green], item: Item::Clutch }, Combo { units: vec![Item::Block, Item::Green, Item::Blue], item: Item::Reflect }, Combo { units: vec![Item::Block, Item::Red, Item::Blue], item: Item::Recharge }, Combo { units: vec![Item::Stun, Item::Red, Item::Red], item: Item::Strangle }, Combo { units: vec![Item::Stun, Item::Green, Item::Green], item: Item::Sleep }, Combo { units: vec![Item::Stun, Item::Blue, Item::Blue], item: Item::Ruin }, Combo { units: vec![Item::Stun, Item::Red, Item::Green], item: Item::Throw }, Combo { units: vec![Item::Stun, Item::Green, Item::Blue], item: Item::Hex }, Combo { units: vec![Item::Stun, Item::Red, Item::Blue], item: Item::Banish }, Combo { units: vec![Item::Attack, Item::Red, Item::Red], item: Item::Strike }, Combo { units: vec![Item::Strike, Item::Strike, Item::Strike], item: Item::StrikeII }, Combo { units: vec![Item::StrikeII, Item::StrikeII, Item::StrikeII], item: Item::StrikeIII }, Combo { units: vec![Item::Attack, Item::Green, Item::Green], item: Item::Heal }, Combo { units: vec![Item::Attack, Item::Blue, Item::Blue], item: Item::Blast }, Combo { units: vec![Item::Attack, Item::Red, Item::Green], item: Item::Slay }, Combo { units: vec![Item::Attack, Item::Green, Item::Blue], item: Item::Siphon }, Combo { units: vec![Item::Attack, Item::Red, Item::Blue], item: Item::Chaos }, Combo { units: vec![Item::Damage, Item::Red, Item::Red], item: Item::RedDamageI }, Combo { units: vec![Item::Damage, Item::Green, Item::Green], item: Item::GreenDamageI }, Combo { units: vec![Item::Damage, Item::Blue, Item::Blue], item: Item::BlueDamageI }, Combo { units: vec![Item::Damage, Item::Red, Item::Green], item: Item::GRDI }, Combo { units: vec![Item::Damage, Item::Green, Item::Blue], item: Item::GBDI }, Combo { units: vec![Item::Damage, Item::Red, Item::Blue], item: Item::RBDI }, Combo { units: vec![Item::Life, Item::Red, Item::Red], item: Item::RedLifeI }, Combo { units: vec![Item::Life, Item::Green, Item::Green], item: Item::GreenLifeI }, Combo { units: vec![Item::Life, Item::Blue, Item::Blue], item: Item::BlueLifeI }, Combo { units: vec![Item::Life, Item::Red, Item::Green], item: Item::GRLI }, Combo { units: vec![Item::Life, Item::Green, Item::Blue], item: Item::GBLI }, Combo { units: vec![Item::Life, Item::Red, Item::Blue], item: Item::RBLI }, Combo { units: vec![Item::Speed, Item::Red, Item::Red], item: Item::RedSpeedI }, Combo { units: vec![Item::Speed, Item::Green, Item::Green], item: Item::GreenSpeedI }, Combo { units: vec![Item::Speed, Item::Blue, Item::Blue], item: Item::BlueSpeedI }, Combo { units: vec![Item::Speed, Item::Red, Item::Green], item: Item::GRSpeedI }, Combo { units: vec![Item::Speed, Item::Green, Item::Blue], item: Item::GBSpeedI }, Combo { units: vec![Item::Speed, Item::Red, Item::Blue], item: Item::RBSpeedI }, ]; combinations.iter_mut().for_each(|set| set.units.sort_unstable()); return combinations; } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct ItemInfo { pub item: Item, pub spec: bool, pub skill: bool, pub description: String, } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct ItemInfoCtr { pub combos: Vec, pub items: Vec, } pub fn item_info() -> ItemInfoCtr { let combos = get_combos(); let mut items = combos .into_iter() .flat_map(|mut c| { c.units.push(c.item); c.units }) .collect::>(); items.sort_unstable(); items.dedup(); let items = items .into_iter() .map(|v| ItemInfo { item: v, spec: v.into_spec().is_some(), skill: v.into_skill().is_some(), description: v.into_description(), }) .collect::>(); let combos = get_combos(); return ItemInfoCtr { combos, items, }; }