fix siphon

This commit is contained in:
ntr 2019-12-13 17:33:14 +10:00
parent 48ebcf921f
commit 852f192ae7
6 changed files with 131 additions and 160 deletions

View File

@ -6,4 +6,5 @@ purify conditional healing
set static speed for dot ticks set static speed for dot ticks
infinite counter loop infinite counter loop
cooldowns set after cast
cooldowns reduced after 1 complete cast cooldowns reduced after 1 complete cast

View File

@ -63,7 +63,7 @@ impl ConstructSkill {
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub enum EffectMeta { pub enum EffectMeta {
CastOnHit(Skill), // maybe needs source/target CastOnHit(Skill), // maybe needs source/target
CastTick { source: Uuid, target: Uuid, skill: Skill }, CastTick { source: Uuid, target: Uuid, skill: Skill, speed: usize, amount: usize },
AddedDamage(usize), AddedDamage(usize),
Multiplier(usize), Multiplier(usize),
} }
@ -98,7 +98,7 @@ impl ConstructEffect {
pub fn get_skill(&self) -> Option<Skill> { pub fn get_skill(&self) -> Option<Skill> {
match self.meta { match self.meta {
Some(EffectMeta::CastTick { source, target, skill }) => Some(skill), Some(EffectMeta::CastTick { source, target, skill, speed, amount }) => Some(skill),
Some(EffectMeta::CastOnHit(s)) => Some(s), Some(EffectMeta::CastOnHit(s)) => Some(s),
_ => None, _ => None,
} }
@ -128,6 +128,7 @@ pub enum Stat {
Cooldowns, Cooldowns,
EffectsCount, EffectsCount,
Skills(Colour), Skills(Colour),
TickDamage(Effect),
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -520,10 +521,28 @@ impl Construct {
Stat::Skills(colour) => self.skills.iter().filter(|cs| cs.skill.colours().contains(&colour)).count(), Stat::Skills(colour) => self.skills.iter().filter(|cs| cs.skill.colours().contains(&colour)).count(),
Stat::EffectsCount => self.effects.iter().filter(|ce| !ce.effect.hidden()).count(), Stat::EffectsCount => self.effects.iter().filter(|ce| !ce.effect.hidden()).count(),
Stat::TickDamage(effect) => self.tick_damage(effect),
_ => panic!("{:?} cannot be calculated without an amount", stat), _ => panic!("{:?} cannot be calculated without an amount", stat),
} }
} }
fn tick_damage(&self, effect: Effect) -> usize {
match self.effects.iter().find_map(|ce| match ce.effect == effect {
true => match ce.meta {
Some(EffectMeta::CastTick { source, target, skill, speed, amount }) => Some(amount),
_ => None,
},
false => None,
}) {
Some(amount) => amount,
None => {
warn!("no tick damage {:?} {:?}", self.effects, effect);
0
}
}
}
pub fn skill_speed(&self, s: Skill) -> usize { pub fn skill_speed(&self, s: Skill) -> usize {
self.stat(Stat::Speed).saturating_mul(s.speed() as usize) self.stat(Stat::Speed).saturating_mul(s.speed() as usize)
} }
@ -988,8 +1007,8 @@ impl Construct {
self.effects.iter().find(|e| e.effect == Effect::Electric).unwrap(); self.effects.iter().find(|e| e.effect == Effect::Electric).unwrap();
match meta { match meta {
Some(EffectMeta::CastTick { source: _, target, skill }) => Some(EffectMeta::CastOnHit(skill)) =>
casts.push(Cast::new(self.id, self.account, *target, *skill)), casts.push(Cast::new(self.id, self.account, cast.target, *skill)),
_ => panic!("no electrify skill {:?}", meta), _ => panic!("no electrify skill {:?}", meta),
}; };
} }

View File

@ -91,8 +91,6 @@ impl Effect {
Skill::SiphonPlus, Skill::SiphonPlus,
Skill::SiphonPlusPlus, Skill::SiphonPlusPlus,
Skill::SiphonTick, Skill::SiphonTick,
Skill::SiphonTickPlus,
Skill::SiphonTickPlusPlus,
].contains(&skill), ].contains(&skill),
Effect::Decayed => [ Effect::Decayed => [
@ -100,8 +98,6 @@ impl Effect {
Skill::DecayPlus, Skill::DecayPlus,
Skill::DecayPlusPlus, Skill::DecayPlusPlus,
Skill::DecayTick, Skill::DecayTick,
Skill::DecayTickPlus,
Skill::DecayTickPlusPlus,
].contains(&skill), ].contains(&skill),
Effect::Triaged => [ Effect::Triaged => [
@ -109,8 +105,6 @@ impl Effect {
Skill::TriagePlus, Skill::TriagePlus,
Skill::TriagePlusPlus, Skill::TriagePlusPlus,
Skill::TriageTick, Skill::TriageTick,
Skill::TriageTickPlus,
Skill::TriageTickPlusPlus,
].contains(&skill), ].contains(&skill),
_ => false, _ => false,

View File

@ -428,7 +428,7 @@ impl Game {
.cloned() .cloned()
.filter_map(|e| e.meta) .filter_map(|e| e.meta)
.filter_map(move |m| match m { .filter_map(move |m| match m {
EffectMeta::CastTick { source, target, skill } => Some(Cast::new(source, c.account, target, skill)), EffectMeta::CastTick { source, target, skill, speed, amount } => Some(Cast::new(source, c.account, target, skill)),
_ => None, _ => None,
}) })
) )
@ -633,6 +633,10 @@ impl Game {
} }
_ => dmg, _ => dmg,
}), }),
Value::TickDamage { construct, effect } =>
self.construct(construct).stat(Stat::TickDamage(effect)),
// Skills { construct: Uuid, colour: Colour }, // Skills { construct: Uuid, colour: Colour },
} }
} }
@ -831,6 +835,7 @@ pub enum Value {
Effects { construct: Uuid }, Effects { construct: Uuid },
Removals { construct: Uuid }, Removals { construct: Uuid },
DamageReceived { construct: Uuid, colour: Colour }, DamageReceived { construct: Uuid, colour: Colour },
TickDamage { construct: Uuid, effect: Effect },
} }
#[derive(Debug,Clone,PartialEq)] #[derive(Debug,Clone,PartialEq)]
@ -1688,7 +1693,7 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Slay)); game.new_resolve(Cast::new(source, player_id, target, Skill::Slay));
let last = game.resolutions.len() - 1; let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
@ -1715,12 +1720,12 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, source_player_id, target, Skill::Decay)); game.new_resolve(Cast::new(source, source_player_id, target, Skill::Decay));
// don't mention 3 we volvo now // don't mention 3 we volvo now
assert!(game.players[1].constructs[0].effects.len() == 3); assert!(game.players[1].constructs[0].effects.len() == 3);
game.resolve(Cast::new(target, target_player_id, target, Skill::Purify)); game.new_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);
@ -1744,9 +1749,9 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Strike)); game.new_resolve(Cast::new(source, player_id, target, Skill::Strike));
game.resolve(Cast::new(source, player_id, target, Skill::Invert)); game.new_resolve(Cast::new(source, player_id, target, Skill::Invert));
game.resolve(Cast::new(source, player_id, target, Skill::Strike)); game.new_resolve(Cast::new(source, player_id, target, Skill::Strike));
let last = game.resolutions.len() - 1; let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
@ -1771,7 +1776,7 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Siphon)); game.new_resolve(Cast::new(source, player_id, target, Skill::Siphon));
let last = game.resolutions.len() - 1; let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
@ -1784,6 +1789,7 @@ mod tests {
_ => false, _ => false,
})); }));
println!("{:#?}", resolutions);
assert!(resolutions.iter().any(|r| match r.event { assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => Event::Damage { construct, colour, amount, mitigation: _, display: _ } =>
construct == target && amount > 0 && colour == Colour::Blue, construct == target && amount > 0 && colour == Colour::Blue,

View File

@ -1215,11 +1215,7 @@ impl From<Skill> for Item {
Skill::ElectrocutePlus => Item::ElectrifyPlus, Skill::ElectrocutePlus => Item::ElectrifyPlus,
Skill::ElectrocutePlusPlus => Item::ElectrifyPlusPlus, Skill::ElectrocutePlusPlus => Item::ElectrifyPlusPlus,
Skill::ElectrocuteTick => Item::Electrify, Skill::ElectrocuteTick => Item::Electrify,
Skill::ElectrocuteTickPlus => Item::ElectrifyPlus,
Skill::ElectrocuteTickPlusPlus => Item::ElectrifyPlus,
Skill::DecayTick => Item::Decay, Skill::DecayTick => Item::Decay,
Skill::DecayTickPlus => Item::DecayPlus,
Skill::DecayTickPlusPlus => Item::DecayPlusPlus,
Skill::Absorption => Item::Absorb, Skill::Absorption => Item::Absorb,
Skill::AbsorptionPlus => Item::AbsorbPlus, Skill::AbsorptionPlus => Item::AbsorbPlus,
Skill::AbsorptionPlusPlus => Item::AbsorbPlusPlus, Skill::AbsorptionPlusPlus => Item::AbsorbPlusPlus,
@ -1229,11 +1225,7 @@ impl From<Skill> for Item {
Skill::CounterAttackPlus => Item::CounterPlus, Skill::CounterAttackPlus => Item::CounterPlus,
Skill::CounterAttackPlusPlus => Item::CounterPlusPlus, Skill::CounterAttackPlusPlus => Item::CounterPlusPlus,
Skill::SiphonTick => Item::Siphon, Skill::SiphonTick => Item::Siphon,
Skill::SiphonTickPlus => Item::SiphonPlus,
Skill::SiphonTickPlusPlus => Item::SiphonPlusPlus,
Skill::TriageTick => Item::Triage, Skill::TriageTick => Item::Triage,
Skill::TriageTickPlus => Item::TriagePlus,
Skill::TriageTickPlusPlus => Item::TriagePlusPlus,
} }
} }
} }

