sort stack speed as resolving

This commit is contained in:
ntr 2019-03-24 18:37:58 +11:00
parent 467db4838f
commit 0143849ec2
4 changed files with 53 additions and 61 deletions

View File

@ -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

View File

@ -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("<Skill Phase>".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<Cast>) -> &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);

View File

@ -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();

View File

@ -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() {