make enum version of all skills for values

This commit is contained in:
Mashy 2019-12-16 17:24:19 +10:00
parent 0ed186cde3
commit efd82f3cf2
4 changed files with 1014 additions and 1359 deletions

View File

@ -98,7 +98,7 @@ impl ConstructEffect {
pub fn get_skill(&self) -> Option<Skill> { pub fn get_skill(&self) -> Option<Skill> {
match self.meta { match self.meta {
Some(EffectMeta::CastTick { source, target, skill, speed, amount }) => Some(skill), Some(EffectMeta::CastTick { source: _, target: _, skill, speed: _, amount: _ }) => Some(skill),
Some(EffectMeta::CastOnHit(s)) => Some(s), Some(EffectMeta::CastOnHit(s)) => Some(s),
_ => None, _ => None,
} }
@ -534,7 +534,7 @@ impl Construct {
fn tick_damage(&self, effect: Effect) -> usize { fn tick_damage(&self, effect: Effect) -> usize {
match self.effects.iter().find_map(|ce| match ce.effect == effect { match self.effects.iter().find_map(|ce| match ce.effect == effect {
true => match ce.meta { true => match ce.meta {
Some(EffectMeta::CastTick { source, target, skill, speed, amount }) => Some(amount), Some(EffectMeta::CastTick { source: _, target: _, skill: _, speed: _, amount }) => Some(amount),
_ => None, _ => None,
}, },
false => None, false => None,

View File

@ -12,7 +12,6 @@ use failure::err_msg;
use construct::{Construct, ConstructEffect, Stat, EffectMeta}; use construct::{Construct, ConstructEffect, Stat, EffectMeta};
use skill::{Skill, Cast}; use skill::{Skill, Cast};
use effect::{Effect}; use effect::{Effect};
use util::{IntPct};
use player::{Player}; use player::{Player};
use instance::{TimeControl}; use instance::{TimeControl};
@ -631,7 +630,7 @@ impl Game {
Value::Removals { construct } => Value::Removals { construct } =>
self.events.iter().fold(0, |dmg, e| match e { self.events.iter().fold(0, |dmg, e| match e {
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } => Event::Damage { construct: event_construct, amount, mitigation:_, colour: _event_colour, display: _ } =>
match construct == *event_construct { match construct == *event_construct {
true => dmg + amount, true => dmg + amount,
false => dmg, false => dmg,
@ -1250,6 +1249,351 @@ mod tests {
assert!(game.player_by_id(y_player.id).unwrap().constructs[0].skill_on_cd(Skill::Block).is_none()); assert!(game.player_by_id(y_player.id).unwrap().constructs[0].skill_on_cd(Skill::Block).is_none());
} }
// #[cfg(test)]
// mod tests {
// use skill::*;
// #[test]
// fn attack_actions_test() {
// let cast = Cast::new(Uuid::new_v4(), Uuid::new_v4(), Uuid::new_v4(), Skill::Attack);
// let actions = cast.actions(Game::);
// match actions[0] {
// Action::Cast => (),
// _ => panic!("{:?}", actions),
// };
// match actions[1] {
// Action::Hit => (),
// _ => panic!("{:?}", actions),
// };
// match actions[2] {
// Action::Damage { construct: _, amount: _, colour } => {
// assert_eq!(colour, Colour::Red);
// },
// _ => panic!("{:?}", actions),
// };
// }
// #[test]
// fn heal_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string())
// .learn(Skill::Heal);
// let mut y = Construct::new()
// .named(&"camel".to_string())
// .learn(Skill::Heal);
// x.deal_red_damage(Skill::Attack, 5);
// heal(&mut y, &mut x, vec![], Skill::Heal);
// }
// #[test]
// fn decay_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// decay(&mut x, &mut y, vec![], Skill::Decay);
// assert!(y.effects.iter().any(|e| e.effect == Effect::Decay));
// y.reduce_effect_durations();
// let _decay = y.effects.iter().find(|e| e.effect == Effect::Decay);
// // assert!(y.green_life() == y.green_life().saturating_sub(decay.unwrap().tick.unwrap().amount));
// }
// #[test]
// fn block_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// // ensure it doesn't have 0 pd
// x.red_power.force(100);
// y.green_life.force(500);
// block(&mut y.clone(), &mut y, vec![], Skill::Block);
// assert!(y.effects.iter().any(|e| e.effect == Effect::Block));
// attack(&mut x, &mut y, vec![], Skill::Attack);
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Damage { amount, mitigation: _, colour: _, skill: _ } =>
// assert!(amount < x.red_power().pct(Skill::Attack.multiplier())),
// _ => panic!("not damage"),
// };
// }
// #[test]
// fn sustain_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// x.red_power.force(10000000000000); // multiplication of int max will cause overflow
// y.green_life.force(1024); // make tests more flexible if we change stats
// sustain(&mut y.clone(), &mut y, vec![], Skill::Sustain);
// assert!(y.affected(Effect::Sustain));
// ruin(&mut x, &mut y, vec![], Skill::Ruin);
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Immunity { skill: _, immunity } => assert!(immunity.contains(&Effect::Sustain)),
// _ => panic!("not immune cluthc"),
// };
// attack(&mut x, &mut y, vec![], Skill::Attack);
// assert!(y.green_life() == 1);
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert_eq!(amount, 1023),
// _ => panic!("not damage"),
// };
// }
// #[test]
// fn invert_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// // give red shield but reduce to 0
// y.red_life.force(64);
// y.red_life.reduce(64);
// x.red_power.force(512);
// invert(&mut y.clone(), &mut y, vec![], Skill::Invert);
// assert!(y.affected(Effect::Invert));
// // heal should deal green damage
// heal(&mut x, &mut y, vec![], Skill::Heal);
// assert!(y.green_life() < 1024);
// // attack should heal and recharge red shield
// attack(&mut x, &mut y, vec![], Skill::Attack);
// // match resolutions.remove(0).event {
// // Event::Inversion { skill } => assert_eq!(skill, Skill::Attack),
// // _ => panic!("not inversion"),
// //};
// match resolutions.remove(0).event {
// Event::Heal { skill: _, overhealing: _, amount } => assert!(amount > 0),
// _ => panic!("not healing from inversion"),
// };
// match resolutions.remove(0).event {
// Event::Recharge { skill: _, red, blue: _ } => assert!(red > 0),
// _ => panic!("not recharge from inversion"),
// };
// }
// #[test]
// fn reflect_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// reflect(&mut y.clone(), &mut y, vec![], Skill::Reflect);
// assert!(y.affected(Effect::Reflect));
// let mut vec![];
// cast_actions(Skill::Blast, &mut x, &mut y, resolutions);
// assert!(x.green_life() < 1024);
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Reflection { skill } => assert_eq!(skill, Skill::Blast),
// _ => panic!("not reflection"),
// };
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Damage { amount, mitigation: _, colour: _, skill: _ } => assert!(amount > 0),
// _ => panic!("not damage"),
// };
// }
// #[test]
// fn siphon_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"camel".to_string());
// x.blue_power.force(256);
// x.green_power.force(220);
// x.green_life.force(1024);
// y.blue_life.force(0);
// x.green_life.reduce(512);
// cast_actions(Skill::Siphon, &mut x, &mut y, vec![]);
// assert!(y.affected(Effect::Siphon));
// assert!(x.green_life() == (512 + 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier())));
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Effect { effect, skill: _, duration: _, construct_effects: _ } => assert_eq!(effect, Effect::Siphon),
// _ => panic!("not siphon"),
// };
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Damage { amount, skill: _, mitigation: _, colour: _} => assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier())
// + 220.pct(Skill::SiphonTick.multiplier())),
// _ => panic!("not damage siphon"),
// };
// let Event { source: _, target, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Heal { amount, skill: _, overhealing: _ } => {
// assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier()));
// assert_eq!(target.id, x.id);
// },
// _ => panic!("not healing"),
// };
// }
// #[test]
// fn triage_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"pretaliation".to_string());
// // ensure it doesn't have 0 sd
// x.blue_power.force(50);
// // remove all mitigation
// y.red_life.force(0);
// y.blue_life.force(0);
// y.deal_red_damage(Skill::Attack, 5);
// let prev_hp = y.green_life();
// triage(&mut x, &mut y, vec![], Skill::Triage);
// assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
// assert!(y.green_life() > prev_hp);
// }
// #[test]
// fn recharge_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"pretaliation".to_string());
// y.red_life.force(50);
// y.blue_life.force(50);
// y.deal_red_damage(Skill::Attack, 5);
// y.deal_blue_damage(Skill::Blast, 5);
// recharge(&mut x, &mut y, vec![], Skill::Recharge);
// resolutions.remove(0);
// let Event { source: _, target: _, event, stages: _ } = resolutions.remove(0);
// match event {
// Event::Recharge { red, blue, skill: _ } => {
// assert!(red == 5);
// assert!(blue == 5);
// }
// _ => panic!("result was not recharge"),
// }
// }
// #[test]
// fn silence_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// silence(&mut x.clone(), &mut x, vec![], Skill::Silence);
// assert!(x.effects.iter().any(|e| e.effect == Effect::Silence));
// assert!(x.disabled(Skill::Silence).is_some());
// }
// #[test]
// fn amplify_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// x.blue_power.force(50);
// amplify(&mut x.clone(), &mut x, vec![], Skill::Amplify);
// assert!(x.effects.iter().any(|e| e.effect == Effect::Amplify));
// assert_eq!(x.blue_power(), 75);
// }
// #[test]
// fn purify_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// decay(&mut x.clone(), &mut x, vec![], Skill::Decay);
// assert!(x.effects.iter().any(|e| e.effect == Effect::Decay));
// purify(&mut x.clone(), &mut x, vec![], Skill::Purify);
// assert!(!x.effects.iter().any(|e| e.effect == Effect::Decay));
// }
// #[test]
// fn bash_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"pretaliation".to_string())
// .learn(Skill::Stun);
// let stun_cd = y.skills.iter().find(|cs| cs.skill == Skill::Stun).unwrap().cd.unwrap();
// bash(&mut x, &mut y, vec![], Skill::Bash);
// assert!(!x.effects.iter().any(|e| e.effect == Effect::Stun));
// assert!(y.skills.iter().any(|cs| cs.skill == Skill::Stun && cs.cd.unwrap() == stun_cd + 1));
// }
// #[test]
// fn purge_test() {
// let mut x = Construct::new()
// .named(&"muji".to_string());
// let mut y = Construct::new()
// .named(&"pretaliation".to_string())
// .learn(Skill::Heal)
// .learn(Skill::HealPlus);
// purge(&mut x, &mut y, vec![], Skill::Purge);
// // 2 turns at lvl 1
// assert!(y.effects.iter().any(|e| e.effect == Effect::Purge && e.duration == 2));
// assert!(y.disabled(Skill::Heal).is_some());
// }
// }
// #[test] // #[test]
// fn sleep_cooldown_test() { // fn sleep_cooldown_test() {
// let mut game = create_test_game(); // let mut game = create_test_game();
@ -1874,11 +2218,11 @@ mod tests {
_ => false, _ => false,
})); }));
assert!(match game.players[1].constructs[0].effects[0].meta { /* assert!(match game.players[1].constructs[0].effects[0].meta {
Some(EffectMeta::AddedDamage(d)) => d, Some(EffectMeta::AddedDamage(d)) => d,
_ => 0 _ => 0
// 320 base blue power and 125 base blue life // 320 base blue power and 125 base blue life
} == 320.pct(Skill::Blast.multiplier()) - 125); } == 320.pct(Skill::Blast.multiplier()) - 125);*/
} }
@ -1896,11 +2240,11 @@ mod tests {
game.new_resolve(Cast::new(source, player_id, target, Skill::Absorb)); game.new_resolve(Cast::new(source, player_id, target, Skill::Absorb));
game.new_resolve(Cast::new(source, player_id, target, Skill::Blast)); game.new_resolve(Cast::new(source, player_id, target, Skill::Blast));
assert!(match game.players[1].constructs[0].effects[0].meta { /*assert!(match game.players[1].constructs[0].effects[0].meta {
Some(EffectMeta::AddedDamage(d)) => d, Some(EffectMeta::AddedDamage(d)) => d,
_ => 0 _ => 0
// 320 base blue power and 125 base blue life // 320 base blue power and 125 base blue life
} == 320.pct(Skill::Blast.multiplier()) - 125); } == 320.pct(Skill::Blast.multiplier()) - 125);*/
} }
#[test] #[test]

View File

@ -590,7 +590,7 @@ impl Item {
Item::Red => format!("Combine two colours with a white base item to create a new combo. \n Fast speed, physical type. Chaos and momentum."), Item::Red => format!("Combine two colours with a white base item to create a new combo. \n Fast speed, physical type. Chaos and momentum."),
// base skills // base skills
Item::Attack => format!("Deal {:?}% RedPower as red damage.", /* Item::Attack => format!("Deal {:?}% RedPower as red damage.",
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Block => format!("Reduce red damage and blue damage taken by {:?}%. Block lasts {:?}T", Item::Block => format!("Reduce red damage and blue damage taken by {:?}%. Block lasts {:?}T",
100 - self.into_skill().unwrap().effect()[0].get_multiplier(), 100 - self.into_skill().unwrap().effect()[0].get_multiplier(),
@ -605,7 +605,7 @@ impl Item {
Item::Debuff => format!("Slows the target reducing SpeedStat by {:?}%. Debuff lasts {:?}T", Item::Debuff => format!("Slows the target reducing SpeedStat by {:?}%. Debuff lasts {:?}T",
100 - self.into_skill().unwrap().effect()[0].get_multiplier(), 100 - self.into_skill().unwrap().effect()[0].get_multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),*/
// specs // specs
// Base // Base
Item::Power => format!("Increases all power stats by {:?}%. Item::Power => format!("Increases all power stats by {:?}%.
@ -710,8 +710,7 @@ impl Item {
If your team meets total colour thresholds the spec provides additional bonuses.", If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()), self.into_spec().unwrap().values().base()),
// Skills <- need to move effect mulltipliers into skills /* Item::Amplify|
Item::Amplify|
Item::AmplifyPlus | Item::AmplifyPlus |
Item::AmplifyPlusPlus => format!("Increase RedPower BluePower by {:?}%. Lasts {:?}T.", Item::AmplifyPlusPlus => format!("Increase RedPower BluePower by {:?}%. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_multiplier() - 100, self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
@ -944,6 +943,8 @@ impl Item {
"Heals target for {:?}% GreenPower each turn. Lasts {:?}T.", "Heals target for {:?}% GreenPower each turn. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
*/
_ => format!("Missing"),
} }
} }

File diff suppressed because it is too large Load Diff