diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0a0a23..f5bad0cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,13 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.0.0] - YYYY-MM-DD +### Added +### Fixed +### Changed + ## [In Progress] *BALANCE* -- strike - - 110 -> 90 - -- strangle - no immunity - - purify - 1 effect from all cryps at level 2 - removes all effects from all cryps at l3 @@ -18,26 +17,81 @@ This project adheres to [Semantic Versioning](http://semver.org/). - fx for buffs when applied to enemies - invert + haste -> doubles all cooldowns -- haste - - additional attack with red skills if affected - - deal % dmg based on speed difference between source and target? - - l2 maybe reduce cooldowns or something - -- heal - - buff % +New skill `Scatter ` + Combines - Buff + BB + Links targets together so dmg taken is split + Recharge 140% source blue damage as blue life to target var / skill info rpc thresholds / bonuses sell cost etc - -## [Unreleased] +## [0.1.2] - 2019-05-07 ### Added -### Changed + +New skill `Impurity` + Combines - Buff + GB + New buff that does the following - + Increase target green damage by 50% + Blue attacks do an additional blast equal to 25% source green damage + ### Fixed -## [0.1.1] - 2019-05-06 +- Ruin sends a skill event so ruin only casts once, followed by debuffs + +### Changed + +- Removed Empower (Buff + RR) -> combined effect with amplify + +- Amplify + Changed to Buff + RB (was Buff + BB) + Increases both red and blue power. + +- Attack + Multiplier changed 100% -> 80% + +- Blast + Multiplier changed 130% -> 110% + +- Chaos + Base Multiplier changed 50% -> 40% + RNG range changed from (0 - 20%) -> (0 - 30%) + Same dmg range but more RNG + +- Haste + Changed to Buff + RG (was Buff + RB) + Buff causes target to deal an extra attack when using red attack base skills (strike / slay / chaos) + Extra attack does 25% source speed as red damage + Cooldown increased to 2T + +- Heal + Changed multiplier 120% -> 130% + +- Siphon + Multiplier changed 30% -> 40% + +- Strangle + No longer provides immunity to source or target + Damage multiplier for strangle tick changed 30% -> 65% + +- Strike + Change multipliers T1/T2/T3 (110/130/150 -> 90/110/130) + +- Taunt + Changed to Buff + RR (was Buff + RG) + Now recharges 80% source red damage as red life to target + +- Throw + Stun duration reduced from 2T -> 1T + +- Triage + Multiplier changed 65% -> 75% + + +## [Unreleased] +## [0.1.1] - 2019-05-03 +>>>>>>> rebalance ### Added Event::Skill needed to convey the use of skill which is followed by other events @@ -77,8 +131,13 @@ var / skill info rpc Cooldown changed 1T -> 2T Debuff duration increased 2T -> 3T Snare +<<<<<<< HEAD Now also deals damage amount of 40% base blue damage This damage amount does 45% more damage per red skill blocked +======= + Now also deals damage amount of 40% base red damage + This damage amount does 45% more damage per red skill blocked +>>>>>>> rebalance Maximum = (0.40)(1.35)*base_red_damage Cooldown changed 1T -> 2T Debuff duration increased 2T -> 3T diff --git a/client/src/utils.jsx b/client/src/utils.jsx index 1ce650e3..b87e0c4c 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -236,7 +236,10 @@ function getCombatSequence(event) { if (['Effect'].includes(event[0]) - && event[1].skill === 'Decay' && event[1].effect === 'Wither') return ['POST_SKILL']; + && ((event[1].skill === 'Decay' && event[1].effect === 'Wither') + || event[1].skill === 'Ruin' + || event[1].skill === 'Taunt' + || event[1].skill === 'Strangling')) return ['POST_SKILL']; if (['Damage'].includes(event[0]) && ((event[1].skill === 'Chaos' && event[1].colour === 'RedDamage') diff --git a/server/src/game.rs b/server/src/game.rs index 84f3e4fc..8487140b 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -17,6 +17,7 @@ use cryp::{Cryp}; use skill::{Skill, Effect, Cast, Resolution, Event, resolve}; use player::{Player}; use instance::{instance_game_finished, global_game_finished}; +use util::{IntPct}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum Phase { @@ -944,7 +945,7 @@ mod tests { .learn(Skill::TestBlock) .learn(Skill::TestParry) .learn(Skill::TestSiphon) - .learn(Skill::Empower) + .learn(Skill::Amplify) .learn(Skill::Stun) .learn(Skill::Block); @@ -956,7 +957,7 @@ mod tests { .learn(Skill::TestBlock) .learn(Skill::TestParry) .learn(Skill::TestSiphon) - .learn(Skill::Empower) + .learn(Skill::Amplify) .learn(Skill::Stun) .learn(Skill::Block); @@ -1174,7 +1175,7 @@ mod tests { // should not be stunned because of parry assert!(game.player_by_id(x_player.id).unwrap().cryps[0].is_stunned() == false); // riposte - assert!(game.player_by_id(y_player.id).unwrap().cryps[0].green_life() == 768); + assert!(game.player_by_id(y_player.id).unwrap().cryps[0].green_life() == (1024 - x_cryp.red_damage().pct(Skill::Riposte.multiplier()))); } #[test] @@ -1205,7 +1206,6 @@ mod tests { assert!(game.skill_phase_finished()); game = game.resolve_phase_start(); - let ruins = game.resolved .into_iter() .filter(|r| { @@ -1216,7 +1216,8 @@ mod tests { assert!(*effect == Effect::Ruin); assert!(*duration == 1); true - } + }, + Event::Skill { skill } => false, _ => panic!("ruin result not effect {:?}", event), } false => false, @@ -1255,7 +1256,7 @@ mod tests { game = game.resolve_phase_start(); - assert!(game.resolved.len() == 4); + assert!(game.resolved.len() == 5); while let Some(r) = game.resolved.pop() { let Resolution { source , target, event: _ } = r; if [i_cryp.id, j_cryp.id].contains(&source.id) { diff --git a/server/src/instance.rs b/server/src/instance.rs index 2dcd0871..46258fcf 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -275,7 +275,7 @@ impl Instance { fn next_round(&mut self) -> &mut Instance { self.phase = InstancePhase::InProgress; self.phase_end = Utc::now() - .checked_add_signed(Duration::seconds(120)) + .checked_add_signed(Duration::seconds(150)) .expect("could not set phase end"); diff --git a/server/src/skill.rs b/server/src/skill.rs index 4f82a5f0..802b6ae6 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -25,6 +25,35 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio return resolve(skill, target, source, resolutions); } + if source.affected(Effect::Haste) { + match skill { + Skill::Attack | + Skill::Slay | + Skill::Chaos | + Skill::Strike => { + let amount = source.speed().pct(Skill::HasteStrike.multiplier()); + target.deal_red_damage(Skill::HasteStrike, amount) + .into_iter() + .for_each(|e| resolutions.push(Resolution::new(source, target).event(e))); + }, + _ => (), + } + } + + if source.affected(Effect::Impurity) { + match skill { + Skill::Blast | + Skill::Chaos | + Skill::Siphon => { + let amount = source.green_damage().pct(Skill::ImpureBlast.multiplier()); + target.deal_blue_damage(Skill::ImpureBlast, amount) + .into_iter() + .for_each(|e| resolutions.push(Resolution::new(source, target).event(e))); + }, + _ => (), + } + } + // match self.category() == Category::Red { // true => { // if let Some(evasion) = target.evade(*self) { @@ -36,57 +65,61 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio // } resolutions = match skill { - Skill::Amplify => amplify(source, target, resolutions, Skill::Amplify), // increase magic damage - Skill::Attack => attack(source, target, resolutions, Skill::Attack), - Skill::Banish => banish(source, target, resolutions, Skill::Banish), // TODO prevent all actions - Skill::Blast => blast(source, target, resolutions, Skill::Blast), - Skill::Block => block(source, target, resolutions, Skill::Block), - Skill::Chaos => chaos(source, target, resolutions, Skill::Chaos), - Skill::Clutch => clutch(source, target, resolutions, Skill::Clutch), - Skill::Corrupt => corrupt(source, target, resolutions, Skill::Corrupt), - Skill::CorruptionTick => corruption_tick(source, target, resolutions, Skill::CorruptionTick), - Skill::Curse => curse(source, target, resolutions, Skill::Curse), - Skill::Decay => decay(source, target, resolutions, Skill::Decay), // dot - Skill::DecayTick => decay_tick(source, target, resolutions, Skill::DecayTick), // dot - Skill::Empower => empower(source, target, resolutions, Skill::Empower), // increased phys damage - Skill::Haste => haste(source, target, resolutions, Skill::Haste), // speed slow - Skill::Heal => heal(source, target, resolutions, Skill::Heal), - Skill::Hex => hex(source, target, resolutions, Skill::Hex), - Skill::Hostility => hostility(source, target, resolutions, Skill::Hostility), - Skill::Invert => invert(source, target, resolutions, Skill::Invert), - Skill::Injure => injure(source, target, resolutions, Skill::Injure), - Skill::Parry => parry(source, target, resolutions, Skill::Parry), - Skill::Purge => purge(source, target, resolutions, Skill::Purge), // dispel all buffs - Skill::Purify => purify(source, target, resolutions, Skill::Purify), // dispel all debuffs - Skill::Recharge => recharge(source, target, resolutions, Skill::Recharge), // target is immune to magic damage and fx - Skill::Reflect => reflect(source, target, resolutions, Skill::Reflect), + Skill::Amplify => amplify(source, target, resolutions, skill), // increase magic damage + Skill::Attack => attack(source, target, resolutions, skill), + Skill::Banish => banish(source, target, resolutions, skill), // TODO prevent all actions + Skill::Blast => blast(source, target, resolutions, skill), + Skill::Block => block(source, target, resolutions, skill), + Skill::Chaos => chaos(source, target, resolutions, skill), + Skill::Clutch => clutch(source, target, resolutions, skill), + Skill::Corrupt => corrupt(source, target, resolutions, skill), + Skill::CorruptionTick => corruption_tick(source, target, resolutions, skill), + Skill::Curse => curse(source, target, resolutions, skill), + Skill::Decay => decay(source, target, resolutions, skill), // dot + Skill::DecayTick => decay_tick(source, target, resolutions, skill), // dot + Skill::Haste => haste(source, target, resolutions, skill), // speed slow + Skill::HasteStrike => panic!("haste strike should not be caste"), + Skill::Heal => heal(source, target, resolutions, skill), + Skill::Hex => hex(source, target, resolutions, skill), + Skill::Hostility => hostility(source, target, resolutions, skill), + Skill::Impurity => impurity(source, target, resolutions, skill), + Skill::ImpureBlast => panic!("impure blast should not be caste"), + Skill::Invert => invert(source, target, resolutions, skill), + Skill::Injure => injure(source, target, resolutions, skill), + Skill::Parry => parry(source, target, resolutions, skill), + Skill::Purge => purge(source, target, resolutions, skill), // dispel all buffs + Skill::Purify => purify(source, target, resolutions, skill), // dispel all debuffs + Skill::Recharge => recharge(source, target, resolutions, skill), // target is immune to magic damage and fx + Skill::Reflect => reflect(source, target, resolutions, skill), Skill::Riposte => panic!("riposte should not be caste"), - Skill::Ruin => ruin(source, target, resolutions, Skill::Ruin), - Skill::Shield => shield(source, target, resolutions, Skill::Shield), // target is immune to magic damage and fx - Skill::Silence => silence(source, target, resolutions, Skill::Silence), // target cannot cast spells - Skill::Siphon => siphon(source, target, resolutions, Skill::Siphon), - Skill::SiphonTick => siphon_tick(source, target, resolutions, Skill::SiphonTick), // hot - Skill::Slay => slay(source, target, resolutions, Skill::Slay), // hybrid dmg self heal - Skill::Sleep => sleep(source, target, resolutions, Skill::Sleep), // speed slow - Skill::Slow => slow(source, target, resolutions, Skill::Slow), // speed slow - Skill::Snare => snare(source, target, resolutions, Skill::Snare), - Skill::Strangle => strangle(source, target, resolutions, Skill::Strangle), - Skill::StrangleTick => strangle_tick(source, target, resolutions, Skill::StrangleTick), + Skill::Ruin => ruin(source, target, resolutions, skill), + Skill::Scatter => scatter(source, target, resolutions, skill), // target is immune to magic damage and fx + Skill::Silence => silence(source, target, resolutions, skill), // target cannot cast spells + Skill::Siphon => siphon(source, target, resolutions, skill), + Skill::SiphonTick => siphon_tick(source, target, resolutions, skill), // hot + Skill::Slay => slay(source, target, resolutions, skill), // hybrid dmg self heal + Skill::Sleep => sleep(source, target, resolutions, skill), // speed slow + Skill::Slow => slow(source, target, resolutions, skill), // speed slow + Skill::Snare => snare(source, target, resolutions, skill), + Skill::Strangle => strangle(source, target, resolutions, skill), + Skill::StrangleTick => strangle_tick(source, target, resolutions, skill), - Skill::Strike => strike(source, target, resolutions, Skill::Strike), - Skill::StrikeII => strike(source, target, resolutions, Skill::StrikeII), - Skill::StrikeIII => strike(source, target, resolutions, Skill::StrikeIII), + Skill::Strike => strike(source, target, resolutions, skill), + Skill::StrikeII => strike(source, target, resolutions, skill), + Skill::StrikeIII => strike(source, target, resolutions, skill), - Skill::Stun => stun(source, target, resolutions, Skill::Stun), - Skill::Taunt => taunt(source, target, resolutions, Skill::Taunt), - Skill::Throw => throw(source, target, resolutions, Skill::Throw), // no damage stun, adds vulnerable - Skill::Triage => triage(source, target, resolutions, Skill::Triage), // hot - Skill::TriageTick => triage_tick(source, target, resolutions, Skill::TriageTick), // hot + Skill::Stun => stun(source, target, resolutions, skill), + Skill::Taunt => taunt(source, target, resolutions, skill), + Skill::Throw => throw(source, target, resolutions, skill), // no damage stun, adds vulnerable + Skill::Triage => triage(source, target, resolutions, skill), // hot + Skill::TriageTick => triage_tick(source, target, resolutions, skill), // hot // ----------------- // Test // ----------------- - Skill::TestTouch => touch(source, target, resolutions, Skill::TestTouch), + Skill::TestAttack => attack(source, target, resolutions, skill), + Skill::TestHeal => heal(source, target, resolutions, skill), + Skill::TestTouch => touch(source, target, resolutions, skill), Skill::TestStun => stun(source, target, resolutions, Skill::Stun), Skill::TestBlock => block(source, target, resolutions, Skill::Block), Skill::TestParry => parry(source, target, resolutions, Skill::Parry), @@ -237,9 +270,8 @@ pub enum Effect { Reflect, - Empower, Taunt, - + Impurity, Invert, Strangle, Strangling, @@ -268,7 +300,7 @@ pub enum Effect { Hatred, // magic immunity - Shield, + Scatter, // effects over time Triage, @@ -290,17 +322,11 @@ impl Effect { Category::Red => true, _ => false, }, - Effect::Shield => match skill.category() { + Effect::Scatter => match skill.category() { Category::Blue => true, Category::Red => false, _ => false, }, - Effect::Strangle => skill != Skill::StrangleTick, - Effect::Strangling => match skill.category() { - Category::BlueTick => false, - Category::RedTick => false, - _ => true, - }, Effect::Banish => true, Effect::Injured => match skill.category() { Category::Green => true, @@ -341,15 +367,15 @@ impl Effect { pub fn modifications(&self) -> Vec { match self { - Effect::Empower => vec![Stat::RedDamage], Effect::Vulnerable => vec![Stat::RedDamageTaken], Effect::Block => vec![Stat::RedDamageTaken], Effect::Hatred => vec![Stat::RedDamage, Stat::BlueDamage], - Effect::Amplify => vec![Stat::BlueDamage], + Effect::Amplify => vec![Stat::RedDamage, Stat::BlueDamage], Effect::Curse => vec![Stat::BlueDamageTaken], + Effect::Impurity => vec![Stat::GreenDamage], Effect::Wither => vec![Stat::GreenDamageTaken], Effect::Haste => vec![Stat::Speed], @@ -361,7 +387,6 @@ impl Effect { pub fn apply(&self, value: u64, meta: Option) -> u64 { match self { - Effect::Empower => value << 1, Effect::Vulnerable => value << 1, Effect::Block => value >> 1, @@ -371,6 +396,7 @@ impl Effect { Effect::Haste => value << 1, Effect::Slow => value >> 1, + Effect::Impurity => value << 1, Effect::Wither => value >> 1, Effect::Hatred => value + match meta { @@ -402,7 +428,6 @@ impl Effect { Effect::Snare => Category::Debuff, Effect::Clutch => Category::Buff, Effect::Taunt => Category::Buff, - Effect::Empower => Category::Buff, Effect::Injured => Category::Debuff, Effect::Strangle => Category::Debuff, Effect::Strangling => Category::Buff, @@ -427,8 +452,9 @@ impl Effect { Effect::Hostility => Category::Buff, - // magic immunity - Effect::Shield => Category::Buff, + // magic + Effect::Impurity => Category::Buff, + Effect::Scatter => Category::Buff, Effect::Invert => Category::Buff, // effects over time @@ -485,6 +511,8 @@ pub enum Skill { Sleep, Clutch, Taunt, + Impurity, + ImpureBlast, Invert, Strangle, @@ -527,8 +555,7 @@ pub enum Skill { // ----------------- // Purity // ----------------- - Empower, - Shield, + Scatter, Silence, Purify, Purge, @@ -540,10 +567,13 @@ pub enum Skill { Chaos, Hex, Haste, + HasteStrike, Slow, - // used by tests, no cd, no damage - TestTouch, + // used by tests, no cd, 100% multiplier + TestAttack, + TestHeal, + TestTouch, // No damage TestStun, TestBlock, TestParry, @@ -554,34 +584,40 @@ impl Skill { pub fn multiplier(&self) -> u64 { match self { // Attack Base - Skill::Attack => 100, // 1.0 to pass tests - Skill::Blast => 130, // BB - Skill::Chaos => 50, // BR - Skill::Heal => 120, //GG + Skill::Attack => 80, // Base + + Skill::Blast => 110, // BB + Skill::Chaos => 40, // BR + Skill::Heal => 130, //GG + Skill::SiphonTick => 40, // GB Skill::Slay => 70, // RG - Skill::Strike => 110, //RR - Skill::StrikeII => 130, - Skill::StrikeIII => 150, + Skill::Strike => 90, //RR + Skill::StrikeII => 110, + Skill::StrikeIII => 130, // Block Base + Skill::CorruptionTick => 80, Skill::Purify => 45, //Green dmg (heal) Skill::Recharge => 85, //restore red and blue life (heal) Skill::Reflect => 45, //restore blue life (heal) + Skill::Riposte => 70, // Stun Base Skill::Sleep => 240, //Green dmg (heal) + Skill::StrangleTick => 65, // Debuff Base Skill::Silence => 55, // Deals more per blue skill on target - Skill::Snare => 40, // Deals more per blue skill on target - - // Others - Skill::CorruptionTick => 80, + Skill::Snare => 40, // Deals more per red skill on target Skill::DecayTick => 25, - Skill::Riposte => 100, - Skill::SiphonTick => 30, - Skill::StrangleTick => 30, - Skill::TriageTick => 65, + + // Buff base + Skill::ImpureBlast => 25, + Skill::HasteStrike => 30, + Skill::Taunt => 80, + Skill::TriageTick => 75, + + _ => 100, } } @@ -601,11 +637,11 @@ impl Skill { Skill::Stun => 2, Skill::Sleep => 3, - Skill::Throw => 2, + Skill::Throw => 1, Skill::Snare => 3, - Skill::Taunt => 1, - Skill::Empower => 2, + Skill::Taunt => 2, + Skill::Impurity => 3, Skill::Invert => 1, Skill::Hex => 2, @@ -622,7 +658,7 @@ impl Skill { Skill::Hostility => 2, // Primary Buff Skill::Corrupt => 2, // Primary Buff - Skill::Shield => 2, + Skill::Scatter => 2, Skill::Triage => 3, Skill::Decay => 3, @@ -668,20 +704,23 @@ impl Skill { Skill::Blast => None, Skill::Chaos => None, Skill::Amplify => Some(1), + Skill::Impurity => None, + Skill::ImpureBlast => None, Skill::Invert => Some(2), Skill::Decay => Some(1), // dot Skill::DecayTick => None, Skill::Siphon => None, Skill::SiphonTick => None, Skill::Curse => Some(1), - Skill::Empower => Some(1), - Skill::Shield => None, + Skill::Scatter => Some(2), Skill::Silence => Some(2), Skill::Purify => None, Skill::Purge => None, Skill::Banish => Some(1), Skill::Hex => Some(1), - Skill::Haste => None, + Skill::Haste => Some(2), + Skill::HasteStrike => None, // Used in haste + Skill::Slow => None, Skill::Reflect => Some(2), Skill::Recharge => Some(2), @@ -692,7 +731,7 @@ impl Skill { Skill::Strangle => Some(2), Skill::StrangleTick => None, Skill::Clutch => Some(2), - Skill::Taunt => Some(1), + Skill::Taunt => Some(2), Skill::Injure => Some(2), Skill::Corrupt => Some(1), @@ -703,6 +742,8 @@ impl Skill { // ----------------- // Test // ----------------- + Skill::TestAttack => None, + Skill::TestHeal => None, Skill::TestTouch => None, Skill::TestStun => None, Skill::TestBlock => None, @@ -728,20 +769,22 @@ impl Skill { Skill::Stun => Category::Red, Skill::Slay => Category::Red, Skill::Taunt => Category::Red, + Skill::HasteStrike => Category::Red, Skill::Heal => Category::Green, Skill::Triage => Category::Green, // hot Skill::TriageTick => Category::GreenTick, // hot Skill::Throw => Category::Green, - Skill::Empower => Category::Green, - Skill::Shield => Category::Green, Skill::Purify => Category::Green, Skill::Recharge => Category::Green, Skill::Reflect => Category::Green, Skill::Haste => Category::Green, + Skill::Impurity => Category::Green, Skill::Invert => Category::Green, Skill::Sleep => Category::Green, - + + Skill::ImpureBlast => Category::Blue, + Skill::Scatter => Category::Blue, Skill::Blast => Category::Blue, Skill::Chaos => Category::Blue, Skill::Amplify => Category::Blue, @@ -764,6 +807,8 @@ impl Skill { // Test // ----------------- + Skill::TestAttack => Category::Red, + Skill::TestHeal => Category::Green, Skill::TestTouch => Category::Red, Skill::TestStun => Category::Red, Skill::TestParry => Category::Red, @@ -819,7 +864,6 @@ impl Skill { Skill::Block => true, Skill::Parry => true, Skill::Clutch => true, - // Skill::Taunt => true, Skill::Corrupt => true, Skill::TestBlock => true, @@ -834,11 +878,10 @@ impl Skill { match self { Skill::Heal | Skill::Triage | - Skill::Empower | Skill::Purify | Skill::Parry | Skill::Clutch | - Skill::Shield | + Skill::Scatter | Skill::Recharge | Skill::Reflect | Skill::Haste | @@ -916,6 +959,9 @@ fn clutch(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: } fn taunt(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { + let red_amount = source.red_damage().pct(skill.multiplier()); + results.push(Resolution::new(source, target).event(target.recharge(skill, red_amount, 0))); + let effect = CrypEffect::new(Effect::Taunt, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, effect))); return results; @@ -986,13 +1032,13 @@ fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: let snare = CrypEffect::new(Effect::Snare, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, snare))); - let mut s_multi: u64 = 100; - for cs in target.skills.iter() { - s_multi += match cs.skill.category() { - Category::Red => 45, - _ => 0, - } - } + let s_multi = target.skills + .iter() + .fold(100, |acc, cs| match cs.skill.category() { + Category::Red => acc + 45, + _ => acc, + }); + let amount = source.red_damage().pct(skill.multiplier()).pct(s_multi); target.deal_red_damage(skill, amount) @@ -1003,12 +1049,6 @@ fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: return results; } -fn empower(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { - let empower = CrypEffect::new(Effect::Empower, skill.duration()); - results.push(Resolution::new(source, target).event(target.add_effect(skill, empower))); - return results; -} - fn slay(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { let amount = source.red_damage().pct(skill.multiplier()); let slay_events = target.deal_red_damage(skill, amount); @@ -1055,12 +1095,12 @@ fn triage_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, s fn chaos(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { let mut rng = thread_rng(); - let b_rng: u64 = rng.gen_range(0, 20); + let b_rng: u64 = rng.gen_range(0, 30); let amount = source.blue_damage().pct(skill.multiplier() + b_rng); target.deal_blue_damage(skill, amount) .into_iter() .for_each(|e| results.push(Resolution::new(source, target).event(e))); - let r_rng: u64 = rng.gen_range(0, 20); + let r_rng: u64 = rng.gen_range(0, 30); let amount = source.red_damage().pct(skill.multiplier() + r_rng); target.deal_red_damage(skill, amount) .into_iter() @@ -1137,6 +1177,7 @@ fn corruption_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolution } fn ruin(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { + results.push(Resolution::new(source, target).event(Event::Skill { skill })); let effect = CrypEffect::new(Effect::Ruin, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, effect))); return results;; @@ -1169,6 +1210,12 @@ fn curse(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: return results;; } +fn impurity(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { + let effect = CrypEffect::new(Effect::Impurity, skill.duration()); + results.push(Resolution::new(source, target).event(target.add_effect(skill, effect))); + return results;; +} + fn invert(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { let effect = CrypEffect::new(Effect::Invert, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, effect))); @@ -1221,9 +1268,9 @@ fn siphon_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, s return results; } -fn shield(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { - let shield = CrypEffect::new(Effect::Shield, skill.duration()); - results.push(Resolution::new(source, target).event(target.add_effect(skill, shield))); +fn scatter(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { + let scatter = CrypEffect::new(Effect::Scatter, skill.duration()); + results.push(Resolution::new(source, target).event(target.add_effect(skill, scatter))); return results; } @@ -1231,13 +1278,12 @@ fn silence(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill let silence = CrypEffect::new(Effect::Silence, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, silence))); - let mut s_multi: u64 = 100; - for cs in target.skills.iter() { - s_multi += match cs.skill.category() { - Category::Blue => 45, - _ => 0, - } - } + let s_multi = target.skills + .iter() + .fold(100, |acc, cs| match cs.skill.category() { + Category::Blue => acc + 45, + _ => acc, + }); let amount = source.blue_damage().pct(skill.multiplier()).pct(s_multi); target.deal_blue_damage(skill, amount) @@ -1331,7 +1377,7 @@ mod tests { block(&mut y.clone(), &mut y, vec![], Skill::Block); assert!(y.effects.iter().any(|e| e.effect == Effect::Block)); - let mut results = attack(&mut x, &mut y, vec![], Skill::Attack); + let mut results = attack(&mut x, &mut y, vec![], Skill::TestAttack); let Resolution { source: _, target: _, event } = results.remove(0); match event { @@ -1388,31 +1434,29 @@ mod tests { y.red_life.force(64); y.red_life.reduce(64); x.red_damage.force(256 + 64); - let damage: u64 = x.red_damage().pct(Skill::Attack.multiplier()); // 320 * 1.0 - let healing: u64 = x.green_damage().pct(Skill::Heal.multiplier()); // 256 * 1.2 invert(&mut y.clone(), &mut y, vec![], Skill::Invert); assert!(y.affected(Effect::Invert)); // heal should deal green damage - heal(&mut x, &mut y, vec![], Skill::Heal); - assert!(y.green_life() == (1024 - healing)); + heal(&mut x, &mut y, vec![], Skill::TestHeal); + assert!(y.green_life() == 768); // attack should heal and recharge red shield - let mut results = attack(&mut x, &mut y, vec![], Skill::Attack); + let mut results = attack(&mut x, &mut y, vec![], Skill::TestAttack); assert!(y.green_life() == 1024); match results.remove(0).event { - Event::Inversion { skill } => assert_eq!(skill, Skill::Attack), + Event::Inversion { skill } => assert_eq!(skill, Skill::TestAttack), _ => panic!("not inversion"), }; match results.remove(0).event { - Event::Healing { skill: _, overhealing: _, amount } => assert_eq!(amount, healing), + Event::Healing { skill: _, overhealing: _, amount } => assert_eq!(amount, 256), _ => panic!("not healing from inversion"), }; match results.remove(0).event { - Event::Recharge { skill: _, red, blue: _ } => assert_eq!(red, (damage - healing)), + Event::Recharge { skill: _, red, blue: _ } => assert_eq!(red, 64), _ => panic!("not recharge from inversion"), }; } @@ -1429,13 +1473,13 @@ mod tests { assert!(y.affected(Effect::Reflect)); let mut results = vec![]; - results = resolve(Skill::Attack, &mut x, &mut y, results); + results = resolve(Skill::TestAttack, &mut x, &mut y, results); assert!(x.green_life() == 768); let Resolution { source: _, target: _, event } = results.remove(0); match event { - Event::Reflection { skill } => assert_eq!(skill, Skill::Attack), + Event::Reflection { skill } => assert_eq!(skill, Skill::TestAttack), _ => panic!("not reflection"), }; @@ -1511,11 +1555,11 @@ mod tests { hostility(&mut y.clone(), &mut y, vec![], Skill::Hostility); assert!(y.affected(Effect::Hostility)); - resolve(Skill::Attack, &mut x, &mut y, vec![]); + resolve(Skill::TestAttack, &mut x, &mut y, vec![]); assert!(y.affected(Effect::Hatred)); - let mut results = resolve(Skill::Attack, &mut y, &mut x, vec![]); + let mut results = resolve(Skill::TestAttack, &mut y, &mut x, vec![]); let Resolution { source: _, target: _, event } = results.remove(0); match event { diff --git a/server/src/vbox.rs b/server/src/vbox.rs index eff3a332..19e32714 100644 --- a/server/src/vbox.rs +++ b/server/src/vbox.rs @@ -70,11 +70,11 @@ pub enum Var { Corrupt, Curse, Decay, - Empower, Hostility, Haste, Heal, Hex, + Impurity, Invert, Parry, Purge, @@ -82,7 +82,7 @@ pub enum Var { Reflect, Recharge, Ruin, - Shield, + Scatter, Silence, Slay, Sleep, @@ -197,11 +197,11 @@ impl Var { Var::Chaos => Some(Skill::Chaos), Var::Curse => Some(Skill::Curse), Var::Decay => Some(Skill::Decay), - Var::Empower => Some(Skill::Empower), Var::Haste => Some(Skill::Haste), Var::Heal => Some(Skill::Heal), Var::Hex => Some(Skill::Hex), Var::Hostility => Some(Skill::Hostility), + Var::Impurity => Some(Skill::Impurity), Var::Invert => Some(Skill::Invert), Var::Parry => Some(Skill::Parry), Var::Purge => Some(Skill::Purge), @@ -209,7 +209,7 @@ impl Var { Var::Recharge => Some(Skill::Recharge), Var::Reflect => Some(Skill::Reflect), Var::Ruin => Some(Skill::Ruin), - Var::Shield => Some(Skill::Shield), + Var::Scatter => Some(Skill::Scatter), Var::Silence => Some(Skill::Silence), Var::Slay => Some(Skill::Slay), Var::Sleep => Some(Skill::Sleep), @@ -273,11 +273,11 @@ impl From for Var { Skill::Curse => Var::Curse, Skill::Clutch => Var::Clutch, Skill::Decay => Var::Decay, - Skill::Empower => Var::Empower, Skill::Haste => Var::Haste, Skill::Hostility => Var::Hostility, Skill::Heal => Var::Heal, Skill::Hex => Var::Hex, + Skill::Impurity => Var::Impurity, Skill::Invert => Var::Invert, Skill::Parry => Var::Parry, Skill::Purge => Var::Purge, @@ -285,7 +285,7 @@ impl From for Var { Skill::Recharge => Var::Recharge, Skill::Reflect => Var::Reflect, Skill::Ruin => Var::Ruin, - Skill::Shield => Var::Shield, + Skill::Scatter => Var::Scatter, Skill::Silence => Var::Silence, Skill::Siphon => Var::Siphon, Skill::Slay => Var::Slay, @@ -352,21 +352,21 @@ pub struct Combo { fn get_combos() -> Vec { let mut combinations = vec![ - Combo { units: vec![Var::Buff, Var::Red, Var::Red], var: Var::Empower }, // Gereric red dmg buff + Combo { units: vec![Var::Buff, Var::Red, Var::Red], var: Var::Taunt }, // Add red recharge Combo { units: vec![Var::Buff, Var::Green, Var::Green], var: Var::Triage }, - Combo { units: vec![Var::Buff, Var::Blue, Var::Blue], var: Var::Amplify }, // Gereric blue dmg buff - Combo { units: vec![Var::Buff, Var::Red, Var::Green], var: Var::Taunt }, - Combo { units: vec![Var::Buff, Var::Green, Var::Blue], var: Var::Curse }, // Needs a buff - Combo { units: vec![Var::Buff, Var::Red, Var::Blue], var: Var::Haste }, // Needs a buff + Combo { units: vec![Var::Buff, Var::Blue, Var::Blue], var: Var::Scatter }, // To be impl - link targets + recharge blue shield + Combo { units: vec![Var::Buff, Var::Red, Var::Green], var: Var::Haste }, // To be reworked + Combo { units: vec![Var::Buff, Var::Green, Var::Blue], var: Var::Impurity }, // To be added + Combo { units: vec![Var::Buff, Var::Red, Var::Blue], var: Var::Amplify }, // Red and blue damage buff - Combo { units: vec![Var::Debuff, Var::Red, Var::Red], var: Var::Snare }, // disable red and dmg - Combo { units: vec![Var::Debuff, Var::Green, Var::Green], var: Var::Purge }, // disable green and remove debuff - Combo { units: vec![Var::Debuff, Var::Blue, Var::Blue], var: Var::Silence }, // disable blue and dmg - Combo { units: vec![Var::Debuff, Var::Red, Var::Green], var: Var::Slow }, // Needs a buff + Combo { units: vec![Var::Debuff, Var::Red, Var::Red], var: Var::Snare }, + Combo { units: vec![Var::Debuff, Var::Green, Var::Green], var: Var::Purge }, // make it disable green + Combo { units: vec![Var::Debuff, Var::Blue, Var::Blue], var: Var::Silence }, + Combo { units: vec![Var::Debuff, Var::Red, Var::Green], var: Var::Curse }, // To be reworked Combo { units: vec![Var::Debuff, Var::Green, Var::Blue], var: Var::Decay }, Combo { units: vec![Var::Debuff, Var::Red, Var::Blue], var: Var::Invert }, - Combo { units: vec![Var::Block, Var::Red, Var::Red], var: Var::Parry }, + Combo { units: vec![Var::Block, Var::Red, Var::Red], var: Var::Parry }, // Add red recharge Combo { units: vec![Var::Block, Var::Green, Var::Green], var: Var::Purify }, Combo { units: vec![Var::Block, Var::Blue, Var::Blue], var: Var::Corrupt }, Combo { units: vec![Var::Block, Var::Red, Var::Green], var: Var::Clutch },