mnml/server/src/item.rs
2019-05-20 18:50:18 +10:00

533 lines
20 KiB
Rust

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<ItemEffect> {
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<Skill> {
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<Spec> {
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<Skill> 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<Spec> 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<Item>,
}
pub fn get_combos() -> Vec<Combo> {
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<Combo>,
pub items: Vec<ItemInfo>,
}
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::<Vec<Item>>();
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::<Vec<ItemInfo>>();
let combos = get_combos();
return ItemInfoCtr {
combos,
items,
};
}