diff --git a/core/src/construct.rs b/core/src/construct.rs index b759b303..bd3c0afa 100644 --- a/core/src/construct.rs +++ b/core/src/construct.rs @@ -1040,8 +1040,6 @@ impl Construct { } pub fn damage_trigger_casts(&mut self, cast: &Cast, event: &Event) -> Vec { - if self.is_ko() { return vec![] } - match event { Event::Damage { construct: _, colour, amount: _, mitigation: _, display: _ } => { let mut casts = vec![]; @@ -1056,6 +1054,9 @@ impl Construct { }; } + // electrocute is a special case, so we only return after we check it when ko + if self.is_ko() { return casts } + if self.affected(Effect::Absorb) { let ConstructEffect { effect: _, duration: _, meta } = self.effects.iter().find(|e| e.effect == Effect::Absorb).unwrap(); diff --git a/core/src/effect.rs b/core/src/effect.rs index 14391d5b..549bb4aa 100644 --- a/core/src/effect.rs +++ b/core/src/effect.rs @@ -81,7 +81,7 @@ impl Effect { Skill::CounterAttackPlus, Skill::CounterAttackPlusPlus, ].contains(&skill), - + // these provide immunity for the ticks // the base skills will still resolve // but they have early return checks @@ -125,6 +125,12 @@ impl Effect { return false; } + // electrocute always goes off baybee + // even if you are stunned particularly + if [Skill::Electrocute, Skill::ElectrocutePlus, Skill::ElectrocutePlusPlus].contains(&skill) { + return false; + } + match self { Effect::Stun => true, Effect::Banish => true, diff --git a/core/src/game.rs b/core/src/game.rs index 12c3bfc5..6a30e96f 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -2210,8 +2210,41 @@ mod tests { assert!(effect_events == 2); assert!(electrocute_dmg_events == 1); // second electrocute application deals no damage + } + #[test] + fn electrocute_ko_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.players[1].constructs[0].blue_life.force(0); + game.players[1].constructs[0].green_life.force(1); + + game.resolve(Cast::new(source, player_id, target, Skill::Electrify)); + game.resolve(Cast::new(source, player_id, target, Skill::Blast)); + + let last = game.resolutions.len() - 1; + let resolutions = &game.resolutions[last]; + + // println!("{:#?}", resolutions); + + assert!(resolutions.iter().any(|r| match r.event { + Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + r.skill == Skill::Electrocute && construct == source && amount > 0 && colour == Colour::Blue, + _ => false, + })); + + let effect_events = resolutions.iter().filter(|r| match r.event { + Event::Effect { construct, effect, duration: _, display: _ } => + construct == source && effect == Effect::Electrocute, + _ => false, + }).count(); + + // println!("{:?}", effect_events); + + assert!(effect_events == 1); } #[test] diff --git a/core/src/skill.rs b/core/src/skill.rs index 5cdb1076..0c7f2338 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -738,6 +738,13 @@ impl Skill { pub fn ko_castable(&self) -> bool { match self { + + // electrocute always goes off + Skill::Electrocute| + Skill::ElectrocutePlus | + Skill::ElectrocutePlusPlus | + + // ticks happen after death Skill::ElectrocuteTick | Skill::DecayTick | Skill::SiphonTick |