fix removing ticks

This commit is contained in:
ntr 2019-05-08 14:07:22 +10:00
parent af03d37404
commit 0ee4a9d18e
2 changed files with 83 additions and 19 deletions

View File

@ -243,7 +243,7 @@ impl Game {
self
}
fn add_skill(&mut self, player_id: Uuid, source_cryp_id: Uuid, target_cryp_id: Option<Uuid>, skill: Skill) -> Result<Uuid, Error> {
fn add_skill(&mut self, player_id: Uuid, source_cryp_id: Uuid, target_cryp_id: Option<Uuid>, skill: Skill) -> Result<&mut Game, Error> {
// check player in game
self.player_by_id(player_id)?;
@ -304,10 +304,9 @@ impl Game {
}
let skill = Cast::new(source_cryp_id, player_id, final_target_id, skill);
let skill_id = skill.id;
self.stack.push(skill);
return Ok(skill_id);
return Ok(self);
}
fn player_ready(&mut self, player_id: Uuid) -> Result<&mut Game, Error> {
@ -1053,7 +1052,7 @@ mod tests {
let x_cryp = x_player.cryps[0].clone();
let y_cryp = y_player.cryps[0].clone();
let _x_stun_id = game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.player_ready(x_player.id).unwrap();
@ -1086,7 +1085,7 @@ mod tests {
// remove all mitigation
game.player_by_id(x_player.id).unwrap().cryp_by_id(x_cryp.id).unwrap().red_life.force(0);
let _x_stun_id = game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::Attack).unwrap();
game.player_ready(x_player.id).unwrap();
@ -1130,8 +1129,8 @@ mod tests {
// second round
// now we block and it should go back on cd
let _x_block_id = game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::Stun).unwrap();
let _y_touch_id = game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::Stun).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
@ -1152,7 +1151,7 @@ mod tests {
let x_cryp = x_player.cryps[0].clone();
let y_cryp = y_player.cryps[0].clone();
let _x_block_id = game.add_skill(x_player.id, x_cryp.id, None, Skill::TestParry).unwrap();
game.add_skill(x_player.id, x_cryp.id, None, Skill::TestParry).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::TestStun).unwrap();
game.player_ready(x_player.id).unwrap();
@ -1416,6 +1415,57 @@ mod tests {
return;
}
#[test]
fn tick_removal_test() {
let mut game = create_test_game();
let x_player = game.players[0].clone();
let y_player = game.players[1].clone();
let x_cryp = x_player.cryps[0].clone();
let y_cryp = y_player.cryps[0].clone();
game.cryp_by_id(x_cryp.id).unwrap().learn_mut(Skill::Decay);
while game.cryp_by_id(x_cryp.id).unwrap().skill_on_cd(Skill::Decay).is_some() {
game.cryp_by_id(x_cryp.id).unwrap().reduce_cooldowns();
}
game.cryp_by_id(y_cryp.id).unwrap().learn_mut(Skill::Purify);
while game.cryp_by_id(y_cryp.id).unwrap().skill_on_cd(Skill::Purify).is_some() {
game.cryp_by_id(y_cryp.id).unwrap().reduce_cooldowns();
}
// apply buff
game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::Decay).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
game = game.resolve_phase_start();
assert!(game.cryp_by_id(y_cryp.id).unwrap().affected(Effect::Decay));
let Resolution { source: _, target: _, event } = game.resolved.pop().unwrap();
match event {
Event::Damage { amount: _, skill, mitigation: _, colour: _ } => assert_eq!(skill, Skill::DecayTick),
_ => panic!("not decay"),
};
game.resolved.clear();
// remove
game.add_skill(y_player.id, y_cryp.id, Some(y_cryp.id), Skill::Purify).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
game = game.resolve_phase_start();
while let Some(Resolution { source: _, target: _, event }) = game.resolved.pop() {
match event {
Event::Damage { amount: _, skill, mitigation: _, colour: _ } => panic!("{:?} damage event", event),
_ => (),
}
};
}
#[test]
fn upkeep_test() {
let mut game = create_2v2_test_game();

View File

@ -16,16 +16,27 @@ pub fn resolution_steps(cast: &Cast, game: &mut Game) -> Resolutions {
}
pub fn pre_resolve(cast: &Cast, game: &mut Game, mut resolutions: Resolutions) -> Resolutions {
let skill = cast.skill;
let source = game.cryp_by_id(cast.source_cryp_id).unwrap().clone();
let targets = game.get_targets(cast.skill, &source, cast.target_cryp_id);
for target_id in targets {
// we clone the current state of the target and source
// so we can modify them during the resolution
// no more than 1 mutable ref allowed on game
let mut source = game.cryp_by_id(cast.source_cryp_id).unwrap().clone();
let mut target = game.cryp_by_id(target_id).unwrap().clone();
// bail out on ticks that have been removed
if cast.is_tick && target.effects.iter().find(|ce| match ce.tick {
Some(t) => t.id == cast.id,
None => false,
}).is_some() {
continue;
}
resolutions = resolve(cast.skill, &mut source, &mut target, resolutions);
// save the clones
// save the changes to the game
game.update_cryp(&mut source);
game.update_cryp(&mut target);
@ -200,7 +211,7 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub struct Cast {
pub id: Uuid,
pub source_player_id: Uuid,
@ -208,7 +219,7 @@ pub struct Cast {
pub target_cryp_id: Uuid,
pub skill: Skill,
pub speed: u64,
pub resolutions: Resolutions,
pub is_tick: bool,
}
impl Cast {
@ -220,12 +231,20 @@ impl Cast {
target_cryp_id,
skill,
speed: 0,
resolutions: vec![],
is_tick: false,
};
}
pub fn new_tick(source: &mut Cryp, target: &mut Cryp, skill: Skill) -> Cast {
Cast::new(source.id, source.account, target.id, skill)
Cast {
id: Uuid::new_v4(),
source_cryp_id: source.id,
source_player_id: source.account,
target_cryp_id: target.id,
skill,
speed: 0,
is_tick: true
}
}
pub fn used_cooldown(&self) -> bool {
@ -360,11 +379,6 @@ impl Effect {
Category::Red => true,
_ => false,
},
Effect::Scatter => match skill.category() {
Category::Blue => true,
Category::Red => false,
_ => false,
},
Effect::Banish => true,
Effect::Injured => match skill.category() {
Category::Green => true,