taunt & ruin fix

This commit is contained in:
ntr 2019-03-25 17:29:47 +11:00
parent d35e1ede60
commit b1f0c76f68
4 changed files with 108 additions and 47 deletions

View File

@ -297,16 +297,8 @@ impl Cryp {
self.available_skills().len() == 0
}
pub fn is_inverted(&self) -> bool {
self.effects.iter().any(|s| s.effect == Effect::Invert)
}
pub fn is_reflecting(&self) -> bool {
self.effects.iter().any(|s| s.effect == Effect::Reflect)
}
pub fn is_clutch(&self) -> bool {
self.effects.iter().any(|s| s.effect == Effect::Clutch)
pub fn affected(&self, effect: Effect) -> bool {
self.effects.iter().any(|s| s.effect == effect)
}
pub fn available_skills(&self) -> Vec<&CrypSkill> {
@ -443,7 +435,7 @@ impl Cryp {
fn reduce_hp(&mut self, amount: u64) {
self.hp.reduce(amount);
if self.is_clutch() && self.hp() == 0 {
if self.affected(Effect::Clutch) && self.hp() == 0 {
self.hp.value = 1;
}
}
@ -480,7 +472,7 @@ impl Cryp {
let modified_healing = healing_mods.iter().fold(amount, |acc, m| m.apply(acc));
match self.is_inverted() {
match self.affected(Effect::Invert) {
false => {
let current_hp = self.hp();
self.hp.increase(modified_healing);
@ -526,7 +518,7 @@ impl Cryp {
let modified_damage = red_damage_mods.iter().fold(amount, |acc, m| m.apply(acc));
match self.is_inverted() {
match self.affected(Effect::Invert) {
false => {
// calculate amount of damage red_shield will not absorb
// eg 50 red_shield 25 damage -> 0 remainder 25 mitigation
@ -585,7 +577,7 @@ impl Cryp {
// println!("{:?}", blue_damage_mods);
let modified_damage = blue_damage_mods.iter().fold(amount, |acc, m| m.apply(acc));
match self.is_inverted() {
match self.affected(Effect::Invert) {
false => {
let remainder = modified_damage.saturating_sub(self.blue_shield.value);
let mitigation = modified_damage.saturating_sub(remainder);

View File

@ -48,6 +48,11 @@ impl Team {
return required;
}
fn taunting(&self) -> Option<&Cryp> {
self.cryps.iter()
.find(|c| c.affected(Effect::Taunt))
}
pub fn set_cryps(&mut self, mut cryps: Vec<Cryp>) -> &mut Team {
cryps.sort_unstable_by_key(|c| c.id);
self.cryps = cryps;
@ -378,13 +383,11 @@ impl Game {
}
fn get_targets(&self, skill: Skill, source: &Cryp, target_cryp_id: Uuid) -> Vec<Uuid> {
// match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == id)) {
// Some(team) => team.cryps.iter_mut().find(|c| c.id == id),
// None => None,
// }
let target_team = self.teams.iter().find(|t| t.id == source.account).unwrap();
// let target_team = self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == id)).unwrap();
// let target = team.cryps.iter_mut().find(|c| c.id == id).unwrap();
if let Some(t) = target_team.taunting() {
return vec![t.id];
}
match source.skill_is_aoe(skill) {
true => self.cryp_aoe_targets(target_cryp_id),
@ -882,7 +885,7 @@ mod tests {
use cryp::*;
fn create_test_game() -> Game {
let x = Cryp::new()
let mut x = Cryp::new()
.named(&"pronounced \"creeep\"".to_string())
.learn(Skill::Attack)
.learn(Skill::TestStun)
@ -894,7 +897,7 @@ mod tests {
.learn(Skill::Stun)
.learn(Skill::Block);
let y = Cryp::new()
let mut y = Cryp::new()
.named(&"lemongrass tea".to_string())
.learn(Skill::Attack)
.learn(Skill::TestStun)
@ -913,11 +916,13 @@ mod tests {
.set_team_size(1);
let x_team_id = Uuid::new_v4();
x.account = x_team_id;
let mut x_team = Team::new(x_team_id);
x_team
.set_cryps(vec![x]);
let y_team_id = Uuid::new_v4();
y.account = y_team_id;
let mut y_team = Team::new(y_team_id);
y_team
.set_cryps(vec![y]);
@ -932,22 +937,22 @@ mod tests {
}
fn create_2v2_test_game() -> Game {
let i = Cryp::new()
let mut i = Cryp::new()
.named(&"pretaliate".to_string())
.learn(Skill::Attack)
.learn(Skill::TestTouch);
let j = Cryp::new()
let mut j = Cryp::new()
.named(&"poy sian".to_string())
.learn(Skill::Attack)
.learn(Skill::TestTouch);
let x = Cryp::new()
let mut x = Cryp::new()
.named(&"pronounced \"creeep\"".to_string())
.learn(Skill::Attack)
.learn(Skill::TestTouch);
let y = Cryp::new()
let mut y = Cryp::new()
.named(&"lemongrass tea".to_string())
.learn(Skill::Attack)
.learn(Skill::TestTouch);
@ -959,11 +964,15 @@ mod tests {
.set_team_size(2);
let i_team_id = Uuid::new_v4();
i.account = i_team_id;
j.account = i_team_id;
let mut i_team = Team::new(i_team_id);
i_team
.set_cryps(vec![i,j]);
let x_team_id = Uuid::new_v4();
x.account = x_team_id;
y.account = x_team_id;
let mut x_team = Team::new(x_team_id);
x_team
.set_cryps(vec![x,y]);
@ -1131,14 +1140,59 @@ mod tests {
assert!(game.skill_phase_finished());
game = game.resolve_phase_start();
assert!(game.resolved.len() == 2);
let Resolution { source: _, target: _, event } = game.resolved.pop().unwrap();
match event {
let ruins = game.resolved
.into_iter()
.filter(|r| {
let Resolution { source, target: _, event } = r;
match source.id == x_cryp.id {
true => match event {
Event::Effect { effect, duration } => {
assert!(effect == Effect::Ruin);
assert!(duration == 1);
assert!(*effect == Effect::Ruin);
assert!(*duration == 1);
true
}
_ => panic!("ruin result not effect {:?}", event),
}
false => false,
}
})
.count();
assert!(ruins == 2);
}
#[test]
fn taunt_test() {
let mut game = create_2v2_test_game();
let i_team = game.teams[0].clone();
let x_team = game.teams[1].clone();
let i_cryp = i_team.cryps[0].clone();
let j_cryp = i_team.cryps[1].clone();
let x_cryp = x_team.cryps[0].clone();
let y_cryp = x_team.cryps[1].clone();
game.cryp_by_id(x_cryp.id).unwrap().learn_mut(Skill::Taunt);
while game.cryp_by_id(x_cryp.id).unwrap().skill_on_cd(Skill::Taunt).is_some() {
game.cryp_by_id(x_cryp.id).unwrap().reduce_cooldowns();
}
game.add_skill(i_team.id, i_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.add_skill(i_team.id, j_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.add_skill(x_team.id, x_cryp.id, Some(i_cryp.id), Skill::Taunt).unwrap();
game.add_skill(x_team.id, y_cryp.id, Some(i_cryp.id), Skill::TestTouch).unwrap();
assert!(game.skill_phase_finished());
game = game.resolve_phase_start();
assert!(game.resolved.len() == 4);
while let Some(r) = game.resolved.pop() {
let Resolution { source , target, event: _ } = r;
if [i_cryp.id, j_cryp.id].contains(&source.id) {
assert!(target.id == x_cryp.id);
}
_ => panic!("ruin result not effect"),
}
}

View File

@ -109,6 +109,7 @@ pub enum Effect {
Reflect,
Empower,
Taunt,
Invert,
Strangle,
@ -242,6 +243,7 @@ impl Effect {
Effect::Blind => Category::RedDebuff,
Effect::Snare => Category::RedDebuff,
Effect::Clutch => Category::RedBuff,
Effect::Taunt => Category::RedBuff,
Effect::Empower => Category::RedBuff,
Effect::Strangle => Category::RedDebuff,
Effect::Strangling => Category::RedBuff,
@ -291,6 +293,7 @@ impl Effect {
Effect::Vulnerable => 2,
Effect::Snare => 2,
Effect::Taunt => 1,
Effect::Empower => 2,
Effect::Invert => 1,
@ -531,7 +534,7 @@ impl Skill {
Skill::Reflect => Category::Blue,
Skill::Ruin => Category::Blue,
Skill::Slay => Category::Blue,
Skill::Taunt => Category::Blue,
Skill::Taunt => Category::Red,
Skill::Toxic => Category::Blue,
@ -600,9 +603,9 @@ impl Skill {
return results;
}
if target.is_reflecting() {
if target.affected(Effect::Reflect) {
// guard against overflow
if source.is_reflecting() {
if source.affected(Effect::Reflect) {
return results;
}
return self.resolve(target, source);
@ -667,13 +670,13 @@ impl Skill {
Skill::Reflect => reflect(source, target, results),
Skill::Ruin => ruin(source, target, results),
Skill::Slay => unimplemented!(),
Skill::Taunt => unimplemented!(),
Skill::Taunt => taunt(source, target, results),
Skill::Toxic => unimplemented!(),
// -----------------
// Test
// -----------------
Skill::TestTouch => results,
Skill::TestTouch => touch(source, target, results),
Skill::TestStun => stun(source, target, results),
Skill::TestBlock => block(source, target, results),
Skill::TestParry => parry(source, target, results),
@ -705,6 +708,11 @@ impl Skill {
}
}
fn touch(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::TestTouch, 0)));
return results;
}
fn attack(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let amount = source.red_damage();
results.push(Resolution::new(source, target).event(target.deal_red_damage(Skill::Attack, amount)));
@ -723,6 +731,12 @@ fn clutch(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Res
return results;
}
fn taunt(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let effect = CrypEffect { effect: Effect::Taunt, duration: Effect::Taunt.duration(), tick: None };
results.push(Resolution::new(source, target).event(target.add_effect(Skill::Taunt, effect)));
return results;
}
fn throw(source: &mut Cryp, target: &mut Cryp, mut results: Resolutions) -> Resolutions {
let stun = CrypEffect { effect: Effect::Stun, duration: Effect::Stun.duration(), tick: None };
let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Effect::Vulnerable.duration(), tick: None };
@ -1028,7 +1042,7 @@ mod tests {
x.red_damage.force(u64::max_value());
clutch(&mut y.clone(), &mut y, vec![]);
assert!(y.is_clutch());
assert!(y.affected(Effect::Clutch));
let mut results = attack(&mut x, &mut y, vec![]);
assert!(y.hp() == 1);
@ -1054,7 +1068,7 @@ mod tests {
x.red_damage.force(256 + 64);
invert(&mut y.clone(), &mut y, vec![]);
assert!(y.is_inverted());
assert!(y.affected(Effect::Invert));
// heal should deal green damage
heal(&mut x, &mut y, vec![]);
@ -1080,7 +1094,7 @@ mod tests {
.named(&"camel".to_string());
reflect(&mut y.clone(), &mut y, vec![]);
assert!(y.is_reflecting());
assert!(y.affected(Effect::Reflect));
let mut results = Skill::Attack.resolve(&mut x, &mut y);

View File

@ -204,7 +204,7 @@ impl Var {
Var::Strangle => Some(Skill::Strangle),
Var::Strike => Some(Skill::Strike),
Var::Clutch => Some(Skill::Clutch),
// Var::Taunt => Some(Skill::Taunt),
Var::Taunt => Some(Skill::Taunt),
Var::Throw => Some(Skill::Throw),
// Var::Toxic => Some(Skill::Toxic),
Var::Triage => Some(Skill::Triage),
@ -252,6 +252,7 @@ impl From<Skill> for Var {
Skill::Blast => Var::Blast,
Skill::Block => Var::Block,
Skill::Curse => Var::Curse,
Skill::Decay => Var::Decay,
Skill::Empower => Var::Empower,
Skill::Haste => Var::Haste,
Skill::Heal => Var::Heal,
@ -260,20 +261,20 @@ impl From<Skill> for Var {
Skill::Parry => Var::Parry,
Skill::Purge => Var::Purge,
Skill::Purify => Var::Purify,
Skill::Recharge => Var::Recharge,
Skill::Reflect => Var::Reflect,
Skill::Ruin => Var::Ruin,
Skill::Shield => Var::Shield,
Skill::Silence => Var::Silence,
Skill::Siphon => Var::Siphon,
Skill::Slow => Var::Slow,
Skill::Snare => Var::Snare,
Skill::Strike => Var::Strike,
Skill::Strangle => Var::Strangle,
Skill::Strike => Var::Strike,
Skill::Stun => Var::Stun,
Skill::Taunt => Var::Taunt,
Skill::Throw => Var::Throw,
Skill::Triage => Var::Triage,
Skill::Decay => Var::Decay,
Skill::Reflect => Var::Reflect,
Skill::Recharge => Var::Recharge,
Skill::Ruin => Var::Ruin,
Skill::TestTouch => Var::TestTouch,
Skill::TestStun => Var::TestStun,