reflection log fix

This commit is contained in:
ntr 2019-03-26 15:01:41 +11:00
parent d3e0fd2f3c
commit 792e781711
2 changed files with 70 additions and 65 deletions

View File

@ -429,7 +429,7 @@ impl Game {
for target_id in targets { for target_id in targets {
// let mut source = game.cryp_by_id(self.source_cryp_id).unwrap(); // let mut source = game.cryp_by_id(self.source_cryp_id).unwrap();
let mut target = self.cryp_by_id(target_id).unwrap(); let mut target = self.cryp_by_id(target_id).unwrap();
resolutions.append(&mut cast.skill.resolve(&mut source, target)); resolutions = cast.skill.resolve(&mut source, target, resolutions);
} }
resolutions.reverse(); resolutions.reverse();
@ -513,7 +513,7 @@ impl Game {
speed, source.name, skill, target.name, amount, mitigation)), speed, source.name, skill, target.name, amount, mitigation)),
Event::Healing { skill, amount, overhealing } => Event::Healing { skill, amount, overhealing } =>
self.log.push(format!("[{:}] {:} {:?} {:} {:} ({:}OH)", self.log.push(format!("[{:}] {:} {:?} {:} {:} healing ({:}OH)",
speed, source.name, skill, target.name, amount, overhealing)), speed, source.name, skill, target.name, amount, overhealing)),
Event::Inversion { skill } => Event::Inversion { skill } =>

View File

