sort stack speed as resolving
This commit is contained in:
parent
467db4838f
commit
0143849ec2
@ -28,8 +28,6 @@ ensure all skills impl
|
|||||||
Skill::Taunt -> redirect incomnig attacks to self
|
Skill::Taunt -> redirect incomnig attacks to self
|
||||||
Skill::Toxic -> apply debuff to attackers
|
Skill::Toxic -> apply debuff to attackers
|
||||||
|
|
||||||
colour speeds
|
|
||||||
|
|
||||||
update speed of rest of stack on cryp speed change
|
update speed of rest of stack on cryp speed change
|
||||||
include target name in effect resolution
|
include target name in effect resolution
|
||||||
eg strangle applies buff to self
|
eg strangle applies buff to self
|
||||||
|
|||||||
@ -196,14 +196,12 @@ impl Game {
|
|||||||
&& self.teams.iter().all(|t| t.cryps.len() == self.team_size)
|
&& 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.log.push("Game starting...".to_string());
|
||||||
|
self.skill_phase_start()
|
||||||
self.skill_phase_start();
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skill_phase_start(&mut self) -> &mut Game {
|
fn skill_phase_start(mut self) -> Game {
|
||||||
self.log.push("<Skill Phase>".to_string());
|
self.log.push("<Skill Phase>".to_string());
|
||||||
|
|
||||||
if ![Phase::Start, Phase::Resolve].contains(&self.phase) {
|
if ![Phase::Start, Phase::Resolve].contains(&self.phase) {
|
||||||
@ -212,11 +210,9 @@ impl Game {
|
|||||||
|
|
||||||
self.phase = Phase::Skill;
|
self.phase = Phase::Skill;
|
||||||
|
|
||||||
self.stack.clear();
|
|
||||||
|
|
||||||
self.pve_add_skills();
|
self.pve_add_skills();
|
||||||
if self.skill_phase_finished() {
|
if self.skill_phase_finished() {
|
||||||
self.resolve_phase_start();
|
return self.resolve_phase_start()
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -343,7 +339,7 @@ impl Game {
|
|||||||
|
|
||||||
// requires no input
|
// requires no input
|
||||||
// just do it
|
// just do it
|
||||||
fn resolve_phase_start(&mut self) -> &mut Game {
|
fn resolve_phase_start(mut self) -> Game {
|
||||||
if self.phase != Phase::Skill {
|
if self.phase != Phase::Skill {
|
||||||
panic!("game not in skill phase");
|
panic!("game not in skill phase");
|
||||||
}
|
}
|
||||||
@ -355,7 +351,10 @@ impl Game {
|
|||||||
self.resolve_skills()
|
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 {
|
match cast.resolution.disable.disabled {
|
||||||
true => {
|
true => {
|
||||||
self.log.push(format!("{:} {:?} {:} disabled {:?}", source.name, cast.skill, target.name, cast.resolution.disable.effects));
|
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 = sorted;
|
||||||
self.stack.reverse();
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_skills(&mut self) -> &mut Game {
|
fn resolve_skills(mut self) -> Game {
|
||||||
if self.phase != Phase::Resolve {
|
if self.phase != Phase::Resolve {
|
||||||
panic!("game not in Resolve phase");
|
panic!("game not in Resolve phase");
|
||||||
}
|
}
|
||||||
@ -440,17 +438,20 @@ impl Game {
|
|||||||
|
|
||||||
self.stack_sort_speed();
|
self.stack_sort_speed();
|
||||||
|
|
||||||
// update the stack with the resolved skills
|
// temp vec of this round's resolving skills
|
||||||
for mut skill in self.stack.clone() {
|
// 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);
|
// println!("{:} resolving ", skill);
|
||||||
let mut source = self.cryp_by_id(skill.source_cryp_id).unwrap().clone();
|
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();
|
let mut target = self.cryp_by_id(skill.target_cryp_id).unwrap().clone();
|
||||||
|
|
||||||
skill.set_resolution(&mut source, &mut target);
|
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 {
|
if target.is_ko() && !target.ko_logged {
|
||||||
self.log.push(format!("{:} KO", target.name));
|
self.log.push(format!("{:} KO", target.name));
|
||||||
@ -467,17 +468,15 @@ impl Game {
|
|||||||
self.update_cryp(&mut source);
|
self.update_cryp(&mut source);
|
||||||
self.update_cryp(&mut target);
|
self.update_cryp(&mut target);
|
||||||
|
|
||||||
// find a way to
|
self.stack_sort_speed();
|
||||||
// resort the stack after each cast because
|
|
||||||
// the cryp speed may have changed
|
|
||||||
// self.stack_sort_speed();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// println!("{:#?}", self.resolved);
|
// println!("{:#?}", self.resolving);
|
||||||
|
|
||||||
// now Resolve has all been assigned
|
// now Resolve has all been assigned
|
||||||
// handle cooldowns and statuses
|
// handle cooldowns and statuses
|
||||||
self.progress_durations();
|
self.progress_durations(&resolving);
|
||||||
|
self.resolved.append(&mut resolving);
|
||||||
|
|
||||||
if self.finished() {
|
if self.finished() {
|
||||||
return self.finish()
|
return self.finish()
|
||||||
@ -486,7 +485,7 @@ impl Game {
|
|||||||
self.skill_phase_start()
|
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() {
|
for mut cryp in self.all_cryps() {
|
||||||
// println!("progressing durations for {:}", cryp.name);
|
// println!("progressing durations for {:}", cryp.name);
|
||||||
|
|
||||||
@ -497,7 +496,7 @@ impl Game {
|
|||||||
// only reduce cooldowns if no cd was used
|
// only reduce cooldowns if no cd was used
|
||||||
// have to borrow self for the skill check
|
// 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() {
|
if skill.used_cooldown() {
|
||||||
cryp.skill_set_cd(skill.skill);
|
cryp.skill_set_cd(skill.skill);
|
||||||
} else {
|
} else {
|
||||||
@ -524,10 +523,9 @@ impl Game {
|
|||||||
self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko()))
|
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.phase = Phase::Finish;
|
||||||
self.log.push(format!("Game finished."));
|
self.log.push(format!("Game finished."));
|
||||||
self.stack.clear();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let winner = self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko()));
|
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)?;
|
game.add_skill(account.id, params.cryp_id, params.target_cryp_id, params.skill)?;
|
||||||
|
|
||||||
if game.skill_phase_finished() {
|
if game.skill_phase_finished() {
|
||||||
game.resolve_phase_start();
|
game = game.resolve_phase_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
game_update(&game, tx)?;
|
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)?;
|
game.team_add(team)?;
|
||||||
|
|
||||||
if game.can_start() {
|
if game.can_start() {
|
||||||
game.start();
|
game = game.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{:?} game joined", game.id);
|
println!("{:?} game joined", game.id);
|
||||||
@ -905,9 +903,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(game.can_start());
|
assert!(game.can_start());
|
||||||
|
|
||||||
game.start();
|
return game.start();
|
||||||
|
|
||||||
return game;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_2v2_test_game() -> Game {
|
fn create_2v2_test_game() -> Game {
|
||||||
@ -953,9 +949,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(game.can_start());
|
assert!(game.can_start());
|
||||||
|
|
||||||
game.start();
|
return game.start();
|
||||||
|
|
||||||
return game;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -973,7 +967,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
assert!(game.skill_phase_finished());
|
||||||
|
|
||||||
game.resolve_phase_start();
|
game = game.resolve_phase_start();
|
||||||
|
|
||||||
assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
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();
|
game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
assert!(game.skill_phase_finished());
|
||||||
game.resolve_phase_start();
|
game = game.resolve_phase_start();
|
||||||
|
|
||||||
// should auto progress back to skill phase
|
// should auto progress back to skill phase
|
||||||
assert!(game.phase == Phase::Skill);
|
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();
|
game.add_skill(y_team.id, y_cryp.id, Some(x_cryp.id), Skill::Attack).unwrap();
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
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.team_by_id(y_team.id).cryps[0].is_stunned());
|
||||||
assert!(game.phase == Phase::Finish);
|
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();
|
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.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
|
// should auto progress back to skill phase
|
||||||
assert!(game.phase == Phase::Skill);
|
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 _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();
|
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(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());
|
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();
|
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.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
|
// should not be stunned because of parry
|
||||||
assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
|
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 _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();
|
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(x_team.id, x_cryp.id, None, Skill::TestBlock).unwrap();
|
||||||
game.add_skill(y_team.id, y_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));
|
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();
|
game.add_skill(x_team.id, y_cryp.id, Some(i_cryp.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
assert!(game.skill_phase_finished());
|
||||||
game.resolve_phase_start();
|
game = game.resolve_phase_start();
|
||||||
|
|
||||||
assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
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.add_skill(x_team.id, x_cryp.id, Some(i_cryp.id), Skill::TestTouch).is_err());
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
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(i_team.id).skills_required() == 1);
|
||||||
assert!(game.team_by_id(x_team.id).skills_required() == 2);
|
assert!(game.team_by_id(x_team.id).skills_required() == 2);
|
||||||
|
|||||||
@ -133,7 +133,7 @@ impl Instance {
|
|||||||
.team_add(plr_team)?
|
.team_add(plr_team)?
|
||||||
.team_add(bot_team)?;
|
.team_add(bot_team)?;
|
||||||
|
|
||||||
game.start();
|
game = game.start();
|
||||||
|
|
||||||
Ok(game)
|
Ok(game)
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ impl Instance {
|
|||||||
.team_add(a_team).unwrap()
|
.team_add(a_team).unwrap()
|
||||||
.team_add(b_team).unwrap();
|
.team_add(b_team).unwrap();
|
||||||
|
|
||||||
game.start();
|
game = game.start();
|
||||||
|
|
||||||
assert!(game.finished());
|
assert!(game.finished());
|
||||||
let winner = game.winner().unwrap();
|
let winner = game.winner().unwrap();
|
||||||
|
|||||||
@ -577,24 +577,24 @@ impl Skill {
|
|||||||
|
|
||||||
let speed = source.skill_speed(*self);
|
let speed = source.skill_speed(*self);
|
||||||
|
|
||||||
let mut resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed };
|
let resolution = Resolution { skill: *self, results: vec![], disable: source.disabled(*self), speed };
|
||||||
|
|
||||||
if target.is_ko() {
|
|
||||||
return resolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolution.disable.disabled {
|
if resolution.disable.disabled {
|
||||||
return resolution;
|
return resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.category() == Category::Red {
|
// match self.category() == Category::Red {
|
||||||
true => {
|
// true => {
|
||||||
if let Some(evasion) = target.evade(*self) {
|
// if let Some(evasion) = target.evade(*self) {
|
||||||
resolution.results.push(evasion);
|
// resolution.results.push(evasion);
|
||||||
return resolution;
|
// return resolution;
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
false => (),
|
// false => (),
|
||||||
|
// }
|
||||||
|
|
||||||
|
if target.is_ko() {
|
||||||
|
return resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
if target.is_reflecting() {
|
if target.is_reflecting() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user