big skill rework simplification

This commit is contained in:
ntr 2018-12-17 23:23:23 +11:00
parent 9c3264cdb1
commit 9f5a736cf8
3 changed files with 77 additions and 132 deletions

View File

@ -41,12 +41,14 @@ pub enum Stat {
Str,
Agi,
Int,
Hp,
Stamina,
PhysicalDamage,
PhysicalDamageTaken,
SpellDamage,
SpellDamageTaken,
Hp,
Stamina,
Healing,
HealingTaken,
}
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -327,41 +329,54 @@ impl Cryp {
self.stamina.base
}
// Stat modifications
pub fn heal(&mut self, amount: u64) -> (u64, u64) {
let current_hp = self.hp();
let new_hp = *[
self.hp().saturating_add(amount),
self.stamina()
].iter().min().unwrap();
pub fn heal(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
let immunity = self.immune(skill);
let immune = immunity.immune;
self.hp.set(new_hp);
if immune {
ResolutionResult::Healing {
amount: 0,
overhealing: 0,
category: Category::PhysHeal,
immunity: immunity.clone(),
};
}
let healing = new_hp - current_hp;
let overhealing = amount - healing;
return (healing, overhealing);
}
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
let phys_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::PhysicalDamageTaken))
let healing_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::HealingTaken))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
let modified_phys_dmg = phys_dmg_mods.iter().fold(amount, |acc, m| m.apply(acc));
println!("{:?}", healing_mods);
self.hp.reduce(modified_phys_dmg);
let modified_healing = healing_mods.iter().fold(amount, |acc, m| m.apply(acc));
return (modified_phys_dmg, 0);
let current_hp = self.hp();
let new_hp = *[
self.hp().saturating_add(modified_healing),
self.stamina()
].iter().min().unwrap();
let healing = new_hp - current_hp;
let overhealing = amount - healing;
self.hp.set(new_hp);
return ResolutionResult::Healing {
amount: healing,
overhealing,
category: Category::PhysHeal,
immunity,
};
}
pub fn deal_phys_dmg_res(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
pub fn deal_phys_dmg(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
let immunity = self.immune(skill);
let immune = immunity.immune;
if immune {
return ResolutionResult::Damage {
amount,
amount: 0,
category: Category::PhysDmg,
immunity,
};
@ -385,17 +400,34 @@ impl Cryp {
};
}
pub fn deal_spell_dmg(&mut self, amount: u64) -> (u64, u64) {
pub fn deal_spell_dmg(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
let immunity = self.immune(skill);
let immune = immunity.immune;
if immune {
return ResolutionResult::Damage {
amount: 0,
category: Category::SpellDmg,
immunity,
};
}
let spell_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::SpellDamageTaken))
.map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>();
println!("{:?}", spell_dmg_mods);
let modified_spell_dmg = spell_dmg_mods.iter().fold(amount, |acc, m| m.apply(acc));
self.hp.reduce(modified_spell_dmg);
return (modified_spell_dmg, 0);
return ResolutionResult::Damage {
amount: modified_spell_dmg,
category: Category::SpellDmg,
immunity,
};
}
pub fn add_effect(&mut self, skill: Skill, effect: CrypEffect) -> ResolutionResult {

View File

@ -435,10 +435,10 @@ impl Game {
false => self.log.push(format!("{:} {:?} {:} {:}", source.name, cast.skill, target.name, amount)),
}
},
ResolutionResult::Healing { amount, category: _, immunity } => {
ResolutionResult::Healing { amount, overhealing, category: _, immunity } => {
match immunity.immune {
true => self.log.push(format!("{:} {:?} {:} immune {:?}", source.name, cast.skill, target.name, immunity.effects)),
false => self.log.push(format!("{:} {:?} {:} {:}", source.name, cast.skill, target.name, amount)),
false => self.log.push(format!("{:} {:?} {:} {:} ({:}OH)", source.name, cast.skill, target.name, amount, overhealing)),
}
},
ResolutionResult::Effect { effect, duration, immunity } => {

View File

@ -82,7 +82,7 @@ impl Disable {
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum ResolutionResult {
Damage { amount: u64, category: Category , immunity: Immunity },
Healing { amount: u64, category: Category , immunity: Immunity },
Healing { amount: u64, overhealing: u64, category: Category , immunity: Immunity },
Effect { effect: Effect, duration: u8, immunity: Immunity },
Removal { effect: Effect, immunity: Immunity },
}
@ -210,7 +210,6 @@ 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,
@ -774,7 +773,7 @@ impl Skill {
fn attack(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.phys_dmg();
resolution.results.push(target.deal_phys_dmg_res(Skill::Attack, amount));
resolution.results.push(target.deal_phys_dmg(Skill::Attack, amount));
return resolution;
}
@ -834,22 +833,6 @@ fn empower(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> R
// TODO put overhealing back
fn heal(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.phys_dmg();
let immunity = target.immune(Skill::Heal);
let immune = immunity.immune;
let heal_result = ResolutionResult::Healing {
amount,
category: Category::PhysHeal,
immunity,
};
resolution.results.push(heal_result);
if !immune {
let (_healing, _overhealing) = target.heal(amount);
}
return resolution;
}
@ -880,42 +863,13 @@ fn triage(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Res
fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg().wrapping_div(2);
let immunity = target.immune(Skill::TriageTick);
let immune = immunity.immune;
let heal_result = ResolutionResult::Healing {
amount,
category: Category::PhysHeal,
immunity,
};
resolution.results.push(heal_result);
if !immune {
let (_healing, _overhealing) = target.heal(amount);
}
resolution.results.push(target.heal(Skill::TriageTick, amount));
return resolution;
}
fn blast(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg();
let immunity = target.immune(Skill::Blast);
let immune = immunity.immune;
let blast_result = ResolutionResult::Damage {
amount,
category: Category::SpellDmg,
immunity,
};
resolution.results.push(blast_result);
if !immune {
target.deal_spell_dmg(amount);
}
resolution.results.push(target.deal_spell_dmg(Skill::Blast, amount));
return resolution;
}
@ -937,41 +891,13 @@ fn decay(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Reso
fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg();
let immunity = target.immune(Skill::DecayTick);
let immune = immunity.immune;
let decay_tick_result = ResolutionResult::Damage {
amount,
category: Category::SpellDmg,
immunity,
};
resolution.results.push(decay_tick_result);
if !immune {
target.deal_spell_dmg(amount);
}
resolution.results.push(target.deal_spell_dmg(Skill::DecayTick, amount));
return resolution;
}
fn hex(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let hex = CrypEffect { effect: Effect::Hex, duration: Effect::Hex.duration(), tick: None };
let immunity = target.immune(Skill::Hex);
let immune = immunity.immune;
let hex_result = ResolutionResult::Effect {
effect: hex.effect,
duration: hex.duration,
immunity,
};
resolution.results.push(hex_result);
if !immune {
target.effects.push(hex);
}
resolution.results.push(target.add_effect(Skill::Hex, hex));
return resolution;;
}
@ -992,30 +918,17 @@ fn drain(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Reso
}
fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg().wrapping_div(2);
let immunity = target.immune(Skill::DrainTick);
let immune = immunity.immune;
let amount = cryp.spell_dmg();
let drain_dmg = target.deal_spell_dmg(Skill::DrainTick, amount);
resolution.results.push(drain_dmg.clone());
let drain_tick_dmg_result = ResolutionResult::Damage {
amount,
category: Category::SpellDmg,
immunity: immunity.clone(),
};
let drain_tick_heal_result = ResolutionResult::Healing {
amount,
category: Category::SpellHeal,
immunity,
};
resolution.results.push(drain_tick_dmg_result);
resolution.results.push(drain_tick_heal_result);
if !immune {
// need to saturate amount and check caster immunity to healing
target.deal_spell_dmg(amount);
let (_healing, _overhealing) = cryp.heal(amount);
match drain_dmg {
ResolutionResult::Damage { amount, category: _, immunity } => {
if !immunity.immune {
resolution.results.push(cryp.heal(Skill::Heal, amount));
}
},
_ => panic!("drain tick dmg not dealt {:?}", drain_dmg),
}
return resolution;
@ -1090,7 +1003,7 @@ mod tests {
.learn(Skill::Heal)
.create();
x.deal_phys_dmg(5);
x.deal_phys_dmg(Skill::Attack, 5);
heal(&mut y, &mut x, Resolution::new(Skill::Heal));
}
@ -1158,7 +1071,7 @@ mod tests {
// ensure it doesn't have 0 sd
x.spell_dmg.set(50);
y.deal_phys_dmg(5);
y.deal_phys_dmg(Skill::Attack, 5);
let prev_hp = y.hp();
let res = Resolution::new(Skill::Triage);