diff --git a/WORKLOG.md b/WORKLOG.md index 9b677b19..cf457b0f 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -40,9 +40,7 @@ change strangle hatred maybe reconnect based on time delta -fix refresh button -locaalstorage team remove rounds consolidate game and instance diff --git a/server/src/game.rs b/server/src/game.rs index 863765f6..598b8054 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -1111,7 +1111,7 @@ mod tests { } // apply buff - game.add_skill(x_player.id, x_construct.id, None, Skill::CorruptI).unwrap(); + game.add_skill(x_player.id, x_construct.id, Some(x_construct.id), Skill::CorruptI).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); diff --git a/server/src/item.rs b/server/src/item.rs index c2988a2f..cbf1582e 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -52,6 +52,9 @@ pub enum Item { BanishI, BanishII, BanishIII, + BashI, + BashII, + BashIII, BlastI, BlastII, BlastIII, @@ -121,9 +124,6 @@ pub enum Item { SnareI, SnareII, SnareIII, - StrangleI, - StrangleII, - StrangleIII, StrikeI, StrikeII, StrikeIII, @@ -332,9 +332,9 @@ impl Item { Item::SnareI => Some(Skill::SnareI), Item::SnareII => Some(Skill::SnareII), Item::SnareIII => Some(Skill::SnareIII), - Item::StrangleI => Some(Skill::StrangleI), - Item::StrangleII => Some(Skill::StrangleII), - Item::StrangleIII => Some(Skill::StrangleIII), + Item::BashI => Some(Skill::BashI), + Item::BashII => Some(Skill::BashII), + Item::BashIII => Some(Skill::BashIII), Item::Stun => Some(Skill::Stun), Item::StrikeI => Some(Skill::StrikeI), Item::StrikeII => Some(Skill::StrikeII), @@ -621,11 +621,11 @@ impl Item { self.into_skill().unwrap().multiplier(), "Deals 35% more Damage per red skill on target"), - Item::StrangleI | - Item::StrangleII | - Item::StrangleIII => format!( - "Strangle the target disabling skills from both the caster and the target. - While strangling deal RedDamage each turn {:?}% RedPower. Lasts {:?}T.", + Item::BashI | + Item::BashII | + Item::BashIII => format!( + "Bash the target increasing the cooldowns of their skills. + Deals {:?}% RedPower per cooldown increased. Lasts {:?}T.", self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_duration()), @@ -726,9 +726,9 @@ impl Item { Item::RechargeII => vec![Item::RechargeI, Item::RechargeI, Item::RechargeI], Item::RechargeIII => vec![Item::RechargeII, Item::RechargeII, Item::RechargeII], - Item::StrangleI => vec![Item::Stun, Item::Red, Item::Red], - Item::StrangleII => vec![Item::StrangleI, Item::StrangleI, Item::StrangleI], - Item::StrangleIII => vec![Item::StrangleII, Item::StrangleII, Item::StrangleII], + Item::BashI => vec![Item::Stun, Item::Red, Item::Red], + Item::BashII => vec![Item::BashI, Item::BashI, Item::BashI], + Item::BashIII => vec![Item::BashII, Item::BashII, Item::BashII], Item::SleepI => vec![Item::Stun, Item::Green, Item::Green], Item::SleepII => vec![Item::SleepI, Item::SleepI, Item::SleepI], Item::SleepIII => vec![Item::SleepII, Item::SleepII, Item::SleepII], @@ -875,9 +875,9 @@ impl From for Item { Skill::SnareI => Item::SnareI, Skill::SnareII => Item::SnareII, Skill::SnareIII => Item::SnareIII, - Skill::StrangleI => Item::StrangleI, - Skill::StrangleII => Item::StrangleII, - Skill::StrangleIII => Item::StrangleIII, + Skill::BashI => Item::BashI, + Skill::BashII => Item::BashII, + Skill::BashIII => Item::BashIII, Skill::StrikeI => Item::StrikeI, Skill::StrikeII => Item::StrikeII, Skill::StrikeIII => Item::StrikeIII, @@ -913,9 +913,6 @@ impl From for Item { Skill::SiphonTickI => Item::SiphonI, Skill::SiphonTickII => Item::SiphonII, Skill::SiphonTickIII => Item::SiphonIII, - Skill::StrangleTickI => Item::StrangleI, - Skill::StrangleTickII => Item::StrangleII, - Skill::StrangleTickIII => Item::StrangleIII, Skill::TriageTickI => Item::TriageI, Skill::TriageTickII => Item::TriageII, Skill::TriageTickIII => Item::TriageIII, @@ -1034,9 +1031,9 @@ pub fn get_combos() -> Vec { Combo { components: Item::RechargeII.combo(), item: Item::RechargeII }, Combo { components: Item::RechargeIII.combo(), item: Item::RechargeIII }, - Combo { components: Item::StrangleI.combo(), item: Item::StrangleI }, - Combo { components: Item::StrangleII.combo(), item: Item::StrangleII }, - Combo { components: Item::StrangleIII.combo(), item: Item::StrangleIII }, + Combo { components: Item::BashI.combo(), item: Item::BashI }, + Combo { components: Item::BashII.combo(), item: Item::BashII }, + Combo { components: Item::BashIII.combo(), item: Item::BashIII }, Combo { components: Item::SleepI.combo(), item: Item::SleepI }, Combo { components: Item::SleepII.combo(), item: Item::SleepII }, Combo { components: Item::SleepIII.combo(), item: Item::SleepIII }, diff --git a/server/src/skill.rs b/server/src/skill.rs index febfa088..55b798c3 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -119,7 +119,11 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut Skill::BanishI | Skill::BanishII | - Skill::BanishIII => banish(source, target, resolutions, skill), // TODO prevent all actions + Skill::BanishIII => banish(source, target, resolutions, skill), + + Skill::BashI | + Skill::BashII | + Skill::BashIII => bash(source, target, resolutions, skill), Skill::BlastI | Skill::BlastII | @@ -226,13 +230,6 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut Skill::SnareII | Skill::SnareIII => snare(source, target, resolutions, skill), - Skill::StrangleI | - Skill::StrangleII | - Skill::StrangleIII => strangle(source, target, resolutions, skill), - Skill::StrangleTickI | - Skill::StrangleTickII | - Skill::StrangleTickIII => strangle_tick(source, target, resolutions, skill), - Skill::StrikeI | Skill::StrikeII | Skill::StrikeIII => strike(source, target, resolutions, skill), @@ -275,7 +272,6 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut // Not used - // Skill::Injure => injure(source, target, resolutions, skill), }; return resolutions; @@ -496,8 +492,6 @@ pub enum Effect { Reflect, Slow, Snare, - Strangle, - Strangling, Stun, Taunt, Vulnerable, @@ -523,7 +517,6 @@ pub enum Effect { Regen, Siphon, - Injured, // Airborne, // Boost // Bleed, @@ -561,14 +554,10 @@ impl Effect { Skill::RuinI, Skill::RuinII, Skill::RuinIII, - Skill::StrangleI, - Skill::StrangleII, - Skill::StrangleIII, Skill::SnareI, Skill::SnareII, Skill::SnareIII ].contains(&skill), - Effect::Injured => skill.colours().contains(&Colour::Green), _ => false, } } @@ -582,13 +571,6 @@ impl Effect { Effect::Stun => true, Effect::Hex => true, Effect::Banish => true, - Effect::Strangle => true, - Effect::Strangling => match skill { - Skill::StrangleTickI | - Skill::StrangleTickII | - Skill::StrangleTickIII => false, - _ => true, - }, Effect::Silence => skill.colours().contains(&Colour::Blue), Effect::Snare => skill.colours().contains(&Colour::Red), Effect::Ko => skill.ko_castable(), @@ -690,13 +672,6 @@ impl Effect { Effect::Regen => EffectCategory::Buff, Effect::Siphon => EffectCategory::Debuff, - // can't be purged or purified - Effect::Strangle => EffectCategory::Constant, - Effect::Strangling => EffectCategory::Constant, - - // not in game - Effect::Injured => EffectCategory::Debuff, - Effect::Ko => EffectCategory::Ko, } } @@ -729,6 +704,10 @@ pub enum Skill { BanishII, BanishIII, + BashI, + BashII, + BashIII, + BlastI, BlastII, BlastIII, @@ -786,7 +765,6 @@ pub enum Skill { ImpurityI, ImpurityII, ImpurityIII, - // Injure, InvertI, InvertII, @@ -846,13 +824,6 @@ pub enum Skill { SnareII, SnareIII, - StrangleI, - StrangleII, - StrangleIII, - StrangleTickI, - StrangleTickII, - StrangleTickIII, - StrikeI, StrikeII, StrikeIII, @@ -931,9 +902,10 @@ impl Skill { Skill::SleepI => 240, //Green dmg (heal) Skill::SleepII => 300, Skill::SleepIII => 400, - Skill::StrangleTickI => 65, - Skill::StrangleTickII => 95, - Skill::StrangleTickIII => 140, + + Skill::BashI => 65, + Skill::BashII => 95, + Skill::BashIII => 140, // Debuff Base Skill::DecayTickI => 25, @@ -1095,27 +1067,24 @@ impl Skill { Skill::SnareII => vec![ConstructEffect {effect: Effect::Snare, duration: 3, meta: None, tick: None}], Skill::SnareIII => vec![ConstructEffect {effect: Effect::Snare, duration: 4, meta: None, tick: None}], - Skill::StrangleI => vec![ConstructEffect {effect: Effect::Strangle, duration: 2, - meta: Some(EffectMeta::Skill(Skill::StrangleTickI)), tick: None}], - Skill::StrangleII => vec![ConstructEffect {effect: Effect::Strangle, duration: 2, - meta: Some(EffectMeta::Skill(Skill::StrangleTickII)), tick: None}], - Skill::StrangleIII => vec![ConstructEffect {effect: Effect::Strangle, duration: 2, - meta: Some(EffectMeta::Skill(Skill::StrangleTickIII)), tick: None}], - Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], + Skill::BashI => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::BashI)), tick: None}], + Skill::BashII => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::BashII)), tick: None}], + Skill::BashIII => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::BashIII)), tick: None}], + Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], - Skill::TauntI => vec![ConstructEffect {effect: Effect::Taunt, duration: 2, meta: None, tick: None}], - Skill::TauntII => vec![ConstructEffect {effect: Effect::Taunt, duration: 3, meta: None, tick: None}], - Skill::TauntIII => vec![ConstructEffect {effect: Effect::Taunt, duration: 4, meta: None, tick: None}], + Skill::TauntI => vec![ConstructEffect {effect: Effect::Taunt, duration: 2, meta: None, tick: None}], + Skill::TauntII => vec![ConstructEffect {effect: Effect::Taunt, duration: 3, meta: None, tick: None}], + Skill::TauntIII => vec![ConstructEffect {effect: Effect::Taunt, duration: 4, meta: None, tick: None}], - Skill::TriageI => vec![ConstructEffect {effect: Effect::Triage, duration: 2, - meta: Some(EffectMeta::Skill(Skill::TriageTickI)), tick: None}], - Skill::TriageII => vec![ConstructEffect {effect: Effect::Triage, duration: 3, + Skill::TriageI => vec![ConstructEffect {effect: Effect::Triage, duration: 2, + meta: Some(EffectMeta::Skill(Skill::TriageTickI)), tick: None}], + Skill::TriageII => vec![ConstructEffect {effect: Effect::Triage, duration: 3, meta: Some(EffectMeta::Skill(Skill::TriageTickII)), tick: None}], - Skill::TriageIII => vec![ConstructEffect {effect: Effect::Triage, duration: 4, + Skill::TriageIII => vec![ConstructEffect {effect: Effect::Triage, duration: 4, meta: Some(EffectMeta::Skill(Skill::TriageTickIII)), tick: None}], - //Unused - // Skill::Injure => vec![ConstructEffect {effect: Effect::Injured, duration: 2, meta: None, tick: None }], - _ => { panic!("{:?} no skill effect", self); }, @@ -1141,6 +1110,10 @@ impl Skill { Skill::SnareIII => Some(2), Skill::Stun => Some(2), + Skill::BashI => Some(2), + Skill::BashII => Some(2), + Skill::BashIII => Some(2), + Skill::HealI => None, Skill::HealII => None, Skill::HealIII => None, @@ -1230,9 +1203,9 @@ impl Skill { Skill::SleepII => Some(3), Skill::SleepIII => Some(3), - Skill::StrangleI => Some(2), - Skill::StrangleII => Some(2), - Skill::StrangleIII => Some(2), + Skill::BashI => Some(2), + Skill::BashII => Some(2), + Skill::BashIII => Some(2), Skill::ClutchI => Some(1), Skill::ClutchII => Some(2), @@ -1241,7 +1214,6 @@ impl Skill { Skill::TauntI => Some(2), Skill::TauntII => Some(2), Skill::TauntIII => Some(2), - // Skill::Injure => Some(2), Skill::CorruptI =>Some(1), Skill::CorruptII =>Some(1), @@ -1277,9 +1249,6 @@ impl Skill { Skill::SiphonTickI | Skill::SiphonTickII | Skill::SiphonTickIII | - Skill::StrangleTickI | - Skill::StrangleTickII | - Skill::StrangleTickIII | Skill::TriageTickI | Skill::TriageTickII | Skill::TriageTickIII => None, @@ -1316,9 +1285,6 @@ impl Skill { Skill::SiphonTickI | Skill::SiphonTickII | Skill::SiphonTickIII | - Skill::StrangleTickI | - Skill::StrangleTickII | - Skill::StrangleTickIII | Skill::TriageTickI | Skill::TriageTickII | @@ -1337,6 +1303,7 @@ impl Skill { Skill::SiphonTickI | Skill::SiphonTickII | Skill::SiphonTickIII => Skill::SiphonI.speed(), + Skill::DecayTickI | Skill::DecayTickII | Skill::DecayTickIII => Skill::DecayI.speed(), @@ -1345,9 +1312,6 @@ impl Skill { Skill::TriageTickII | Skill::TriageTickIII => Skill::TriageI.speed(), - Skill::StrangleTickI | - Skill::StrangleTickII | - Skill::StrangleTickIII => Skill::StrangleI.speed(), Skill::CorruptionTickI | Skill::CorruptionTickII | Skill::CorruptionTickIII => Skill::CorruptI.speed(), @@ -1368,9 +1332,6 @@ impl Skill { pub fn self_targeting(&self) -> bool { match self { Skill::Block | - Skill::CorruptI | - Skill::CorruptII | - Skill::CorruptIII | Skill::ClutchI | Skill::ClutchII | Skill::ClutchIII | @@ -1480,18 +1441,6 @@ fn strike(source: &mut Construct, target: &mut Construct, mut results: Resolutio return results; } -/*fn injure(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let amount = source.red_power().pct(skill.multiplier()); - target.deal_red_damage(skill, amount) - .into_iter() - .for_each(|e| results.push(Resolution::new(source, target).event(e))); - - skill.effect().into_iter() - .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e))))); - - return results; -} -*/ fn stun(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { skill.effect().into_iter() .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e))))); @@ -1499,6 +1448,37 @@ fn stun(source: &mut Construct, target: &mut Construct, mut results: Resolutions return results; } +fn bash(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { + skill.effect().into_iter() + .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e))))); + + if results.iter().any(|r| match r.event { + Event::Effect { effect, skill: effect_skill, duration: _, construct_effects: _ } + => effect == Effect::Stun && skill == effect_skill, + _ => false, + }) { + let mut cds = 0; + for cs in target.skills.iter_mut() { + if cs.skill.base_cd().is_some() { + cs.cd = match cs.cd { + None => Some(1), + Some(i) => Some(i + 1), + }; + + cds += 1; + } + } + + let amount = source.red_power().pct(skill.multiplier().saturating_mul(cds)); + target.deal_red_damage(skill, amount) + .into_iter() + .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(LogStages::PostOnly))); + } + + return results; +} + + fn sleep(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { skill.effect().into_iter() .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e))))); @@ -1535,46 +1515,6 @@ fn throw(source: &mut Construct, target: &mut Construct, mut results: Resolution return results; } -fn strangle(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let ConstructEffect { effect, duration, meta, tick: _ } = skill.effect()[0]; - let tick_skill = match meta { - Some(EffectMeta::Skill(s)) => s, - _ => panic!("no strangle tick skill"), - }; - let strangle = ConstructEffect::new(effect, duration).set_tick(Cast::new_tick(source, target, tick_skill)); - results.push(Resolution::new(source, target).event(target.add_effect(skill, strangle))); - - let attacker_strangle = ConstructEffect::new(Effect::Strangling, duration); - results.push(Resolution::new(source, source).event(source.add_effect(skill, attacker_strangle)).stages(LogStages::PostOnly)); - return strangle_tick(source, target, results, tick_skill); -} - -fn strangle_tick(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let amount = source.red_power().pct(skill.multiplier()); - target.deal_red_damage(skill, amount) - .into_iter() - .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(LogStages::EndPost))); - - // remove immunity if target ko - if target.is_ko() && !source.is_ko() { - if let Some(i) = source.effects - .iter() - .position(|e| e.effect == Effect::Strangling) { - source.effects.remove(i); - results.push(Resolution::new(source, source) - .event(Event::Removal { effect: Effect::Strangling, construct_effects: target.effects.clone() }) - .stages(LogStages::PostOnly)); - } - else { - error!("{:?}", results); - println!("{:?}", results); - panic!("no strangling on source"); - } - } - - return results; -} - fn block(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { results.push(Resolution::new(source, target) .event(target.add_effect(skill, skill.effect()[0])) @@ -2044,19 +1984,6 @@ mod tests { }; } -/* #[test] - fn injure_test() { - let mut x = Construct::new() - .named(&"muji".to_string()); - - let mut y = Construct::new() - .named(&"camel".to_string()); - - resolve(Skill::Injure, &mut x, &mut y, vec![]); - assert!(y.immune(Skill::HealI).is_some()); - // resolutions = heal(&mut y.clone(), &mut y, resolutions); - } -*/ #[test] fn invert_test() { let mut x = Construct::new() @@ -2247,22 +2174,19 @@ mod tests { } #[test] - fn strangle_test() { + fn bash_test() { let mut x = Construct::new() .named(&"muji".to_string()); let mut y = Construct::new() - .named(&"pretaliation".to_string()); + .named(&"pretaliation".to_string()) + .learn(Skill::Stun); - strangle(&mut x, &mut y, vec![], Skill::StrangleI); - assert!(y.effects.iter().any(|e| e.effect == Effect::Strangle)); - assert!(x.effects.iter().any(|e| e.effect == Effect::Strangling)); + let stun_cd = y.skills.iter().find(|cs| cs.skill == Skill::Stun).unwrap().cd.unwrap(); - // ensure can't be removed - purify(&mut x, &mut y, vec![], Skill::PurifyI); - assert!(y.effects.iter().any(|e| e.effect == Effect::Strangle)); - purge(&mut x.clone(), &mut x, vec![], Skill::PurgeI); - assert!(x.effects.iter().any(|e| e.effect == Effect::Strangling)); + bash(&mut x, &mut y, vec![], Skill::BashI); + assert!(!x.effects.iter().any(|e| e.effect == Effect::Stun)); + assert!(y.skills.iter().any(|cs| cs.skill == Skill::Stun && cs.cd.unwrap() == stun_cd + 1)); } }