diff --git a/server/src/cryp.rs b/server/src/cryp.rs index a128204a..16052d3c 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -9,7 +9,7 @@ use failure::err_msg; use account::{Account}; use rpc::{CrypSpawnParams}; -use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, ResolutionResult}; +use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, Event}; use spec::{Spec}; use game::{Log}; use vbox::Var; @@ -449,9 +449,9 @@ impl Cryp { } } - pub fn recharge(&mut self) -> ResolutionResult { + pub fn recharge(&mut self) -> Event { if let Some(immunity) = self.immune(Skill::Recharge) { - return ResolutionResult::Immunity { + return Event::Immunity { immunity, }; } @@ -462,12 +462,12 @@ impl Cryp { let blue = self.blue_shield.max.saturating_sub(self.blue_shield.value); self.blue_shield.value = self.blue_shield.max; - ResolutionResult::Recharge { red, blue } + Event::Recharge { red, blue } } - pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult { + pub fn deal_green_damage(&mut self, skill: Skill, amount: u64) -> Event { if let Some(immunity) = self.immune(skill) { - return ResolutionResult::Immunity { + return Event::Immunity { immunity, }; } @@ -490,7 +490,7 @@ impl Cryp { let healing = new_hp - current_hp; let overhealing = modified_healing - healing; - return ResolutionResult::Healing { + return Event::Healing { amount: healing, overhealing, }; @@ -501,7 +501,7 @@ impl Cryp { self.reduce_hp(modified_healing); let delta = current_hp - self.hp(); - return ResolutionResult::Inversion { + return Event::Inversion { damage: delta, healing: 0, recharge: 0, @@ -511,9 +511,9 @@ impl Cryp { } } - pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult { + pub fn deal_red_damage(&mut self, skill: Skill, amount: u64) -> Event { if let Some(immunity) = self.immune(skill) { - return ResolutionResult::Immunity { + return Event::Immunity { immunity, }; } @@ -544,7 +544,7 @@ impl Cryp { self.reduce_hp(remainder); let delta = current_hp - self.hp(); - return ResolutionResult::Damage { + return Event::Damage { amount: delta, mitigation, category: Category::RedDamage, @@ -561,7 +561,7 @@ impl Cryp { self.red_shield.increase(overhealing); let recharge = self.red_shield.value - current_shield; - return ResolutionResult::Inversion { + return Event::Inversion { damage: 0, healing, recharge, @@ -571,9 +571,9 @@ impl Cryp { } } - pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> ResolutionResult { + pub fn deal_blue_damage(&mut self, skill: Skill, amount: u64) -> Event { if let Some(immunity) = self.immune(skill) { - return ResolutionResult::Immunity { + return Event::Immunity { immunity, }; } @@ -597,7 +597,7 @@ impl Cryp { self.reduce_hp(remainder); let delta = current_hp - self.hp(); - return ResolutionResult::Damage { + return Event::Damage { amount: delta, mitigation, category: Category::BlueDamage, @@ -614,7 +614,7 @@ impl Cryp { self.blue_shield.increase(overhealing); let recharge = self.blue_shield.value - current_shield; - return ResolutionResult::Inversion { + return Event::Inversion { damage: 0, healing, recharge, @@ -624,15 +624,15 @@ impl Cryp { } } - pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult { + pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> Event { if let Some(immunity) = self.immune(skill) { - return ResolutionResult::Immunity { + return Event::Immunity { immunity, }; } // todo modified durations cause of buffs - let result = ResolutionResult::Effect { + let result = Event::Effect { effect: effect.effect, duration: effect.effect.duration(), }; @@ -643,7 +643,7 @@ impl Cryp { return result; } - pub fn evade(&self, skill: Skill) -> Option { + pub fn evade(&self, skill: Skill) -> Option { if self.evasion.value == 0 { return None; } @@ -655,7 +655,7 @@ impl Cryp { println!("{:} < {:?}", roll, evasion_rating); match roll < evasion_rating { - true => Some(ResolutionResult::Evasion { + true => Some(Event::Evasion { skill, evasion_rating: evasion_rating, }), diff --git a/server/src/game.rs b/server/src/game.rs index 71399bfa..77f7cad6 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -10,7 +10,7 @@ use failure::err_msg; use account::Account; use rpc::{GameStateParams, GameSkillParams}; use cryp::{Cryp}; -use skill::{Skill, Cast, ResolutionResult}; +use skill::{Skill, Cast, Resolution, Event}; use player::{Player}; use instance::{instance_game_finished, global_game_finished}; @@ -168,6 +168,17 @@ impl Game { } } + pub fn cryp_name(&mut self, id: Uuid) -> String { + match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == id)) { + Some(team) => { + let cryp = team.cryps.iter_mut().find(|c| c.id == id).expect("cryp not in team"); + return cryp.name.clone(); + } + None => panic!("{:?} not in game", id), + } + } + + fn all_cryps(&self) -> Vec { self.teams.clone() .into_iter() @@ -361,56 +372,61 @@ impl Game { self.resolve_skills() } - fn log_resolution(&mut self, cast: &Cast) -> &mut Game { - let source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone(); - let target = self.cryp_by_id(cast.target_cryp_id).unwrap().clone(); + // remove names from the cast + // put them in teh result + // just add the results to the resolved vec + // try remove casts altogether - for result in cast.resolution.results.iter() { - match result { - ResolutionResult::Disable { disable } => + fn log_resolution(&mut self, cast: &Cast) -> &mut Game { + for resolution in cast.resolutions.iter() { + let Resolution { source, target, event } = resolution; + match event { + Event::Disable { disable } => self.log.push(format!("{:} {:?} {:} disabled {:?}", source.name, cast.skill, target.name, disable)), - ResolutionResult::Immunity { immunity } => + Event::Immunity { immunity } => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}", - cast.resolution.speed, source.name, cast.skill, target.name, immunity)), + cast.speed, source.name, cast.skill, target.name, immunity)), - ResolutionResult::TargetKo => + Event::TargetKo => self.log.push(format!("[{:}] {:} {:?} {:} - KO", - cast.resolution.speed, source.name, cast.skill, target.name)), + cast.speed, source.name, cast.skill, target.name)), - ResolutionResult::Damage { amount, mitigation, category: _ } => + Event::Damage { amount, mitigation, category: _ } => self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)", - cast.resolution.speed, source.name, cast.skill, target.name, amount, mitigation)), + cast.speed, source.name, cast.skill, target.name, amount, mitigation)), - ResolutionResult::Healing { amount, overhealing } => + Event::Healing { amount, overhealing } => self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:}OH)", - cast.resolution.speed, source.name, cast.skill, target.name, amount, overhealing)), + cast.speed, source.name, cast.skill, target.name, amount, overhealing)), - ResolutionResult::Inversion { healing, damage, recharge, category: _ } => { + Event::Inversion { healing, damage, recharge, category: _ } => { match *healing > 0 { true => self.log.push(format!("[{:}] {:} {:?} {:} INVERTED {:} ({:} recharge)", - cast.resolution.speed, source.name, cast.skill, target.name, healing, recharge)), + cast.speed, source.name, cast.skill, target.name, healing, recharge)), false => self.log.push(format!("[{:}] {:} {:?} {:} INVERTED {:}", - cast.resolution.speed, source.name, cast.skill, target.name, damage)), + cast.speed, source.name, cast.skill, target.name, damage)), } }, - ResolutionResult::Effect { effect, duration } => + Event::Effect { effect, duration } => self.log.push(format!("[{:}] {:} {:?} {:} {:?} {:}T", - cast.resolution.speed, source.name, cast.skill, target.name, effect, duration)), + cast.speed, source.name, cast.skill, target.name, effect, duration)), - ResolutionResult::Removal { effect } => + Event::Removal { effect } => self.log.push(format!("[{:}] {:?} removed {:} {:?}", - cast.resolution.speed, source.name, target.name, effect)), + cast.speed, source.name, target.name, effect)), - ResolutionResult::Recharge { red, blue } => + Event::Recharge { red, blue } => self.log.push(format!("[{:}] {:} {:?} {:} {:}R {:}B", - cast.resolution.speed, source.name, cast.skill, target.name, red, blue)), + cast.speed, source.name, cast.skill, target.name, red, blue)), - ResolutionResult::Evasion { skill: _, evasion_rating } => + Event::Evasion { skill: _, evasion_rating } => self.log.push(format!("[{:}] {:} {:?} {:} evaded ({:}%)", - cast.resolution.speed, source.name, cast.skill, target.name, evasion_rating)), + cast.speed, source.name, cast.skill, target.name, evasion_rating)), + + Event::Incomplete => panic!("incomplete resolution {:?}", resolution), } } diff --git a/server/src/skill.rs b/server/src/skill.rs index ffe15237..c8b4712b 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -8,11 +8,12 @@ use game::{Game}; #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Cast { pub id: Uuid, - pub skill: Skill, pub source_team_id: Uuid, pub source_cryp_id: Uuid, pub target_cryp_id: Uuid, - pub resolution: Resolution, + pub skill: Skill, + pub speed: u64, + pub resolutions: Resolutions, } impl Cast { @@ -23,7 +24,8 @@ impl Cast { source_team_id, target_cryp_id, skill, - resolution: Resolution::new(skill), + speed: 0, + resolutions: vec![], }; } @@ -34,7 +36,7 @@ impl Cast { pub fn finalise(&mut self, game: &mut Game) -> &mut Cast { let mut results = vec![]; let mut source = game.cryp_by_id(self.source_cryp_id).unwrap().clone(); - self.resolution.speed = source.skill_speed(self.skill); + self.speed = source.skill_speed(self.skill); let targets = match source.skill_is_aoe(self.skill) { true => game.cryp_aoe_targets(self.target_cryp_id), @@ -47,7 +49,7 @@ impl Cast { results.append(&mut self.skill.resolve(&mut source, target)); } - self.resolution.results = results; + self.resolutions = results; self } @@ -60,7 +62,36 @@ pub type Disable = Vec; pub type Immunity = Vec; #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] -pub enum ResolutionResult { +pub struct LogCryp { + pub id: Uuid, + pub name: String, +} + +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +pub struct Resolution { + pub source: LogCryp, + pub target: LogCryp, + pub event: Event, +} + +impl Resolution { + fn new(source: &Cryp, target: &Cryp) -> Resolution { + Resolution { + source: LogCryp { id: source.id, name: source.name.clone() }, + target: LogCryp { id: target.id, name: target.name.clone() }, + event: Event::Incomplete, + } + } + + fn event(mut self, e: Event) -> Resolution { + self.event = e; + self + } +} + + +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +pub enum Event { TargetKo, Disable { disable: Disable }, Immunity { immunity: Immunity }, @@ -71,21 +102,11 @@ pub enum ResolutionResult { Effect { effect: Effect, duration: u8 }, Removal { effect: Effect }, Evasion { skill: Skill, evasion_rating: u64 }, + + Incomplete, } -#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] -pub struct Resolution { - pub skill: Skill, - pub speed: u64, - pub results: Vec, -} - -impl Resolution { - fn new(skill: Skill) -> Resolution { - Resolution { skill, results: vec![], speed: 0 } - } -} - +type Resolutions = Vec; pub type Cooldown = Option; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -579,14 +600,14 @@ impl Skill { } } - pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp) -> Vec { + pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp) -> Resolutions { let mut rng = thread_rng(); let _base: u64 = rng.gen(); let mut results = vec![]; if let Some(disable) = source.disabled(*self) { - results.push(ResolutionResult::Disable { disable }); + results.push(Resolution::new(source, target).event(Event::Disable { disable })); return results; } @@ -594,14 +615,14 @@ impl Skill { // true => { // if let Some(evasion) = target.evade(*self) { // results.push(evasion); - // return resolution; + // return Event; // } // }, // false => (), // } if target.is_ko() { - results.push(ResolutionResult::TargetKo); + results.push(Resolution::new(source, target).event(Event::TargetKo)); return results; } @@ -687,197 +708,198 @@ impl Skill { } } -fn attack(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.red_damage(); - results.push(target.deal_red_damage(Skill::Attack, amount)); +fn attack(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.red_damage(); + results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::Attack, amount))); return results; } -fn stun(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn stun(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None }; - results.push(target.add_effect(Skill::Stun, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Stun, effect))); return results; } -fn clutch(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn clutch(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Clutch, duration: Effect::Clutch.duration(), tick: None }; - results.push(target.add_effect(Skill::Clutch, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Clutch, effect))); return results; } -fn throw(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn throw(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let stun = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None }; let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Effect::Vulnerable.duration(), tick: None }; - results.push(target.add_effect(Skill::Throw, stun)); - results.push(target.add_effect(Skill::Throw, vulnerable)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Throw, stun))); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Throw, vulnerable))); return results; } -fn strangle(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn strangle(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let target_stun = CrypEffect { effect: Effect::Strangle, duration: Effect::Strangle.duration(), - tick: Some(Cast::new_tick(cryp, target, Skill::StrangleTick)) + tick: Some(Cast::new_tick(source, target, Skill::StrangleTick)) }; let attacker_immunity = CrypEffect { effect: Effect::Strangling, duration: Effect::Strangling.duration(), tick: None }; - results.push(target.add_effect(Skill::Strangle, target_stun)); - results.push(cryp.add_effect(Skill::Strangle, attacker_immunity)); - return strangle_tick(cryp, target, results); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Strangle, target_stun))); + results.push(Resolution::new(source, source).event(source.add_effect(Skill::Strangle, attacker_immunity))); + return strangle_tick(source, target, results); } -fn strangle_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.red_damage(); - results.push(target.deal_red_damage(Skill::StrangleTick, amount)); +fn strangle_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.red_damage(); + results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::StrangleTick, amount))); // remove immunity if target ko if target.is_ko() { - let i = cryp.effects + let i = source.effects .iter() .position(|e| e.effect == Effect::Strangling) .expect("no strangling on cryp"); - cryp.effects.remove(i); + source.effects.remove(i); + results.push(Resolution::new(source, source).event(Event::Removal { effect: Effect::Strangling })); } return results; } -fn block(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn block(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let block = CrypEffect { effect: Effect::Block, duration: Effect::Block.duration(), tick: None }; - results.push(target.add_effect(Skill::Block, block)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Block, block))); return results; } -fn parry(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn parry(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Parry, duration: Effect::Parry.duration(), tick: None }; - results.push(target.add_effect(Skill::Parry, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Parry, effect))); return results; } -fn snare(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let snare = CrypEffect { effect: Effect::Snare, duration: Effect::Snare.duration(), tick: None }; - results.push(target.add_effect(Skill::Snare, snare)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Snare, snare))); return results; } -fn empower(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn empower(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let empower = CrypEffect { effect: Effect::Empower, duration: Effect::Empower.duration(), tick: None }; - results.push(target.add_effect(Skill::Empower, empower)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Empower, empower))); return results; } -fn heal(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.green_damage(); - results.push(target.deal_green_damage(Skill::Heal, amount)); +fn heal(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.green_damage(); + results.push(Resolution::new(source, target).event(target.deal_green_damage(Skill::Heal, amount))); return results; } -fn triage(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn triage(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Triage, duration: Effect::Triage.duration(), - tick: Some(Cast::new_tick(cryp, target, Skill::TriageTick)), + tick: Some(Cast::new_tick(source, target, Skill::TriageTick)), }; - results.push(target.add_effect(Skill::Triage, effect)); - return triage_tick(cryp, target, results); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Triage, effect))); + return triage_tick(source, target, results); } -fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.blue_damage().wrapping_div(2); - results.push(target.deal_green_damage(Skill::TriageTick, amount)); +fn triage_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.green_damage().wrapping_div(2); + results.push(Resolution::new(source, target).event(target.deal_green_damage(Skill::TriageTick, amount))); return results; } -fn blast(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.blue_damage(); - results.push(target.deal_blue_damage(Skill::Blast, amount)); +fn blast(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.blue_damage(); + results.push(Resolution::new(source, target).event(target.deal_blue_damage(Skill::Blast, amount))); return results; } -fn amplify(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn amplify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let amplify = CrypEffect { effect: Effect::Amplify, duration: Effect::Amplify.duration(), tick: None }; - results.push(target.add_effect(Skill::Amplify, amplify)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Amplify, amplify))); return results;; } -fn haste(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn haste(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Haste, duration: Effect::Haste.duration(), tick: None }; - results.push(target.add_effect(Skill::Haste, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Haste, effect))); return results;; } -fn slow(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn slow(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Slow, duration: Effect::Slow.duration(), tick: None }; - results.push(target.add_effect(Skill::Slow, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Slow, effect))); return results;; } -fn decay(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn decay(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let decay = CrypEffect { effect: Effect::Decay, duration: Effect::Decay.duration(), - tick: Some(Cast::new_tick(cryp, target, Skill::DecayTick)), + tick: Some(Cast::new_tick(source, target, Skill::DecayTick)), }; - results.push(target.add_effect(Skill::Decay, decay)); - return decay_tick(cryp, target, results); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Decay, decay))); + return decay_tick(source, target, results); } -fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.blue_damage(); - results.push(target.deal_blue_damage(Skill::DecayTick, amount)); +fn decay_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.blue_damage(); + results.push(Resolution::new(source, target).event(target.deal_blue_damage(Skill::DecayTick, amount))); return results; } -fn hex(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn hex(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let hex = CrypEffect { effect: Effect::Hex, duration: Effect::Hex.duration(), tick: None }; - results.push(target.add_effect(Skill::Hex, hex)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Hex, hex))); return results;; } -fn curse(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn curse(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let curse = CrypEffect { effect: Effect::Curse, duration: Effect::Curse.duration(), tick: None }; - results.push(target.add_effect(Skill::Curse, curse)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Curse, curse))); return results;; } -fn invert(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn invert(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Invert, duration: Effect::Invert.duration(), tick: None }; - results.push(target.add_effect(Skill::Invert, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Invert, effect))); return results;; } -fn reflect(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn reflect(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let effect = CrypEffect { effect: Effect::Reflect, duration: Effect::Reflect.duration(), tick: None }; - results.push(target.add_effect(Skill::Reflect, effect)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Reflect, effect))); return results;; } -fn recharge(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - results.push(target.recharge()); +fn recharge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + results.push(Resolution::new(source, target).event(target.recharge())); return results; } -fn siphon(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn siphon(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let siphon = CrypEffect { effect: Effect::Siphon, duration: Effect::Siphon.duration(), - tick: Some(Cast::new_tick(cryp, target, Skill::SiphonTick)), + tick: Some(Cast::new_tick(source, target, Skill::SiphonTick)), }; - results.push(target.add_effect(Skill::Siphon, siphon)); - return siphon_tick(cryp, target, results); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Siphon, siphon))); + return siphon_tick(source, target, results); } -fn siphon_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let amount = cryp.blue_damage(); +fn siphon_tick(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.blue_damage(); let siphon_damage = target.deal_blue_damage(Skill::SiphonTick, amount); - results.push(siphon_damage.clone()); + results.push(Resolution::new(source, target).event(siphon_damage.clone())); match siphon_damage { - ResolutionResult::Damage { amount, mitigation: _, category: _, } => { - results.push(cryp.deal_green_damage(Skill::Heal, amount)); + Event::Damage { amount, mitigation: _, category: _, } => { + results.push(Resolution::new(source, source).event(source.deal_green_damage(Skill::Heal, amount))); }, _ => panic!("siphon tick damage not dealt {:?}", siphon_damage), } @@ -885,49 +907,49 @@ fn siphon_tick(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn shield(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let shield = CrypEffect { effect: Effect::Shield, duration: Effect::Shield.duration(), tick: None }; - results.push(target.add_effect(Skill::Shield, shield)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Shield, shield))); return results; } -fn silence(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn silence(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let silence = CrypEffect { effect: Effect::Silence, duration: Effect::Silence.duration(), tick: None }; - results.push(target.add_effect(Skill::Silence, silence)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Silence, silence))); return results; } -fn purge(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn purge(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { for (i, ce) in target.effects.clone().iter_mut().enumerate() { if ce.effect.category() == Category::BlueBuff { target.effects.remove(i); - results.push(ResolutionResult::Removal { effect: ce.effect }); + results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect })); } } return results; } -fn purify(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn purify(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { for (i, ce) in target.effects.clone().iter_mut().enumerate() { if ce.effect.category() == Category::BlueDebuff { target.effects.remove(i); - results.push(ResolutionResult::Removal { effect: ce.effect }); + results.push(Resolution::new(source, target).event(Event::Removal { effect: ce.effect })); } } return results; } -fn banish(_cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { +fn banish(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let banish = CrypEffect { effect: Effect::Banish, duration: Effect::Banish.duration(), tick: None }; - results.push(target.add_effect(Skill::Banish, banish)); + results.push(Resolution::new(source, target).event(target.add_effect(Skill::Banish, banish))); return results; } -fn strike(cryp: &mut Cryp, target: &mut Cryp, mut results: Vec) -> Vec { - let _amount = cryp.red_damage(); - results.push(target.deal_red_damage(Skill::Attack, u64::max_value())); +fn strike(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let _amount = source.red_damage(); + results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::Attack, u64::max_value()))); return results; } @@ -984,10 +1006,11 @@ mod tests { block(&mut y.clone(), &mut y, vec![]); assert!(y.effects.iter().any(|e| e.effect == Effect::Block)); - let results = attack(&mut x, &mut y, vec![]); + let mut results = attack(&mut x, &mut y, vec![]); - match results[0] { - ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 50), + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 50), _ => panic!("not damage"), }; } @@ -1005,11 +1028,12 @@ mod tests { clutch(&mut y.clone(), &mut y, vec![]); assert!(y.is_clutch()); - let results = attack(&mut x, &mut y, vec![]); + let mut results = attack(&mut x, &mut y, vec![]); assert!(y.hp() == 1); - match results[0] { - ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 1023), + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 1023), _ => panic!("not damage"), }; } @@ -1035,11 +1059,12 @@ mod tests { assert!(y.hp() == 768); // attack should heal and recharge red shield - let results = attack(&mut x, &mut y, vec![]); + let mut results = attack(&mut x, &mut y, vec![]); assert!(y.hp() == 1024); - match results[0] { - ResolutionResult::Inversion { damage: _, healing: _, recharge, category: _ } => assert_eq!(recharge, 64), + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Inversion { damage: _, healing: _, recharge, category: _ } => assert_eq!(recharge, 64), _ => panic!("not inversion"), }; } @@ -1055,12 +1080,13 @@ mod tests { reflect(&mut y.clone(), &mut y, vec![]); assert!(y.is_reflecting()); - let results = Skill::Attack.resolve(&mut x, &mut y); + let mut results = Skill::Attack.resolve(&mut x, &mut y); assert!(x.hp() == 768); - match results[0] { - ResolutionResult::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 256), + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Damage { amount, mitigation: _, category: _ } => assert_eq!(amount, 256), _ => panic!("not damage"), }; } @@ -1083,7 +1109,7 @@ mod tests { y.deal_red_damage(Skill::Attack, 5); let prev_hp = y.hp(); - let results = triage(&mut x, &mut y, vec![]); + let _results = triage(&mut x, &mut y, vec![]); assert!(y.effects.iter().any(|e| e.effect == Effect::Triage)); assert!(y.hp() > prev_hp); @@ -1103,10 +1129,11 @@ mod tests { y.deal_red_damage(Skill::Attack, 5); y.deal_blue_damage(Skill::Blast, 5); - let results = recharge(&mut x, &mut y, vec![]); + let mut results = recharge(&mut x, &mut y, vec![]); - match results[0] { - ResolutionResult::Recharge { red, blue } => { + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Recharge { red, blue } => { assert!(red == 5); assert!(blue == 5); }