@ -610,114 +610,112 @@ impl Skill {
} }
} }
pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp) -> Resolutions { pub fn resolve(&self, source: &mut Cryp, target: &mut Cryp, mut resolutions: Vec<Resolution>) -> Resolutions {
let mut rng = thread_rng(); let mut rng = thread_rng();
let _base: u64 = rng.gen(); let _base: u64 = rng.gen();
let mut results = vec![];
if let Some(disable) = source.disabled(*self) { if let Some(disable) = source.disabled(*self) {
results.push(Resolution::new(source, target).event(Event::Disable { disable, skill: *self })); resolutions.push(Resolution::new(source, target).event(Event::Disable { disable, skill: *self }));
return results; return resolutions;
} }
if target.is_ko() { if target.is_ko() {
results.push(Resolution::new(source, target).event(Event::TargetKo { skill: *self })); resolutions.push(Resolution::new(source, target).event(Event::TargetKo { skill: *self }));
return results; return resolutions;
} }
if target.affected(Effect::Reflect) { if target.affected(Effect::Reflect) {
// guard against overflow // guard against overflow
if source.affected(Effect::Reflect) { if source.affected(Effect::Reflect) {
return results; return resolutions;
} }
results.push(Resolution::new(source, target).event(Event::Reflection { skill: *self })); resolutions.push(Resolution::new(source, target).event(Event::Reflection { skill: *self }));
return self.resolve(target, source); return self.resolve(target, source, resolutions);
} }
// match self.category() == Category::Red { // match self.category() == Category::Red {
// true => { // true => {
// if let Some(evasion) = target.evade(*self) { // if let Some(evasion) = target.evade(*self) {
// results.push(evasion); // resolutions.push(evasion);
// return Event; // return Event;
// } // }
// }, // },
// false => (), // false => (),
// } // }
results = match self { resolutions = match self {
Skill::Amplify => amplify(source, target, results), // increase magic damage Skill::Amplify => amplify(source, target, resolutions), // increase magic damage
Skill::Attack => attack(source, target, results), Skill::Attack => attack(source, target, resolutions),
Skill::Banish => banish(source, target, results), // TODO prevent all actions Skill::Banish => banish(source, target, resolutions), // TODO prevent all actions
Skill::Blast => blast(source, target, results), Skill::Blast => blast(source, target, resolutions),
Skill::Block => block(source, target, results), Skill::Block => block(source, target, resolutions),
Skill::Curse => curse(source, target, results), Skill::Curse => curse(source, target, resolutions),
Skill::Decay => decay(source, target, results), // dot Skill::Decay => decay(source, target, resolutions), // dot
Skill::DecayTick => decay_tick(source, target, results), // dot Skill::DecayTick => decay_tick(source, target, resolutions), // dot
Skill::Empower => empower(source, target, results), // increased phys damage Skill::Empower => empower(source, target, resolutions), // increased phys damage
Skill::Haste => haste(source, target, results), // speed slow Skill::Haste => haste(source, target, resolutions), // speed slow
Skill::Heal => heal(source, target, results), Skill::Heal => heal(source, target, resolutions),
Skill::Hex => hex(source, target, results), // todo prevent casting Skill::Hex => hex(source, target, resolutions), // todo prevent casting
Skill::Invert => invert(source, target, results), // todo prevent casting Skill::Invert => invert(source, target, resolutions), // todo prevent casting
Skill::Parry => parry(source, target, results), Skill::Parry => parry(source, target, resolutions),
Skill::Purge => purge(source, target, results), // dispel all buffs Skill::Purge => purge(source, target, resolutions), // dispel all buffs
Skill::Purify => purify(source, target, results), // dispel all debuffs Skill::Purify => purify(source, target, resolutions), // dispel all debuffs
Skill::Recharge => recharge(source, target, results), // target is immune to magic damage and fx Skill::Recharge => recharge(source, target, resolutions), // target is immune to magic damage and fx
Skill::Shield => shield(source, target, results), // target is immune to magic damage and fx Skill::Shield => shield(source, target, resolutions), // target is immune to magic damage and fx
Skill::Silence => silence(source, target, results), // target cannot cast spells Skill::Silence => silence(source, target, resolutions), // target cannot cast spells
Skill::Siphon => siphon(source, target, results), Skill::Siphon => siphon(source, target, resolutions),
Skill::SiphonTick => siphon_tick(source, target, results), // hot Skill::SiphonTick => siphon_tick(source, target, resolutions), // hot
Skill::Slow => slow(source, target, results), // speed slow Skill::Slow => slow(source, target, resolutions), // speed slow
Skill::Snare => snare(source, target, results), // TODO prevent physical moves Skill::Snare => snare(source, target, resolutions), // TODO prevent physical moves
Skill::Strike => strike(source, target, results), Skill::Strike => strike(source, target, resolutions),
Skill::Stun => stun(source, target, results), Skill::Stun => stun(source, target, resolutions),
Skill::Throw => throw(source, target, results), // no damage stun, adds vulnerable Skill::Throw => throw(source, target, resolutions), // no damage stun, adds vulnerable
Skill::Triage => triage(source, target, results), // hot Skill::Triage => triage(source, target, resolutions), // hot
Skill::TriageTick => triage_tick(source, target, results), // hot Skill::TriageTick => triage_tick(source, target, resolutions), // hot
Skill::Clutch => clutch(source, target, results), Skill::Clutch => clutch(source, target, resolutions),
Skill::Strangle => strangle(source, target, results), Skill::Strangle => strangle(source, target, resolutions),
Skill::StrangleTick => strangle_tick(source, target, results), Skill::StrangleTick => strangle_tick(source, target, resolutions),
Skill::Reflect => reflect(source, target, results), Skill::Reflect => reflect(source, target, resolutions),
Skill::Ruin => ruin(source, target, results), Skill::Ruin => ruin(source, target, resolutions),
Skill::Slay => unimplemented!(), Skill::Slay => unimplemented!(),
Skill::Taunt => taunt(source, target, results), Skill::Taunt => taunt(source, target, resolutions),
Skill::Corrupt => corrupt(source, target, results), Skill::Corrupt => corrupt(source, target, resolutions),
Skill::Corruption => panic!("corruption should not be castable"), Skill::Corruption => panic!("corruption should not be castable"),
Skill::CorruptionTick => corruption_tick(source, target, results), Skill::CorruptionTick => corruption_tick(source, target, resolutions),
// ----------------- // -----------------
// Test // Test
// ----------------- // -----------------
Skill::TestTouch => touch(source, target, results), Skill::TestTouch => touch(source, target, resolutions),
Skill::TestStun => stun(source, target, results), Skill::TestStun => stun(source, target, resolutions),
Skill::TestBlock => block(source, target, results), Skill::TestBlock => block(source, target, resolutions),
Skill::TestParry => parry(source, target, results), Skill::TestParry => parry(source, target, resolutions),
Skill::TestSiphon => siphon(source, target, results), Skill::TestSiphon => siphon(source, target, resolutions),
}; };
// if any event dealt damage to target cryp // if any event dealt damage to target cryp
// hit them with corruption // hit them with corruption
results = match target.affected(Effect::Corrupt) { resolutions = match target.affected(Effect::Corrupt) {
true => match results.iter().any(|r| true => match resolutions.iter().any(|r|
match r.event { match r.event {
Event::Damage { amount: _, mitigation: _, category: _, skill: _ } => true, Event::Damage { amount: _, mitigation: _, category: _, skill: _ } => true,
_ => false, _ => false,
}) { }) {
true => corruption(target, source, results), true => corruption(target, source, resolutions),
false => results, false => resolutions,
}, },
false => results, false => resolutions,
}; };
// i don't think we need to check the source being ko // i don't think we need to check the source being ko
if target.is_ko() { if target.is_ko() {
results.push(Resolution::new(source, target).event(Event::Ko)); resolutions.push(Resolution::new(source, target).event(Event::Ko));
target.effects.clear(); target.effects.clear();
} }
return results; return resolutions;
} }
pub fn self_targeting(&self) -> bool { pub fn self_targeting(&self) -> bool {
@ -1195,10 +1193,17 @@ mod tests {
reflect(&mut y.clone(), &mut y, vec![]); reflect(&mut y.clone(), &mut y, vec![]);
assert!(y.affected(Effect::Reflect)); assert!(y.affected(Effect::Reflect));
let mut results = Skill::Attack.resolve(&mut x, &mut y); let mut results = vec![];
results = Skill::Attack.resolve(&mut x, &mut y, results);
assert!(x.hp() == 768); assert!(x.hp() == 768);
let Resolution { source: _, target: _, event } = results.remove(0);
match event {
Event::Reflection { skill } => assert_eq!(skill, Skill::Attack),
_ => panic!("not reflection"),
};
let Resolution { source: _, target: _, event } = results.remove(0); let Resolution { source: _, target: _, event } = results.remove(0);
match event { match event {
Event::Damage { amount, mitigation: _, category: _, skill: _ } => assert_eq!(amount, 256), Event::Damage { amount, mitigation: _, category: _, skill: _ } => assert_eq!(amount, 256),
@ -1217,7 +1222,7 @@ mod tests {
corrupt(&mut y.clone(), &mut y, vec![]); corrupt(&mut y.clone(), &mut y, vec![]);
assert!(y.affected(Effect::Corrupt)); assert!(y.affected(Effect::Corrupt));
let _results = Skill::Attack.resolve(&mut x, &mut y); Skill::Attack.resolve(&mut x, &mut y, vec![]);
assert!(x.affected(Effect::Corruption)); assert!(x.affected(Effect::Corruption));
} }
@ -1240,7 +1245,7 @@ mod tests {
y.deal_red_damage(Skill::Attack, 5); y.deal_red_damage(Skill::Attack, 5);
let prev_hp = y.hp(); let prev_hp = y.hp();
let _results = triage(&mut x, &mut y, vec![]); triage(&mut x, &mut y, vec![]);
assert!(y.effects.iter().any(|e| e.effect == Effect::Triage)); assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
assert!(y.hp() > prev_hp); assert!(y.hp() > prev_hp);