This commit is contained in:
ntr 2019-01-12 00:13:30 +11:00
parent 5b07922a3a
commit 5b98ce151a
6 changed files with 56 additions and 57 deletions

View File

@ -168,10 +168,6 @@ module.exports = {
description: 'drain hp from target cryp with a spell damage based debuff' }, description: 'drain hp from target cryp with a spell damage based debuff' },
{ name: 'Empower', { name: 'Empower',
description: 'increase the physical damage dealt by a cryp' }, 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', { name: 'Haste',
description: 'magical skill that increases speed of target cryp' }, description: 'magical skill that increases speed of target cryp' },
{ name: 'Heal', description: 'heal a cryp with spell dmg' }, { name: 'Heal', description: 'heal a cryp with spell dmg' },

View File

@ -7,11 +7,15 @@
* 10d chaos maths, not rock paper scissors * 10d chaos maths, not rock paper scissors
* phys is faster and chaotic * phys is faster and chaotic
* spells are slow and reliable * spells are slow and reliable
* defensives are implicit
* armour is restored, not gained
* players can feel aggressive
# ask sam # ask sam
* icons * icons
* skill type / damage type * skill type / damage type
* skills themselves * skills themselves
* passive nodes / notables
# WORK WORK # WORK WORK

View File

@ -52,6 +52,7 @@ pub enum Stat {
HealingTaken, HealingTaken,
Armour, Armour,
SpellShield, SpellShield,
Evasion,
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -98,6 +99,7 @@ pub struct Cryp {
pub hp: CrypStat, pub hp: CrypStat,
pub armour: CrypStat, pub armour: CrypStat,
pub spell_shield: CrypStat, pub spell_shield: CrypStat,
pub evasion: CrypStat,
pub xp: u64, pub xp: u64,
pub lvl: u8, pub lvl: u8,
pub skills: Vec<CrypSkill>, pub skills: Vec<CrypSkill>,
@ -122,8 +124,9 @@ impl Cryp {
speed: CrypStat { base: 0, stat: Stat::Speed }, speed: CrypStat { base: 0, stat: Stat::Speed },
stamina: CrypStat { base: 0, stat: Stat::Stamina }, stamina: CrypStat { base: 0, stat: Stat::Stamina },
hp: CrypStat { base: 0, stat: Stat::Hp }, hp: CrypStat { base: 0, stat: Stat::Hp },
armour: CrypStat { base: 50, stat: Stat::Armour }, armour: CrypStat { base: 0, stat: Stat::Armour },
spell_shield: CrypStat { base: 50, stat: Stat::SpellShield }, spell_shield: CrypStat { base: 0, stat: Stat::SpellShield },
evasion: CrypStat { base: 0, stat: Stat::Evasion },
lvl: 0, lvl: 0,
xp: 0, xp: 0,
skills: vec![], skills: vec![],
@ -163,18 +166,18 @@ impl Cryp {
} }
} }
pub fn add_xp(mut self) -> Cryp { // pub fn add_xp(mut self) -> Cryp {
self.xp = self.xp.saturating_add(1); // self.xp = self.xp.saturating_add(1);
if self.xp.is_power_of_two() { // if self.xp.is_power_of_two() {
return self.level_up(); // return self.level_up();
} // }
self // self
} // }
pub fn level_up(mut self) -> Cryp { // pub fn level_up(mut self) -> Cryp {
self.lvl = self.lvl.saturating_add(1); // self.lvl = self.lvl.saturating_add(1);
self.create() // self.create()
} // }
pub fn roll_stat(&mut self, stat: Stat) -> &mut Cryp { pub fn roll_stat(&mut self, stat: Stat) -> &mut Cryp {
let mut rng = thread_rng(); let mut rng = thread_rng();
@ -461,7 +464,7 @@ impl Cryp {
self.hp.reduce(remainder); self.hp.reduce(remainder);
return ResolutionResult::Damage { return ResolutionResult::Damage {
amount: modified_dmg, amount: remainder,
mitigation, mitigation,
category: Category::PhysDmg, category: Category::PhysDmg,
immunity, immunity,
@ -496,7 +499,7 @@ impl Cryp {
self.hp.reduce(remainder); self.hp.reduce(remainder);
return ResolutionResult::Damage { return ResolutionResult::Damage {
amount: modified_dmg, amount: remainder,
mitigation, mitigation,
category: Category::SpellDmg, category: Category::SpellDmg,
immunity, immunity,
@ -521,6 +524,18 @@ impl Cryp {
return result; return result;
} }
pub fn evade(&self, skill: Skill) -> Option<ResolutionResult> {
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<Cryp, Error> { pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Cryp, Error> {

View File

@ -351,8 +351,8 @@ impl Game {
match immunity.immune { match immunity.immune {
true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}", true => self.log.push(format!("[{:}] {:} {:?} {:} immune {:?}",
cast.resolution.speed, source.name, cast.skill, target.name, immunity.effects)), cast.resolution.speed, source.name, cast.skill, target.name, immunity.effects)),
false => self.log.push(format!("[{:}] {:} {:?} {:} {:}", false => self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:} mitigated)",
cast.resolution.speed, source.name, cast.skill, target.name, amount)), cast.resolution.speed, source.name, cast.skill, target.name, amount, mitigation)),
} }
}, },
ResolutionResult::Healing { amount, overhealing, category: _, immunity } => { ResolutionResult::Healing { amount, overhealing, category: _, immunity } => {
@ -379,6 +379,10 @@ impl Game {
cast.resolution.speed, source.name, target.name, effect)), 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));
},
} }
} }

