From 0143849ec25f3fcb7d3e32534e970255080821cb Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 24 Mar 2019 18:37:58 +1100 Subject: [PATCH] sort stack speed as resolving --- server/WORKLOG.md | 2 -- server/src/game.rs | 82 ++++++++++++++++++++---------------------- server/src/instance.rs | 4 +-- server/src/skill.rs | 26 +++++++------- 4 files changed, 53 insertions(+), 61 deletions(-) diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 95c9ff40..8d2d3e1f 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -28,8 +28,6 @@ ensure all skills impl Skill::Taunt -> redirect incomnig attacks to self Skill::Toxic -> apply debuff to attackers -colour speeds - update speed of rest of stack on cryp speed change include target name in effect resolution eg strangle applies buff to self diff --git a/server/src/game.rs b/server/src/game.rs index 77da22ac..f09dd29f 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -196,14 +196,12 @@ impl Game { && self.teams.iter().all(|t| t.cryps.len() == self.team_size) } - pub fn start(&mut self) -> &mut Game { + pub fn start(mut self) -> Game { self.log.push("Game starting...".to_string()); - - self.skill_phase_start(); - self + self.skill_phase_start() } - fn skill_phase_start(&mut self) -> &mut Game { + fn skill_phase_start(mut self) -> Game { self.log.push("".to_string()); if ![Phase::Start, Phase::Resolve].contains(&self.phase) { @@ -212,11 +210,9 @@ impl Game { self.phase = Phase::Skill; - self.stack.clear(); - self.pve_add_skills(); if self.skill_phase_finished() { - self.resolve_phase_start(); + return self.resolve_phase_start() } self @@ -343,7 +339,7 @@ impl Game { // requires no input // just do it - fn resolve_phase_start(&mut self) -> &mut Game { + fn resolve_phase_start(mut self) -> Game { if self.phase != Phase::Skill { panic!("game not in skill phase"); } @@ -355,7 +351,10 @@ impl Game { self.resolve_skills() } - fn log_resolution(&mut self, source: &mut Cryp, target: &mut Cryp, cast: &Cast) -> &mut Game { + fn log_resolution(&mut self, cast: &Cast) -> &mut Game { + let source = self.cryp_by_id(cast.source_cryp_id).unwrap().clone(); + let target = self.cryp_by_id(cast.target_cryp_id).unwrap().clone(); + match cast.resolution.disable.disabled { true => { self.log.push(format!("{:} {:?} {:} disabled {:?}", source.name, cast.skill, target.name, cast.resolution.disable.effects)); @@ -415,12 +414,11 @@ impl Game { }); self.stack = sorted; - self.stack.reverse(); self } - fn resolve_skills(&mut self) -> &mut Game { + fn resolve_skills(mut self) -> Game { if self.phase != Phase::Resolve { panic!("game not in Resolve phase"); } @@ -440,17 +438,20 @@ impl Game { self.stack_sort_speed(); - // update the stack with the resolved skills - for mut skill in self.stack.clone() { + // temp vec of this round's resolving skills + // because need to check cooldown use before pushing them into the complete list + let mut resolving = vec![]; + + while let Some(mut skill) = self.stack.pop() { // println!("{:} resolving ", skill); let mut source = self.cryp_by_id(skill.source_cryp_id).unwrap().clone(); let mut target = self.cryp_by_id(skill.target_cryp_id).unwrap().clone(); skill.set_resolution(&mut source, &mut target); - self.log_resolution(&mut source, &mut target, &skill); + self.log_resolution(&skill); - self.resolved.push(skill); + resolving.push(skill); if target.is_ko() && !target.ko_logged { self.log.push(format!("{:} KO", target.name)); @@ -467,17 +468,15 @@ impl Game { self.update_cryp(&mut source); self.update_cryp(&mut target); - // find a way to - // resort the stack after each cast because - // the cryp speed may have changed - // self.stack_sort_speed(); + self.stack_sort_speed(); }; - // println!("{:#?}", self.resolved); + // println!("{:#?}", self.resolving); // now Resolve has all been assigned // handle cooldowns and statuses - self.progress_durations(); + self.progress_durations(&resolving); + self.resolved.append(&mut resolving); if self.finished() { return self.finish() @@ -486,7 +485,7 @@ impl Game { self.skill_phase_start() } - fn progress_durations(&mut self) -> &mut Game { + fn progress_durations(&mut self, resolved: &Vec) -> &mut Game { for mut cryp in self.all_cryps() { // println!("progressing durations for {:}", cryp.name); @@ -497,7 +496,7 @@ impl Game { // only reduce cooldowns if no cd was used // have to borrow self for the skill check { - if let Some(skill) = self.stack.iter_mut().find(|s| s.source_cryp_id == cryp.id) { + if let Some(skill) = resolved.iter().find(|s| s.source_cryp_id == cryp.id) { if skill.used_cooldown() { cryp.skill_set_cd(skill.skill); } else { @@ -524,10 +523,9 @@ impl Game { self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())) } - fn finish(&mut self) -> &mut Game { + fn finish(mut self) -> Game { self.phase = Phase::Finish; self.log.push(format!("Game finished.")); - self.stack.clear(); { let winner = self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())); @@ -567,7 +565,7 @@ pub fn game_skill(params: GameSkillParams, tx: &mut Transaction, account: &Accou game.add_skill(account.id, params.cryp_id, params.target_cryp_id, params.skill)?; if game.skill_phase_finished() { - game.resolve_phase_start(); + game = game.resolve_phase_start(); } game_update(&game, tx)?; @@ -843,7 +841,7 @@ pub fn game_instance_join(tx: &mut Transaction, player: Player, game_id: Uuid) - game.team_add(team)?; if game.can_start() { - game.start(); + game = game.start(); } println!("{:?} game joined", game.id); @@ -905,9 +903,7 @@ mod tests { assert!(game.can_start()); - game.start(); - - return game; + return game.start(); } fn create_2v2_test_game() -> Game { @@ -953,9 +949,7 @@ mod tests { assert!(game.can_start()); - game.start(); - - return game; + return game.start(); } #[test] @@ -973,7 +967,7 @@ mod tests { assert!(game.skill_phase_finished()); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!([Phase::Skill, Phase::Finish].contains(&game.phase)); @@ -994,7 +988,7 @@ mod tests { game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap(); assert!(game.skill_phase_finished()); - game.resolve_phase_start(); + game = game.resolve_phase_start(); // should auto progress back to skill phase assert!(game.phase == Phase::Skill); @@ -1024,7 +1018,7 @@ mod tests { game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::Attack).unwrap(); assert!(game.skill_phase_finished()); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!(!game.team_by_id(y_team.id).cryps[0].is_stunned()); assert!(game.phase == Phase::Finish); @@ -1050,7 +1044,7 @@ mod tests { let _x_stun_id = game.add_skill(x_team.id, x_cryp.id, Some(y_cryp.id), Skill::TestTouch).unwrap(); game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap(); - game.resolve_phase_start(); + game = game.resolve_phase_start(); // should auto progress back to skill phase assert!(game.phase == Phase::Skill); @@ -1061,7 +1055,7 @@ mod tests { let _x_block_id = game.add_skill(x_team.id, x_cryp.id, Some(y_cryp.id), Skill::Stun).unwrap(); let _y_touch_id = game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap(); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Stun).is_some()); assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_none()); @@ -1080,7 +1074,7 @@ mod tests { let _x_block_id = game.add_skill(x_team.id, x_cryp.id, None, Skill::TestParry).unwrap(); game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestStun).unwrap(); - game.resolve_phase_start(); + game = game.resolve_phase_start(); // should not be stunned because of parry assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false); @@ -1099,12 +1093,12 @@ mod tests { let _x_siphon_id = game.add_skill(x_team.id, x_cryp.id, Some(y_cryp.id), Skill::TestSiphon).unwrap(); let _y_touch_id = game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap(); - game.resolve_phase_start(); + game = game.resolve_phase_start(); game.add_skill(x_team.id, x_cryp.id, None, Skill::TestBlock).unwrap(); game.add_skill(y_team.id, y_cryp.id, None, Skill::TestBlock).unwrap(); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!(game.resolved.iter().any(|r| r.skill == Skill::SiphonTick)); } @@ -1127,7 +1121,7 @@ mod tests { game.add_skill(x_team.id, y_cryp.id, Some(i_cryp.id), Skill::TestTouch).unwrap(); assert!(game.skill_phase_finished()); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!([Phase::Skill, Phase::Finish].contains(&game.phase)); @@ -1144,7 +1138,7 @@ mod tests { assert!(game.add_skill(x_team.id, x_cryp.id, Some(i_cryp.id), Skill::TestTouch).is_err()); assert!(game.skill_phase_finished()); - game.resolve_phase_start(); + game = game.resolve_phase_start(); assert!(game.team_by_id(i_team.id).skills_required() == 1); assert!(game.team_by_id(x_team.id).skills_required() == 2); diff --git a/server/src/instance.rs b/server/src/instance.rs index 81e7d6d9..4cf3ddfc 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -133,7 +133,7 @@ impl Instance { .team_add(plr_team)? .team_add(bot_team)?; - game.start(); + game = game.start(); Ok(game) } @@ -253,7 +253,7 @@ impl Instance { .team_add(a_team).unwrap() .team_add(b_team).unwrap(); - game.start(); + game = game.start(); assert!(game.finished()); let winner = game.winner().unwrap(); diff --git a/server/src/skill.rs b/server/src/skill.rs index 7bcde9c7..d2ada432 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -577,24 +577,24 @@ impl Skill { let speed = source.skill_speed(*self); - let mut resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed }; - - if target.is_ko() { - return resolution; - } + let resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed }; if resolution.disable.disabled { return resolution; } - match self.category() == Category::Red { - true => { - if let Some(evasion) = target.evade(*self) { - resolution.results.push(evasion); - return resolution; - } - }, - false => (), + // match self.category() == Category::Red { + // true => { + // if let Some(evasion) = target.evade(*self) { + // resolution.results.push(evasion); + // return resolution; + // } + // }, + // false => (), + // } + + if target.is_ko() { + return resolution; } if target.is_reflecting() {