From d4c43ce50f4e86ac7870dc97c73087d38037477c Mon Sep 17 00:00:00 2001 From: ntr Date: Wed, 27 Mar 2019 01:02:01 +1100 Subject: [PATCH] siphon test --- server/WORKLOG.md | 9 +++----- server/src/game.rs | 22 +++++++++++++++--- server/src/skill.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 258574fc..c533abaa 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -23,15 +23,9 @@ cryp vbox consolidate buffs debuffs and disables no more red/blue -siphon test - -make parry semi-aggressive -constants -change to ownership pattern make strike *really* hit first / resolve at same time? ## SOON -* Remove debuffs on KO * Descriptions * Stats - How they work * Items - What they give @@ -66,6 +60,9 @@ make strike *really* hit first / resolve at same time? * chat * notifications * elo + leaderboards +* constants +* change to ownership pattern + $$$ * Items diff --git a/server/src/game.rs b/server/src/game.rs index 552ed08e..64451d24 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -171,6 +171,17 @@ impl Game { } } + pub fn cryp_by_id_take(&mut self, id: Uuid) -> Cryp { + match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == id)) { + Some(team) => { + let i = team.cryps.iter().position(|c| c.id == id).unwrap(); + team.cryps.remove(i) + } + None => panic!("id not in game {:}", id), + } + } + + fn all_cryps(&self) -> Vec { self.teams.clone() .into_iter() @@ -425,9 +436,12 @@ impl Game { let targets = self.get_targets(cast.skill, &source, cast.target_cryp_id); for target_id in targets { - // let mut source = game.cryp_by_id(self.source_cryp_id).unwrap(); - let mut target = self.cryp_by_id(target_id).unwrap(); - resolutions = resolve(cast.skill, &mut source, target, resolutions); + let mut source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone(); + let mut target = self.cryp_by_id(target_id).unwrap().clone(); + resolutions = resolve(cast.skill, &mut source, &mut target, resolutions); + // save the clones + self.update_cryp(&mut source); + self.update_cryp(&mut target); } resolutions.reverse(); @@ -1112,6 +1126,8 @@ mod tests { // should not be stunned because of parry assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false); + // riposte + assert!(game.team_by_id(y_team.id).cryps[0].hp() == 768); } #[test] diff --git a/server/src/skill.rs b/server/src/skill.rs index 8b4da010..b8f21ec4 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -60,6 +60,7 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio Skill::Purify => purify(source, target, resolutions), // dispel all debuffs Skill::Recharge => recharge(source, target, resolutions), // target is immune to magic damage and fx Skill::Reflect => reflect(source, target, resolutions), + Skill::Riposte => panic!("riposte should not be caste"), Skill::Ruin => ruin(source, target, resolutions), Skill::Shield => shield(source, target, resolutions), // target is immune to magic damage and fx Skill::Silence => silence(source, target, resolutions), // target cannot cast spells @@ -103,7 +104,10 @@ pub fn resolve(skill: Skill, source: &mut Cryp, target: &mut Cryp, mut resolutio if target.affected(Effect::Hostility) { resolutions = hatred(target, source, resolutions, skill, amount); } - + }, + Event::Immunity { skill: _, immunity } => match immunity.contains(&Effect::Parry) { + true => resolutions = riposte(target, source, resolutions), + false => (), }, _ => (), } @@ -493,6 +497,7 @@ pub enum Skill { // ----------------- Block, // reduce damage Parry, // avoid all damage + Riposte, Snare, Recharge, @@ -570,6 +575,7 @@ impl Skill { Skill::Strike => None, Skill::Block => None, // reduce damage Skill::Parry => None, // avoid all damage + Skill::Riposte => None, // used on parry Skill::Snare => Some(1), Skill::Stun => Some(1), Skill::Heal => None, @@ -631,6 +637,7 @@ impl Skill { // ----------------- Skill::Block => Category::Red, // reduce damage Skill::Parry => Category::Red, // avoid all damage + Skill::Riposte => Category::Red, // avoid all damage Skill::Snare => Category::Red, Skill::Clutch => Category::Red, @@ -867,6 +874,15 @@ fn parry(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Reso return results; } +fn riposte(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { + let amount = source.red_damage(); + target.deal_red_damage(Skill::Riposte, amount) + .into_iter() + .for_each(|e| results.push(Resolution::new(source, target).event(e))); + + return results; +} + fn snare(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions { let snare = CrypEffect::new(Effect::Snare); results.push(Resolution::new(source, target).event(target.add_effect(Skill::Snare, snare))); @@ -1240,6 +1256,42 @@ mod tests { }; } + #[test] + fn siphon_test() { + let mut x = Cryp::new() + .named(&"muji".to_string()); + + let mut y = Cryp::new() + .named(&"camel".to_string()); + + x.hp.reduce(512); + + let mut results = resolve(Skill::Siphon, &mut x, &mut y, vec![]); + + assert!(y.affected(Effect::Siphon)); + assert!(x.hp() == 768); + + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Effect { effect, skill: _, duration: _ } => assert_eq!(effect, Effect::Siphon), + _ => panic!("not siphon"), + }; + + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Healing { amount, skill: _, overhealing: _ } => assert_eq!(amount, 256), + _ => panic!("not healing"), + }; + + let Resolution { source: _, target: _, event } = results.remove(0); + match event { + Event::Damage { amount, skill: _, mitigation: _, category: _} => assert_eq!(amount, 256), + _ => panic!("not damage siphon"), + }; + + } + + #[test] fn corrupt_test() { let mut x = Cryp::new()