From 2a002d08d4f37e39d123d884c9a1d27ab6bd15c2 Mon Sep 17 00:00:00 2001 From: ntr Date: Mon, 26 Nov 2018 23:07:07 +1100 Subject: [PATCH 1/4] goddamn borrow checker --- server/src/cryp.rs | 10 +- server/src/game.rs | 11 +- server/src/skill.rs | 728 +++++++++++++++++++++++++++++++------------- 3 files changed, 533 insertions(+), 216 deletions(-) diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 72aaa149..fbe75b83 100755 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -9,7 +9,7 @@ use failure::err_msg; use account::Account; use rpc::{CrypSpawnParams, CrypLearnParams, CrypForgetParams}; -use skill::{Skill, Cooldown, Effect, Cast, Source}; +use skill::{Skill, Cooldown, Effect, Cast, Immunity}; use game::{Log}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -29,7 +29,7 @@ impl CrypSkill { } } -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct CrypEffect { pub effect: Effect, pub duration: u8, @@ -178,17 +178,17 @@ impl Cryp { self.hp.base == 0 } - pub fn immune(&self, skill: Skill) -> (bool, Vec) { + pub fn immune(&self, skill: Skill) -> Immunity { let immunities = self.effects.iter() .filter(|e| e.effect.immune(skill)) .map(|e| e.effect) .collect::>(); if immunities.len() > 0 { - return (true, immunities); + return Immunity { immune: true, effects: immunities}; } - return (false, vec![]); + return Immunity { immune: false, effects: vec![]}; } pub fn is_stunned(&self) -> bool { diff --git a/server/src/game.rs b/server/src/game.rs index 8c5c546f..8d8cc35f 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -389,11 +389,9 @@ impl Game { let mut source = self.cryp_by_id(skill.source_cryp_id).unwrap().clone(); let mut target = self.cryp_by_id(skill.target_cryp_id.unwrap()).unwrap().clone(); - // self.log.push(format!("{:?} uses {:?} on {:?}", source.name, skill.skill, target.name)); skill.set_resolution(&mut source, &mut target, &mut self.log); self.resolved.push(skill.clone()); - self.update_cryp(&mut source); self.update_cryp(&mut target); @@ -444,6 +442,15 @@ impl Game { fn finish(&mut self) -> &mut Game { self.phase = Phase::Finish; + self.log.push(format!("Game finished.")); + + { + let winner = self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())); + match winner { + Some(w) => self.log.push(format!("Winner: {:?}", w.id)), + None => self.log.push(format!("Game was drawn.")), + }; + } self.stack.clear(); diff --git a/server/src/skill.rs b/server/src/skill.rs index 24077b5e..3b038521 100755 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -4,13 +4,15 @@ use uuid::Uuid; use game::{Log}; use cryp::{Cryp, CrypEffect, Stat}; -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Cast { pub id: Uuid, - pub skill: Skill, pub source_team_id: Uuid, + pub skill: Skill, + pub source_team_id: Uuid, pub source_cryp_id: Uuid, pub target_cryp_id: Option, pub target_team_id: Uuid, + pub resolution: Resolution, } impl Cast { @@ -28,6 +30,7 @@ impl Cast { target_cryp_id, target_team_id, skill, + resolution: Resolution { skill, results: vec![] }, }; } @@ -38,7 +41,7 @@ impl Cast { } pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> &mut Cast { - self.skill.resolve(cryp, target, log); + self.resolution = self.skill.resolve(cryp, target, log); self } @@ -52,15 +55,29 @@ impl Cast { } } + +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +pub struct Immunity { + pub immune: bool, + pub effects: Vec +} + +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +pub enum ResolutionResult { + Damage { amount: u64, category: Category , immunity: Immunity }, + Effect { effect: Effect, duration: u8, immunity: Immunity }, + Removal { effect: Effect, immunity: Immunity }, +} + #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub struct Resolution { - pub base: u64, - pub result: Option, + pub skill: Skill, + pub results: Vec, } pub type Cooldown = Option; -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] pub enum Effect { // physical Stun, @@ -111,9 +128,10 @@ impl Effect { Skill::Attack => true, _ => false, }, - Effect::Shield => match skill.cast_type() { - Damage::Magic => true, - Damage::Physical => false, + Effect::Shield => match skill.category() { + Category::Spell => true, + Category::Physical => false, + _ => false, }, Effect::Banish => true, _ => false, @@ -123,9 +141,10 @@ impl Effect { pub fn prevents_casting(&self, skill: Skill) -> bool { match self { Effect::Stun => true, - Effect::Silence => match skill.cast_type() { - Damage::Magic => true, - Damage::Physical => false, + Effect::Silence => match skill.category() { + Category::Spell => true, + Category::Physical => false, + _ => false, }, _ => false, } @@ -150,67 +169,62 @@ impl Effect { } } - pub fn source(&self) -> Source { + pub fn category(&self) -> Category { match self { // physical - Effect::Stun => Source::Debuff, - Effect::Block => Source::Buff, - Effect::Bleed => Source::Debuff, - Effect::Leech => Source::Debuff, - Effect::Airborne => Source::Buff, - Effect::Untouchable => Source::Buff, - Effect::Deadly => Source::Buff, - Effect::Vulnerable => Source::Debuff, - Effect::Fury => Source::Buff, - Effect::Evasion => Source::Buff, - Effect::Blind => Source::Debuff, - Effect::Snare => Source::Debuff, + Effect::Stun => Category::PhysDebuff, + Effect::Block => Category::PhysBuff, + Effect::Bleed => Category::PhysDebuff, + Effect::Leech => Category::PhysDebuff, + Effect::Airborne => Category::PhysDebuff, + Effect::Untouchable => Category::PhysBuff, + Effect::Deadly => Category::PhysBuff, + Effect::Vulnerable => Category::PhysDebuff, + Effect::Fury => Category::PhysBuff, + Effect::Evasion => Category::PhysBuff, + Effect::Blind => Category::PhysDebuff, + Effect::Snare => Category::PhysDebuff, - Effect::Empower => Source::Buff, + Effect::Empower => Category::PhysBuff, // magic - Effect::Hex => Source::Debuff, - Effect::Curse => Source::Debuff, - Effect::Banish => Source::Debuff, // todo randomise - Effect::Slow => Source::Debuff, - Effect::Haste => Source::Buff, - Effect::Enslave => Source::Debuff, - Effect::Mesmerise => Source::Debuff, - Effect::Amplify => Source::Buff, - Effect::Silence => Source::Debuff, + Effect::Hex => Category::SpellDebuff, + Effect::Curse => Category::SpellDebuff, + Effect::Banish => Category::SpellDebuff, // todo randomise + Effect::Slow => Category::SpellDebuff, + Effect::Haste => Category::SpellBuff, + Effect::Enslave => Category::SpellDebuff, + Effect::Mesmerise => Category::SpellDebuff, + Effect::Amplify => Category::SpellBuff, + Effect::Silence => Category::SpellDebuff, // magic immunity - Effect::Shield => Source::Buff, + Effect::Shield => Category::SpellBuff, // effects over time - Effect::Triage => Source::Buff, - Effect::Decay => Source::Debuff, - Effect::Regen => Source::Buff, - Effect::Drain => Source::Debuff, + Effect::Triage => Category::SpellBuff, + Effect::Decay => Category::SpellDebuff, + Effect::Regen => Category::SpellBuff, + Effect::Drain => Category::SpellDebuff, - Effect::SpeedDrain => Source::Debuff, - Effect::SpeedIncrease => Source::Buff, + Effect::SpeedDrain => Category::SpellDebuff, + Effect::SpeedIncrease => Category::SpellBuff, } } } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] -pub enum Damage { +pub enum Category { Physical, - Magic, -} - -// #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] -// enum Style { -// Offensive, -// Defensive, -// } - -#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] -pub enum Source { - Buff, - Debuff, - Stat, + PhysHeal, + PhysDmg, + PhysDebuff, + PhysBuff, + Spell, + SpellDmg, + SpellHeal, + SpellDebuff, + SpellBuff, } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -379,88 +393,88 @@ impl Skill { } } - pub fn cast_type(&self) -> Damage { + pub fn category(&self) -> Category { match self { - Skill::Attack => Damage::Physical, + Skill::Attack => Category::Physical, // ----------------- // Nature // ----------------- - Skill::Block => Damage::Physical, // reduce dmg - Skill::Evade => Damage::Physical, - Skill::Parry => Damage::Physical, // avoid all dmg - Skill::Snare => Damage::Physical, + Skill::Block => Category::Physical, // reduce dmg + Skill::Evade => Category::Physical, + Skill::Parry => Category::Physical, // avoid all dmg + Skill::Snare => Category::Physical, - Skill::Paralyse => Damage::Physical, - Skill::Strangle => Damage::Physical, + Skill::Paralyse => Category::Physical, + Skill::Strangle => Category::Physical, // Strangle - Skill::Stun => Damage::Physical, - Skill::Evasion => Damage::Physical, // additional layer of dmg avoidance + Skill::Stun => Category::Physical, + Skill::Evasion => Category::Physical, // additional layer of dmg avoidance // ----------------- // Technology // ----------------- - Skill::Replicate => Damage::Physical, - Skill::Swarm => Damage::Physical, - Skill::Orbit => Damage::Physical, - Skill::Repair => Damage::Physical, - Skill::Scan => Damage::Physical, // track? + Skill::Replicate => Category::Physical, + Skill::Swarm => Category::Physical, + Skill::Orbit => Category::Physical, + Skill::Repair => Category::Physical, + Skill::Scan => Category::Physical, // track? // ----------------- // Preservation // ----------------- - Skill::Heal => Damage::Physical, - Skill::Triage => Damage::Physical, // hot - Skill::TriageTick => Damage::Physical, // hot - Skill::Throw => Damage::Physical, // no dmg stun, adds vulnerable - Skill::Charm => Damage::Physical, - Skill::Calm => Damage::Physical, - Skill::Rez => Damage::Physical, + Skill::Heal => Category::Physical, + Skill::Triage => Category::Physical, // hot + Skill::TriageTick => Category::Physical, // hot + Skill::Throw => Category::Physical, // no dmg stun, adds vulnerable + Skill::Charm => Category::Physical, + Skill::Calm => Category::Physical, + Skill::Rez => Category::Physical, // ----------------- // Destruction // ----------------- - Skill::Blast => Damage::Magic, - Skill::Amplify => Damage::Magic, - Skill::Decay => Damage::Magic, // dot - Skill::DecayTick => Damage::Magic, // hot - Skill::Drain => Damage::Magic, - Skill::DrainTick => Damage::Magic, // hot - Skill::Curse => Damage::Magic, - Skill::Plague => Damage::Magic, // aoe dot - Skill::Ruin => Damage::Magic, // aoe + Skill::Blast => Category::Spell, + Skill::Amplify => Category::Spell, + Skill::Decay => Category::Spell, // dot + Skill::DecayTick => Category::Spell, // hot + Skill::Drain => Category::Spell, + Skill::DrainTick => Category::Spell, // hot + Skill::Curse => Category::Spell, + Skill::Plague => Category::Spell, // aoe dot + Skill::Ruin => Category::Spell, // aoe // ----------------- // Purity // ----------------- // Skill::Precision => 1, - Skill::Empower => Damage::Physical, - Skill::Slay => Damage::Physical, - Skill::Shield => Damage::Magic, - Skill::Silence => Damage::Magic, - Skill::Inquiry => Damage::Magic, - Skill::Purify => Damage::Magic, - Skill::Purge => Damage::Magic, + Skill::Empower => Category::Physical, + Skill::Slay => Category::Physical, + Skill::Shield => Category::Spell, + Skill::Silence => Category::Spell, + Skill::Inquiry => Category::Spell, + Skill::Purify => Category::Spell, + Skill::Purge => Category::Spell, // ----------------- // Chaos // ----------------- - Skill::Banish => Damage::Magic, - Skill::Hex => Damage::Magic, - Skill::Fear => Damage::Magic, - Skill::Taunt => Damage::Magic, - Skill::Pause => Damage::Magic, // extend durations + Skill::Banish => Category::Spell, + Skill::Hex => Category::Spell, + Skill::Fear => Category::Spell, + Skill::Taunt => Category::Spell, + Skill::Pause => Category::Spell, // extend durations // Skill::Lag => 2, // // ----------------- // Test // ----------------- - Skill::TestTouch => Damage::Physical, - Skill::TestStun => Damage::Physical, - Skill::TestBlock => Damage::Physical, - Skill::TestDrain => Damage::Magic, + Skill::TestTouch => Category::Physical, + Skill::TestStun => Category::Physical, + Skill::TestBlock => Category::Physical, + Skill::TestDrain => Category::Spell, } } @@ -549,28 +563,10 @@ impl Skill { } } - pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { + pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let mut rng = thread_rng(); let base: u64 = rng.gen(); - // let res = Resolution { base, result: None }; - - // println!("{:?}'s stats", self.name); - // println!("{:064b} <- finalised", roll.result); - // roll.result = roll.result & stat(); - - // println!("{:064b} & <- attribute roll", stat()); - // println!("{:064b} = {:?}", roll.result, roll.result); - // println!(""); - - // return Some(roll); - - let (immune, reason) = target.immune(*self); - if immune { - log.push(format!("{:?} -> {:?} | {:?} immune: {:?}", cryp.name, target.name, self, reason)); - return; - } - match self { Skill::Attack => attack(cryp, target, log), // ----------------- @@ -644,11 +640,11 @@ impl Skill { // ----------------- // Test // ----------------- - Skill::TestTouch => (), + Skill::TestTouch => Resolution { skill: Skill::TestTouch, results: vec![] }, Skill::TestStun => stun(cryp, target, log), Skill::TestBlock => block(cryp, target, log), Skill::TestDrain => drain(cryp, target, log), - }; + } } pub fn duration(&self) -> u8 { @@ -685,159 +681,473 @@ impl Skill { } } -fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - target.deal_phys_dmg(cryp.phys_dmg()); +fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let amount = cryp.phys_dmg(); + let immunity = target.immune(Skill::Attack); + + let attack_result = ResolutionResult::Damage { + amount, + category: Category::PhysDmg, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Attack, results: vec![attack_result] }; + + if !immunity.immune { + target.deal_phys_dmg(amount); + } + log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, cryp.phys_dmg)); + + return resolution; } -fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None }; - target.effects.push(stun); + let immunity = target.immune(Skill::Stun); + + let attack_result = ResolutionResult::Effect { + effect: stun.effect, + duration: stun.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Stun, results: vec![attack_result] }; + + if !immunity.immune { + target.effects.push(stun); + } + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration)); + return resolution; } -fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None }; let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Skill::Stun.duration(), tick: None }; - target.effects.push(stun); - target.effects.push(vulnerable); + let immunity = target.immune(Skill::Throw); + + let stun_result = ResolutionResult::Effect { + effect: stun.effect, + duration: stun.duration, + immunity, + }; + + let vulnerable_result = ResolutionResult::Effect { + effect: vulnerable.effect, + duration: vulnerable.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Throw, results: vec![stun_result, vulnerable_result] }; + + if !immunity.immune { + target.effects.push(stun); + target.effects.push(vulnerable); + } + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration)); - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, vulnerable.effect, vulnerable.duration)); + return resolution; } -fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let block = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration(), tick: None }; + let immunity = target.immune(Skill::Block); + + let block_result = ResolutionResult::Effect { + effect: block.effect, + duration: block.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Block, results: vec![block_result] }; + + if !immunity.immune { + target.effects.push(block); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", target.name, target.name, block.effect, block.duration)); + return resolution; } -fn snare(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Snare, duration: Skill::Snare.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn snare(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let snare = CrypEffect { effect: Effect::Snare, duration: Skill::Snare.duration(), tick: None }; + let immunity = target.immune(Skill::Snare); + + let snare_result = ResolutionResult::Effect { + effect: snare.effect, + duration: snare.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Snare, results: vec![snare_result] }; + + if !immunity.immune { + target.effects.push(snare); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, snare.effect, snare.duration)); + return resolution; } -fn empower(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Empower, duration: Skill::Empower.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn empower(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let empower = CrypEffect { effect: Effect::Empower, duration: Skill::Empower.duration(), tick: None }; + let immunity = target.immune(Skill::Empower); + + let snare_result = ResolutionResult::Effect { + effect: empower.effect, + duration: empower.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Empower, results: vec![snare_result] }; + + if !immunity.immune { + target.effects.push(empower); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, empower.effect, empower.duration)); + return resolution; } -fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let (healing, overhealing) = target.heal(cryp.phys_dmg()); - log.push(format!("{:?} -> {:?} | Heal for {:?} ({:?} OH)", cryp.name, target.name, healing, overhealing)); +// TODO put overhealing back +fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let amount = cryp.phys_dmg(); + let immunity = target.immune(Skill::Heal); + + let heal_result = ResolutionResult::Damage { + amount, + category: Category::PhysHeal, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Heal, results: vec![heal_result] }; + + if !immunity.immune { + let (healing, overhealing) = target.heal(amount); + } + + log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, amount)); + + return resolution; + } -fn triage(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { +fn triage(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let triage = CrypEffect { effect: Effect::Triage, duration: Skill::Triage.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::TriageTick)), }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); + let immunity = target.immune(Skill::Triage); + + let snare_result = ResolutionResult::Effect { + effect: triage.effect, + duration: triage.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Triage, results: vec![snare_result] }; + + if !immunity.immune { + target.effects.push(triage); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, triage.effect, triage.duration)); + return resolution; } -fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let amount = cryp.spell_dmg().wrapping_div(2); - let (healing, overhealing) = target.heal(amount); - log.push(format!("{:?} -> {:?} | Triage for {:?} ({:?} OH)", cryp.name, target.name, healing, overhealing)); + let immunity = target.immune(Skill::TriageTick); + + let heal_result = ResolutionResult::Damage { + amount, + category: Category::PhysHeal, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::TriageTick, results: vec![heal_result] }; + + if !immunity.immune { + let (healing, overhealing) = target.heal(amount); + } + + log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, amount)); + + return resolution; } -fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let amount = cryp.spell_dmg(); - log.push(format!("{:?} -> {:?} | Blast for {:?}", cryp.name, target.name, amount)); - target.deal_spell_dmg(amount); + let immunity = target.immune(Skill::Blast); + + let blast_result = ResolutionResult::Damage { + amount, + category: Category::SpellDmg, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Blast, results: vec![blast_result] }; + + if !immunity.immune { + target.deal_spell_dmg(amount); + } + + return resolution; } -fn amplify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Amplify, duration: Skill::Amplify.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn amplify(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let amplify = CrypEffect { effect: Effect::Amplify, duration: Skill::Amplify.duration(), tick: None }; + let immunity = target.immune(Skill::Amplify); + + let amplify_result = ResolutionResult::Effect { + effect: amplify.effect, + duration: amplify.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Amplify, results: vec![amplify_result] }; + + if !immunity.immune { + target.effects.push(amplify); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, amplify.effect, amplify.duration)); + return resolution;; } -fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { +fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let decay = CrypEffect { effect: Effect::Decay, duration: Skill::Decay.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::DecayTick)), }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); + let immunity = target.immune(Skill::Empower); + + let decay_result = ResolutionResult::Effect { + effect: decay.effect, + duration: decay.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Decay, results: vec![decay_result] }; + + if !immunity.immune { + target.effects.push(decay); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, decay.effect, decay.duration)); + return resolution; } -fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { +fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { let amount = cryp.spell_dmg(); - log.push(format!("{:?} -> {:?} | Decay for {:?}", cryp.name, target.name, amount)); - target.deal_spell_dmg(amount); + let immunity = target.immune(Skill::DecayTick); + + let decay_tick_result = ResolutionResult::Damage { + amount, + category: Category::SpellDmg, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::DecayTick, results: vec![decay_tick_result] }; + + if !immunity.immune { + target.deal_spell_dmg(amount); + } + + return resolution; } -fn hex(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Hex, duration: Skill::Hex.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn hex(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let hex = CrypEffect { effect: Effect::Hex, duration: Skill::Hex.duration(), tick: None }; + let immunity = target.immune(Skill::Hex); + + let hex_result = ResolutionResult::Effect { + effect: hex.effect, + duration: hex.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Hex, results: vec![hex_result] }; + + if !immunity.immune { + target.effects.push(hex); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, hex.effect, hex.duration)); + return resolution;; } -fn curse(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Curse, duration: Skill::Curse.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn curse(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let curse = CrypEffect { effect: Effect::Curse, duration: Skill::Curse.duration(), tick: None }; + let immunity = target.immune(Skill::Curse); + + let curse_result = ResolutionResult::Effect { + effect: curse.effect, + duration: curse.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Curse, results: vec![curse_result] }; + + if !immunity.immune { + target.effects.push(curse); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, curse.effect, curse.duration)); + return resolution;; } -fn drain(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { +fn drain(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let drain = CrypEffect { effect: Effect::Drain, duration: Skill::Drain.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::DrainTick)), }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); + let immunity = target.immune(Skill::Drain); + + let drain_result = ResolutionResult::Effect { + effect: drain.effect, + duration: drain.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Drain, results: vec![drain_result] }; + + if !immunity.immune { + target.effects.push(drain); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, drain.effect, drain.duration)); + return resolution;; } -fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - // Damage part - let (damage, _) = target.deal_spell_dmg(cryp.spell_dmg().wrapping_div(2)); - log.push(format!("{:?} | Drain Damage {:?}", target.name, damage)); +// TODO is fukt +fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let amount = cryp.spell_dmg().wrapping_div(2); + let immunity = target.immune(Skill::DrainTick); - let (healing, overhealing) = target.heal(damage); - log.push(format!("{:?} | Drain healing {:?} ({:?} OH)", cryp.name, healing, overhealing)); + let drain_tick_dmg_result = ResolutionResult::Damage { + amount, + category: Category::SpellDmg, + immunity, + }; + + let drain_tick_heal_result = ResolutionResult::Damage { + amount, + category: Category::SpellHeal, + immunity, + }; + + + let mut resolution = Resolution { skill: Skill::DrainTick, results: vec![drain_tick_dmg_result, drain_tick_heal_result] }; + + if !immunity.immune { + // need to saturate amount and check caster immunity to healing + target.deal_spell_dmg(amount); + let (healing, overhealing) = cryp.heal(amount); + } + + return resolution; } -fn shield(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Shield, duration: Skill::Shield.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn shield(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let shield = CrypEffect { effect: Effect::Shield, duration: Skill::Shield.duration(), tick: None }; + let immunity = target.immune(Skill::Shield); + + let shield_result = ResolutionResult::Effect { + effect: shield.effect, + duration: shield.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Shield, results: vec![shield_result] }; + + if !immunity.immune { + target.effects.push(shield); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, shield.effect, shield.duration)); + return resolution; } -fn silence(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Silence, duration: Skill::Silence.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn silence(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let silence = CrypEffect { effect: Effect::Silence, duration: Skill::Silence.duration(), tick: None }; + let immunity = target.immune(Skill::Silence); + + let silence_result = ResolutionResult::Effect { + effect: silence.effect, + duration: silence.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Silence, results: vec![silence_result] }; + + if !immunity.immune { + target.effects.push(silence); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, silence.effect, silence.duration)); + return resolution; } -fn purge(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - for (i, ce) in target.effects.clone().iter_mut().enumerate() { - if ce.effect.source() == Source::Buff { - target.effects.remove(i); - log.push(format!("{:?} < {:?} purged", target.name, ce.effect)); +fn purge(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let immunity = target.immune(Skill::Purge); + + let mut resolution = Resolution { skill: Skill::Silence, results: vec![] }; + + if !immunity.immune { + for (i, ce) in target.effects.clone().iter_mut().enumerate() { + if ce.effect.category() == Category::SpellBuff { + target.effects.remove(i); + resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity }); + log.push(format!("{:?} < {:?} purged", target.name, ce.effect)); + } } } + + return resolution; } -fn purify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - for (i, ce) in target.effects.clone().iter_mut().enumerate() { - if ce.effect.source() == Source::Debuff { - target.effects.remove(i); - log.push(format!("{:?} < {:?} purified", target.name, ce.effect)); +fn purify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let immunity = target.immune(Skill::Purify); + + let mut resolution = Resolution { skill: Skill::Silence, results: vec![] }; + + if !immunity.immune { + for (i, ce) in target.effects.clone().iter_mut().enumerate() { + if ce.effect.category() == Category::SpellDebuff { + target.effects.remove(i); + resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity }); + log.push(format!("{:?} < {:?} purified", target.name, ce.effect)); + } } } + + return resolution; } -fn banish(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) { - let effect = CrypEffect { effect: Effect::Banish, duration: Skill::Banish.duration(), tick: None }; - target.effects.push(effect); - log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration)); +fn banish(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + let banish = CrypEffect { effect: Effect::Banish, duration: Skill::Banish.duration(), tick: None }; + let immunity = target.immune(Skill::Banish); + + let banish_result = ResolutionResult::Effect { + effect: banish.effect, + duration: banish.duration, + immunity, + }; + + let mut resolution = Resolution { skill: Skill::Banish, results: vec![banish_result] }; + + if !immunity.immune { + target.effects.push(banish); + } + + log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, banish.effect, banish.duration)); + return resolution; } From 4f0d349cd613c44cbc4e8dcf4e7cea7cae9cc7f1 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 27 Nov 2018 11:55:39 +1100 Subject: [PATCH 2/4] we're back, no logs --- server/src/game.rs | 87 ++++++++------- server/src/skill.rs | 266 ++++++++++++++++++++++---------------------- 2 files changed, 175 insertions(+), 178 deletions(-) diff --git a/server/src/game.rs b/server/src/game.rs index 8d8cc35f..06ff65ac 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -374,6 +374,7 @@ impl Game { .flat_map( |c| c.effects .iter() + .cloned() .filter_map(|e| e.tick)) .collect::>(); @@ -389,7 +390,7 @@ impl Game { let mut source = self.cryp_by_id(skill.source_cryp_id).unwrap().clone(); let mut target = self.cryp_by_id(skill.target_cryp_id.unwrap()).unwrap().clone(); - skill.set_resolution(&mut source, &mut target, &mut self.log); + skill.set_resolution(&mut source, &mut target); self.resolved.push(skill.clone()); self.update_cryp(&mut source); @@ -768,7 +769,7 @@ mod tests { use cryp::*; fn create_test_game() -> Game { - let mut x = Cryp::new() + let x = Cryp::new() .named(&"pronounced \"creeep\"".to_string()) .level(8) .learn(Skill::TestStun) @@ -816,58 +817,58 @@ mod tests { return game; } - fn create_2v2_test_game() -> Game { - let mut i = Cryp::new() - .named(&"pretaliate".to_string()) - .level(8) - .learn(Skill::Attack) - .create(); + // fn create_2v2_test_game() -> Game { + // let mut i = Cryp::new() + // .named(&"pretaliate".to_string()) + // .level(8) + // .learn(Skill::Attack) + // .create(); - let mut j = Cryp::new() - .named(&"poy sian".to_string()) - .level(8) - .learn(Skill::Attack) - .create(); + // let mut j = Cryp::new() + // .named(&"poy sian".to_string()) + // .level(8) + // .learn(Skill::Attack) + // .create(); - let mut x = Cryp::new() - .named(&"pronounced \"creeep\"".to_string()) - .level(8) - .learn(Skill::Attack) - .create(); + // let mut x = Cryp::new() + // .named(&"pronounced \"creeep\"".to_string()) + // .level(8) + // .learn(Skill::Attack) + // .create(); - let mut y = Cryp::new() - .named(&"lemongrass tea".to_string()) - .level(8) - .learn(Skill::Attack) - .create(); + // let mut y = Cryp::new() + // .named(&"lemongrass tea".to_string()) + // .level(8) + // .learn(Skill::Attack) + // .create(); - let mut game = Game::new(); + // let mut game = Game::new(); - game - .set_team_num(2) - .set_team_size(2) - .set_pve(false); + // game + // .set_team_num(2) + // .set_team_size(2) + // .set_pve(false); - let x_team_id = Uuid::new_v4(); - let mut x_team = Team::new(x_team_id); - x_team - .set_cryps(vec![x]); + // let x_team_id = Uuid::new_v4(); + // let mut x_team = Team::new(x_team_id); + // x_team + // .set_cryps(vec![x]); - let y_team_id = Uuid::new_v4(); - let mut y_team = Team::new(y_team_id); - y_team - .set_cryps(vec![y]); + // let y_team_id = Uuid::new_v4(); + // let mut y_team = Team::new(y_team_id); + // y_team + // .set_cryps(vec![y]); - game - .team_add(x_team).unwrap() - .team_add(y_team).unwrap(); + // game + // .team_add(x_team).unwrap() + // .team_add(y_team).unwrap(); - assert!(game.can_start()); + // assert!(game.can_start()); - game.start(); + // game.start(); - return game; - } + // return game; + // } #[test] fn phase_test() { diff --git a/server/src/skill.rs b/server/src/skill.rs index 3b038521..875687bc 100755 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -40,8 +40,8 @@ impl Cast { return cast; } - pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> &mut Cast { - self.resolution = self.skill.resolve(cryp, target, log); + pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp) -> &mut Cast { + self.resolution = self.skill.resolve(cryp, target); self } @@ -77,7 +77,7 @@ pub struct Resolution { pub type Cooldown = Option; -#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] +#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum Effect { // physical Stun, @@ -563,24 +563,24 @@ impl Skill { } } - pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { + pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let mut rng = thread_rng(); let base: u64 = rng.gen(); match self { - Skill::Attack => attack(cryp, target, log), + Skill::Attack => attack(cryp, target), // ----------------- // Nature // ----------------- - Skill::Block => block(cryp, target, log), + Skill::Block => block(cryp, target), Skill::Evade => panic!("nyi"), // Skill::Parry => panic!("nyi"), // avoid all dmg - Skill::Snare => snare(cryp, target, log), // TODO prevent physical moves + Skill::Snare => snare(cryp, target), // TODO prevent physical moves Skill::Paralyse => panic!("nyi"), // no physical moves Skill::Strangle => panic!("nyi"), // no physical moves - Skill::Stun => stun(cryp, target, log), + Skill::Stun => stun(cryp, target), Skill::Evasion => panic!("nyi"), // additional layer of dmg avoidance // ----------------- @@ -595,10 +595,10 @@ impl Skill { // ----------------- // Preservation // ----------------- - Skill::Heal => heal(cryp, target, log), - Skill::Triage => triage(cryp, target, log), // hot - Skill::TriageTick => triage_tick(cryp, target, log), // hot - Skill::Throw => throw(cryp, target, log), // no dmg stun, adds vulnerable + Skill::Heal => heal(cryp, target), + Skill::Triage => triage(cryp, target), // hot + Skill::TriageTick => triage_tick(cryp, target), // hot + Skill::Throw => throw(cryp, target), // no dmg stun, adds vulnerable Skill::Charm => panic!("nyi"), // target casts random spell on teammate Skill::Calm => panic!("nyi"), // physical fear, taunt removal Skill::Rez => panic!("nyi"), @@ -606,13 +606,13 @@ impl Skill { // ----------------- // Destruction // ----------------- - Skill::Blast => blast(cryp, target, log), - Skill::Amplify => amplify(cryp, target, log), // increase magic dmg - Skill::Decay => decay(cryp, target, log), // dot - Skill::DecayTick => decay_tick(cryp, target, log), // hot - Skill::Drain => drain(cryp, target, log), - Skill::DrainTick => drain_tick(cryp, target, log), // hot - Skill::Curse => curse(cryp, target, log), + Skill::Blast => blast(cryp, target), + Skill::Amplify => amplify(cryp, target), // increase magic dmg + Skill::Decay => decay(cryp, target), // dot + Skill::DecayTick => decay_tick(cryp, target), // hot + Skill::Drain => drain(cryp, target), + Skill::DrainTick => drain_tick(cryp, target), // hot + Skill::Curse => curse(cryp, target), Skill::Plague => panic!("nyi"), // dot that spreads every turn Skill::Ruin => panic!("nyi"), // aoe version of blast @@ -620,19 +620,19 @@ impl Skill { // Purity // ----------------- // Skill::Precision => panic!("nyi"), - Skill::Empower => empower(cryp, target, log), // increased phys dmg + Skill::Empower => empower(cryp, target), // increased phys dmg Skill::Slay => panic!("nyi"), // phys dmg mult by target magic dmg - Skill::Shield => shield(cryp, target, log), // target is immune to magic dmg and fx - Skill::Silence => silence(cryp, target, log), // target cannot cast spells + Skill::Shield => shield(cryp, target), // target is immune to magic dmg and fx + Skill::Silence => silence(cryp, target), // target cannot cast spells Skill::Inquiry => panic!("nyi"), // - Skill::Purify => purify(cryp, target, log), // dispel all debuffs - Skill::Purge => purge(cryp, target, log), // dispel all buffs + Skill::Purify => purify(cryp, target), // dispel all debuffs + Skill::Purge => purge(cryp, target), // dispel all buffs // ----------------- // Chaos // ----------------- - Skill::Banish => banish(cryp, target, log), // TODO prevent all actions - Skill::Hex => hex(cryp, target, log), // todo prevent casting + Skill::Banish => banish(cryp, target), // TODO prevent all actions + Skill::Hex => hex(cryp, target), // todo prevent casting Skill::Fear => panic!("nyi"), // cast random spell on self Skill::Taunt => panic!("nyi"), // target forced to attack Skill::Pause => panic!("nyi"), // speed slow @@ -641,9 +641,9 @@ impl Skill { // Test // ----------------- Skill::TestTouch => Resolution { skill: Skill::TestTouch, results: vec![] }, - Skill::TestStun => stun(cryp, target, log), - Skill::TestBlock => block(cryp, target, log), - Skill::TestDrain => drain(cryp, target, log), + Skill::TestStun => stun(cryp, target), + Skill::TestBlock => block(cryp, target), + Skill::TestDrain => drain(cryp, target), } } @@ -681,9 +681,10 @@ impl Skill { } } -fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn attack(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.phys_dmg(); let immunity = target.immune(Skill::Attack); + let immune = immunity.immune; let attack_result = ResolutionResult::Damage { amount, @@ -691,20 +692,20 @@ fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Attack, results: vec![attack_result] }; + let resolution = Resolution { skill: Skill::Attack, results: vec![attack_result] }; - if !immunity.immune { + if !immune { target.deal_phys_dmg(amount); } - log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, cryp.phys_dmg)); return resolution; } -fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn stun(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None }; let immunity = target.immune(Skill::Stun); + let immune = immunity.immune; let attack_result = ResolutionResult::Effect { effect: stun.effect, @@ -712,25 +713,25 @@ fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Stun, results: vec![attack_result] }; + let resolution = Resolution { skill: Skill::Stun, results: vec![attack_result] }; - if !immunity.immune { + if !immune { target.effects.push(stun); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration)); return resolution; } -fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn throw(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None }; let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Skill::Stun.duration(), tick: None }; let immunity = target.immune(Skill::Throw); + let immune = immunity.immune; let stun_result = ResolutionResult::Effect { effect: stun.effect, duration: stun.duration, - immunity, + immunity: immunity.clone(), }; let vulnerable_result = ResolutionResult::Effect { @@ -739,21 +740,21 @@ fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Throw, results: vec![stun_result, vulnerable_result] }; + let resolution = Resolution { skill: Skill::Throw, results: vec![stun_result, vulnerable_result] }; - if !immunity.immune { + if !immune { target.effects.push(stun); target.effects.push(vulnerable); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration)); return resolution; } -fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn block(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let block = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration(), tick: None }; let immunity = target.immune(Skill::Block); + let immune = immunity.immune; let block_result = ResolutionResult::Effect { effect: block.effect, @@ -761,19 +762,19 @@ fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Block, results: vec![block_result] }; + let resolution = Resolution { skill: Skill::Block, results: vec![block_result] }; - if !immunity.immune { + if !immune { target.effects.push(block); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", target.name, target.name, block.effect, block.duration)); return resolution; } -fn snare(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn snare(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let snare = CrypEffect { effect: Effect::Snare, duration: Skill::Snare.duration(), tick: None }; let immunity = target.immune(Skill::Snare); + let immune = immunity.immune; let snare_result = ResolutionResult::Effect { effect: snare.effect, @@ -781,19 +782,19 @@ fn snare(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Snare, results: vec![snare_result] }; + let resolution = Resolution { skill: Skill::Snare, results: vec![snare_result] }; - if !immunity.immune { + if !immune { target.effects.push(snare); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, snare.effect, snare.duration)); return resolution; } -fn empower(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn empower(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let empower = CrypEffect { effect: Effect::Empower, duration: Skill::Empower.duration(), tick: None }; let immunity = target.immune(Skill::Empower); + let immune = immunity.immune; let snare_result = ResolutionResult::Effect { effect: empower.effect, @@ -801,20 +802,20 @@ fn empower(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Empower, results: vec![snare_result] }; + let resolution = Resolution { skill: Skill::Empower, results: vec![snare_result] }; - if !immunity.immune { + if !immune { target.effects.push(empower); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, empower.effect, empower.duration)); return resolution; } // TODO put overhealing back -fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn heal(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.phys_dmg(); let immunity = target.immune(Skill::Heal); + let immune = immunity.immune; let heal_result = ResolutionResult::Damage { amount, @@ -822,25 +823,25 @@ fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Heal, results: vec![heal_result] }; + let resolution = Resolution { skill: Skill::Heal, results: vec![heal_result] }; - if !immunity.immune { - let (healing, overhealing) = target.heal(amount); + if !immune { + let (_healing, _overhealing) = target.heal(amount); } - log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, amount)); return resolution; } -fn triage(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn triage(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let triage = CrypEffect { effect: Effect::Triage, duration: Skill::Triage.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::TriageTick)), }; let immunity = target.immune(Skill::Triage); + let immune = immunity.immune; let snare_result = ResolutionResult::Effect { effect: triage.effect, @@ -848,19 +849,19 @@ fn triage(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Triage, results: vec![snare_result] }; + let resolution = Resolution { skill: Skill::Triage, results: vec![snare_result] }; - if !immunity.immune { + if !immune { target.effects.push(triage); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, triage.effect, triage.duration)); return resolution; } -fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn triage_tick(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.spell_dmg().wrapping_div(2); let immunity = target.immune(Skill::TriageTick); + let immune = immunity.immune; let heal_result = ResolutionResult::Damage { amount, @@ -868,20 +869,20 @@ fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution immunity, }; - let mut resolution = Resolution { skill: Skill::TriageTick, results: vec![heal_result] }; + let resolution = Resolution { skill: Skill::TriageTick, results: vec![heal_result] }; - if !immunity.immune { - let (healing, overhealing) = target.heal(amount); + if !immune { + let (_healing, _overhealing) = target.heal(amount); } - log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, amount)); return resolution; } -fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn blast(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.spell_dmg(); let immunity = target.immune(Skill::Blast); + let immune = immunity.immune; let blast_result = ResolutionResult::Damage { amount, @@ -889,18 +890,19 @@ fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Blast, results: vec![blast_result] }; + let resolution = Resolution { skill: Skill::Blast, results: vec![blast_result] }; - if !immunity.immune { + if !immune { target.deal_spell_dmg(amount); } return resolution; } -fn amplify(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn amplify(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amplify = CrypEffect { effect: Effect::Amplify, duration: Skill::Amplify.duration(), tick: None }; let immunity = target.immune(Skill::Amplify); + let immune = immunity.immune; let amplify_result = ResolutionResult::Effect { effect: amplify.effect, @@ -908,23 +910,23 @@ fn amplify(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Amplify, results: vec![amplify_result] }; + let resolution = Resolution { skill: Skill::Amplify, results: vec![amplify_result] }; - if !immunity.immune { + if !immune { target.effects.push(amplify); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, amplify.effect, amplify.duration)); return resolution;; } -fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn decay(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let decay = CrypEffect { effect: Effect::Decay, duration: Skill::Decay.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::DecayTick)), }; let immunity = target.immune(Skill::Empower); + let immune = immunity.immune; let decay_result = ResolutionResult::Effect { effect: decay.effect, @@ -932,19 +934,19 @@ fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Decay, results: vec![decay_result] }; + let resolution = Resolution { skill: Skill::Decay, results: vec![decay_result] }; - if !immunity.immune { + if !immune { target.effects.push(decay); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, decay.effect, decay.duration)); return resolution; } -fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn decay_tick(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.spell_dmg(); let immunity = target.immune(Skill::DecayTick); + let immune = immunity.immune; let decay_tick_result = ResolutionResult::Damage { amount, @@ -952,18 +954,19 @@ fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::DecayTick, results: vec![decay_tick_result] }; + let resolution = Resolution { skill: Skill::DecayTick, results: vec![decay_tick_result] }; - if !immunity.immune { + if !immune { target.deal_spell_dmg(amount); } return resolution; } -fn hex(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn hex(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let hex = CrypEffect { effect: Effect::Hex, duration: Skill::Hex.duration(), tick: None }; let immunity = target.immune(Skill::Hex); + let immune = immunity.immune; let hex_result = ResolutionResult::Effect { effect: hex.effect, @@ -971,19 +974,19 @@ fn hex(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Hex, results: vec![hex_result] }; + let resolution = Resolution { skill: Skill::Hex, results: vec![hex_result] }; - if !immunity.immune { + if !immune { target.effects.push(hex); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, hex.effect, hex.duration)); return resolution;; } -fn curse(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn curse(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let curse = CrypEffect { effect: Effect::Curse, duration: Skill::Curse.duration(), tick: None }; let immunity = target.immune(Skill::Curse); + let immune = immunity.immune; let curse_result = ResolutionResult::Effect { effect: curse.effect, @@ -991,23 +994,23 @@ fn curse(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Curse, results: vec![curse_result] }; + let resolution = Resolution { skill: Skill::Curse, results: vec![curse_result] }; - if !immunity.immune { + if !immune { target.effects.push(curse); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, curse.effect, curse.duration)); return resolution;; } -fn drain(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn drain(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let drain = CrypEffect { effect: Effect::Drain, duration: Skill::Drain.duration(), tick: Some(Cast::new_tick(cryp, target, Skill::DrainTick)), }; let immunity = target.immune(Skill::Drain); + let immune = immunity.immune; let drain_result = ResolutionResult::Effect { effect: drain.effect, @@ -1015,25 +1018,25 @@ fn drain(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Drain, results: vec![drain_result] }; + let resolution = Resolution { skill: Skill::Drain, results: vec![drain_result] }; - if !immunity.immune { + if !immune { target.effects.push(drain); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, drain.effect, drain.duration)); return resolution;; } // TODO is fukt -fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn drain_tick(cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let amount = cryp.spell_dmg().wrapping_div(2); let immunity = target.immune(Skill::DrainTick); + let immune = immunity.immune; let drain_tick_dmg_result = ResolutionResult::Damage { amount, category: Category::SpellDmg, - immunity, + immunity: immunity.clone(), }; let drain_tick_heal_result = ResolutionResult::Damage { @@ -1043,20 +1046,21 @@ fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { }; - let mut resolution = Resolution { skill: Skill::DrainTick, results: vec![drain_tick_dmg_result, drain_tick_heal_result] }; + let resolution = Resolution { skill: Skill::DrainTick, results: vec![drain_tick_dmg_result, drain_tick_heal_result] }; - if !immunity.immune { + if !immune { // need to saturate amount and check caster immunity to healing target.deal_spell_dmg(amount); - let (healing, overhealing) = cryp.heal(amount); + let (_healing, _overhealing) = cryp.heal(amount); } return resolution; } -fn shield(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn shield(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let shield = CrypEffect { effect: Effect::Shield, duration: Skill::Shield.duration(), tick: None }; let immunity = target.immune(Skill::Shield); + let immune = immunity.immune; let shield_result = ResolutionResult::Effect { effect: shield.effect, @@ -1064,19 +1068,19 @@ fn shield(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Shield, results: vec![shield_result] }; + let resolution = Resolution { skill: Skill::Shield, results: vec![shield_result] }; - if !immunity.immune { + if !immune { target.effects.push(shield); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, shield.effect, shield.duration)); return resolution; } -fn silence(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn silence(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let silence = CrypEffect { effect: Effect::Silence, duration: Skill::Silence.duration(), tick: None }; let immunity = target.immune(Skill::Silence); + let immune = immunity.immune; let silence_result = ResolutionResult::Effect { effect: silence.effect, @@ -1084,27 +1088,26 @@ fn silence(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Silence, results: vec![silence_result] }; + let resolution = Resolution { skill: Skill::Silence, results: vec![silence_result] }; - if !immunity.immune { + if !immune { target.effects.push(silence); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, silence.effect, silence.duration)); return resolution; } -fn purge(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn purge(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let immunity = target.immune(Skill::Purge); + let immune = immunity.immune; let mut resolution = Resolution { skill: Skill::Silence, results: vec![] }; - if !immunity.immune { + if !immune { for (i, ce) in target.effects.clone().iter_mut().enumerate() { if ce.effect.category() == Category::SpellBuff { target.effects.remove(i); - resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity }); - log.push(format!("{:?} < {:?} purged", target.name, ce.effect)); + resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity: immunity.clone() }); } } } @@ -1112,17 +1115,17 @@ fn purge(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { return resolution; } -fn purify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn purify(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let immunity = target.immune(Skill::Purify); + let immune = immunity.immune; let mut resolution = Resolution { skill: Skill::Silence, results: vec![] }; - if !immunity.immune { + if !immune { for (i, ce) in target.effects.clone().iter_mut().enumerate() { if ce.effect.category() == Category::SpellDebuff { target.effects.remove(i); - resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity }); - log.push(format!("{:?} < {:?} purified", target.name, ce.effect)); + resolution.results.push(ResolutionResult::Removal { effect: ce.effect, immunity: immunity.clone() }); } } } @@ -1130,9 +1133,10 @@ fn purify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { return resolution; } -fn banish(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { +fn banish(_cryp: &mut Cryp, target: &mut Cryp) -> Resolution { let banish = CrypEffect { effect: Effect::Banish, duration: Skill::Banish.duration(), tick: None }; let immunity = target.immune(Skill::Banish); + let immune = immunity.immune; let banish_result = ResolutionResult::Effect { effect: banish.effect, @@ -1140,13 +1144,12 @@ fn banish(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution { immunity, }; - let mut resolution = Resolution { skill: Skill::Banish, results: vec![banish_result] }; + let resolution = Resolution { skill: Skill::Banish, results: vec![banish_result] }; - if !immunity.immune { + if !immune { target.effects.push(banish); } - log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, banish.effect, banish.duration)); return resolution; } @@ -1171,8 +1174,7 @@ mod tests { x.deal_phys_dmg(5); - let mut log = vec![]; - heal(&mut y, &mut x, &mut log); + heal(&mut y, &mut x); } #[test] @@ -1188,12 +1190,12 @@ mod tests { .create(); let mut log = vec![]; - decay(&mut x, &mut y, &mut log); + decay(&mut x, &mut y); assert!(y.effects.iter().any(|e| e.effect == Effect::Decay)); y.reduce_effect_durations(&mut log); - let decay = y.effects.iter().find(|e| e.effect == Effect::Decay); + let _decay = y.effects.iter().find(|e| e.effect == Effect::Decay); // assert!(y.hp() == y.stamina().saturating_sub(decay.unwrap().tick.unwrap().amount)); } @@ -1209,18 +1211,16 @@ mod tests { .level(8) .create(); - let mut log = vec![]; - // ensure it doesn't have 0 sd x.spell_dmg.set(50); y.deal_phys_dmg(5); let prev_hp = y.hp(); - triage(&mut x, &mut y, &mut log); + triage(&mut x, &mut y); assert!(y.effects.iter().any(|e| e.effect == Effect::Triage)); - triage_tick(&mut x, &mut y, &mut log); + triage_tick(&mut x, &mut y); assert!(y.hp() > prev_hp); } @@ -1231,9 +1231,7 @@ mod tests { .level(8) .create(); - let mut log = vec![]; - - silence(&mut x.clone(), &mut x, &mut log); + silence(&mut x.clone(), &mut x); assert!(x.effects.iter().any(|e| e.effect == Effect::Silence)); assert!(!Skill::Decay.castable(&x)); } @@ -1247,8 +1245,7 @@ mod tests { x.spell_dmg.set(50); - let mut log = vec![]; - amplify(&mut x.clone(), &mut x, &mut log); + amplify(&mut x.clone(), &mut x); assert!(x.effects.iter().any(|e| e.effect == Effect::Amplify)); assert_eq!(x.spell_dmg(), 100); } @@ -1260,11 +1257,10 @@ mod tests { .level(8) .create(); - let mut log = vec![]; - decay(&mut x.clone(), &mut x, &mut log); + decay(&mut x.clone(), &mut x); assert!(x.effects.iter().any(|e| e.effect == Effect::Decay)); - purify(&mut x.clone(), &mut x, &mut log); + purify(&mut x.clone(), &mut x); assert!(!x.effects.iter().any(|e| e.effect == Effect::Decay)); } } From b2507d706ce8338fd4ab10238a9b9e87ebb7c5eb Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 27 Nov 2018 12:12:56 +1100 Subject: [PATCH 3/4] logging back --- server/src/game.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/server/src/game.rs b/server/src/game.rs index 06ff65ac..983c2f65 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -12,7 +12,7 @@ use failure::err_msg; use account::Account; use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameTargetParams, GameJoinParams}; use cryp::{Cryp, cryp_get}; -use skill::{Skill, Cast}; +use skill::{Skill, Cast, ResolutionResult}; pub type Log = Vec; @@ -363,6 +363,24 @@ impl Game { self.resolve_skills() } + fn log_resolution(&mut self, source: &Cryp, target: &Cryp, cast: &Cast) -> &mut Game { + for result in cast.resolution.results.iter() { + match result { + ResolutionResult::Damage { amount, category: _, immunity: _ } => { + self.log.push(format!("{:?} {:?} {:?} {:?}", source.name, cast.skill, target.name, amount)); + }, + ResolutionResult::Effect { effect, duration, immunity: _ } => { + self.log.push(format!("{:?} {:?} {:?} {:?} {:?}T", source.name, cast.skill, target.name, effect, duration)); + }, + ResolutionResult::Removal { effect, immunity: _ } => { + self.log.push(format!("{:?} removed {:?} {:?}", source.name, target.name, effect)); + }, + } + } + + self + } + fn resolve_skills(&mut self) -> &mut Game { if self.phase != Phase::Resolve { panic!("game not in Resolve phase"); @@ -391,6 +409,9 @@ impl Game { let mut target = self.cryp_by_id(skill.target_cryp_id.unwrap()).unwrap().clone(); skill.set_resolution(&mut source, &mut target); + + self.log_resolution(&source, &target, skill); + self.resolved.push(skill.clone()); self.update_cryp(&mut source); @@ -1053,6 +1074,8 @@ mod tests { assert!([Phase::Skill, Phase::Finish].contains(&game.phase)); + println!("{:#?}", game); + return; } From a222d87830b15c9a6ae5006b972dbc7c155b0432 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 27 Nov 2018 14:10:45 +1100 Subject: [PATCH 4/4] ko checks --- client/src/scenes/constants.js | 1 + client/src/socket.js | 3 --- server/src/cryp.rs | 5 +++++ server/src/game.rs | 6 +++--- server/src/skill.rs | 5 +++++ 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/src/scenes/constants.js b/client/src/scenes/constants.js index a7b52d58..374a0761 100644 --- a/client/src/scenes/constants.js +++ b/client/src/scenes/constants.js @@ -129,6 +129,7 @@ module.exports = { 'Strangle', // physical dot and disable 'Stun', + 'Throw', 'Evade', // actively evade 'Evasion', // adds evasion to cryp diff --git a/client/src/socket.js b/client/src/socket.js index 53c07114..5f5c2a21 100644 --- a/client/src/socket.js +++ b/client/src/socket.js @@ -12,9 +12,6 @@ function errorToast(err) { }); } -// Create WebSocket connection. -// requires the redux store in order to push updates -// to components function createSocket(events) { let ws; diff --git a/server/src/cryp.rs b/server/src/cryp.rs index fbe75b83..ce317541 100755 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -179,6 +179,11 @@ impl Cryp { } pub fn immune(&self, skill: Skill) -> Immunity { + + if self.is_ko() { + return Immunity { immune: true, effects: vec![Effect::Ko]}; + } + let immunities = self.effects.iter() .filter(|e| e.effect.immune(skill)) .map(|e| e.effect) diff --git a/server/src/game.rs b/server/src/game.rs index 983c2f65..d54c5a90 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -436,6 +436,8 @@ impl Game { // println!("progressing durations for {:?}", cryp.name); if cryp.is_ko() { + self.log.push(format!("{:?} KO", cryp.name)); + cryp.effects.clear(); continue; } @@ -1045,7 +1047,7 @@ mod tests { assert!(game.resolved.iter().any(|r| r.skill == Skill::DrainTick)); - // println!("{:#?}", game); + println!("{:#?}", game); } #[test] @@ -1074,8 +1076,6 @@ mod tests { assert!([Phase::Skill, Phase::Finish].contains(&game.phase)); - println!("{:#?}", game); - return; } diff --git a/server/src/skill.rs b/server/src/skill.rs index 875687bc..b6591b4a 100755 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -117,6 +117,8 @@ pub enum Effect { SpeedDrain, SpeedIncrease, + + Ko, } impl Effect { @@ -209,6 +211,8 @@ impl Effect { Effect::SpeedDrain => Category::SpellDebuff, Effect::SpeedIncrease => Category::SpellBuff, + + Effect::Ko => Category::Ko, } } } @@ -225,6 +229,7 @@ pub enum Category { SpellHeal, SpellDebuff, SpellBuff, + Ko, } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]