View File

@ -107,9 +107,7 @@ impl Cast {
Skill::Decay => decay(self, game), Skill::Decay => decay(self, game),
Skill::DecayPlus => decay_plus(self, game), Skill::DecayPlus => decay_plus(self, game),
Skill::DecayPlusPlus => decay_plus_plus(self, game), Skill::DecayPlusPlus => decay_plus_plus(self, game),
Skill::DecayTick | Skill::DecayTick => decay_tick(self, game),
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus => decay_tick(self, game),
Skill::Electrify => electrify(self, game), Skill::Electrify => electrify(self, game),
Skill::ElectrifyPlus => electrify_plus(self, game), Skill::ElectrifyPlus => electrify_plus(self, game),
@ -117,9 +115,7 @@ impl Cast {
Skill::Electrocute => electrocute(self, game), Skill::Electrocute => electrocute(self, game),
Skill::ElectrocutePlus => electrocute_plus(self, game), Skill::ElectrocutePlus => electrocute_plus(self, game),
Skill::ElectrocutePlusPlus => electrocute_plus_plus(self, game), Skill::ElectrocutePlusPlus => electrocute_plus_plus(self, game),
Skill::ElectrocuteTick | Skill::ElectrocuteTick => electrocute_tick(self, game),
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus => electrocute_tick(self, game),
Skill::Heal | Skill::Heal |
Skill::HealPlus | Skill::HealPlus |
@ -178,9 +174,7 @@ impl Cast {
Skill::Siphon => siphon(self, game), Skill::Siphon => siphon(self, game),
Skill::SiphonPlus => siphon_plus(self, game), Skill::SiphonPlus => siphon_plus(self, game),
Skill::SiphonPlusPlus => siphon_plus_plus(self, game), Skill::SiphonPlusPlus => siphon_plus_plus(self, game),
Skill::SiphonTick | Skill::SiphonTick=> siphon_tick(self, game),
Skill::SiphonTickPlus |
Skill::SiphonTickPlusPlus => siphon_tick(self, game),
Skill::Slay | Skill::Slay |
Skill::SlayPlus | Skill::SlayPlus |
@ -205,9 +199,7 @@ impl Cast {
Skill::Triage => triage(self, game), Skill::Triage => triage(self, game),
Skill::TriagePlus => triage_plus(self, game), Skill::TriagePlus => triage_plus(self, game),
Skill::TriagePlusPlus => triage_plus_plus(self, game), Skill::TriagePlusPlus => triage_plus_plus(self, game),
Skill::TriageTick | Skill::TriageTick => triage_tick(self, game),
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => triage_tick(self, game),
}; };
// actions.append(&mut rest); // actions.append(&mut rest);
@ -301,6 +293,7 @@ pub enum Skill {
DecayPlus, DecayPlus,
#[serde(rename = "Decay++")] #[serde(rename = "Decay++")]
DecayPlusPlus, DecayPlusPlus,
DecayTick, // dot
Haste, Haste,
#[serde(rename = "Haste+")] #[serde(rename = "Haste+")]
@ -403,6 +396,7 @@ pub enum Skill {
SiphonPlus, SiphonPlus,
#[serde(rename = "Siphon++")] #[serde(rename = "Siphon++")]
SiphonPlusPlus, SiphonPlusPlus,
SiphonTick,
Intercept, Intercept,
#[serde(rename = "Intercept+")] #[serde(rename = "Intercept+")]
@ -421,6 +415,7 @@ pub enum Skill {
TriagePlus, TriagePlus,
#[serde(rename = "Triage++")] #[serde(rename = "Triage++")]
TriagePlusPlus, TriagePlusPlus,
TriageTick,
Absorption, Absorption,
#[serde(rename = "Absorption+")] #[serde(rename = "Absorption+")]
@ -440,31 +435,11 @@ pub enum Skill {
#[serde(rename = "Electrocute++")] #[serde(rename = "Electrocute++")]
ElectrocutePlusPlus, ElectrocutePlusPlus,
ElectrocuteTick, ElectrocuteTick,
#[serde(rename = "ElectrocuteTick+")]
ElectrocuteTickPlus,
#[serde(rename = "ElectrocuteTick++")]
ElectrocuteTickPlusPlus,
DecayTick, // dot
#[serde(rename = "DecayTick+")]
DecayTickPlus,
#[serde(rename = "DecayTick++")]
DecayTickPlusPlus,
HasteStrike, HasteStrike,
HybridBlast, HybridBlast,
SiphonTick,
#[serde(rename = "SiphonTick+")]
SiphonTickPlus,
#[serde(rename = "SiphonTick++")]
SiphonTickPlusPlus,
TriageTick,
#[serde(rename = "TriageTick+")]
TriageTickPlus,
#[serde(rename = "TriageTick++")]
TriageTickPlusPlus,
} }
impl Skill { impl Skill {
@ -485,9 +460,9 @@ impl Skill {
Skill::HealPlus => 135, //GG Skill::HealPlus => 135, //GG
Skill::HealPlusPlus => 160, //GG Skill::HealPlusPlus => 160, //GG
Skill::SiphonTick => 25, // GB Skill::Siphon => 25, // GB
Skill::SiphonTickPlus => 27, Skill::SiphonPlus => 27,
Skill::SiphonTickPlusPlus => 30, Skill::SiphonPlusPlus => 30,
Skill::Slay => 40, // RG Skill::Slay => 40, // RG
Skill::SlayPlus => 50, Skill::SlayPlus => 50,
@ -498,9 +473,9 @@ impl Skill {
Skill::StrikePlusPlus => 140, Skill::StrikePlusPlus => 140,
// Block Base // Block Base
Skill::ElectrocuteTick => 80, Skill::Electrocute => 80,
Skill::ElectrocuteTickPlus => 90, Skill::ElectrocutePlus => 90,
Skill::ElectrocuteTickPlusPlus => 100, Skill::ElectrocutePlusPlus => 100,
Skill::CounterAttack => 115, Skill::CounterAttack => 115,
Skill::CounterAttackPlus => 130, Skill::CounterAttackPlus => 130,
@ -544,9 +519,9 @@ impl Skill {
Skill::RuinPlusPlus => 70, Skill::RuinPlusPlus => 70,
// Debuff Base // Debuff Base
Skill::DecayTick => 33, Skill::Decay => 33,
Skill::DecayTickPlus => 37, Skill::DecayPlus => 37,
Skill::DecayTickPlusPlus => 45, Skill::DecayPlusPlus => 45,
Skill::Silence => 55, // Deals more per blue skill on target Skill::Silence => 55, // Deals more per blue skill on target
Skill::SilencePlus => 65, Skill::SilencePlus => 65,
@ -569,9 +544,9 @@ impl Skill {
Skill::InterceptPlus => 100, Skill::InterceptPlus => 100,
Skill::InterceptPlusPlus => 125, Skill::InterceptPlusPlus => 125,
Skill::TriageTick => 75, Skill::Triage => 75,
Skill::TriageTickPlus => 90, Skill::TriagePlus => 90,
Skill::TriageTickPlusPlus => 110, Skill::TriagePlusPlus => 110,
_ => 100, _ => 100,
} }
@ -605,9 +580,9 @@ impl Skill {
Skill::Electrocute => vec![ConstructEffect { effect: Effect::Electrocute, duration: 2, Skill::Electrocute => vec![ConstructEffect { effect: Effect::Electrocute, duration: 2,
meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTick)) }], meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTick)) }],
Skill::ElectrocutePlus => vec![ConstructEffect { effect: Effect::Electrocute, duration: 3, Skill::ElectrocutePlus => vec![ConstructEffect { effect: Effect::Electrocute, duration: 3,
meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTickPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTick)) }],
Skill::ElectrocutePlusPlus => vec![ConstructEffect { effect: Effect::Electrocute, duration: 4, Skill::ElectrocutePlusPlus => vec![ConstructEffect { effect: Effect::Electrocute, duration: 4,
meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTickPlusPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::ElectrocuteTick)) }],
Skill::Sustain => vec![ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }], Skill::Sustain => vec![ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }],
Skill::SustainPlus => vec![ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }], Skill::SustainPlus => vec![ConstructEffect { effect: Effect::Sustain, duration: 1, meta: None }],
@ -630,11 +605,11 @@ impl Skill {
Skill::DecayPlus => vec![ConstructEffect { effect: Effect::Wither, duration: 3, Skill::DecayPlus => vec![ConstructEffect { effect: Effect::Wither, duration: 3,
meta: Some(EffectMeta::Multiplier(35)) }, meta: Some(EffectMeta::Multiplier(35)) },
ConstructEffect { effect: Effect::Decay, duration: 3, ConstructEffect { effect: Effect::Decay, duration: 3,
meta: Some(EffectMeta::CastOnHit(Skill::DecayTickPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::DecayTick)) }],
Skill::DecayPlusPlus => vec![ConstructEffect { effect: Effect::Wither, duration: 4, Skill::DecayPlusPlus => vec![ConstructEffect { effect: Effect::Wither, duration: 4,
meta: Some(EffectMeta::Multiplier(20)) }, meta: Some(EffectMeta::Multiplier(20)) },
ConstructEffect { effect: Effect::Decay, duration: 4, ConstructEffect { effect: Effect::Decay, duration: 4,
meta: Some(EffectMeta::CastOnHit(Skill::DecayTickPlusPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::DecayTick)) }],
Skill::Haste => vec![ConstructEffect { effect: Effect::Haste, duration: 3, Skill::Haste => vec![ConstructEffect { effect: Effect::Haste, duration: 3,
meta: Some(EffectMeta::Multiplier(150)) }], meta: Some(EffectMeta::Multiplier(150)) }],
@ -705,9 +680,9 @@ impl Skill {
Skill::Siphon => vec![ConstructEffect { effect: Effect::Siphon, duration: 2, Skill::Siphon => vec![ConstructEffect { effect: Effect::Siphon, duration: 2,
meta: Some(EffectMeta::CastOnHit(Skill::SiphonTick)) }], meta: Some(EffectMeta::CastOnHit(Skill::SiphonTick)) }],
Skill::SiphonPlus => vec![ConstructEffect { effect: Effect::Siphon, duration: 3, Skill::SiphonPlus => vec![ConstructEffect { effect: Effect::Siphon, duration: 3,
meta: Some(EffectMeta::CastOnHit(Skill::SiphonTickPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::SiphonTick)) }],
Skill::SiphonPlusPlus => vec![ConstructEffect { effect: Effect::Siphon, duration: 4, Skill::SiphonPlusPlus => vec![ConstructEffect { effect: Effect::Siphon, duration: 4,
meta: Some(EffectMeta::CastOnHit(Skill::SiphonTickPlusPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::SiphonTick)) }],
Skill::Sleep => vec![ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }], Skill::Sleep => vec![ConstructEffect { effect: Effect::Stun, duration: 2, meta: None }],
Skill::SleepPlus => vec![ConstructEffect { effect: Effect::Stun, duration: 3, meta: None }], Skill::SleepPlus => vec![ConstructEffect { effect: Effect::Stun, duration: 3, meta: None }],
@ -732,9 +707,9 @@ impl Skill {
Skill::Triage => vec![ConstructEffect { effect: Effect::Triage, duration: 2, Skill::Triage => vec![ConstructEffect { effect: Effect::Triage, duration: 2,
meta: Some(EffectMeta::CastOnHit(Skill::TriageTick)) }], meta: Some(EffectMeta::CastOnHit(Skill::TriageTick)) }],
Skill::TriagePlus => vec![ConstructEffect { effect: Effect::Triage, duration: 3, Skill::TriagePlus => vec![ConstructEffect { effect: Effect::Triage, duration: 3,
meta: Some(EffectMeta::CastOnHit(Skill::TriageTickPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::TriageTick)) }],
Skill::TriagePlusPlus => vec![ConstructEffect { effect: Effect::Triage, duration: 4, Skill::TriagePlusPlus => vec![ConstructEffect { effect: Effect::Triage, duration: 4,
meta: Some(EffectMeta::CastOnHit(Skill::TriageTickPlusPlus)) }], meta: Some(EffectMeta::CastOnHit(Skill::TriageTick)) }],
Skill::Purify => vec![ConstructEffect { effect: Effect::Pure, duration: 2, Skill::Purify => vec![ConstructEffect { effect: Effect::Pure, duration: 2,
meta: Some(EffectMeta::Multiplier(150)) }], meta: Some(EffectMeta::Multiplier(150)) }],
@ -894,17 +869,9 @@ impl Skill {
Skill::AbsorptionPlusPlus | Skill::AbsorptionPlusPlus |
// Ticks // Ticks
Skill::ElectrocuteTick| Skill::ElectrocuteTick|
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus |
Skill::DecayTick| Skill::DecayTick|
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus |
Skill::SiphonTick| Skill::SiphonTick|
Skill::SiphonTickPlus | Skill::TriageTick => None,
Skill::SiphonTickPlusPlus |
Skill::TriageTick|
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => None,
} }
} }
@ -922,17 +889,9 @@ impl Skill {
Skill::AbsorptionPlus | Skill::AbsorptionPlus |
Skill::AbsorptionPlusPlus | Skill::AbsorptionPlusPlus |
Skill::ElectrocuteTick | Skill::ElectrocuteTick |
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus |
Skill::DecayTick | Skill::DecayTick |
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus |
Skill::SiphonTick | Skill::SiphonTick |
Skill::SiphonTickPlus | Skill::TriageTick => false,
Skill::SiphonTickPlusPlus |
Skill::TriageTick|
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => false,
_ => true, _ => true,
} }
} }
@ -940,18 +899,9 @@ impl Skill {
pub fn ko_castable(&self) -> bool { pub fn ko_castable(&self) -> bool {
match self { match self {
Skill::ElectrocuteTick | Skill::ElectrocuteTick |
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus |
Skill::DecayTick | Skill::DecayTick |
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus |
Skill::SiphonTick | Skill::SiphonTick |
Skill::SiphonTickPlus | Skill::TriageTick => true,
Skill::SiphonTickPlusPlus |
Skill::TriageTick |
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => true,
_ => false, _ => false,
} }
} }
@ -959,17 +909,9 @@ impl Skill {
pub fn is_tick(&self) -> bool { pub fn is_tick(&self) -> bool {
match self { match self {
Skill::ElectrocuteTick | Skill::ElectrocuteTick |
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus |
Skill::DecayTick | Skill::DecayTick |
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus |
Skill::SiphonTick | Skill::SiphonTick |
Skill::SiphonTickPlus | Skill::TriageTick => true,
Skill::SiphonTickPlusPlus |
Skill::TriageTick |
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => true,
_ => false, _ => false,
} }
@ -977,21 +919,10 @@ impl Skill {
pub fn speed(&self) -> usize { pub fn speed(&self) -> usize {
match self { match self {
Skill::SiphonTick | Skill::SiphonTick => Skill::Siphon.speed(),
Skill::SiphonTickPlus | Skill::DecayTick => Skill::Decay.speed(),
Skill::SiphonTickPlusPlus => Skill::Siphon.speed(), Skill::TriageTick => Skill::Triage.speed(),
Skill::ElectrocuteTick => Skill::Electrify.speed(),
Skill::DecayTick |
Skill::DecayTickPlus |
Skill::DecayTickPlusPlus => Skill::Decay.speed(),
Skill::TriageTick |
Skill::TriageTickPlus |
Skill::TriageTickPlusPlus => Skill::Triage.speed(),
Skill::ElectrocuteTick |
Skill::ElectrocuteTickPlus |
Skill::ElectrocuteTickPlusPlus => Skill::Electrify.speed(),
_ => Item::from(*self).speed(), _ => Item::from(*self).speed(),
} }
@ -1490,11 +1421,12 @@ fn counter_attack(cast: Cast, game: &mut Game) {
} }
fn decay(cast: Cast, game: &mut Game) { fn decay(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -1507,7 +1439,7 @@ fn decay(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Decay, duration: 2, meta: effect: ConstructEffect { effect: Effect::Decay, duration: 2, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
@ -1519,11 +1451,12 @@ fn decay(cast: Cast, game: &mut Game) {
} }
fn decay_plus(cast: Cast, game: &mut Game) { fn decay_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -1536,7 +1469,7 @@ fn decay_plus(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
@ -1548,11 +1481,12 @@ fn decay_plus(cast: Cast, game: &mut Game) {
} }
fn decay_plus_plus(cast: Cast, game: &mut Game) { fn decay_plus_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -1565,7 +1499,7 @@ fn decay_plus_plus(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta: effect: ConstructEffect { effect: Effect::Decay, duration: 4, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTickPlusPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
@ -1577,11 +1511,13 @@ fn decay_plus_plus(cast: Cast, game: &mut Game) {
} }
fn decay_tick(cast: Cast, game: &mut Game) { fn decay_tick(cast: Cast, game: &mut Game) {
let amount = game.value(Value::TickDamage { construct: cast.target, effect: Effect::Decay });
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -1620,6 +1556,8 @@ fn electrify_plus_plus(cast: Cast, game: &mut Game) {
} }
fn electrocute(cast: Cast, game: &mut Game) { fn electrocute(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Remove { Action::Remove {
construct: cast.source, construct: cast.source,
@ -1630,11 +1568,13 @@ fn electrocute(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Electric, duration: 2, meta: effect: ConstructEffect { effect: Effect::Electric, duration: 2, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) },
}, },
); );
} }
fn electrocute_plus(cast: Cast, game: &mut Game) { fn electrocute_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Remove { Action::Remove {
construct: cast.source, construct: cast.source,
@ -1645,12 +1585,14 @@ fn electrocute_plus(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Electric, duration: 3, meta: effect: ConstructEffect { effect: Effect::Electric, duration: 3, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) },
}, },
); );
} }
fn electrocute_plus_plus(cast: Cast, game: &mut Game) { fn electrocute_plus_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Remove { Action::Remove {
construct: cast.source, construct: cast.source,
@ -1661,7 +1603,7 @@ fn electrocute_plus_plus(cast: Cast, game: &mut Game) {
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Electric, duration: 4, meta: effect: ConstructEffect { effect: Effect::Electric, duration: 4, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTickPlusPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) },
}, },
); );
} }
@ -1671,7 +1613,7 @@ fn electrocute_tick(cast: Cast, game: &mut Game) {
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount: game.value(Value::TickDamage { construct: cast.target, effect: Effect::Electrocute }),
}, },
); );
} }
@ -2002,20 +1944,23 @@ fn ruin(cast: Cast, game: &mut Game) {
); );
} }
fn siphon(cast: Cast, game: &mut Game) { fn siphon(cast: Cast, game: &mut Game) {
let amount =
game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier())
+ game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Siphon, duration: 2, meta: effect: ConstructEffect { effect: Effect::Siphon, duration: 2, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2034,18 +1979,22 @@ fn siphon(cast: Cast, game: &mut Game) {
} }
fn siphon_plus(cast: Cast, game: &mut Game) { fn siphon_plus(cast: Cast, game: &mut Game) {
let amount =
game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier())
+ game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Siphon, duration: 3, meta: effect: ConstructEffect { effect: Effect::Siphon, duration: 3, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2064,18 +2013,22 @@ fn siphon_plus(cast: Cast, game: &mut Game) {
} }
fn siphon_plus_plus(cast: Cast, game: &mut Game) { fn siphon_plus_plus(cast: Cast, game: &mut Game) {
let amount =
game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier())
+ game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Siphon, duration: 4, meta: effect: ConstructEffect { effect: Effect::Siphon, duration: 4, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTickPlusPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2098,7 +2051,7 @@ fn siphon_tick(cast: Cast, game: &mut Game) {
Action::Damage { Action::Damage {
construct: cast.target, construct: cast.target,
colour: Colour::Blue, colour: Colour::Blue,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()), amount: game.value(Value::TickDamage { construct: cast.target, effect: Effect::Siphon }),
} }
); );
game.action(cast, game.action(cast,
@ -2228,18 +2181,20 @@ fn sustain(cast: Cast, game: &mut Game) {
} }
fn triage(cast: Cast, game: &mut Game) { fn triage(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Triage, duration: 2, meta: effect: ConstructEffect { effect: Effect::Triage, duration: 2, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Heal { Action::Heal {
construct: cast.target, construct: cast.target,
colour: Colour::Green, colour: Colour::Green,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2251,18 +2206,20 @@ fn triage(cast: Cast, game: &mut Game) {
} }
fn triage_plus(cast: Cast, game: &mut Game) { fn triage_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Triage, duration: 3, meta: effect: ConstructEffect { effect: Effect::Triage, duration: 3, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Heal { Action::Heal {
construct: cast.target, construct: cast.target,
colour: Colour::Green, colour: Colour::Green,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2274,18 +2231,20 @@ fn triage_plus(cast: Cast, game: &mut Game) {
} }
fn triage_plus_plus(cast: Cast, game: &mut Game) { fn triage_plus_plus(cast: Cast, game: &mut Game) {
let amount = game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier());
game.action(cast, game.action(cast,
Action::Effect { Action::Effect {
construct: cast.target, construct: cast.target,
effect: ConstructEffect { effect: Effect::Triage, duration: 4, meta: effect: ConstructEffect { effect: Effect::Triage, duration: 4, meta:
Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTickPlusPlus }) }, Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick, speed: cast.speed, amount }) },
} }
); );
game.action(cast, game.action(cast,
Action::Heal { Action::Heal {
construct: cast.target, construct: cast.target,
colour: Colour::Green, colour: Colour::Green,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier()), amount,
} }
); );
game.action(cast, game.action(cast,
@ -2301,7 +2260,7 @@ fn triage_tick(cast: Cast, game: &mut Game) {
Action::Heal { Action::Heal {
construct: cast.target, construct: cast.target,
colour: Colour::Green, colour: Colour::Green,
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::GreenPower }).pct(cast.skill.multiplier()), amount: game.value(Value::TickDamage { construct: cast.target, effect: Effect::Electrocute }),
} }
); );
game.action(cast, game.action(cast,