add effect method

This commit is contained in:
ntr 2018-12-17 22:44:42 +11:00
parent 2b1fc76f58
commit 9c3264cdb1
3 changed files with 116 additions and 258 deletions

View File

@ -9,7 +9,7 @@ use failure::err_msg;
use account::Account;
use rpc::{CrypSpawnParams, CrypLearnParams, CrypForgetParams};
use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable};
use skill::{Skill, Cooldown, Effect, Cast, Category, Immunity, Disable, ResolutionResult};
use game::{Log};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -41,8 +41,10 @@ pub enum Stat {
Str,
Agi,
Int,
PhysDmg,
SpellDmg,
PhysicalDamage,
PhysicalDamageTaken,
SpellDamage,
SpellDamageTaken,
Hp,
Stamina,
}
@ -98,8 +100,8 @@ impl Cryp {
return Cryp {
id,
account: id,
phys_dmg: CrypStat { base: 0, stat: Stat::PhysDmg },
spell_dmg: CrypStat { base: 0, stat: Stat::SpellDmg },
phys_dmg: CrypStat { base: 0, stat: Stat::PhysicalDamage },
spell_dmg: CrypStat { base: 0, stat: Stat::SpellDamage },
stamina: CrypStat { base: 0, stat: Stat::Stamina },
hp: CrypStat { base: 0, stat: Stat::Hp },
lvl: 0,
@ -298,8 +300,7 @@ impl Cryp {
// Stats
pub fn phys_dmg(&self) -> u64 {
let phys_dmg_mods = self.effects.iter()
.filter(|e| e.effect.category() == Category::PhysBuff)
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
.filter(|e| e.effect.modifications().contains(&Stat::PhysicalDamage))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
@ -310,8 +311,7 @@ impl Cryp {
pub fn spell_dmg(&self) -> u64 {
let spell_dmg_mods = self.effects.iter()
.filter(|e| e.effect.category() == Category::SpellBuff)
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
.filter(|e| e.effect.modifications().contains(&Stat::SpellDamage))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
@ -344,8 +344,7 @@ impl Cryp {
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
let phys_dmg_mods = self.effects.iter()
.filter(|e| e.effect.category() == Category::PhysDebuff)
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
.filter(|e| e.effect.modifications().contains(&Stat::PhysicalDamageTaken))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
@ -356,10 +355,39 @@ impl Cryp {
return (modified_phys_dmg, 0);
}
pub fn deal_phys_dmg_res(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
let immunity = self.immune(skill);
let immune = immunity.immune;
if immune {
return ResolutionResult::Damage {
amount,
category: Category::PhysDmg,
immunity,
};
}
let phys_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::PhysicalDamageTaken))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
println!("{:?}", phys_dmg_mods);
let modified_phys_dmg = phys_dmg_mods.iter().fold(amount, |acc, m| m.apply(acc));
self.hp.reduce(modified_phys_dmg);
return ResolutionResult::Damage {
amount: modified_phys_dmg,
category: Category::PhysDmg,
immunity,
};
}
pub fn deal_spell_dmg(&mut self, amount: u64) -> (u64, u64) {
let spell_dmg_mods = self.effects.iter()
.filter(|e| e.effect.category() == Category::SpellDebuff)
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
.filter(|e| e.effect.modifications().contains(&Stat::SpellDamageTaken))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
@ -370,6 +398,24 @@ impl Cryp {
return (modified_spell_dmg, 0);
}
pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult {
let immunity = self.immune(skill);
let immune = immunity.immune;
// todo modified durations cause of buffs
let result = ResolutionResult::Effect {
effect: effect.effect,
duration: effect.effect.duration(),
immunity,
};
if !immune {
self.effects.push(effect);
}
return result;
}
}
pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Cryp, Error> {

View File

@ -13,7 +13,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, Effect, ResolutionResult};
use skill::{Skill, Cast, ResolutionResult};
pub type Log = Vec<String>;
@ -935,25 +935,25 @@ mod tests {
}
fn create_2v2_test_game() -> Game {
let mut i = Cryp::new()
let i = Cryp::new()
.named(&"pretaliate".to_string())
.level(8)
.learn(Skill::TestTouch)
.create();
let mut j = Cryp::new()
let j = Cryp::new()
.named(&"poy sian".to_string())
.level(8)
.learn(Skill::TestTouch)
.create();
let mut x = Cryp::new()
let x = Cryp::new()
.named(&"pronounced \"creeep\"".to_string())
.level(8)
.learn(Skill::TestTouch)
.create();
let mut y = Cryp::new()
let y = Cryp::new()
.named(&"lemongrass tea".to_string())
.level(8)
.learn(Skill::TestTouch)
@ -1140,7 +1140,7 @@ mod tests {
game.resolve_phase_start();
// should not be stunned because of block
// should not be stunned because of parry
assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
}

View File

@ -196,12 +196,12 @@ impl Effect {
pub fn modifications(&self) -> Vec<Stat> {
match self {
Effect::Empower => vec![Stat::PhysDmg],
Effect::Vulnerable => vec![Stat::PhysDmg],
Effect::Block => vec![Stat::PhysDmg],
Effect::Empower => vec![Stat::PhysicalDamage],
Effect::Vulnerable => vec![Stat::PhysicalDamageTaken],
Effect::Block => vec![Stat::PhysicalDamageTaken],
Effect::Amplify => vec![Stat::SpellDmg],
Effect::Curse => vec![Stat::SpellDmg],
Effect::Amplify => vec![Stat::SpellDamage],
Effect::Curse => vec![Stat::SpellDamageTaken],
_ => vec![],
}
}
@ -210,6 +210,7 @@ impl Effect {
// roll little endian bits
// and OR with base stat
pub fn apply(&self, value: u64) -> u64 {
println!("{:?} {:?} {:?}", self, value, value >> 1);
match self {
Effect::Empower => value << 1,
Effect::Vulnerable => value << 1,
@ -773,70 +774,22 @@ impl Skill {
fn attack(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.phys_dmg();
let immunity = target.immune(Skill::Attack);
let immune = immunity.immune;
let attack_result = ResolutionResult::Damage {
amount,
category: Category::PhysDmg,
immunity,
};
resolution.results.push(attack_result);
if !immune {
target.deal_phys_dmg(amount);
}
resolution.results.push(target.deal_phys_dmg_res(Skill::Attack, amount));
return resolution;
}
fn stun(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let stun = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
let immunity = target.immune(Skill::Stun);
let immune = immunity.immune;
let attack_result = ResolutionResult::Effect {
effect: stun.effect,
duration: stun.duration,
immunity,
};
resolution.results.push(attack_result);
if !immune {
target.effects.push(stun);
}
let effect = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
resolution.results.push(target.add_effect(Skill::Stun, effect));
return resolution;
}
fn throw(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let stun = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Effect::Vulnerable.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.clone(),
};
let vulnerable_result = ResolutionResult::Effect {
effect: vulnerable.effect,
duration: vulnerable.duration,
immunity,
};
resolution.results.push(stun_result);
resolution.results.push(vulnerable_result);
if !immune {
target.effects.push(stun);
target.effects.push(vulnerable);
}
resolution.results.push(target.add_effect(Skill::Throw, stun));
resolution.results.push(target.add_effect(Skill::Throw, vulnerable));
return resolution;
}
@ -844,62 +797,20 @@ fn throw(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Res
fn block(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let block = CrypEffect { effect: Effect::Block, duration: Effect::Block.duration(), tick: None };
let immunity = target.immune(Skill::Block);
let immune = immunity.immune;
let block_result = ResolutionResult::Effect {
effect: block.effect,
duration: block.duration,
immunity,
};
resolution.results.push(block_result);
if !immune {
target.effects.push(block);
}
resolution.results.push(target.add_effect(Skill::Block, block));
return resolution;
}
fn parry(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let parry = CrypEffect { effect: Effect::Parry, duration: Effect::Parry.duration(), tick: None };
let immunity = target.immune(Skill::Parry);
let immune = immunity.immune;
let result = ResolutionResult::Effect {
effect: parry.effect,
duration: parry.duration,
immunity,
};
resolution.results.push(result);
if !immune {
target.effects.push(parry);
}
let effect = CrypEffect { effect: Effect::Parry, duration: Effect::Parry.duration(), tick: None };
resolution.results.push(target.add_effect(Skill::Parry, effect));
return resolution;
}
fn evade(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let evade = CrypEffect { effect: Effect::Evasion, duration: Effect::Evasion.duration(), tick: None };
let immunity = target.immune(Skill::Evade);
let immune = immunity.immune;
let result = ResolutionResult::Effect {
effect: evade.effect,
duration: evade.duration,
immunity,
};
resolution.results.push(result);
if !immune {
target.effects.push(evade);
}
resolution.results.push(target.add_effect(Skill::Evade, evade));
return resolution;
}
@ -910,41 +821,13 @@ fn evade_roll() -> bool {
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 immunity = target.immune(Skill::Snare);
let immune = immunity.immune;
let snare_result = ResolutionResult::Effect {
effect: snare.effect,
duration: snare.duration,
immunity,
};
resolution.results.push(snare_result);
if !immune {
target.effects.push(snare);
}
resolution.results.push(target.add_effect(Skill::Snare, snare));
return resolution;
}
fn empower(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let empower = CrypEffect { effect: Effect::Empower, duration: Effect::Empower.duration(), tick: None };
let immunity = target.immune(Skill::Empower);
let immune = immunity.immune;
let snare_result = ResolutionResult::Effect {
effect: empower.effect,
duration: empower.duration,
immunity,
};
resolution.results.push(snare_result);
if !immune {
target.effects.push(empower);
}
resolution.results.push(target.add_effect(Skill::Empower, empower));
return resolution;
}
@ -1038,21 +921,7 @@ fn blast(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Reso
fn amplify(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amplify = CrypEffect { effect: Effect::Amplify, duration: Effect::Amplify.duration(), tick: None };
let immunity = target.immune(Skill::Amplify);
let immune = immunity.immune;
let amplify_result = ResolutionResult::Effect {
effect: amplify.effect,
duration: amplify.duration,
immunity,
};
resolution.results.push(amplify_result);
if !immune {
target.effects.push(amplify);
}
resolution.results.push(target.add_effect(Skill::Amplify, amplify));
return resolution;;
}
@ -1062,21 +931,7 @@ fn decay(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Reso
duration: Effect::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,
duration: decay.duration,
immunity,
};
resolution.results.push(decay_result);
if !immune {
target.effects.push(decay);
}
resolution.results.push(target.add_effect(Skill::Decay, decay));
return resolution;
}
@ -1122,21 +977,7 @@ fn hex(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resol
fn curse(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let curse = CrypEffect { effect: Effect::Curse, duration: Effect::Curse.duration(), tick: None };
let immunity = target.immune(Skill::Curse);
let immune = immunity.immune;
let curse_result = ResolutionResult::Effect {
effect: curse.effect,
duration: curse.duration,
immunity,
};
resolution.results.push(curse_result);
if !immune {
target.effects.push(curse);
}
resolution.results.push(target.add_effect(Skill::Curse, curse));
return resolution;;
}
@ -1146,21 +987,7 @@ fn drain(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Reso
duration: Effect::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,
duration: drain.duration,
immunity,
};
resolution.results.push(drain_result);
if !immune {
target.effects.push(drain);
}
resolution.results.push(target.add_effect(Skill::Drain, drain));
return resolution;;
}
@ -1196,41 +1023,13 @@ fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) ->
fn shield(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let shield = CrypEffect { effect: Effect::Shield, duration: Effect::Shield.duration(), tick: None };
let immunity = target.immune(Skill::Shield);
let immune = immunity.immune;
let shield_result = ResolutionResult::Effect {
effect: shield.effect,
duration: shield.duration,
immunity,
};
resolution.results.push(shield_result);
if !immune {
target.effects.push(shield);
}
resolution.results.push(target.add_effect(Skill::Shield, shield));
return resolution;
}
fn silence(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let silence = CrypEffect { effect: Effect::Silence, duration: Effect::Silence.duration(), tick: None };
let immunity = target.immune(Skill::Silence);
let immune = immunity.immune;
let silence_result = ResolutionResult::Effect {
effect: silence.effect,
duration: silence.duration,
immunity,
};
resolution.results.push(silence_result);
if !immune {
target.effects.push(silence);
}
resolution.results.push(target.add_effect(Skill::Silence, silence));
return resolution;
}
@ -1268,21 +1067,7 @@ fn purify(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Re
fn banish(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let banish = CrypEffect { effect: Effect::Banish, duration: Effect::Banish.duration(), tick: None };
let immunity = target.immune(Skill::Banish);
let immune = immunity.immune;
let banish_result = ResolutionResult::Effect {
effect: banish.effect,
duration: banish.duration,
immunity,
};
resolution.results.push(banish_result);
if !immune {
target.effects.push(banish);
}
resolution.results.push(target.add_effect(Skill::Banish, banish));
return resolution;
}
@ -1332,6 +1117,33 @@ mod tests {
// assert!(y.hp() == y.stamina().saturating_sub(decay.unwrap().tick.unwrap().amount));
}
#[test]
fn block_test() {
let mut x = Cryp::new()
.named(&"muji".to_string())
.level(8)
.create();
let mut y = Cryp::new()
.named(&"camel".to_string())
.level(8)
.create();
// ensure it doesn't have 0 pd
x.phys_dmg.set(100);
y.hp.set(500);
block(&mut y.clone(), &mut y, Resolution::new(Skill::Block));
assert!(y.effects.iter().any(|e| e.effect == Effect::Block));
let res = attack(&mut x, &mut y, Resolution::new(Skill::Attack));
match res.results[0] {
ResolutionResult::Damage { amount, category: _, immunity: _ } => assert_eq!(amount, 50),
_ => panic!("not damage"),
};
}
#[test]
fn triage_test() {
let mut x = Cryp::new()