View File

@ -107,7 +107,7 @@ fn zone_3v3_healer_boss(player_lvl: u8) -> Vec<Cryp> {
.named(&"coinage".to_string()) .named(&"coinage".to_string())
.level(player_lvl) .level(player_lvl)
.learn(Skill::Attack) .learn(Skill::Attack)
.learn(Skill::Evade) .learn(Skill::Parry)
.learn(Skill::Block) .learn(Skill::Block)
.create(); .create();
@ -124,7 +124,7 @@ fn zone_3v3_healer_boss(player_lvl: u8) -> Vec<Cryp> {
.named(&"quarry".to_string()) .named(&"quarry".to_string())
.level(player_lvl) .level(player_lvl)
.learn(Skill::Attack) .learn(Skill::Attack)
.learn(Skill::Evade) .learn(Skill::Parry)
.learn(Skill::Stun) .learn(Skill::Stun)
.create(); .create();

View File

@ -70,6 +70,7 @@ pub enum ResolutionResult {
Healing { amount: u64, overhealing: u64, category: Category , immunity: Immunity }, Healing { amount: u64, overhealing: u64, category: Category , immunity: Immunity },
Effect { effect: Effect, duration: u8, immunity: Immunity }, Effect { effect: Effect, duration: u8, immunity: Immunity },
Removal { effect: Effect, immunity: Immunity }, Removal { effect: Effect, immunity: Immunity },
Evasion { skill: Skill },
} }
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
@ -101,7 +102,6 @@ pub enum Effect {
Deadly, Deadly,
Vulnerable, Vulnerable,
Fury, Fury,
Evasion,
Blind, Blind,
Snare, Snare,
@ -146,11 +146,6 @@ impl Effect {
Category::Physical => false, Category::Physical => false,
_ => false, _ => false,
}, },
Effect::Evasion => match skill.category() {
Category::Spell => false,
Category::Physical => evade_roll(),
_ => false,
},
Effect::Banish => true, Effect::Banish => true,
_ => false, _ => false,
} }
@ -231,7 +226,6 @@ impl Effect {
Effect::Deadly => Category::PhysBuff, Effect::Deadly => Category::PhysBuff,
Effect::Vulnerable => Category::PhysDebuff, Effect::Vulnerable => Category::PhysDebuff,
Effect::Fury => Category::PhysBuff, Effect::Fury => Category::PhysBuff,
Effect::Evasion => Category::PhysBuff,
Effect::Blind => Category::PhysDebuff, Effect::Blind => Category::PhysDebuff,
Effect::Snare => Category::PhysDebuff, Effect::Snare => Category::PhysDebuff,
@ -266,7 +260,6 @@ impl Effect {
pub fn duration(&self) -> u8 { pub fn duration(&self) -> u8 {
match self { match self {
Effect::Evasion => 1,
Effect::Block => 1, Effect::Block => 1,
Effect::Parry => 1, Effect::Parry => 1,
@ -330,8 +323,7 @@ pub enum Skill {
Strangle, // physical dot and disable Strangle, // physical dot and disable
Stun, Stun,
Evade, // actively evade // Evade, // actively evade
Evasion, // adds evasion to cryp
// ----------------- // -----------------
@ -419,8 +411,6 @@ impl Skill {
// Strangle // Strangle
Skill::Stun => Some(1), Skill::Stun => Some(1),
Skill::Evade => None,
Skill::Evasion => None, // additional layer of dmg avoidance
// ----------------- // -----------------
// Technology // Technology
@ -497,7 +487,6 @@ impl Skill {
// Nature // Nature
// ----------------- // -----------------
Skill::Block => Category::Physical, // reduce dmg Skill::Block => Category::Physical, // reduce dmg
Skill::Evade => Category::Physical,
Skill::Parry => Category::Physical, // avoid all dmg Skill::Parry => Category::Physical, // avoid all dmg
Skill::Snare => Category::Physical, Skill::Snare => Category::Physical,
@ -507,7 +496,6 @@ impl Skill {
// Strangle // Strangle
Skill::Stun => Category::Physical, Skill::Stun => Category::Physical,
Skill::Evasion => Category::Physical, // additional layer of dmg avoidance
// ----------------- // -----------------
// Technology // Technology
@ -592,7 +580,6 @@ impl Skill {
// defensive block // defensive block
Skill::Block => 10, // reduce dmg Skill::Block => 10, // reduce dmg
Skill::Evade => 10,
Skill::Parry => 10, // avoid all dmg Skill::Parry => 10, // avoid all dmg
Skill::Snare => 10, Skill::Snare => 10,
Skill::Shield => 10, // avoid magic dmg, Skill::Shield => 10, // avoid magic dmg,
@ -606,7 +593,6 @@ impl Skill {
Skill::Decay => 5, // dot Skill::Decay => 5, // dot
// magic combat trickery // magic combat trickery
Skill::Evasion => 3, // additional layer of dmg avoidance
Skill::Triage => 3, // hot Skill::Triage => 3, // hot
Skill::Slow => 3, Skill::Slow => 3,
Skill::Fear => 2, Skill::Fear => 2,
@ -664,7 +650,7 @@ impl Skill {
let speed = source.skill_speed(*self); 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() { if target.is_ko() {
return resolution; return resolution;
@ -674,6 +660,16 @@ impl Skill {
return resolution; return resolution;
} }
match self.category() == Category::Physical {
true => {
if let Some(evasion) = target.evade(*self) {
resolution.results.push(evasion);
return resolution;
}
},
false => (),
}
match self { match self {
Skill::Attack => attack(source, target, resolution), Skill::Attack => attack(source, target, resolution),
// ----------------- // -----------------
@ -681,14 +677,12 @@ impl Skill {
// ----------------- // -----------------
Skill::Block => block(source, target, resolution), Skill::Block => block(source, target, resolution),
Skill::Parry => parry(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::Snare => snare(source, target, resolution), // TODO prevent physical moves
Skill::Paralyse => panic!("nyi"), // no physical moves Skill::Paralyse => panic!("nyi"), // no physical moves
Skill::Strangle => panic!("nyi"), // no physical moves Skill::Strangle => panic!("nyi"), // no physical moves
Skill::Stun => stun(source, target, resolution), Skill::Stun => stun(source, target, resolution),
Skill::Evasion => evade(source, target, resolution), // additional layer of dmg avoidance
// ----------------- // -----------------
// Technology // Technology
@ -760,7 +754,6 @@ impl Skill {
pub fn self_targeting(&self) -> bool { pub fn self_targeting(&self) -> bool {
match self { match self {
Skill::Block => true, Skill::Block => true,
Skill::Evasion => true,
Skill::Parry => true, Skill::Parry => true,
Skill::TestBlock => true, Skill::TestBlock => true,
Skill::TestParry => true, Skill::TestParry => true,
@ -775,10 +768,8 @@ impl Skill {
Skill::Empower | Skill::Empower |
Skill::Purify | Skill::Purify |
Skill::Calm | Skill::Calm |
Skill::Evasion |
Skill::Parry | Skill::Parry |
Skill::Block | Skill::Block => true,
Skill::Evade => true,
_ => false, _ => 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 { fn snare(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let snare = CrypEffect { effect: Effect::Snare, duration: Effect::Snare.duration(), tick: None }; let snare = CrypEffect { effect: Effect::Snare, duration: Effect::Snare.duration(), tick: None };
resolution.results.push(target.add_effect(Skill::Snare, snare)); resolution.results.push(target.add_effect(Skill::Snare, snare));