diff --git a/CHANGELOG.md b/CHANGELOG.md index 67672e8a..df4e7d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). (Proposed changes not all impl) -New skill `Scatter ` +New skill `Scatter` Combines - Buff + BB Links targets together so dmg taken is split Recharge 140% source blue damage as blue life to target @@ -31,7 +31,7 @@ New skill `Impurity` - Removed Empower (Buff + RR) -> combined effect with amplify -- Amplify +- Amplify Changed to Buff + RB (was Buff + BB) Increases both red and blue power. Red and blue attacks recharge red and blue life (to be impl) @@ -47,7 +47,7 @@ New skill `Impurity` RNG range changed from (0 - 20%) -> (0 - 30%) Same dmg range but more RNG -- Haste +- 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 @@ -65,7 +65,7 @@ New skill `Impurity` - Strike Change multipliers T1/T2/T3 (110/130/150 -> 90/110/130) -- Taunt +- Taunt Changed to Buff + RR (was Buff + RG) Now recharges 80% source red damage as red life to target @@ -77,13 +77,13 @@ New skill `Impurity` ## [0.1.1] - 2019-05-03 ### Added Event::Skill - needed to convey the use of skill which is followed by other events + needed to convey the use of skill which is followed by other events used for skill Purify to show that it is used and then followed by removal and other events New Skill `Sleep` Combined using Stun + GG Stuns target for 3T (might need to be 4T) Deals 240% green damage (heal) - Concept - high duration stun with the drawback of a big heal on the target + Concept - high duration stun with the drawback of a big heal on the target Base cooldown 3T (Could be played aggressively or defensively) @@ -91,31 +91,31 @@ New skill `Impurity` ### Changed Switch purify with reflect - - Purify + - Purify Now GG + block (was GB + block) Now applies a small heal 45% multiplier green damage (power) for each debuff removed - - - Reflect + + - Reflect Now GB + block (was GG + block) Recharges blue life at 45% blue damage - + - Server function recharge changed to take skill, red amount and blue amount as inputs - + - Recharge Skill reworked No longer restores full Red and Blue life - Now restores Red life and Blue life based on respective red and blue damage + Now restores Red life and Blue life based on respective red and blue damage Recharge value calculated at 85% multiplier with red and blue damage - Silence + Silence No longer Stun + GB (already exists as debuff BB) Now also deals damage amount of 55% base blue damage - This damage amount does 45% more damage per blue skill blocked + This damage amount does 45% more damage per blue skill blocked Maximum = (0.55)(1.35)*base_blue_damage Cooldown changed 1T -> 2T Debuff duration increased 2T -> 3T Snare Now also deals damage amount of 40% base red damage - This damage amount does 45% more damage per red skill blocked + This damage amount does 45% more damage per red skill blocked Maximum = (0.40)(1.35)*base_red_damage Cooldown changed 1T -> 2T Debuff duration increased 2T -> 3T @@ -126,24 +126,24 @@ New skill `Impurity` Taunt now GR + Buff No longer self-target only - + Hex is now Stun + GB (was Stun + RB) Banish is now Stun + RB (was Stun + RG) for rng theme - Throw is now Stun + RG (was Stun + GG) + Throw is now Stun + RG (was Stun + GG) - Better fit as it applies inc Red taken debuff (vulnerability) ## [0.1.0] - 2019-05-02 ### Added - New skill `Chaos` + New skill `Chaos` - 50% base red & blue with an additional rng 20% blue & red - Combo'd with Attack + Red + Blue - New skill `Slay` + New skill `Slay` - 70% base red, heals (green damage) for equivalent dmg dealt - Combo'd with Attack + Red + Green - New effect `Wither` + New effect `Wither` - Reduces green damage taken by 50% ### Fixed @@ -163,7 +163,7 @@ New skill `Impurity` - Changed skill damage multipliers `Blast` 100% -> 130% - `CorruptionTick` 100% -> 80% + `CorruptionTick` 100% -> 80% `Decay` 50% -> 25% `Heal` 100% -> 120% `SiphonTick` 100% -> 30% diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 7cdc4af6..e6628891 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -64,6 +64,7 @@ impl CrypSkill { pub enum EffectMeta { TickAmount(u64), AddedDamage(u64), + ScatterTarget(Uuid), } #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] @@ -470,7 +471,7 @@ impl Cryp { .fold(self.speed.value, |acc, fx| fx.0.apply(acc, fx.1)); return modified_speed; } - + pub fn red_life(&self) -> u64 { self.red_life.value } diff --git a/server/src/game.rs b/server/src/game.rs index d4874419..86971630 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -14,7 +14,7 @@ use failure::err_msg; use account::Account; use rpc::{GameStateParams, GameSkillParams}; use cryp::{Cryp}; -use skill::{Skill, Effect, Cast, Resolution, Event, resolve}; +use skill::{Skill, Effect, Cast, Resolution, Event, resolution_steps}; use player::{Player}; use instance::{instance_game_finished, global_game_finished}; use util::{IntPct}; @@ -133,7 +133,7 @@ impl Game { .collect::>() } - fn update_cryp(&mut self, cryp: &mut Cryp) -> &mut Game { + pub fn update_cryp(&mut self, cryp: &mut Cryp) -> &mut Game { match self.players.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == cryp.id)) { Some(player) => { let index = player.cryps.iter().position(|t| t.id == cryp.id).unwrap(); @@ -373,7 +373,7 @@ impl Game { .collect() } - fn get_targets(&self, skill: Skill, source: &Cryp, target_cryp_id: Uuid) -> Vec { + pub fn get_targets(&self, skill: Skill, source: &Cryp, target_cryp_id: Uuid) -> Vec { let target_player = self.players.iter() .find(|t| t.cryps.iter().any(|c| c.id == target_cryp_id)) .unwrap(); @@ -415,19 +415,7 @@ impl Game { while let Some(cast) = self.stack.pop() { // println!("{:} casts ", cast); - let mut resolutions = vec![]; - let mut source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone(); - - let targets = self.get_targets(cast.skill, &source, cast.target_cryp_id); - for target_id in targets { - let mut source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone(); - let mut target = self.cryp_by_id(target_id).unwrap().clone(); - resolutions = resolve(cast.skill, &mut source, &mut target, resolutions); - // save the clones - self.update_cryp(&mut source); - self.update_cryp(&mut target); - } - + let mut resolutions = resolution_steps(&cast, &mut self); resolutions.reverse(); while let Some(resolution) = resolutions.pop() { self.log_resolution(cast.speed, &resolution); diff --git a/server/src/skill.rs b/server/src/skill.rs index 533d86bf..2d8b434d 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -5,6 +5,33 @@ use util::{IntPct}; use cryp::{Cryp, CrypEffect, EffectMeta, Stat}; use vbox::{Var}; +use game::{Game}; + +pub fn resolution_steps(cast: &Cast, game: &mut Game) -> Resolutions { + let mut resolutions = vec![]; + + resolutions = pre_resolve(cast, game, resolutions); + + return resolutions; +} + +pub fn pre_resolve(cast: &Cast, game: &mut Game, mut resolutions: Resolutions) -> Resolutions { + let skill = cast.skill; + let mut source = game.cryp_by_id(cast.source_cryp_id).unwrap().clone(); + + let targets = game.get_targets(cast.skill, &source, cast.target_cryp_id); + for target_id in targets { + let mut source = game.cryp_by_id(cast.source_cryp_id).unwrap().clone(); + let mut target = game.cryp_by_id(target_id).unwrap().clone(); + resolutions = resolve(cast.skill, &mut source, &mut target, resolutions); + // save the clones + game.update_cryp(&mut source); + game.update_cryp(&mut target); + } + + return resolutions; +} + pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutions: Vec) -> Resolutions { if let Some(disable) = source.disabled(skill) { resolutions.push(Resolution::new(source, target).event(Event::Disable { disable, skill })); @@ -25,6 +52,10 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio return resolve(skill, target, source, resolutions); } + if target.affected(Effect::Scatter) { + resolutions = resolve(skill, target, source, resolutions); + } + // match self.category() == Category::Red { // true => { // if let Some(evasion) = target.evade(*self) { @@ -421,7 +452,7 @@ impl Effect { Effect::Hostility => Category::Buff, - // magic + // magic Effect::Impurity => Category::Buff, Effect::Scatter => Category::Buff, Effect::Invert => Category::Buff, @@ -579,7 +610,7 @@ impl Skill { Skill::CorruptionTick => 80, Skill::DecayTick => 25, Skill::Riposte => 70, - + _ => 100, } } @@ -986,7 +1017,7 @@ fn riposte(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { 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() { @@ -1093,7 +1124,7 @@ fn decay(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: let wither = CrypEffect::new(Effect::Wither, skill.duration()); let decay = CrypEffect::new(Effect::Decay, skill.duration()) .set_tick(Cast::new_tick(source, target, Skill::DecayTick)); - + results.push(Resolution::new(source, target).event(target.add_effect(skill, decay))); results.push(Resolution::new(source, target).event(target.add_effect(skill, wither))); return decay_tick(source, target, results, Skill::DecayTick); @@ -1180,7 +1211,7 @@ fn invert(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: fn reflect(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { let effect = CrypEffect::new(Effect::Reflect, skill.duration()); results.push(Resolution::new(source, target).event(target.add_effect(skill, effect))); - + let blue_amount = source.blue_damage().pct(skill.multiplier()); results.push(Resolution::new(source, target).event(target.recharge(skill, 0, blue_amount))); @@ -1232,14 +1263,13 @@ fn scatter(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill fn silence(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions, skill: Skill) -> Resolutions { 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)