damage calculations

This commit is contained in:
ntr 2018-11-15 15:25:36 +11:00
parent ecabde3389
commit 82e49c56bf
3 changed files with 79 additions and 32 deletions

View File

@ -17,6 +17,7 @@
* skills
* offensive -> choose target ✔
* ensure cryp untargetable and doesn't resolve when KO
* calculate
* hp increase/decrease
* spell/phys dmg

View File

@ -41,31 +41,31 @@ pub enum Stat {
Str,
Agi,
Int,
PhysicalDmg,
SpellPower,
PhysDmg,
SpellDmg,
Hp,
Stam,
}
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub struct CrypStat {
value: u64,
base: u64,
pub stat: Stat,
}
impl CrypStat {
pub fn set(&mut self, v: u64) -> &CrypStat {
self.value = v;
self.base = v;
self
}
pub fn reduce(&mut self, amt: u64) -> &mut CrypStat {
self.value = self.value.saturating_sub(amt);
self.base = self.base.saturating_sub(amt);
self
}
pub fn increase(&mut self, amt: u64) -> &mut CrypStat {
self.value = self.value.saturating_add(amt);
self.base = self.base.saturating_add(amt);
self
}
@ -97,10 +97,10 @@ impl Cryp {
return Cryp {
id,
account: id,
phys_dmg: CrypStat { value: 0, stat: Stat::Str },
spell_dmg: CrypStat { value: 0, stat: Stat::Int },
stamina: CrypStat { value: 0, stat: Stat::Stam },
hp: CrypStat { value: 0, stat: Stat::Hp },
phys_dmg: CrypStat { base: 0, stat: Stat::Str },
spell_dmg: CrypStat { base: 0, stat: Stat::Int },
stamina: CrypStat { base: 0, stat: Stat::Stam },
hp: CrypStat { base: 0, stat: Stat::Hp },
lvl: 0,
xp: 0,
skills: vec![CrypSkill::new(Skill::Attack)],
@ -159,13 +159,13 @@ impl Cryp {
self.phys_dmg.set(rng.gen_range(min, max));
self.spell_dmg.set(rng.gen_range(min, max));
self.stamina.set(rng.gen_range(min, max));
self.hp.set(self.stamina.value);
self.hp.set(self.stamina.base);
self
}
pub fn is_ko(&self) -> bool {
self.hp.value == 0
self.hp.base == 0
}
pub fn immune(&self, skill: Skill) -> bool {
@ -232,25 +232,39 @@ impl Cryp {
}
pub fn rez(&mut self) -> &mut Cryp {
self.hp.set(self.stamina.value);
self.hp.set(self.stamina.base);
self
}
// Stats
pub fn phys_dmg(&self) -> u64 {
self.phys_dmg.value
let phys_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
println!("{:?} phys_dmg mods : {:?}", self.name, phys_dmg_mods);
let modified_phys_dmg = phys_dmg_mods.iter().fold(self.phys_dmg.base, |acc, m| m.apply(acc));
println!("{:?} phys_dmg : {:?}", self.name, modified_phys_dmg);
return modified_phys_dmg;
}
pub fn spell_dmg(&self) -> u64 {
self.spell_dmg.value
let spell_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
println!("{:?} spell_dmg mods : {:?}", self.name, spell_dmg_mods);
let modified_spell_dmg = spell_dmg_mods.iter().fold(self.spell_dmg.base, |acc, m| m.apply(acc));
println!("{:?} spell_dmg : {:?}", self.name, modified_spell_dmg);
return modified_spell_dmg;
}
pub fn hp(&self) -> u64 {
self.hp.value
self.hp.base
}
pub fn stamina(&self) -> u64 {
self.stamina.value
self.stamina.base
}
// Stat modifications
@ -261,6 +275,8 @@ impl Cryp {
self.stamina()
].iter().min().unwrap();
self.hp.set(new_hp);
let healing = new_hp - current_hp;
let overhealing = amount - healing;
return (healing, overhealing);
@ -268,6 +284,7 @@ impl Cryp {
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
self.hp.reduce(amount);
println!("{:?} dealt {:?} phys dmg", self.name, amount);
return (amount, 0);
}
@ -380,7 +397,7 @@ mod tests {
// ,final_str
// ,self.name
// ,blocked
// ,self.hp.value));
// ,self.hp.base));
// plr_t.log.push(format!(""));
// self
@ -400,9 +417,9 @@ mod tests {
// // finally combine with CrypStat
// log.push(format!("{:064b} <- finalised", roll.result));
// roll.result = roll.result & self.value;
// roll.result = roll.result & self.base;
// log.push(format!("{:064b} & <- attribute roll", self.value));
// log.push(format!("{:064b} & <- attribute roll", self.base));
// log.push(format!("{:064b} = {:?}", roll.result, roll.result));
// log.push(format!(""));

View File

@ -2,13 +2,12 @@ use rand::{thread_rng, Rng};
use uuid::Uuid;
use game::{Log};
use cryp::{Cryp, CrypEffect};
use cryp::{Cryp, CrypEffect, Stat};
#[derive(Debug,Clone,Copy,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<Uuid>,
pub target_team_id: Uuid,
@ -123,6 +122,20 @@ impl Effect {
_ => false,
}
}
pub fn modifications(&self) -> Vec<Stat> {
match self {
Effect::Amplify => vec![Stat::SpellDmg],
_ => vec![],
}
}
pub fn apply(&self, value: u64) -> u64 {
match self {
Effect::Amplify => value << 1,
_ => panic!("{:?} does not have a mod effect", self),
}
}
}
pub enum Damage {
@ -510,7 +523,7 @@ impl Skill {
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::Charm => panic!("nyi"), // cast random spell on teammate
Skill::Charm => panic!("nyi"), // target casts random spell on teammate
Skill::Calm => panic!("nyi"), // remove fear, taunt
Skill::Rez => panic!("nyi"),
@ -533,10 +546,10 @@ impl Skill {
// Skill::Precision => panic!("nyi"),
Skill::Inspire => panic!("nyi"), // increased phys dmg
Skill::Slay => panic!("nyi"), // phys dmg mult by target magic dmg
Skill::Shield => panic!("nyi"),
Skill::Silence => silence(cryp, target, log),
Skill::Inquiry => panic!("nyi"),
Skill::Purify => panic!("nyi"),
Skill::Shield => panic!("nyi"), // target is immune to magic dmg and fx
Skill::Silence => silence(cryp, target, log), // target cannot cast spells
Skill::Inquiry => panic!("nyi"), //
Skill::Purify => panic!("nyi"), // dispel all debuffs
// -----------------
// Chaos
@ -544,7 +557,7 @@ impl Skill {
Skill::Banish => banish(cryp, target, log), // TODO prevent all actions
Skill::Hex => hex(cryp, target, log), // todo prevent casting
Skill::Fear => panic!("nyi"), // cast random spell on self
Skill::Taunt => panic!("nyi"),
Skill::Taunt => panic!("nyi"), // target
Skill::Pause => panic!("nyi"), // speed slow
// -----------------
@ -567,6 +580,7 @@ impl Skill {
Skill::Drain => 3,
Skill::Triage => 3,
Skill::Amplify => 2,
Skill::Silence => 3,
Skill::TestBlock => 1,
@ -785,15 +799,14 @@ mod tests {
// 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);
assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
// y.reduce_effect_durations(&mut log);
// assert!(y.hp() > prev_hp);
triage_tick(&mut x, &mut y, &mut log);
assert!(y.hp() > prev_hp);
}
#[test]
@ -809,6 +822,22 @@ mod tests {
assert!(x.effects.iter().any(|e| e.effect == Effect::Silence));
assert!(!Skill::Decay.castable(&x));
}
#[test]
fn amplify_test() {
let mut x = Cryp::new()
.named(&"muji".to_string())
.level(8)
.create();
x.spell_dmg.set(50);
let mut log = vec![];
amplify(&mut x.clone(), &mut x, &mut log);
assert!(x.effects.iter().any(|e| e.effect == Effect::Amplify));
assert_eq!(x.spell_dmg(), 100);
}
}
// #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]