diff --git a/core/src/effect.rs b/core/src/effect.rs index c1d98d39..14391d5b 100644 --- a/core/src/effect.rs +++ b/core/src/effect.rs @@ -32,6 +32,7 @@ pub enum Effect { // electrocute the dmg debuff Electric, Electrocute, + Electrocuted, // absorbtion is the buff // absorb is the increased damage @@ -75,27 +76,31 @@ impl Effect { match self { Effect::Banish => true, - // these provide immunity for the ticks - // the base skills will still resolve - // but they have early return checks - // to ensure the effect is reapplied but damage is not - Effect::Siphoned => [ - Skill::SiphonTick, - ].contains(&skill), - - Effect::Decayed => [ - Skill::DecayTick, - ].contains(&skill), - - Effect::Triaged => [ - Skill::TriageTick, - ].contains(&skill), - Effect::Countered => [ Skill::CounterAttack, Skill::CounterAttackPlus, Skill::CounterAttackPlusPlus, ].contains(&skill), + + // these provide immunity for the ticks + // the base skills will still resolve + // but they have early return checks + // to ensure the effect is reapplied but damage is not + Effect::Decayed => [ + Skill::DecayTick, + ].contains(&skill), + + Effect::Electrocuted => [ + Skill::ElectrocuteTick, + ].contains(&skill), + + Effect::Siphoned => [ + Skill::SiphonTick, + ].contains(&skill), + + Effect::Triaged => [ + Skill::TriageTick, + ].contains(&skill), _ => false, } @@ -106,10 +111,11 @@ impl Effect { // and not included in counts pub fn hidden(&self) -> bool { match self { - Effect::Siphoned => true, - Effect::Decayed => true, - Effect::Triaged => true, Effect::Countered => true, + Effect::Decayed => true, + Effect::Electrocuted => true, + Effect::Siphoned => true, + Effect::Triaged => true, _ => false, } } diff --git a/core/src/game.rs b/core/src/game.rs index 73c01aa7..141c1530 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -2260,6 +2260,31 @@ mod tests { construct == source && amount > 0 && colour == Colour::Blue, _ => false, })); + + 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]; + + let electrocute_dmg_events = resolutions.iter().filter(|r| match r.event { + Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => match r.skill { + Skill::Electrocute => true, + _ => false + }, + _ => false, + }).count(); + + let effect_events = resolutions.iter().filter(|r| match r.event { + Event::Effect { construct, effect, duration: _, display: _ } => + construct == source && effect == Effect::Electrocute, + _ => false, + }).count(); + + assert!(effect_events == 2); + assert!(electrocute_dmg_events == 1); // second electrocute application deals no damage + + } #[test] diff --git a/core/src/skill.rs b/core/src/skill.rs index 5eb2f7c3..3b31613d 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -1689,13 +1689,22 @@ fn electrocute(cast: Cast, game: &mut Game, values: Electrocute) { Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) }, }, ); - game.action(cast, - Action::Damage { - construct: cast.target, - colour: Colour::Blue, - amount, - }, - ); + + if !game.affected(cast.target, Effect::Electrocuted) { + game.action(cast, + Action::Damage { + construct: cast.target, + colour: Colour::Blue, + amount, + }, + ); + game.action(cast, + Action::Effect { + construct: cast.target, + effect: ConstructEffect { effect: Effect::Electrocuted, duration: 1, meta: None }, // immunity to additional ticks + }, + ); + } game.action(cast, Action::Remove { @@ -1713,6 +1722,13 @@ fn electrocute_tick(cast: Cast, game: &mut Game) { amount: game.value(Value::TickDamage { construct: cast.target, effect: Effect::Electrocute }), }, ); + + game.action(cast, + Action::Effect { + construct: cast.target, + effect: ConstructEffect { effect: Effect::Electrocuted, duration: 1, meta: None }, // immunity to additional ticks + }, + ); } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]