tick consistency

This commit is contained in:
ntr 2019-12-13 18:21:29 +10:00
parent 852f192ae7
commit db05505691
2 changed files with 31 additions and 25 deletions

View File

@ -166,7 +166,7 @@ impl Game {
fn skill_phase_start(mut self, resolution_animation_ms: i64) -> Game { fn skill_phase_start(mut self, resolution_animation_ms: i64) -> Game {
if ![Phase::Start, Phase::Resolve].contains(&self.phase) { if ![Phase::Start, Phase::Resolve].contains(&self.phase) {
panic!("game not in Resolve or start phase"); panic!("game not in Resolve or start phase {:?}", self.phase);
} }
self.phase = Phase::Skill; self.phase = Phase::Skill;
@ -428,7 +428,8 @@ impl Game {
.cloned() .cloned()
.filter_map(|e| e.meta) .filter_map(|e| e.meta)
.filter_map(move |m| match m { .filter_map(move |m| match m {
EffectMeta::CastTick { source, target, skill, speed, amount } => Some(Cast::new(source, c.account, target, skill)), EffectMeta::CastTick { source, target, skill, speed, amount: _ } =>
Some(Cast::new(source, c.account, target, skill).set_speed(speed)),
_ => None, _ => None,
}) })
) )
@ -854,6 +855,7 @@ pub enum Action {
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
pub struct Resolution { pub struct Resolution {
pub skill: Skill, pub skill: Skill,
pub speed: usize,
pub focus: Vec<Uuid>, pub focus: Vec<Uuid>,
pub event: Event, pub event: Event,
pub delay: i64, pub delay: i64,
@ -870,6 +872,7 @@ impl Resolution {
Resolution { Resolution {
skill: cast.skill, skill: cast.skill,
speed: cast.speed,
delay: 0, // set at the end of the resolve phase because of changes depending on what's before/after delay: 0, // set at the end of the resolve phase because of changes depending on what's before/after
focus, focus,
event, event,
@ -1789,7 +1792,6 @@ mod tests {
_ => false, _ => false,
})); }));
println!("{:#?}", resolutions);
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,
@ -1969,35 +1971,42 @@ mod tests {
} }
#[test] #[test]
fn tick_speed_tests() { fn tick_consistency_test() {
let mut game = create_2v2_test_game(); let mut game = create_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.new_resolve(Cast::new(source, player_id, target, Skill::Decay));
game.new_resolve(Cast::new(source, player_id, target, Skill::Siphon)); game.new_resolve(Cast::new(source, player_id, target, Skill::Siphon));
game = game.resolve_phase_start();
let last = game.resolutions.len() - 1; let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
assert!(Skill::DecayTick == resolutions[0].skill);
// Check speed ticks are static after they're cast let (siphon_speed, siphon_dmg) = resolutions.iter()
game = create_2v2_test_game(); .filter(|r| r.skill == Skill::Siphon)
let player_id = game.players[0].id; .find_map(|r| match r.event {
let source = game.players[0].constructs[0].id; Event::Damage { construct: _, colour: _, amount, mitigation, display: _ } => Some((r.speed, amount + mitigation)),
let target = game.players[1].constructs[0].id; _ => None,
})
.unwrap();
game.progress_durations(); // pretend it's a new turn
game.new_resolve(Cast::new(source, player_id, target, Skill::Decay));
game.new_resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus)); game.new_resolve(Cast::new(source, player_id, source, Skill::HastePlusPlus));
game.new_resolve(Cast::new(source, player_id, target, Skill::Siphon));
game = game.resolve_phase_start(); game = game.resolve_phase_start();
let last = game.resolutions.len() - 1; let last = game.resolutions.len() - 1;
let resolutions = &game.resolutions[last]; let resolutions = &game.resolutions[last];
assert!(Skill::SiphonTick == resolutions[0].skill);
let (siphon_tick_speed, siphon_tick_dmg) = resolutions.iter()
.filter(|r| r.skill == Skill::SiphonTick)
.find_map(|r| match r.event {
Event::Damage { construct: _, colour: _, amount, mitigation, display: _ } => Some((r.speed, amount + mitigation)),
_ => None,
})
.unwrap();
assert_eq!(siphon_tick_dmg, siphon_dmg);
assert_eq!(siphon_tick_speed, siphon_speed);
} }
} }

View File

@ -36,14 +36,10 @@ impl Cast {
self.target self.target
} }
pub fn new_tick(source: &mut Construct, target: &mut Construct, skill: Skill) -> Cast { pub fn set_speed(self, speed: usize) -> Cast {
Cast { Cast {
id: Uuid::new_v4(), speed,
source: source.id, ..self
player: source.account,
target: target.id,
skill,
speed: source.skill_speed(skill),
} }
} }
@ -1944,6 +1940,7 @@ fn ruin(cast: Cast, game: &mut Game) {
); );
} }
fn siphon(cast: Cast, game: &mut Game) { fn siphon(cast: Cast, game: &mut Game) {
let amount = let amount =
game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier()) game.value(Value::Stat { construct: cast.source, stat: Stat::BluePower }).pct(cast.skill.multiplier())