maybe it works?

This commit is contained in:
ntr 2019-12-13 14:50:31 +10:00
parent 416ec01b77
commit ca6ab14282
2 changed files with 1488 additions and 1479 deletions

View File

@ -29,6 +29,7 @@ pub struct Game {
pub players: Vec<Player>, pub players: Vec<Player>,
pub phase: Phase, pub phase: Phase,
pub stack: Vec<Cast>, pub stack: Vec<Cast>,
events: Vec<Event>,
pub resolutions: Vec<Vec<Resolution>>, pub resolutions: Vec<Vec<Resolution>>,
pub instance: Option<Uuid>, pub instance: Option<Uuid>,
pub time_control: TimeControl, pub time_control: TimeControl,
@ -45,6 +46,7 @@ impl Game {
players: vec![], players: vec![],
phase: Phase::Start, phase: Phase::Start,
stack: vec![], stack: vec![],
events: vec![],
resolutions: vec![], resolutions: vec![],
instance: None, instance: None,
time_control: TimeControl::Standard, time_control: TimeControl::Standard,
@ -440,7 +442,8 @@ impl Game {
// because need to check cooldown use before pushing them into the complete list // because need to check cooldown use before pushing them into the complete list
let mut r_animation_ms = 0; let mut r_animation_ms = 0;
while let Some(cast) = self.stack.pop() { while let Some(cast) = self.stack.pop() {
self.resolve(cast, vec![]); self.events = vec![];
self.resolve(cast);
// sort the stack again in case speeds have changed // sort the stack again in case speeds have changed
self.stack_sort_speed(); self.stack_sort_speed();
@ -463,16 +466,16 @@ impl Game {
self.skill_phase_start(r_animation_ms) self.skill_phase_start(r_animation_ms)
} }
fn resolve(&mut self, cast: Cast, mut events: Vec<Event>) -> Vec<Event> { fn resolve(&mut self, cast: Cast) -> &mut Game {
// If the skill is disabled for source nothing else will happen // If the skill is disabled for source nothing else will happen
if let Some(effects) = self.construct(cast.source).disabled(cast.skill) { if let Some(effects) = self.construct(cast.source).disabled(cast.skill) {
self.add_resolution(&cast, &Event::Disable { construct: cast.source, effects }); self.add_resolution(&cast, &Event::Disable { construct: cast.source, effects });
return events; return self;
} }
// hastestrike / hybridblast // hastestrike / hybridblast
for skill in self.construct(cast.source).additional_skills(cast.skill) { for skill in self.construct(cast.source).additional_skills(cast.skill) {
events = self.resolve(Cast { skill, ..cast }, events); self.resolve(Cast { skill, ..cast });
} }
// for aoe events send the source / target animations before each set of casts // for aoe events send the source / target animations before each set of casts
@ -487,10 +490,10 @@ impl Game {
let casts = self.modify_cast(cast); let casts = self.modify_cast(cast);
for cast in casts { for cast in casts {
events = self.execute(cast, events); self.execute(cast);
} }
events self
} }
fn modify_cast(&self, cast: Cast) -> Vec<Cast> { fn modify_cast(&self, cast: Cast) -> Vec<Cast> {
@ -516,15 +519,15 @@ impl Game {
return casts; return casts;
} }
fn execute(&mut self, cast: Cast, mut events: Vec<Event>) -> Vec<Event> { fn execute(&mut self, cast: Cast) -> &mut Game {
if self.construct(cast.target).is_ko() { if self.construct(cast.target).is_ko() {
self.add_resolution(&cast, &Event::TargetKo { construct: cast.target }); self.add_resolution(&cast, &Event::TargetKo { construct: cast.target });
return events; return self;
} }
if let Some(immunity) = self.construct(cast.target).immune(cast.skill) { if let Some(immunity) = self.construct(cast.target).immune(cast.skill) {
self.add_resolution(&cast, &Event::Immune { construct: cast.target, effects: immunity }); self.add_resolution(&cast, &Event::Immune { construct: cast.target, effects: immunity });
return events; return self;
} }
if self.construct(cast.target).affected(Effect::Reflect) && cast.skill.colours().contains(&Colour::Blue) && !cast.skill.is_tick() { if self.construct(cast.target).affected(Effect::Reflect) && cast.skill.colours().contains(&Colour::Blue) && !cast.skill.is_tick() {
@ -533,52 +536,56 @@ impl Game {
// both reflecting, show it and bail // both reflecting, show it and bail
if self.construct(cast.source).affected(Effect::Reflect) { if self.construct(cast.source).affected(Effect::Reflect) {
self.add_resolution(&cast, &Event::Reflection { construct: cast.source }); self.add_resolution(&cast, &Event::Reflection { construct: cast.source });
return events; return self;
} }
return self.execute(Cast { target: cast.source, ..cast }, events); return self.resolve(Cast { target: cast.source, ..cast });
} }
for action in cast.actions(self, &events) { cast.resolve(self);
let new_events = match action {
Action::Cast => vec![self.cast(cast)],
Action::Hit => vec![self.hit(cast)],
Action::Damage { construct, amount, colour } => self.damage(construct, amount, colour), self
Action::Heal { construct, amount, colour } => self.heal(construct, amount, colour), }
Action::Effect { construct, effect } => self.effect(construct, effect), pub fn action(&mut self, cast: Cast, action: Action) -> &mut Game {
Action::Remove { construct, effect } => self.effect_remove(construct, effect), let new_events = match action {
Action::RemoveAll { construct } => self.remove_all(construct), Action::Cast => vec![self.cast(cast)],
Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns), Action::Hit => vec![self.hit(cast)],
Action::SetEffectMeta { construct, amount, effect } => self.effect_meta(construct, effect, amount),
Action::Damage { construct, amount, colour } => self.damage(construct, amount, colour),
Action::Heal { construct, amount, colour } => self.heal(construct, amount, colour),
Action::Effect { construct, effect } => self.effect(construct, effect),
Action::Remove { construct, effect } => self.effect_remove(construct, effect),
Action::RemoveAll { construct } => self.remove_all(construct),
Action::IncreaseCooldowns { construct, turns } => self.increase_cooldowns(construct, turns),
Action::SetEffectMeta { construct, amount, effect } => self.effect_meta(construct, effect, amount),
};
// this event is now considered to have happened
// for chronological ordering it is added to the resolution list
// before extra processing on it begins
for event in new_events {
self.add_resolution(&cast, &event);
let casts = match event {
Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } =>
self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event),
// Event::Cast {} => set_cooldown()
Event::Ko { construct } =>
self.construct_by_id(construct).unwrap().on_ko(&cast, &event),
_ => vec![],
}; };
// this event is now considered to have happened self.events.push(event);
// for chronological ordering it is added to the resolution list
// before extra processing on it begins
for event in new_events { for cast in casts {
self.add_resolution(&cast, &event); self.resolve(cast);
let casts = match event {
Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } =>
self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event),
// Event::Cast {} => set_cooldown()
Event::Ko { construct } =>
self.construct_by_id(construct).unwrap().on_ko(&cast, &event),
_ => vec![],
};
events.push(event);
for cast in casts {
events = self.resolve(cast, events);
}
} }
} }
events self
} }
fn add_resolution(&mut self, cast: &Cast, event: &Event) -> &mut Game { fn add_resolution(&mut self, cast: &Cast, event: &Event) -> &mut Game {
@ -587,7 +594,7 @@ impl Game {
self self
} }
pub fn value(&self, value: Value, events: &Vec<Event>) -> usize { pub fn value(&self, value: Value) -> usize {
match value { match value {
Value::Stat { construct, stat } => Value::Stat { construct, stat } =>
self.construct(construct).stat(stat), self.construct(construct).stat(stat),
@ -602,7 +609,7 @@ impl Game {
self.construct(construct).stat(Stat::Skills(colour)), self.construct(construct).stat(Stat::Skills(colour)),
Value::DamageReceived { construct, colour } => Value::DamageReceived { construct, colour } =>
events.iter().fold(0, |dmg, e| match e { self.events.iter().fold(0, |dmg, e| match e {
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } => Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } =>
match construct == *event_construct && colour == *event_colour { match construct == *event_construct && colour == *event_colour {
true => dmg + amount, true => dmg + amount,
@ -612,7 +619,7 @@ impl Game {
}), }),
Value::Removals { construct } => Value::Removals { construct } =>
events.iter().fold(0, |dmg, e| match e { self.events.iter().fold(0, |dmg, e| match e {
Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } => Event::Damage { construct: event_construct, amount, mitigation:_, colour: event_colour, display: _ } =>
match construct == *event_construct { match construct == *event_construct {
true => dmg + amount, true => dmg + amount,
@ -817,7 +824,7 @@ pub enum Value {
ColourSkills { construct: Uuid, colour: Colour }, ColourSkills { construct: Uuid, colour: Colour },
Effects { construct: Uuid }, Effects { construct: Uuid },
Removals { construct: Uuid }, Removals { construct: Uuid },
DamageReceived { construct: Uuid, colour: Colour, mult: usize }, DamageReceived { construct: Uuid, colour: Colour },
} }
#[derive(Debug,Clone,PartialEq)] #[derive(Debug,Clone,PartialEq)]
@ -1640,313 +1647,313 @@ mod tests {
// } // }
#[test] // #[test]
fn upkeep_test() { // fn upkeep_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
game.players[0].set_ready(true); // game.players[0].set_ready(true);
game.phase_end = Some(Utc::now().checked_sub_signed(Duration::seconds(500)).unwrap()); // game.phase_end = Some(Utc::now().checked_sub_signed(Duration::seconds(500)).unwrap());
game = game.upkeep(); // game = game.upkeep();
// assert!(game.players[1].warnings == 1); // // assert!(game.players[1].warnings == 1);
} // }
#[test] // #[test]
fn attack_test() { // fn attack_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.add_skill(player_id, source, target, Skill::Attack).unwrap(); // game.add_skill(player_id, source, target, Skill::Attack).unwrap();
game = game.resolve_phase_start(); // game = game.resolve_phase_start();
} // }
#[test] // #[test]
fn bash_test() { // fn bash_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Bash), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Bash));
} // }
#[test] // #[test]
fn slay_test() { // fn slay_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Slay), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Slay));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => // Event::Damage { construct, colour, amount, mitigation: _, display: _ } =>
construct == target && amount > 0 && colour == Colour::Red, // construct == target && amount > 0 && colour == Colour::Red,
_ => false, // _ => false,
})); // }));
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => // Event::Damage { construct, colour, amount, mitigation: _, display: _ } =>
construct == target && amount > 0 && colour == Colour::Red, // construct == target && amount > 0 && colour == Colour::Red,
_ => false, // _ => false,
})); // }));
} // }
#[test] // #[test]
fn purify_test() { // fn purify_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let source_player_id = game.players[0].id; // let source_player_id = game.players[0].id;
let target_player_id = game.players[1].id; // let target_player_id = game.players[1].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, source_player_id, target, Skill::Decay), vec![]); // game.resolve(Cast::new(source, source_player_id, target, Skill::Decay));
// don't mention 3 we volvo now // // don't mention 3 we volvo now
assert!(game.players[1].constructs[0].effects.len() == 3); // assert!(game.players[1].constructs[0].effects.len() == 3);
game.resolve(Cast::new(target, target_player_id, target, Skill::Purify), vec![]); // game.resolve(Cast::new(target, target_player_id, target, Skill::Purify));
assert!(game.players[1].constructs[0].effects.len() == 1); // assert!(game.players[1].constructs[0].effects.len() == 1);
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Effect { construct, effect, duration: _, display: _ } => // Event::Effect { construct, effect, duration: _, display: _ } =>
construct == target && effect == Effect::Pure, // construct == target && effect == Effect::Pure,
_ => false, // _ => false,
})); // }));
// Check for healing here // // Check for healing here
} // }
#[test] // #[test]
fn invert_test() { // fn invert_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Strike), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Strike));
game.resolve(Cast::new(source, player_id, target, Skill::Invert), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Invert));
game.resolve(Cast::new(source, player_id, target, Skill::Strike), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Strike));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Healing { construct, colour, amount, overhealing: _, display: _, } => // Event::Healing { construct, colour, amount, overhealing: _, display: _, } =>
construct == target && amount > 0 && colour == Colour::Green, // construct == target && amount > 0 && colour == Colour::Green,
_ => false, // _ => false,
})); // }));
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Healing { construct, colour, amount, overhealing: _, display: _ } => // Event::Healing { construct, colour, amount, overhealing: _, display: _ } =>
construct == target && amount > 0 && colour == Colour::Red, // construct == target && amount > 0 && colour == Colour::Red,
_ => false, // _ => false,
})); // }));
} // }
#[test] // #[test]
fn siphon_test() { // fn siphon_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Siphon));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
// siphon should // // siphon should
// apply effect // damage target // heal source // // apply effect // damage target // heal source
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Effect { construct, effect, duration: _, display: _ } => // Event::Effect { construct, effect, duration: _, display: _ } =>
construct == target && effect == Effect::Siphon, // construct == target && effect == Effect::Siphon,
_ => false, // _ => false,
})); // }));
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => // Event::Damage { construct, colour, amount, mitigation: _, display: _ } =>
construct == target && amount > 0 && colour == Colour::Blue, // construct == target && amount > 0 && colour == Colour::Blue,
_ => false, // _ => false,
})); // }));
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Healing { construct, colour, amount: _, overhealing: _, display: _ } => // Event::Healing { construct, colour, amount: _, overhealing: _, display: _ } =>
construct == source && colour == Colour::Green, // construct == source && colour == Colour::Green,
_ => false, // _ => false,
})); // }));
game = game.resolve_phase_start(); // game = game.resolve_phase_start();
// que ota? // // que ota?
game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Siphon));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
let damage_events = resolutions.iter().filter(|r| match r.event { // let damage_resolutions.iter().filter(|r| match r.event {
Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => true, // Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => true,
_ => false, // _ => false,
}).count(); // }).count();
assert_eq!(damage_events, 1); // assert_eq!(damage_events, 1);
} // }
#[test] // #[test]
fn reflect_test() { // fn reflect_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Reflect), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Reflect));
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => // Event::Damage { construct, colour, amount, mitigation: _, display: _ } =>
construct == source && amount > 0 && colour == Colour::Blue, // construct == source && amount > 0 && colour == Colour::Blue,
_ => false, // _ => false,
})); // }));
} // }
#[test] // #[test]
fn absorb_test() { // fn absorb_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Absorb), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Absorb));
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation: _, display: _ } => { // Event::Damage { construct, colour, amount, mitigation: _, display: _ } => {
assert!(construct == target && amount > 0 && colour == Colour::Blue && r.skill == Skill::Blast); // assert!(construct == target && amount > 0 && colour == Colour::Blue && r.skill == Skill::Blast);
resolutions.iter().any(|r| match r.event { // resolutions.iter().any(|r| match r.event {
Event::Meta { construct, effect, meta } => // Event::Meta { construct, effect, meta } =>
construct == target && effect == Effect::Absorption && { // construct == target && effect == Effect::Absorption && {
match meta { // match meta {
EffectMeta::AddedDamage(added_dmg) => added_dmg == amount, // EffectMeta::AddedDamage(added_dmg) => added_dmg == amount,
_ => false, // _ => false,
} // }
}, // },
_ => false, // _ => false,
}) // })
}, // },
_ => false, // _ => false,
})); // }));
assert!(match game.players[1].constructs[0].effects[0].meta { // assert!(match game.players[1].constructs[0].effects[0].meta {
Some(EffectMeta::AddedDamage(d)) => d, // Some(EffectMeta::AddedDamage(d)) => d,
_ => 0 // _ => 0
// 320 base blue power and 125 base blue life // // 320 base blue power and 125 base blue life
} == 320.pct(Skill::Blast.multiplier()) - 125); // } == 320.pct(Skill::Blast.multiplier()) - 125);
} // }
#[test] // #[test]
fn absorb_multi_damage_test() { // fn absorb_multi_damage_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
// Abosrb restores blue life here // // Abosrb restores blue life here
game.resolve(Cast::new(source, player_id, target, Skill::Absorb), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Absorb));
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
assert!(match game.players[1].constructs[0].effects[0].meta { // assert!(match game.players[1].constructs[0].effects[0].meta {
Some(EffectMeta::AddedDamage(d)) => d, // Some(EffectMeta::AddedDamage(d)) => d,
_ => 0 // _ => 0
// 320 base blue power and 125 base blue life // // 320 base blue power and 125 base blue life
} == 320.pct(Skill::Blast.multiplier()) - 125); // } == 320.pct(Skill::Blast.multiplier()) - 125);
} // }
#[test] // #[test]
fn multi_reflect_test() { // fn multi_reflect_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let target_player_id = game.players[1].id; // let target_player_id = game.players[1].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, source, Skill::Reflect), vec![]); // game.resolve(Cast::new(source, player_id, source, Skill::Reflect));
game.resolve(Cast::new(target, target_player_id, target, Skill::Reflect), vec![]); // game.resolve(Cast::new(target, target_player_id, target, Skill::Reflect));
game.resolve(Cast::new(source, player_id, target, Skill::Blast), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Blast));
assert!(game.players[0].constructs[0].is_ko() == false); // assert!(game.players[0].constructs[0].is_ko() == false);
assert!(game.players[1].constructs[0].is_ko() == false); // assert!(game.players[1].constructs[0].is_ko() == false);
} // }
// refer fixme.md (infinite counterattack loop) // // refer fixme.md (infinite counterattack loop)
/*#[test] // /*#[test]
fn multi_counter_test() { // fn multi_counter_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let target_player_id = game.players[1].id; // let target_player_id = game.players[1].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, source, Skill::Counter), vec![]); // game.resolve(Cast::new(source, player_id, source, Skill::Counter));
game.resolve(Cast::new(target, target_player_id, target, Skill::Counter), vec![]); // game.resolve(Cast::new(target, target_player_id, target, Skill::Counter));
game.resolve(Cast::new(source, player_id, target, Skill::Attack), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Attack));
assert!(game.players[0].constructs[0].is_ko() == false); // assert!(game.players[0].constructs[0].is_ko() == false);
assert!(game.players[1].constructs[0].is_ko() == false); // assert!(game.players[1].constructs[0].is_ko() == false);
}*/ // }*/
#[test] // #[test]
fn intercept_test() { // fn intercept_test() {
let mut game = create_2v2_test_game(); // let mut game = create_2v2_test_game();
let player_id = game.players[0].id; // let player_id = game.players[0].id;
let other_player_id = game.players[1].id; // let other_player_id = game.players[1].id;
let source = game.players[0].constructs[0].id; // let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; // let target = game.players[1].constructs[0].id;
let interceptor = game.players[1].constructs[1].id; // let interceptor = game.players[1].constructs[1].id;
// Cast intercept // // Cast intercept
game.resolve(Cast::new(interceptor, other_player_id, interceptor, Skill::Intercept), vec![]); // game.resolve(Cast::new(interceptor, other_player_id, interceptor, Skill::Intercept));
// Enemy casts skill on target which as a teammate intercepting // // Enemy casts skill on target which as a teammate intercepting
game.resolve(Cast::new(source, player_id, target, Skill::Attack), vec![]); // game.resolve(Cast::new(source, player_id, target, Skill::Attack));
// Intercepting teammate attacks someone on same team // // Intercepting teammate attacks someone on same team
game.resolve(Cast::new(interceptor, other_player_id, target, Skill::Attack), vec![]); // game.resolve(Cast::new(interceptor, other_player_id, target, Skill::Attack));
let last = game.resolutions.len() - 1; // let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; // let resolutions = &game.resolutions[last];
// There should be no damage events on the target // // There should be no damage events on the target
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation, display: _ } => // Event::Damage { construct, colour, amount, mitigation, display: _ } =>
construct == target && (amount > 0 || mitigation > 0) && colour == Colour::Red, // construct == target && (amount > 0 || mitigation > 0) && colour == Colour::Red,
_ => false, // _ => false,
}) == false); // }) == false);
// Should be damage events on the interceptor // // Should be damage events on the interceptor
assert!(resolutions.iter().any(|r| match r.event { // assert!(resolutions.iter().any(|r| match r.event {
Event::Damage { construct, colour, amount, mitigation, display: _ } => // Event::Damage { construct, colour, amount, mitigation, display: _ } =>
construct == interceptor && (amount > 0 || mitigation > 0) && colour == Colour::Red, // construct == interceptor && (amount > 0 || mitigation > 0) && colour == Colour::Red,
_ => false, // _ => false,
})); // }));
} }
/* /*
@ -1957,8 +1964,8 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Decay), vec![]); game.resolve(Cast::new(source, player_id, target, Skill::Decay));
game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); game.resolve(Cast::new(source, player_id, target, Skill::Siphon));
game = game.resolve_phase_start(); game = game.resolve_phase_start();
@ -1972,9 +1979,9 @@ mod tests {
let source = game.players[0].constructs[0].id; let source = game.players[0].constructs[0].id;
let target = game.players[1].constructs[0].id; let target = game.players[1].constructs[0].id;
game.resolve(Cast::new(source, player_id, target, Skill::Decay), vec![]); game.resolve(Cast::new(source, player_id, target, Skill::Decay));
game.resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus), vec![]); game.resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus));
game.resolve(Cast::new(source, player_id, target, Skill::Siphon), vec![]); game.resolve(Cast::new(source, player_id, target, Skill::Siphon));
game = game.resolve_phase_start(); game = game.resolve_phase_start();
@ -1982,4 +1989,4 @@ mod tests {
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
assert!(Skill::SiphonTick == resolutions[0].skill); assert!(Skill::SiphonTick == resolutions[0].skill);
}*/ }*/
} // }

File diff suppressed because it is too large Load Diff