From ca6ab14282027d29ed6646518e80648386469ded Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 13 Dec 2019 14:50:31 +1000 Subject: [PATCH] maybe it works? --- core/src/game.rs | 603 ++++++------ core/src/skill.rs | 2364 +++++++++++++++++++++++---------------------- 2 files changed, 1488 insertions(+), 1479 deletions(-) diff --git a/core/src/game.rs b/core/src/game.rs index 13b2ea58..94d0a2e6 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -29,6 +29,7 @@ pub struct Game { pub players: Vec, pub phase: Phase, pub stack: Vec, + events: Vec, pub resolutions: Vec>, pub instance: Option, pub time_control: TimeControl, @@ -45,6 +46,7 @@ impl Game { players: vec![], phase: Phase::Start, stack: vec![], + events: vec![], resolutions: vec![], instance: None, time_control: TimeControl::Standard, @@ -440,7 +442,8 @@ impl Game { // because need to check cooldown use before pushing them into the complete list let mut r_animation_ms = 0; while let Some(cast) = self.stack.pop() { - self.resolve(cast, vec![]); + self.events = vec![]; + self.resolve(cast); // sort the stack again in case speeds have changed self.stack_sort_speed(); @@ -463,16 +466,16 @@ impl Game { self.skill_phase_start(r_animation_ms) } - fn resolve(&mut self, cast: Cast, mut events: Vec) -> Vec { + fn resolve(&mut self, cast: Cast) -> &mut Game { // If the skill is disabled for source nothing else will happen if let Some(effects) = self.construct(cast.source).disabled(cast.skill) { self.add_resolution(&cast, &Event::Disable { construct: cast.source, effects }); - return events; + return self; } // hastestrike / hybridblast for skill in self.construct(cast.source).additional_skills(cast.skill) { - events = self.resolve(Cast { skill, ..cast }, events); + self.resolve(Cast { skill, ..cast }); } // for aoe events send the source / target animations before each set of casts @@ -487,10 +490,10 @@ impl Game { let casts = self.modify_cast(cast); for cast in casts { - events = self.execute(cast, events); + self.execute(cast); } - events + self } fn modify_cast(&self, cast: Cast) -> Vec { @@ -516,15 +519,15 @@ impl Game { return casts; } - fn execute(&mut self, cast: Cast, mut events: Vec) -> Vec { + fn execute(&mut self, cast: Cast) -> &mut Game { if self.construct(cast.target).is_ko() { self.add_resolution(&cast, &Event::TargetKo { construct: cast.target }); - return events; + return self; } if let Some(immunity) = self.construct(cast.target).immune(cast.skill) { self.add_resolution(&cast, &Event::Immune { construct: cast.target, effects: immunity }); - return events; + return self; } if self.construct(cast.target).affected(Effect::Reflect) && cast.skill.colours().contains(&Colour::Blue) && !cast.skill.is_tick() { @@ -533,52 +536,56 @@ impl Game { // both reflecting, show it and bail if self.construct(cast.source).affected(Effect::Reflect) { self.add_resolution(&cast, &Event::Reflection { construct: cast.source }); - return events; + return self; } - return self.execute(Cast { target: cast.source, ..cast }, events); + return self.resolve(Cast { target: cast.source, ..cast }); } - for action in cast.actions(self, &events) { - let new_events = match action { - Action::Cast => vec![self.cast(cast)], - Action::Hit => vec![self.hit(cast)], + cast.resolve(self); - Action::Damage { construct, amount, colour } => self.damage(construct, amount, colour), - Action::Heal { construct, amount, colour } => self.heal(construct, amount, colour), + self + } - Action::Effect { construct, effect } => self.effect(construct, effect), - Action::Remove { construct, effect } => self.effect_remove(construct, effect), - Action::RemoveAll { construct } => self.remove_all(construct), - Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns), - Action::SetEffectMeta { construct, amount, effect } => self.effect_meta(construct, effect, amount), + pub fn action(&mut self, cast: Cast, action: Action) -> &mut Game { + let new_events = match action { + Action::Cast => vec![self.cast(cast)], + Action::Hit => vec![self.hit(cast)], + + Action::Damage { construct, amount, colour } => self.damage(construct, amount, colour), + Action::Heal { construct, amount, colour } => self.heal(construct, amount, colour), + + Action::Effect { construct, effect } => self.effect(construct, effect), + Action::Remove { construct, effect } => self.effect_remove(construct, effect), + Action::RemoveAll { construct } => self.remove_all(construct), + Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns), + Action::SetEffectMeta { construct, amount, effect } => self.effect_meta(construct, effect, amount), + }; + + // this event is now considered to have happened + // for chronological ordering it is added to the resolution list + // before extra processing on it begins + + for event in new_events { + self.add_resolution(&cast, &event); + + let casts = match event { + Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } => + self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event), + // Event::Cast {} => set_cooldown() + Event::Ko { construct } => + self.construct_by_id(construct).unwrap().on_ko(&cast, &event), + _ => vec![], }; - // this event is now considered to have happened - // for chronological ordering it is added to the resolution list - // before extra processing on it begins + self.events.push(event); - for event in new_events { - self.add_resolution(&cast, &event); - - let casts = match event { - Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } => - self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event), - // Event::Cast {} => set_cooldown() - Event::Ko { construct } => - self.construct_by_id(construct).unwrap().on_ko(&cast, &event), - _ => vec![], - }; - - events.push(event); - - for cast in casts { - events = self.resolve(cast, events); - } + for cast in casts { + self.resolve(cast); } } - events + self } fn add_resolution(&mut self, cast: &Cast, event: &Event) -> &mut Game { @@ -587,7 +594,7 @@ impl Game { self } - pub fn value(&self, value: Value, events: &Vec) -> usize { + pub fn value(&self, value: Value) -> usize { match value { Value::Stat { construct, stat } => self.construct(construct).stat(stat), @@ -602,7 +609,7 @@ impl Game { self.construct(construct).stat(Stat::Skills(colour)), Value::DamageReceived { construct, colour } => - 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: _ } => match construct == *event_construct && colour == *event_colour { true => dmg + amount, @@ -612,7 +619,7 @@ impl Game { }), Value::Removals { construct } => - 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: _ } => match construct == *event_construct { true => dmg + amount, @@ -817,7 +824,7 @@ pub enum Value { ColourSkills { construct: Uuid, colour: Colour }, Effects { construct: Uuid }, Removals { construct: Uuid }, - DamageReceived { construct: Uuid, colour: Colour, mult: usize }, + DamageReceived { construct: Uuid, colour: Colour }, } #[derive(Debug,Clone,PartialEq)] @@ -1640,313 +1647,313 @@ mod tests { // } - #[test] - fn upkeep_test() { - let mut game = create_2v2_test_game(); - game.players[0].set_ready(true); - game.phase_end = Some(Utc::now().checked_sub_signed(Duration::seconds(500)).unwrap()); - game = game.upkeep(); - // assert!(game.players[1].warnings == 1); - } + // #[test] + // fn upkeep_test() { + // let mut game = create_2v2_test_game(); + // game.players[0].set_ready(true); + // game.phase_end = Some(Utc::now().checked_sub_signed(Duration::seconds(500)).unwrap()); + // game = game.upkeep(); + // // assert!(game.players[1].warnings == 1); + // } - #[test] - fn attack_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; - game.add_skill(player_id, source, target, Skill::Attack).unwrap(); - game = game.resolve_phase_start(); - } + // #[test] + // fn attack_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; + // game.add_skill(player_id, source, target, Skill::Attack).unwrap(); + // game = game.resolve_phase_start(); + // } - #[test] - fn bash_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn bash_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Bash), vec![]); - } + // game.resolve(Cast::new(source, player_id, target, Skill::Bash)); + // } - #[test] - fn slay_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn slay_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Slay), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Slay)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation: _, display: _ } => - construct == target && amount > 0 && colour == Colour::Red, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + // construct == target && amount > 0 && colour == Colour::Red, + // _ => false, + // })); - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation: _, display: _ } => - construct == target && amount > 0 && colour == Colour::Red, - _ => false, - })); - } + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + // construct == target && amount > 0 && colour == Colour::Red, + // _ => false, + // })); + // } - #[test] - fn purify_test() { - let mut game = create_2v2_test_game(); - let source_player_id = game.players[0].id; - let target_player_id = game.players[1].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn purify_test() { + // let mut game = create_2v2_test_game(); + // let source_player_id = game.players[0].id; + // let target_player_id = game.players[1].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, source_player_id, target, Skill::Decay), vec![]); + // game.resolve(Cast::new(source, source_player_id, target, Skill::Decay)); - // don't mention 3 we volvo now - assert!(game.players[1].constructs[0].effects.len() == 3); + // // don't mention 3 we volvo now + // assert!(game.players[1].constructs[0].effects.len() == 3); - game.resolve(Cast::new(target, target_player_id, target, Skill::Purify), vec![]); + // game.resolve(Cast::new(target, target_player_id, target, Skill::Purify)); - assert!(game.players[1].constructs[0].effects.len() == 1); + // assert!(game.players[1].constructs[0].effects.len() == 1); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - assert!(resolutions.iter().any(|r| match r.event { - Event::Effect { construct, effect, duration: _, display: _ } => - construct == target && effect == Effect::Pure, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Effect { construct, effect, duration: _, display: _ } => + // construct == target && effect == Effect::Pure, + // _ => false, + // })); - // Check for healing here + // // Check for healing here - } + // } - #[test] - fn invert_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn invert_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Strike), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Invert), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Strike), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Strike)); + // game.resolve(Cast::new(source, player_id, target, Skill::Invert)); + // game.resolve(Cast::new(source, player_id, target, Skill::Strike)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - assert!(resolutions.iter().any(|r| match r.event { - Event::Healing { construct, colour, amount, overhealing: _, display: _, } => - construct == target && amount > 0 && colour == Colour::Green, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Healing { construct, colour, amount, overhealing: _, display: _, } => + // construct == target && amount > 0 && colour == Colour::Green, + // _ => false, + // })); - assert!(resolutions.iter().any(|r| match r.event { - Event::Healing { construct, colour, amount, overhealing: _, display: _ } => - construct == target && amount > 0 && colour == Colour::Red, - _ => false, - })); - } + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Healing { construct, colour, amount, overhealing: _, display: _ } => + // construct == target && amount > 0 && colour == Colour::Red, + // _ => false, + // })); + // } - #[test] - fn siphon_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn siphon_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Siphon)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - // siphon should - // apply effect // damage target // heal source - assert!(resolutions.iter().any(|r| match r.event { - Event::Effect { construct, effect, duration: _, display: _ } => - construct == target && effect == Effect::Siphon, - _ => false, - })); + // // siphon should + // // apply effect // damage target // heal source + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Effect { construct, effect, duration: _, display: _ } => + // construct == target && effect == Effect::Siphon, + // _ => false, + // })); - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation: _, display: _ } => - construct == target && amount > 0 && colour == Colour::Blue, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + // construct == target && amount > 0 && colour == Colour::Blue, + // _ => false, + // })); - assert!(resolutions.iter().any(|r| match r.event { - Event::Healing { construct, colour, amount: _, overhealing: _, display: _ } => - construct == source && colour == Colour::Green, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Healing { construct, colour, amount: _, overhealing: _, display: _ } => + // construct == source && colour == Colour::Green, + // _ => false, + // })); - game = game.resolve_phase_start(); + // game = game.resolve_phase_start(); - // que ota? - game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // // que ota? + // game.resolve(Cast::new(source, player_id, target, Skill::Siphon)); + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - let damage_events = resolutions.iter().filter(|r| match r.event { - Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => true, - _ => false, - }).count(); + // let damage_resolutions.iter().filter(|r| match r.event { + // Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => true, + // _ => false, + // }).count(); - assert_eq!(damage_events, 1); - } + // assert_eq!(damage_events, 1); + // } - #[test] - fn reflect_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn reflect_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Reflect), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Reflect)); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation: _, display: _ } => - construct == source && amount > 0 && colour == Colour::Blue, - _ => false, - })); - } + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + // construct == source && amount > 0 && colour == Colour::Blue, + // _ => false, + // })); + // } - #[test] - fn absorb_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn absorb_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Absorb), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Absorb)); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation: _, display: _ } => { - assert!(construct == target && amount > 0 && colour == Colour::Blue && r.skill == Skill::Blast); - resolutions.iter().any(|r| match r.event { - Event::Meta { construct, effect, meta } => - construct == target && effect == Effect::Absorption && { - match meta { - EffectMeta::AddedDamage(added_dmg) => added_dmg == amount, - _ => false, - } - }, - _ => false, - }) - }, - _ => false, - })); + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => { + // assert!(construct == target && amount > 0 && colour == Colour::Blue && r.skill == Skill::Blast); + // resolutions.iter().any(|r| match r.event { + // Event::Meta { construct, effect, meta } => + // construct == target && effect == Effect::Absorption && { + // match meta { + // EffectMeta::AddedDamage(added_dmg) => added_dmg == amount, + // _ => false, + // } + // }, + // _ => false, + // }) + // }, + // _ => false, + // })); - assert!(match game.players[1].constructs[0].effects[0].meta { - Some(EffectMeta::AddedDamage(d)) => d, - _ => 0 - // 320 base blue power and 125 base blue life - } == 320.pct(Skill::Blast.multiplier()) - 125); + // assert!(match game.players[1].constructs[0].effects[0].meta { + // Some(EffectMeta::AddedDamage(d)) => d, + // _ => 0 + // // 320 base blue power and 125 base blue life + // } == 320.pct(Skill::Blast.multiplier()) - 125); - } + // } - #[test] - fn absorb_multi_damage_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // #[test] + // fn absorb_multi_damage_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); - // Abosrb restores blue life here - game.resolve(Cast::new(source, player_id, target, Skill::Absorb), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); + // // Abosrb restores blue life here + // game.resolve(Cast::new(source, player_id, target, Skill::Absorb)); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); - assert!(match game.players[1].constructs[0].effects[0].meta { - Some(EffectMeta::AddedDamage(d)) => d, - _ => 0 - // 320 base blue power and 125 base blue life - } == 320.pct(Skill::Blast.multiplier()) - 125); - } + // assert!(match game.players[1].constructs[0].effects[0].meta { + // Some(EffectMeta::AddedDamage(d)) => d, + // _ => 0 + // // 320 base blue power and 125 base blue life + // } == 320.pct(Skill::Blast.multiplier()) - 125); + // } - #[test] - fn multi_reflect_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let target_player_id = game.players[1].id; + // #[test] + // fn multi_reflect_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let target_player_id = game.players[1].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, source, Skill::Reflect), vec![]); - game.resolve(Cast::new(target, target_player_id, target, Skill::Reflect), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); + // game.resolve(Cast::new(source, player_id, source, Skill::Reflect)); + // game.resolve(Cast::new(target, target_player_id, target, Skill::Reflect)); + // game.resolve(Cast::new(source, player_id, target, Skill::Blast)); - assert!(game.players[0].constructs[0].is_ko() == false); - assert!(game.players[1].constructs[0].is_ko() == false); - } + // assert!(game.players[0].constructs[0].is_ko() == false); + // assert!(game.players[1].constructs[0].is_ko() == false); + // } - // refer fixme.md (infinite counterattack loop) - /*#[test] - fn multi_counter_test() { - let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let target_player_id = game.players[1].id; + // // refer fixme.md (infinite counterattack loop) + // /*#[test] + // fn multi_counter_test() { + // let mut game = create_2v2_test_game(); + // let player_id = game.players[0].id; + // let target_player_id = game.players[1].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, source, Skill::Counter), vec![]); - game.resolve(Cast::new(target, target_player_id, target, Skill::Counter), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Attack), vec![]); + // game.resolve(Cast::new(source, player_id, source, Skill::Counter)); + // game.resolve(Cast::new(target, target_player_id, target, Skill::Counter)); + // game.resolve(Cast::new(source, player_id, target, Skill::Attack)); - assert!(game.players[0].constructs[0].is_ko() == false); - assert!(game.players[1].constructs[0].is_ko() == false); - }*/ + // assert!(game.players[0].constructs[0].is_ko() == false); + // assert!(game.players[1].constructs[0].is_ko() == false); + // }*/ - #[test] - fn intercept_test() { + // #[test] + // fn intercept_test() { - let mut game = create_2v2_test_game(); + // let mut game = create_2v2_test_game(); - let player_id = game.players[0].id; - let other_player_id = game.players[1].id; + // let player_id = game.players[0].id; + // let other_player_id = game.players[1].id; - let source = game.players[0].constructs[0].id; - let target = game.players[1].constructs[0].id; - let interceptor = game.players[1].constructs[1].id; + // let source = game.players[0].constructs[0].id; + // let target = game.players[1].constructs[0].id; + // let interceptor = game.players[1].constructs[1].id; - // Cast intercept - game.resolve(Cast::new(interceptor, other_player_id, interceptor, Skill::Intercept), vec![]); - // Enemy casts skill on target which as a teammate intercepting - game.resolve(Cast::new(source, player_id, target, Skill::Attack), vec![]); - // Intercepting teammate attacks someone on same team - game.resolve(Cast::new(interceptor, other_player_id, target, Skill::Attack), vec![]); + // // Cast intercept + // game.resolve(Cast::new(interceptor, other_player_id, interceptor, Skill::Intercept)); + // // Enemy casts skill on target which as a teammate intercepting + // game.resolve(Cast::new(source, player_id, target, Skill::Attack)); + // // Intercepting teammate attacks someone on same team + // game.resolve(Cast::new(interceptor, other_player_id, target, Skill::Attack)); - let last = game.resolutions.len() - 1; - let resolutions = &game.resolutions[last]; + // let last = game.resolutions.len() - 1; + // let resolutions = &game.resolutions[last]; - // There should be no damage events on the target - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation, display: _ } => - construct == target && (amount > 0 || mitigation > 0) && colour == Colour::Red, - _ => false, - }) == false); + // // There should be no damage events on the target + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation, display: _ } => + // construct == target && (amount > 0 || mitigation > 0) && colour == Colour::Red, + // _ => false, + // }) == false); - // Should be damage events on the interceptor - assert!(resolutions.iter().any(|r| match r.event { - Event::Damage { construct, colour, amount, mitigation, display: _ } => - construct == interceptor && (amount > 0 || mitigation > 0) && colour == Colour::Red, - _ => false, - })); + // // Should be damage events on the interceptor + // assert!(resolutions.iter().any(|r| match r.event { + // Event::Damage { construct, colour, amount, mitigation, display: _ } => + // construct == interceptor && (amount > 0 || mitigation > 0) && colour == Colour::Red, + // _ => false, + // })); } /* @@ -1957,8 +1964,8 @@ mod tests { let source = game.players[0].constructs[0].id; let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Decay), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); + game.resolve(Cast::new(source, player_id, target, Skill::Decay)); + game.resolve(Cast::new(source, player_id, target, Skill::Siphon)); game = game.resolve_phase_start(); @@ -1972,9 +1979,9 @@ mod tests { let source = game.players[0].constructs[0].id; let target = game.players[1].constructs[0].id; - game.resolve(Cast::new(source, player_id, target, Skill::Decay), vec![]); - game.resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus), vec![]); - game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); + game.resolve(Cast::new(source, player_id, target, Skill::Decay)); + game.resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus)); + game.resolve(Cast::new(source, player_id, target, Skill::Siphon)); game = game.resolve_phase_start(); @@ -1982,4 +1989,4 @@ mod tests { let resolutions = &game.resolutions[last]; assert!(Skill::SiphonTick == resolutions[0].skill); }*/ -} +// } diff --git a/core/src/skill.rs b/core/src/skill.rs index d22cf382..8698454b 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -47,7 +47,7 @@ impl Cast { } } - pub fn actions(&self, game: &Game, events: &Vec) -> Vec { + pub fn resolve(self, game: &mut Game) { let mut actions = vec![]; if !self.skill.aoe() { @@ -57,163 +57,164 @@ impl Cast { actions.push(Action::Hit); } - let mut rest = match self.skill { - Skill::Attack => attack(self, game, events), - Skill::Block => block(self, game, events), - Skill::Buff => buff(self, game, events), - Skill::Debuff => debuff(self, game, events), - Skill::Stun => stun(self, game, events), + match self.skill { + _ => attack(self, game), + // Skill::Attack => attack(self, game, events), + // Skill::Block => block(self, game, events), + // Skill::Buff => buff(self, game, events), + // Skill::Debuff => debuff(self, game, events), + // Skill::Stun => stun(self, game, events), - Skill::Amplify => amplify(self, game, events), - Skill::AmplifyPlus => amplify_plus(self, game, events), - Skill::AmplifyPlusPlus => amplify_plus_plus(self, game, events), + // Skill::Amplify => amplify(self, game, events), + // Skill::AmplifyPlus => amplify_plus(self, game, events), + // Skill::AmplifyPlusPlus => amplify_plus_plus(self, game, events), - Skill::Absorb => absorb(self, game, events), - Skill::AbsorbPlus => absorb_plus(self, game, events), - Skill::AbsorbPlusPlus => absorb_plus_plus(self, game, events), - Skill::Absorption => absorption(self, game, events), - Skill::AbsorptionPlus => absorption_plus(self, game, events), - Skill::AbsorptionPlusPlus => absorption_plus_plus(self, game, events), + // Skill::Absorb => absorb(self, game, events), + // Skill::AbsorbPlus => absorb_plus(self, game, events), + // Skill::AbsorbPlusPlus => absorb_plus_plus(self, game, events), + // Skill::Absorption => absorption(self, game, events), + // Skill::AbsorptionPlus => absorption_plus(self, game, events), + // Skill::AbsorptionPlusPlus => absorption_plus_plus(self, game, events), - Skill::Banish | - Skill::BanishPlus | - Skill::BanishPlusPlus => banish(self, game, events), + // Skill::Banish | + // Skill::BanishPlus | + // Skill::BanishPlusPlus => banish(self, game, events), - Skill::Bash | - Skill::BashPlus | - Skill::BashPlusPlus => bash(self, game, events), + // Skill::Bash | + // Skill::BashPlus | + // Skill::BashPlusPlus => bash(self, game, events), - Skill::Blast | - Skill::BlastPlus | - Skill::BlastPlusPlus => blast(self, game, events), + // Skill::Blast | + // Skill::BlastPlus | + // Skill::BlastPlusPlus => blast(self, game, events), - Skill::Break => break_zero(self, game, events), - Skill::BreakPlus => break_plus(self, game, events), - Skill::BreakPlusPlus => break_plus_plus(self, game, events), + // Skill::Break => break_zero(self, game, events), + // Skill::BreakPlus => break_plus(self, game, events), + // Skill::BreakPlusPlus => break_plus_plus(self, game, events), - Skill::Curse => curse(self, game, events), - Skill::CursePlus => curse_plus(self, game, events), - Skill::CursePlusPlus => curse_plus_plus(self, game, events), + // Skill::Curse => curse(self, game, events), + // Skill::CursePlus => curse_plus(self, game, events), + // Skill::CursePlusPlus => curse_plus_plus(self, game, events), - Skill::Chaos | - Skill::ChaosPlus | - Skill::ChaosPlusPlus => chaos(self, game, events), + // Skill::Chaos | + // Skill::ChaosPlus | + // Skill::ChaosPlusPlus => chaos(self, game, events), - Skill::Counter => counter(self, game, events), - Skill::CounterPlus => counter_plus(self, game, events), - Skill::CounterPlusPlus => counter_plus_plus(self, game, events), - Skill::CounterAttack | - Skill::CounterAttackPlus | - Skill::CounterAttackPlusPlus => counter_attack(self, game, events), + // Skill::Counter => counter(self, game, events), + // Skill::CounterPlus => counter_plus(self, game, events), + // Skill::CounterPlusPlus => counter_plus_plus(self, game, events), + // Skill::CounterAttack | + // Skill::CounterAttackPlus | + // Skill::CounterAttackPlusPlus => counter_attack(self, game, events), - Skill::Decay => decay(self, game, events), - Skill::DecayPlus => decay_plus(self, game, events), - Skill::DecayPlusPlus => decay_plus_plus(self, game, events), - Skill::DecayTick | - Skill::DecayTickPlus | - Skill::DecayTickPlusPlus => decay_tick(self, game, events), + // Skill::Decay => decay(self, game, events), + // Skill::DecayPlus => decay_plus(self, game, events), + // Skill::DecayPlusPlus => decay_plus_plus(self, game, events), + // Skill::DecayTick | + // Skill::DecayTickPlus | + // Skill::DecayTickPlusPlus => decay_tick(self, game, events), - Skill::Electrify => electrify(self, game, events), - Skill::ElectrifyPlus => electrify_plus(self, game, events), - Skill::ElectrifyPlusPlus => electrify_plus_plus(self, game, events), - Skill::Electrocute => electrocute(self, game, events), - Skill::ElectrocutePlus => electrocute_plus(self, game, events), - Skill::ElectrocutePlusPlus => electrocute_plus_plus(self, game, events), - Skill::ElectrocuteTick | - Skill::ElectrocuteTickPlus | - Skill::ElectrocuteTickPlusPlus => electrocute_tick(self, game, events), + // Skill::Electrify => electrify(self, game, events), + // Skill::ElectrifyPlus => electrify_plus(self, game, events), + // Skill::ElectrifyPlusPlus => electrify_plus_plus(self, game, events), + // Skill::Electrocute => electrocute(self, game, events), + // Skill::ElectrocutePlus => electrocute_plus(self, game, events), + // Skill::ElectrocutePlusPlus => electrocute_plus_plus(self, game, events), + // Skill::ElectrocuteTick | + // Skill::ElectrocuteTickPlus | + // Skill::ElectrocuteTickPlusPlus => electrocute_tick(self, game, events), - Skill::Heal | - Skill::HealPlus | - Skill::HealPlusPlus => heal(self, game, events), + // Skill::Heal | + // Skill::HealPlus | + // Skill::HealPlusPlus => heal(self, game, events), - Skill::Haste => haste(self, game, events), - Skill::HastePlus => haste_plus(self, game, events), - Skill::HastePlusPlus => haste_plus_plus(self, game, events), + // Skill::Haste => haste(self, game, events), + // Skill::HastePlus => haste_plus(self, game, events), + // Skill::HastePlusPlus => haste_plus_plus(self, game, events), - Skill::HasteStrike => haste_strike(self, game, events), + // Skill::HasteStrike => haste_strike(self, game, events), - Skill::Hybrid => hybrid(self, game, events), - Skill::HybridPlus => hybrid_plus(self, game, events), - Skill::HybridPlusPlus => hybrid_plus_plus(self, game, events), + // Skill::Hybrid => hybrid(self, game, events), + // Skill::HybridPlus => hybrid_plus(self, game, events), + // Skill::HybridPlusPlus => hybrid_plus_plus(self, game, events), - Skill::HybridBlast => hybrid_blast(self, game, events), + // Skill::HybridBlast => hybrid_blast(self, game, events), - Skill::Intercept | - Skill::InterceptPlus | - Skill::InterceptPlusPlus => intercept(self, game, events), + // Skill::Intercept | + // Skill::InterceptPlus | + // Skill::InterceptPlusPlus => intercept(self, game, events), - Skill::Invert => invert(self, game, events), - Skill::InvertPlus => invert_plus(self, game, events), - Skill::InvertPlusPlus => invert_plus_plus(self, game, events), + // Skill::Invert => invert(self, game, events), + // Skill::InvertPlus => invert_plus(self, game, events), + // Skill::InvertPlusPlus => invert_plus_plus(self, game, events), - Skill::Link | - Skill::LinkPlus | - Skill::LinkPlusPlus => link(self, game, events), + // Skill::Link | + // Skill::LinkPlus | + // Skill::LinkPlusPlus => link(self, game, events), - Skill::Purge => purge(self, game, events), - Skill::PurgePlus => purge_plus(self, game, events), - Skill::PurgePlusPlus => purge_plus_plus(self, game, events), + // Skill::Purge => purge(self, game, events), + // Skill::PurgePlus => purge_plus(self, game, events), + // Skill::PurgePlusPlus => purge_plus_plus(self, game, events), - Skill::Purify => purify(self, game, events), - Skill::PurifyPlus => purify_plus(self, game, events), - Skill::PurifyPlusPlus => purify_plus_plus(self, game, events), + // Skill::Purify => purify(self, game, events), + // Skill::PurifyPlus => purify_plus(self, game, events), + // Skill::PurifyPlusPlus => purify_plus_plus(self, game, events), - Skill::Recharge | - Skill::RechargePlus | - Skill::RechargePlusPlus => recharge(self, game, events), + // Skill::Recharge | + // Skill::RechargePlus | + // Skill::RechargePlusPlus => recharge(self, game, events), - Skill::Reflect | - Skill::ReflectPlus | - Skill::ReflectPlusPlus => reflect(self, game, events), + // Skill::Reflect | + // Skill::ReflectPlus | + // Skill::ReflectPlusPlus => reflect(self, game, events), - Skill::Restrict | - Skill::RestrictPlus | - Skill::RestrictPlusPlus => restrict(self, game, events), + // Skill::Restrict | + // Skill::RestrictPlus | + // Skill::RestrictPlusPlus => restrict(self, game, events), - Skill::Ruin | - Skill::RuinPlus | - Skill::RuinPlusPlus => ruin(self, game, events), + // Skill::Ruin | + // Skill::RuinPlus | + // Skill::RuinPlusPlus => ruin(self, game, events), - Skill::Siphon => siphon(self, game, events), - Skill::SiphonPlus => siphon_plus(self, game, events), - Skill::SiphonPlusPlus => siphon_plus_plus(self, game, events), - Skill::SiphonTick | - Skill::SiphonTickPlus | - Skill::SiphonTickPlusPlus => siphon_tick(self, game, events), + // Skill::Siphon => siphon(self, game, events), + // Skill::SiphonPlus => siphon_plus(self, game, events), + // Skill::SiphonPlusPlus => siphon_plus_plus(self, game, events), + // Skill::SiphonTick | + // Skill::SiphonTickPlus | + // Skill::SiphonTickPlusPlus => siphon_tick(self, game, events), - Skill::Slay | - Skill::SlayPlus | - Skill::SlayPlusPlus => slay(self, game, events), + // Skill::Slay | + // Skill::SlayPlus | + // Skill::SlayPlusPlus => slay(self, game, events), - Skill::Sleep => sleep(self, game, events), - Skill::SleepPlus => sleep_plus(self, game, events), - Skill::SleepPlusPlus => sleep_plus_plus(self, game, events), + // Skill::Sleep => sleep(self, game, events), + // Skill::SleepPlus => sleep_plus(self, game, events), + // Skill::SleepPlusPlus => sleep_plus_plus(self, game, events), - Skill::Silence | - Skill::SilencePlus | - Skill::SilencePlusPlus => silence(self, game, events), + // Skill::Silence | + // Skill::SilencePlus | + // Skill::SilencePlusPlus => silence(self, game, events), - Skill::Strike | - Skill::StrikePlus | - Skill::StrikePlusPlus => strike(self, game, events), + // Skill::Strike | + // Skill::StrikePlus | + // Skill::StrikePlusPlus => strike(self, game, events), - Skill::Sustain | - Skill::SustainPlus | - Skill::SustainPlusPlus => sustain(self, game, events), + // Skill::Sustain | + // Skill::SustainPlus | + // Skill::SustainPlusPlus => sustain(self, game, events), - Skill::Triage => triage(self, game, events), - Skill::TriagePlus => triage_plus(self, game, events), - Skill::TriagePlusPlus => triage_plus_plus(self, game, events), - Skill::TriageTick | - Skill::TriageTickPlus | - Skill::TriageTickPlusPlus => triage_tick(self, game, events), + // Skill::Triage => triage(self, game, events), + // Skill::TriagePlus => triage_plus(self, game, events), + // Skill::TriagePlusPlus => triage_plus_plus(self, game, events), + // Skill::TriageTick | + // Skill::TriageTickPlus | + // Skill::TriageTickPlusPlus => triage_tick(self, game, events), }; - actions.append(&mut rest); - return actions; + // actions.append(&mut rest); + // return actions; } } @@ -1112,1068 +1113,1069 @@ impl Skill { } } -fn attack(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ +fn attack(cast: Cast, game: &mut Game) { + game.action( + cast, Action::Damage { construct: cast.target, colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn block(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Block, duration: 1, meta: Some(EffectMeta::Multiplier(35)) }, - }, - ] -} - -fn buff(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Buff, duration: 3, meta: Some(EffectMeta::Multiplier(130)) }, - }, - ] -} - -fn debuff(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Slow, duration: 3, meta: Some(EffectMeta::Multiplier(50)) }, - }, - ] -} - -fn stun(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, - }, - ] -} - - -fn amplify(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)) }, - }, - ] -} - -fn amplify_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)) }, - }, - ] -} - -fn amplify_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)) }, - }, - ] -} - -fn absorb(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::Absorption)) }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn absorb_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::AbsorptionPlus)) }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn absorb_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::AbsorptionPlusPlus)) }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn absorption(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Absorb, - }, - Action::Effect { - construct: cast.source, - effect: ConstructEffect { effect: Effect::Absorption, duration: 3, meta: Some(EffectMeta::AddedDamage(0)) }, - }, - Action::SetEffectMeta { - construct: cast.source, - effect: Effect::Absorption, - amount: game.value(Value::DamageReceived { construct: cast.source, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn absorption_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Absorb, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Absorption, duration: 4, meta: Some(EffectMeta::AddedDamage(0)) }, - }, - Action::SetEffectMeta { - construct: cast.target, - effect: Effect::Absorption, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn absorption_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Absorb, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Absorption, duration: 5, meta: Some(EffectMeta::AddedDamage(0)) }, - }, - Action::SetEffectMeta { - construct: cast.target, - effect: Effect::Absorption, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events), - }, - ] -} - -fn banish(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.target, stat: Stat::RedLife }, events).pct(cast.skill.multiplier()), - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.target, stat: Stat::BlueLife }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None } - } - ] -} - -fn bash(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let cds = game.value(Value::Cooldowns { construct: cast.source }, events); - let red_power = game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events); - let amount = red_power.pct(cast.skill.multiplier().pct(100 + 45usize.saturating_mul(cds))); - - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None } - }, - Action::IncreaseCooldowns { - construct: cast.target, - turns: 1, - }, - ] -} - -fn blast(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn break_zero(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Vulnerable, duration: 3, meta: Some(EffectMeta::Multiplier(150)), }, - }, - ] -} - -fn break_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(175)), }, - }, - ] -} - -fn break_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(200)), }, - }, - ] -} - - -fn curse(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Curse, duration: 2, meta: Some(EffectMeta::Multiplier(150)) }, - }, - ] -} - -fn curse_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Curse, duration: 2, meta: Some(EffectMeta::Multiplier(175)) }, - }, - ] -} - -fn curse_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Curse, duration: 3, meta: Some(EffectMeta::Multiplier(200)) }, - }, - ] -} - - -fn chaos(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let mut rng = thread_rng(); - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: - game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier() + rng.gen_range(0, 30)) - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: - game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier() + rng.gen_range(0, 30)) - }, - ] -} - -fn counter(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttack)) }, - }, - ] -} - -fn counter_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttackPlus)) }, - }, - ] -} - -fn counter_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttackPlusPlus)) }, - }, - ] -} - -fn counter_attack(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn decay(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(50)) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decay, duration: 2, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick }) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks - }, - ] -} - -fn decay_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(35)) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlus }) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks - }, - ] -} - -fn decay_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Wither, duration: 4, meta: Some(EffectMeta::Multiplier(20)) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlusPlus }) }, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks - }, - ] -} - -fn decay_tick(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks - }, - ] -} - -fn electrify(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::Electrocute)) }, - }, - ] -} - -fn electrify_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::ElectrocutePlus)) }, - }, - ] -} - -fn electrify_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::ElectrocutePlusPlus)) }, - }, - ] -} - -fn electrocute(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Electric, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 2, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick }) }, - }, - ] -} -fn electrocute_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Electric, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 3, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlus }) }, - }, - ] -} - -fn electrocute_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Remove { - construct: cast.source, - effect: Effect::Electric, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Electric, duration: 4, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlusPlus }) }, - }, - ] -} - -fn electrocute_tick(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn heal(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn haste(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(150)) }, - }, - ] -} - -fn haste_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(175)) }, - }, - ] -} - -fn haste_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(225)) }, - }, - ] -} - -fn haste_strike(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::Speed }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn hybrid(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Hybrid, duration: 3, meta: Some(EffectMeta::Multiplier(150)) }, - }, - ] -} - -fn hybrid_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Hybrid, duration: 4, meta: Some(EffectMeta::Multiplier(175)) }, - }, - ] -} - -fn hybrid_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Hybrid, duration: 5, meta: Some(EffectMeta::Multiplier(200)) }, - }, - ] -} - -fn hybrid_blast(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn intercept(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Intercept, duration: 1, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - colour: Colour::Red, - }, - ] -} - -fn invert(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Invert, duration: 2, meta: None }, - }, - ] -} - -fn invert_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Invert, duration: 3, meta: None }, - }, - ] -} - -fn invert_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Invert, duration: 4, meta: None }, - }, - ] -} - -fn link(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Effects { construct: cast.target }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn purge(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Purge, duration: 2, meta: None } - }, - ] -} - -fn purge_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Purge, duration: 3, meta: None } - }, - ] -} - -fn purge_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Purge, duration: 4, meta: None } - }, - ] -} - -fn purify(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); - let rms = game.value(Value::Removals { construct: cast.target }, events); - let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); - - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(150)) } - }, - ] -} - -fn purify_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); - let rms = game.value(Value::Removals { construct: cast.target }, events); - let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); - - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(175)) } - }, - ] -} - -fn purify_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); - let rms = game.value(Value::Removals { construct: cast.target }, events); - let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); - - vec![ - Action::RemoveAll { - construct: cast.target, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount, - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(200)) } - }, - ] -} - -fn recharge(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Heal { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - }, - Action::Heal { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn reflect(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Reflect, duration: 1, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn restrict(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Restrict, duration: 2, meta: None } - }, - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::ColourSkills { construct: cast.source, colour: Colour::Red }, events).pct(cast.skill.multiplier()), - }, - ] -} - - -fn ruin(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.target, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None } - } - ] -} - - -fn siphon(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphon, duration: 2, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick }) }, - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks - }, - Action::Heal { - construct: cast.source, - colour: Colour::Green, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn siphon_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphon, duration: 3, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlus }) }, - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks - }, - Action::Heal { - construct: cast.source, - colour: Colour::Green, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn siphon_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphon, duration: 4, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlusPlus }) }, - }, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks - }, - Action::Heal { - construct: cast.source, - colour: Colour::Green, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn siphon_tick(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks - }, - Action::Heal { - construct: cast.source, - colour: Colour::Green, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), - }, - ] -} - -fn slay(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - }, - Action::Heal { - construct: cast.source, - colour: Colour::Green, - amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Red, mult: 50 }, events), - }, - ] -} - -fn sleep(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn sleep_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn sleep_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - colour: Colour::Blue, - }, - ] -} - -fn silence(cast: &Cast, game: &Game, events: &Vec) -> Vec { - let bp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); - let silences = game.value(Value::ColourSkills { construct: cast.target, colour: Colour::Blue }, events); - let amount = bp.pct(45usize.saturating_mul(silences)); - - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Silence, duration: 2, meta: None }, - }, - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount, - }, - ] -} - -fn strike(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Damage { - construct: cast.target, - colour: Colour::Red, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - }, - ] -} - -fn sustain(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }, - }, - Action::Heal { - construct: cast.target, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), - colour: Colour::Red, - }, - ] -} - -fn triage(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triage, duration: 2, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick }) }, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, - }, - ] -} - -fn triage_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triage, duration: 3, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlus }) }, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, - }, - ] -} - -fn triage_plus_plus(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triage, duration: 4, meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlusPlus }) }, - }, - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, - }, - ] -} - -fn triage_tick(cast: &Cast, game: &Game, events: &Vec) -> Vec { - vec![ - Action::Heal { - construct: cast.target, - colour: Colour::Green, - amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), - }, - Action::Effect { - construct: cast.target, - effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, - }, - ] -} + amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }).pct(cast.skill.multiplier()), + }, + ); +} + +// fn block(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Block, duration: 1, meta: Some(EffectMeta::Multiplier(35)) }, +// }, +// ] +// } + +// fn buff(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Buff, duration: 3, meta: Some(EffectMeta::Multiplier(130)) }, +// }, +// ] +// } + +// fn debuff(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Slow, duration: 3, meta: Some(EffectMeta::Multiplier(50)) }, +// }, +// ] +// } + +// fn stun(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, +// }, +// ] +// } + + +// fn amplify(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Amplify, duration: 2, meta: Some(EffectMeta::Multiplier(150)) }, +// }, +// ] +// } + +// fn amplify_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Amplify, duration: 3, meta: Some(EffectMeta::Multiplier(175)) }, +// }, +// ] +// } + +// fn amplify_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Amplify, duration: 4, meta: Some(EffectMeta::Multiplier(200)) }, +// }, +// ] +// } + +// fn absorb(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::Absorption)) }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn absorb_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::AbsorptionPlus)) }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn absorb_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Absorb, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::AbsorptionPlusPlus)) }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn absorption(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Absorb, +// }, +// Action::Effect { +// construct: cast.source, +// effect: ConstructEffect { effect: Effect::Absorption, duration: 3, meta: Some(EffectMeta::AddedDamage(0)) }, +// }, +// Action::SetEffectMeta { +// construct: cast.source, +// effect: Effect::Absorption, +// amount: game.value(Value::DamageReceived { construct: cast.source, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn absorption_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Absorb, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Absorption, duration: 4, meta: Some(EffectMeta::AddedDamage(0)) }, +// }, +// Action::SetEffectMeta { +// construct: cast.target, +// effect: Effect::Absorption, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn absorption_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Absorb, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Absorption, duration: 5, meta: Some(EffectMeta::AddedDamage(0)) }, +// }, +// Action::SetEffectMeta { +// construct: cast.target, +// effect: Effect::Absorption, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events), +// }, +// ] +// } + +// fn banish(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.target, stat: Stat::RedLife }, events).pct(cast.skill.multiplier()), +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.target, stat: Stat::BlueLife }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Banish, duration: 2, meta: None } +// } +// ] +// } + +// fn bash(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let cds = game.value(Value::Cooldowns { construct: cast.source }, events); +// let red_power = game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events); +// let amount = red_power.pct(cast.skill.multiplier().pct(100 + 45usize.saturating_mul(cds))); + +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None } +// }, +// Action::IncreaseCooldowns { +// construct: cast.target, +// turns: 1, +// }, +// ] +// } + +// fn blast(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn break_zero(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Vulnerable, duration: 3, meta: Some(EffectMeta::Multiplier(150)), }, +// }, +// ] +// } + +// fn break_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(175)), }, +// }, +// ] +// } + +// fn break_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(200)), }, +// }, +// ] +// } + + +// fn curse(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Curse, duration: 2, meta: Some(EffectMeta::Multiplier(150)) }, +// }, +// ] +// } + +// fn curse_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Curse, duration: 2, meta: Some(EffectMeta::Multiplier(175)) }, +// }, +// ] +// } + +// fn curse_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Curse, duration: 3, meta: Some(EffectMeta::Multiplier(200)) }, +// }, +// ] +// } + + +// fn chaos(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let mut rng = thread_rng(); +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: +// game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier() + rng.gen_range(0, 30)) +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: +// game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier() + rng.gen_range(0, 30)) +// }, +// ] +// } + +// fn counter(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttack)) }, +// }, +// ] +// } + +// fn counter_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttackPlus)) }, +// }, +// ] +// } + +// fn counter_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Counter, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::CounterAttackPlusPlus)) }, +// }, +// ] +// } + +// fn counter_attack(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn decay(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(50)) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decay, duration: 2, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick }) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks +// }, +// ] +// } + +// fn decay_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(35)) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlus }) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks +// }, +// ] +// } + +// fn decay_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Wither, duration: 4, meta: Some(EffectMeta::Multiplier(20)) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlusPlus }) }, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks +// }, +// ] +// } + +// fn decay_tick(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Decayed, duration: 1, meta: None }, // immunity to additional ticks +// }, +// ] +// } + +// fn electrify(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::Electrocute)) }, +// }, +// ] +// } + +// fn electrify_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::ElectrocutePlus)) }, +// }, +// ] +// } + +// fn electrify_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 1, meta: Some(EffectMeta::CastOnHit(Skill::ElectrocutePlusPlus)) }, +// }, +// ] +// } + +// fn electrocute(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Electric, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 2, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick }) }, +// }, +// ] +// } +// fn electrocute_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Electric, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 3, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlus }) }, +// }, +// ] +// } + +// fn electrocute_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Remove { +// construct: cast.source, +// effect: Effect::Electric, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Electric, duration: 4, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlusPlus }) }, +// }, +// ] +// } + +// fn electrocute_tick(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn heal(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn haste(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(150)) }, +// }, +// ] +// } + +// fn haste_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(175)) }, +// }, +// ] +// } + +// fn haste_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Haste, duration: 3, meta: Some(EffectMeta::Multiplier(225)) }, +// }, +// ] +// } + +// fn haste_strike(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::Speed }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn hybrid(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Hybrid, duration: 3, meta: Some(EffectMeta::Multiplier(150)) }, +// }, +// ] +// } + +// fn hybrid_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Hybrid, duration: 4, meta: Some(EffectMeta::Multiplier(175)) }, +// }, +// ] +// } + +// fn hybrid_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Hybrid, duration: 5, meta: Some(EffectMeta::Multiplier(200)) }, +// }, +// ] +// } + +// fn hybrid_blast(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn intercept(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Intercept, duration: 1, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Red, +// }, +// ] +// } + +// fn invert(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Invert, duration: 2, meta: None }, +// }, +// ] +// } + +// fn invert_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Invert, duration: 3, meta: None }, +// }, +// ] +// } + +// fn invert_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Invert, duration: 4, meta: None }, +// }, +// ] +// } + +// fn link(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None }, +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Effects { construct: cast.target }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn purge(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Purge, duration: 2, meta: None } +// }, +// ] +// } + +// fn purge_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Purge, duration: 3, meta: None } +// }, +// ] +// } + +// fn purge_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Purge, duration: 4, meta: None } +// }, +// ] +// } + +// fn purify(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); +// let rms = game.value(Value::Removals { construct: cast.target }, events); +// let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); + +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(150)) } +// }, +// ] +// } + +// fn purify_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); +// let rms = game.value(Value::Removals { construct: cast.target }, events); +// let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); + +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(175)) } +// }, +// ] +// } + +// fn purify_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let gp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); +// let rms = game.value(Value::Removals { construct: cast.target }, events); +// let amount = gp.pct(cast.skill.multiplier().saturating_mul(rms)); + +// vec![ +// Action::RemoveAll { +// construct: cast.target, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount, +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Pure, duration: 2, meta: Some(EffectMeta::Multiplier(200)) } +// }, +// ] +// } + +// fn recharge(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Heal { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn reflect(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Reflect, duration: 1, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn restrict(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Restrict, duration: 2, meta: None } +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::ColourSkills { construct: cast.source, colour: Colour::Red }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + + +// fn ruin(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.target, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 1, meta: None } +// } +// ] +// } + + +// fn siphon(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphon, duration: 2, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick }) }, +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks +// }, +// Action::Heal { +// construct: cast.source, +// colour: Colour::Green, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn siphon_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphon, duration: 3, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlus }) }, +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks +// }, +// Action::Heal { +// construct: cast.source, +// colour: Colour::Green, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn siphon_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphon, duration: 4, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlusPlus }) }, +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks +// }, +// Action::Heal { +// construct: cast.source, +// colour: Colour::Green, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn siphon_tick(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Blue, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Siphoned, duration: 1, meta: None }, // immunity to additional ticks +// }, +// Action::Heal { +// construct: cast.source, +// colour: Colour::Green, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Blue }, events).pct(100), +// }, +// ] +// } + +// fn slay(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Heal { +// construct: cast.source, +// colour: Colour::Green, +// amount: game.value(Value::DamageReceived { construct: cast.target, colour: Colour::Red, mult: 50 }, events), +// }, +// ] +// } + +// fn sleep(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn sleep_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn sleep_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Blue, +// }, +// ] +// } + +// fn silence(cast: &Cast, game: &Game, events: Vec) -> Vec { +// let bp = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events); +// let silences = game.value(Value::ColourSkills { construct: cast.target, colour: Colour::Blue }, events); +// let amount = bp.pct(45usize.saturating_mul(silences)); + +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Silence, duration: 2, meta: None }, +// }, +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount, +// }, +// ] +// } + +// fn strike(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Damage { +// construct: cast.target, +// colour: Colour::Red, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// }, +// ] +// } + +// fn sustain(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }, +// }, +// Action::Heal { +// construct: cast.target, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }, events).pct(cast.skill.multiplier()), +// colour: Colour::Red, +// }, +// ] +// } + +// fn triage(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triage, duration: 2, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick }) }, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, +// }, +// ] +// } + +// fn triage_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triage, duration: 3, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlus }) }, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, +// }, +// ] +// } + +// fn triage_plus_plus(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triage, duration: 4, meta: +// Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlusPlus }) }, +// }, +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, +// }, +// ] +// } + +// fn triage_tick(cast: &Cast, game: &Game, events: Vec) -> Vec { +// vec![ +// Action::Heal { +// construct: cast.target, +// colour: Colour::Green, +// amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }, events).pct(cast.skill.multiplier()), +// }, +// Action::Effect { +// construct: cast.target, +// effect: ConstructEffect { effect: Effect::Triaged, duration: 1, meta: None }, +// }, +// ] +// } // #[cfg(test)]