From 5b98ce151a37b54a665cfcea43500d71b2e5deaf Mon Sep 17 00:00:00 2001 From: ntr Date: Sat, 12 Jan 2019 00:13:30 +1100 Subject: [PATCH] evasion --- client/src/scenes/constants.js | 4 --- server/WORKLOG.md | 4 +++ server/src/cryp.rs | 45 ++++++++++++++++++++----------- server/src/game.rs | 8 ++++-- server/src/mob.rs | 4 +-- server/src/skill.rs | 48 ++++++++++------------------------ 6 files changed, 56 insertions(+), 57 deletions(-) diff --git a/client/src/scenes/constants.js b/client/src/scenes/constants.js index 3acebda5..78e88cde 100644 --- a/client/src/scenes/constants.js +++ b/client/src/scenes/constants.js @@ -168,10 +168,6 @@ module.exports = { description: 'drain hp from target cryp with a spell damage based debuff' }, { name: 'Empower', description: 'increase the physical damage dealt by a cryp' }, - { name: 'Evade', - description: 'gives a chance to evade physical damage for 1T' }, - { name: 'Evasion', - description: 'grants Evade effect to a cryp' }, { name: 'Haste', description: 'magical skill that increases speed of target cryp' }, { name: 'Heal', description: 'heal a cryp with spell dmg' }, diff --git a/server/WORKLOG.md b/server/WORKLOG.md index ea39c527..4dc7ad91 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -7,11 +7,15 @@ * 10d chaos maths, not rock paper scissors * phys is faster and chaotic * spells are slow and reliable +* defensives are implicit + * armour is restored, not gained + * players can feel aggressive # ask sam * icons * skill type / damage type * skills themselves + * passive nodes / notables # WORK WORK diff --git a/server/src/cryp.rs b/server/src/cryp.rs index d8cc960e..d3e862cd 100644 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -52,6 +52,7 @@ pub enum Stat { HealingTaken, Armour, SpellShield, + Evasion, } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -98,6 +99,7 @@ pub struct Cryp { pub hp: CrypStat, pub armour: CrypStat, pub spell_shield: CrypStat, + pub evasion: CrypStat, pub xp: u64, pub lvl: u8, pub skills: Vec, @@ -122,8 +124,9 @@ impl Cryp { speed: CrypStat { base: 0, stat: Stat::Speed }, stamina: CrypStat { base: 0, stat: Stat::Stamina }, hp: CrypStat { base: 0, stat: Stat::Hp }, - armour: CrypStat { base: 50, stat: Stat::Armour }, - spell_shield: CrypStat { base: 50, stat: Stat::SpellShield }, + armour: CrypStat { base: 0, stat: Stat::Armour }, + spell_shield: CrypStat { base: 0, stat: Stat::SpellShield }, + evasion: CrypStat { base: 0, stat: Stat::Evasion }, lvl: 0, xp: 0, skills: vec![], @@ -163,18 +166,18 @@ impl Cryp { } } - pub fn add_xp(mut self) -> Cryp { - self.xp = self.xp.saturating_add(1); - if self.xp.is_power_of_two() { - return self.level_up(); - } - self - } + // pub fn add_xp(mut self) -> Cryp { + // self.xp = self.xp.saturating_add(1); + // if self.xp.is_power_of_two() { + // return self.level_up(); + // } + // self + // } - pub fn level_up(mut self) -> Cryp { - self.lvl = self.lvl.saturating_add(1); - self.create() - } + // pub fn level_up(mut self) -> Cryp { + // self.lvl = self.lvl.saturating_add(1); + // self.create() + // } pub fn roll_stat(&mut self, stat: Stat) -> &mut Cryp { let mut rng = thread_rng(); @@ -461,7 +464,7 @@ impl Cryp { self.hp.reduce(remainder); return ResolutionResult::Damage { - amount: modified_dmg, + amount: remainder, mitigation, category: Category::PhysDmg, immunity, @@ -496,7 +499,7 @@ impl Cryp { self.hp.reduce(remainder); return ResolutionResult::Damage { - amount: modified_dmg, + amount: remainder, mitigation, category: Category::SpellDmg, immunity, @@ -521,6 +524,18 @@ impl Cryp { return result; } + pub fn evade(&self, skill: Skill) -> Option { + let mut rng = thread_rng(); + let rating = 100 - self.evasion.base; + let roll = rng.gen_range(0, 100); + + match roll > rating { + true => Some(ResolutionResult::Evasion { + skill, + }), + false => None, + } + } } pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result { diff --git a/server/src/game.rs b/server/src/game.rs index e82c95c3..24b5fe96 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -351,8 +351,8 @@ impl Game { match immunity.immune { true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}", cast.resolution.speed, source.name, cast.skill, target.name, immunity.effects)), - false => self.log.push(format!("[{:}] {:} {:?} {:} {:}", - cast.resolution.speed, source.name, cast.skill, target.name, amount)), + false => self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)", + cast.resolution.speed, source.name, cast.skill, target.name, amount, mitigation)), } }, ResolutionResult::Healing { amount, overhealing, category: _, immunity } => { @@ -379,6 +379,10 @@ impl Game { cast.resolution.speed, source.name, target.name, effect)), } }, + ResolutionResult::Evasion { skill: _ } => { + self.log.push(format!("[{:}] {:} {:?} {:} evaded", + cast.resolution.speed, source.name, cast.skill, target.name)); + }, } } diff --git a/server/src/mob.rs b/server/src/mob.rs index 79c1e795..29ed5b5b 100644 --- a/server/src/mob.rs +++ b/server/src/mob.rs @@ -107,7 +107,7 @@ fn zone_3v3_healer_boss(player_lvl: u8) -> Vec { .named(&"coinage".to_string()) .level(player_lvl) .learn(Skill::Attack) - .learn(Skill::Evade) + .learn(Skill::Parry) .learn(Skill::Block) .create(); @@ -124,7 +124,7 @@ fn zone_3v3_healer_boss(player_lvl: u8) -> Vec { .named(&"quarry".to_string()) .level(player_lvl) .learn(Skill::Attack) - .learn(Skill::Evade) + .learn(Skill::Parry) .learn(Skill::Stun) .create(); diff --git a/server/src/skill.rs b/server/src/skill.rs index 2de591ce..7f9f376c 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -70,6 +70,7 @@ pub enum ResolutionResult { Healing { amount: u64, overhealing: u64, category: Category , immunity: Immunity }, Effect { effect: Effect, duration: u8, immunity: Immunity }, Removal { effect: Effect, immunity: Immunity }, + Evasion { skill: Skill }, } #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] @@ -101,7 +102,6 @@ pub enum Effect { Deadly, Vulnerable, Fury, - Evasion, Blind, Snare, @@ -146,11 +146,6 @@ impl Effect { Category::Physical => false, _ => false, }, - Effect::Evasion => match skill.category() { - Category::Spell => false, - Category::Physical => evade_roll(), - _ => false, - }, Effect::Banish => true, _ => false, } @@ -231,7 +226,6 @@ impl Effect { Effect::Deadly => Category::PhysBuff, Effect::Vulnerable => Category::PhysDebuff, Effect::Fury => Category::PhysBuff, - Effect::Evasion => Category::PhysBuff, Effect::Blind => Category::PhysDebuff, Effect::Snare => Category::PhysDebuff, @@ -266,7 +260,6 @@ impl Effect { pub fn duration(&self) -> u8 { match self { - Effect::Evasion => 1, Effect::Block => 1, Effect::Parry => 1, @@ -330,8 +323,7 @@ pub enum Skill { Strangle, // physical dot and disable Stun, - Evade, // actively evade - Evasion, // adds evasion to cryp + // Evade, // actively evade // ----------------- @@ -419,8 +411,6 @@ impl Skill { // Strangle Skill::Stun => Some(1), - Skill::Evade => None, - Skill::Evasion => None, // additional layer of dmg avoidance // ----------------- // Technology @@ -497,7 +487,6 @@ impl Skill { // Nature // ----------------- Skill::Block => Category::Physical, // reduce dmg - Skill::Evade => Category::Physical, Skill::Parry => Category::Physical, // avoid all dmg Skill::Snare => Category::Physical, @@ -507,7 +496,6 @@ impl Skill { // Strangle Skill::Stun => Category::Physical, - Skill::Evasion => Category::Physical, // additional layer of dmg avoidance // ----------------- // Technology @@ -592,7 +580,6 @@ impl Skill { // defensive block Skill::Block => 10, // reduce dmg - Skill::Evade => 10, Skill::Parry => 10, // avoid all dmg Skill::Snare => 10, Skill::Shield => 10, // avoid magic dmg, @@ -606,7 +593,6 @@ impl Skill { Skill::Decay => 5, // dot // magic combat trickery - Skill::Evasion => 3, // additional layer of dmg avoidance Skill::Triage => 3, // hot Skill::Slow => 3, Skill::Fear => 2, @@ -664,7 +650,7 @@ impl Skill { let speed = source.skill_speed(*self); - let resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed }; + let mut resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed }; if target.is_ko() { return resolution; @@ -674,6 +660,16 @@ impl Skill { return resolution; } + match self.category() == Category::Physical { + true => { + if let Some(evasion) = target.evade(*self) { + resolution.results.push(evasion); + return resolution; + } + }, + false => (), + } + match self { Skill::Attack => attack(source, target, resolution), // ----------------- @@ -681,14 +677,12 @@ impl Skill { // ----------------- Skill::Block => block(source, target, resolution), Skill::Parry => parry(source, target, resolution), - Skill::Evade => evade(source, target, resolution), Skill::Snare => snare(source, target, resolution), // TODO prevent physical moves Skill::Paralyse => panic!("nyi"), // no physical moves Skill::Strangle => panic!("nyi"), // no physical moves Skill::Stun => stun(source, target, resolution), - Skill::Evasion => evade(source, target, resolution), // additional layer of dmg avoidance // ----------------- // Technology @@ -760,7 +754,6 @@ impl Skill { pub fn self_targeting(&self) -> bool { match self { Skill::Block => true, - Skill::Evasion => true, Skill::Parry => true, Skill::TestBlock => true, Skill::TestParry => true, @@ -775,10 +768,8 @@ impl Skill { Skill::Empower | Skill::Purify | Skill::Calm | - Skill::Evasion | Skill::Parry | - Skill::Block | - Skill::Evade => true, + Skill::Block => true, _ => false, } } @@ -820,17 +811,6 @@ fn parry(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Res } -fn evade(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { - let evade = CrypEffect { effect: Effect::Evasion, duration: Effect::Evasion.duration(), tick: None }; - resolution.results.push(target.add_effect(Skill::Evade, evade)); - return resolution; -} - -fn evade_roll() -> bool { - let mut rng = thread_rng(); - return rng.gen_bool(0.5); -} - fn snare(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { let snare = CrypEffect { effect: Effect::Snare, duration: Effect::Snare.duration(), tick: None }; resolution.results.push(target.add_effect(Skill::Snare, snare));