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, Str,
Agi, Agi,
Int, Int,
Hp,
Stamina,
PhysicalDamage, PhysicalDamage,
PhysicalDamageTaken, PhysicalDamageTaken,
SpellDamage, SpellDamage,
SpellDamageTaken, SpellDamageTaken,
Hp, Healing,
Stamina, HealingTaken,
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -327,41 +329,54 @@ impl Cryp {
self.stamina.base self.stamina.base
} }
// Stat modifications pub fn heal(&mut self, skill: Skill, amount: u64) -> ResolutionResult {
pub fn heal(&mut self, amount: u64) -> (u64, u64) { let immunity = self.immune(skill);
let current_hp = self.hp(); let immune = immunity.immune;
let new_hp = *[
self.hp().saturating_add(amount),
self.stamina()
].iter().min().unwrap();
self.hp.set(new_hp); if immune {
ResolutionResult::Healing {
let healing = new_hp - current_hp; amount: 0,
let overhealing = amount - healing; overhealing: 0,
return (healing, overhealing); category: Category::PhysHeal,
immunity: immunity.clone(),
};
} }
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) { let healing_mods = self.effects.iter()
let phys_dmg_mods = self.effects.iter() .filter(|e| e.effect.modifications().contains(&Stat::HealingTaken))
.filter(|e| e.effect.modifications().contains(&Stat::PhysicalDamageTaken))
.map(|cryp_effect| cryp_effect.effect) .map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<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 immunity = self.immune(skill);
let immune = immunity.immune; let immune = immunity.immune;
if immune { if immune {
return ResolutionResult::Damage { return ResolutionResult::Damage {
amount, amount: 0,
category: Category::PhysDmg, category: Category::PhysDmg,
immunity, 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() let spell_dmg_mods = self.effects.iter()
.filter(|e| e.effect.modifications().contains(&Stat::SpellDamageTaken)) .filter(|e| e.effect.modifications().contains(&Stat::SpellDamageTaken))
.map(|cryp_effect| cryp_effect.effect) .map(|cryp_effect| cryp_effect.effect)
.collect::<Vec<Effect>>(); .collect::<Vec<Effect>>();
println!("{:?}", spell_dmg_mods);
let modified_spell_dmg = spell_dmg_mods.iter().fold(amount, |acc, m| m.apply(acc)); let modified_spell_dmg = spell_dmg_mods.iter().fold(amount, |acc, m| m.apply(acc));
self.hp.reduce(modified_spell_dmg); 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 { 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)), 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 { match immunity.immune {
true => self.log.push(format!("{:} {:?} {:} immune {:?}", source.name, cast.skill, target.name, immunity.effects)), 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 } => { ResolutionResult::Effect { effect, duration, immunity } => {

View File

@ -82,7 +82,7 @@ impl Disable {
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub enum ResolutionResult { pub enum ResolutionResult {
Damage { amount: u64, category: Category , immunity: Immunity }, 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 }, Effect { effect: Effect, duration: u8, immunity: Immunity },
Removal { effect: Effect, immunity: Immunity }, Removal { effect: Effect, immunity: Immunity },
} }
@ -210,7 +210,6 @@ impl Effect {
// roll little endian bits // roll little endian bits
// and OR with base stat // and OR with base stat
pub fn apply(&self, value: u64) -> u64 { pub fn apply(&self, value: u64) -> u64 {
println!("{:?} {:?} {:?}", self, value, value >> 1);
match self { match self {
Effect::Empower => value << 1, Effect::Empower => value << 1,
Effect::Vulnerable => value << 1, Effect::Vulnerable => value << 1,
@ -774,7 +773,7 @@ impl Skill {
fn attack(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { fn attack(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.phys_dmg(); 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; return resolution;
} }
@ -834,22 +833,6 @@ fn empower(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> R
// TODO put overhealing back // TODO put overhealing back
fn heal(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { fn heal(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.phys_dmg(); 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; 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 { fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg().wrapping_div(2); let amount = cryp.spell_dmg().wrapping_div(2);
let immunity = target.immune(Skill::TriageTick); resolution.results.push(target.heal(Skill::TriageTick, amount));
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; return resolution;
} }
fn blast(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution { fn blast(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg(); let amount = cryp.spell_dmg();
let immunity = target.immune(Skill::Blast); resolution.results.push(target.deal_spell_dmg(Skill::Blast, amount));
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);
}
return resolution; 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 { fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg(); let amount = cryp.spell_dmg();
let immunity = target.immune(Skill::DecayTick); resolution.results.push(target.deal_spell_dmg(Skill::DecayTick, amount));
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);
}
return resolution; return resolution;
} }
fn hex(_cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> 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 hex = CrypEffect { effect: Effect::Hex, duration: Effect::Hex.duration(), tick: None };
let immunity = target.immune(Skill::Hex); resolution.results.push(target.add_effect(Skill::Hex, 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);
}
return resolution;; 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 { fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, mut resolution: Resolution) -> Resolution {
let amount = cryp.spell_dmg().wrapping_div(2); let amount = cryp.spell_dmg();
let immunity = target.immune(Skill::DrainTick); let drain_dmg = target.deal_spell_dmg(Skill::DrainTick, amount);
let immune = immunity.immune; resolution.results.push(drain_dmg.clone());
let drain_tick_dmg_result = ResolutionResult::Damage { match drain_dmg {
amount, ResolutionResult::Damage { amount, category: _, immunity } => {
category: Category::SpellDmg, if !immunity.immune {
immunity: immunity.clone(), resolution.results.push(cryp.heal(Skill::Heal, amount));
}; }
},
let drain_tick_heal_result = ResolutionResult::Healing { _ => panic!("drain tick dmg not dealt {:?}", drain_dmg),
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);
} }
return resolution; return resolution;
@ -1090,7 +1003,7 @@ mod tests {
.learn(Skill::Heal) .learn(Skill::Heal)
.create(); .create();
x.deal_phys_dmg(5); x.deal_phys_dmg(Skill::Attack, 5);
heal(&mut y, &mut x, Resolution::new(Skill::Heal)); heal(&mut y, &mut x, Resolution::new(Skill::Heal));
} }
@ -1158,7 +1071,7 @@ mod tests {
// ensure it doesn't have 0 sd // ensure it doesn't have 0 sd
x.spell_dmg.set(50); x.spell_dmg.set(50);
y.deal_phys_dmg(5); y.deal_phys_dmg(Skill::Attack, 5);
let prev_hp = y.hp(); let prev_hp = y.hp();
let res = Resolution::new(Skill::Triage); let res = Resolution::new(Skill::Triage);