max targets and multiplayer test
This commit is contained in:
parent
b38be6d7bb
commit
63ec7a27ad
@ -147,6 +147,7 @@ function createSocket(events) {
|
|||||||
// this object wraps the reply types to a function
|
// this object wraps the reply types to a function
|
||||||
const handlers = {
|
const handlers = {
|
||||||
cryp_spawn: crypSpawn,
|
cryp_spawn: crypSpawn,
|
||||||
|
cryp_learn: () => true,
|
||||||
game_pve: gamePve,
|
game_pve: gamePve,
|
||||||
game_state: gameState,
|
game_state: gameState,
|
||||||
game_joinable_list: gameJoinableList,
|
game_joinable_list: gameJoinableList,
|
||||||
@ -183,10 +184,12 @@ function createSocket(events) {
|
|||||||
position: 'topRight',
|
position: 'topRight',
|
||||||
});
|
});
|
||||||
|
|
||||||
events.loginPrompt();
|
if (!account) events.loginPrompt();
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
|
send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for messages
|
// Listen for messages
|
||||||
@ -200,7 +203,10 @@ function createSocket(events) {
|
|||||||
|
|
||||||
ws.addEventListener('close', (event) => {
|
ws.addEventListener('close', (event) => {
|
||||||
console.error('WebSocket closed', event);
|
console.error('WebSocket closed', event);
|
||||||
// account = null;
|
toast.warn({
|
||||||
|
message: 'disconnected',
|
||||||
|
position: 'topRight',
|
||||||
|
});
|
||||||
return setTimeout(connect, 5000);
|
return setTimeout(connect, 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -248,7 +248,7 @@ impl Cryp {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("reduced effect {:?}", effect);
|
// println!("reduced effect {:?}", effect);
|
||||||
return Some(effect);
|
return Some(effect);
|
||||||
}).collect::<Vec<CrypEffect>>();
|
}).collect::<Vec<CrypEffect>>();
|
||||||
|
|
||||||
@ -266,9 +266,9 @@ impl Cryp {
|
|||||||
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
|
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
|
||||||
.map(|cryp_effect| cryp_effect.effect)
|
.map(|cryp_effect| cryp_effect.effect)
|
||||||
.collect::<Vec<Effect>>();
|
.collect::<Vec<Effect>>();
|
||||||
println!("{:?} phys_dmg mods : {:?}", self.name, phys_dmg_mods);
|
// println!("{:?} phys_dmg mods : {:?}", self.name, phys_dmg_mods);
|
||||||
let modified_phys_dmg = phys_dmg_mods.iter().fold(self.phys_dmg.base, |acc, m| m.apply(acc));
|
let modified_phys_dmg = phys_dmg_mods.iter().fold(self.phys_dmg.base, |acc, m| m.apply(acc));
|
||||||
println!("{:?} phys_dmg : {:?}", self.name, modified_phys_dmg);
|
// println!("{:?} phys_dmg : {:?}", self.name, modified_phys_dmg);
|
||||||
return modified_phys_dmg;
|
return modified_phys_dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,9 +277,9 @@ impl Cryp {
|
|||||||
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
|
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
|
||||||
.map(|cryp_effect| cryp_effect.effect)
|
.map(|cryp_effect| cryp_effect.effect)
|
||||||
.collect::<Vec<Effect>>();
|
.collect::<Vec<Effect>>();
|
||||||
println!("{:?} spell_dmg mods : {:?}", self.name, spell_dmg_mods);
|
// println!("{:?} spell_dmg mods : {:?}", self.name, spell_dmg_mods);
|
||||||
let modified_spell_dmg = spell_dmg_mods.iter().fold(self.spell_dmg.base, |acc, m| m.apply(acc));
|
let modified_spell_dmg = spell_dmg_mods.iter().fold(self.spell_dmg.base, |acc, m| m.apply(acc));
|
||||||
println!("{:?} spell_dmg : {:?}", self.name, modified_spell_dmg);
|
// println!("{:?} spell_dmg : {:?}", self.name, modified_spell_dmg);
|
||||||
return modified_spell_dmg;
|
return modified_spell_dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ impl Cryp {
|
|||||||
|
|
||||||
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
|
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
|
||||||
self.hp.reduce(amount);
|
self.hp.reduce(amount);
|
||||||
println!("{:?} dealt {:?} phys dmg", self.name, amount);
|
// println!("{:?} dealt {:?} phys dmg", self.name, amount);
|
||||||
return (amount, 0);
|
return (amount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -166,7 +166,8 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn can_start(&self) -> bool {
|
fn can_start(&self) -> bool {
|
||||||
self.teams.len() == self.team_num
|
return self.teams.len() == self.team_num
|
||||||
|
&& self.teams.iter().all(|t| t.cryps.len() == self.team_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&mut self) -> &mut Game {
|
fn start(&mut self) -> &mut Game {
|
||||||
@ -299,7 +300,7 @@ impl Game {
|
|||||||
let mob_team_id = Uuid::nil();
|
let mob_team_id = Uuid::nil();
|
||||||
let mobs = self.team_by_id(mob_team_id).clone();
|
let mobs = self.team_by_id(mob_team_id).clone();
|
||||||
let target_id = mobs.cryps.iter().find(|c| !c.is_ko()).map(|c| c.id).unwrap();
|
let target_id = mobs.cryps.iter().find(|c| !c.is_ko()).map(|c| c.id).unwrap();
|
||||||
println!("targeting {:?}", target_id);
|
|
||||||
// TODO attack multiple players based on some criteria
|
// TODO attack multiple players based on some criteria
|
||||||
for incoming_skill_id in self.stack.clone().iter()
|
for incoming_skill_id in self.stack.clone().iter()
|
||||||
.filter(|s| s.target_cryp_id.is_none() && s.target_team_id == mob_team_id)
|
.filter(|s| s.target_cryp_id.is_none() && s.target_team_id == mob_team_id)
|
||||||
@ -311,23 +312,56 @@ impl Game {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// each cryp can be the target of
|
||||||
|
// incomingSkills / activeCryps rounded up
|
||||||
|
// maybe a problem with friendly / self targeting skills
|
||||||
|
fn cryp_targetable(&mut self, team_id: Uuid, cryp_id: Uuid) -> Result<(), Error> {
|
||||||
|
// whose team is this?
|
||||||
|
let team = self.teams.iter()
|
||||||
|
.find(|t| t.id == team_id)
|
||||||
|
.ok_or(err_msg("team not found"))?;
|
||||||
|
|
||||||
|
// is the target in the team?
|
||||||
|
let cryp = team.cryps.iter()
|
||||||
|
.find(|c| c.id == cryp_id)
|
||||||
|
.ok_or(err_msg("cryp not in team"))?;
|
||||||
|
|
||||||
|
if cryp.is_ko() {
|
||||||
|
return Err(err_msg("you cannot target ko cryps"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let incoming = self.stack.iter()
|
||||||
|
.filter(|i| i.target_team_id == team.id)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
let incoming = incoming as u32 as f64;
|
||||||
|
|
||||||
|
let active_cryps = team.cryps.iter()
|
||||||
|
.filter(|c| !c.is_ko())
|
||||||
|
.count();
|
||||||
|
|
||||||
|
let active_cryps = active_cryps as u32 as f64;
|
||||||
|
let max_targets = (incoming / active_cryps).ceil();
|
||||||
|
|
||||||
|
let targeted = self.stack.iter()
|
||||||
|
.filter(|s| s.target_cryp_id.is_some())
|
||||||
|
.filter(|s| s.target_cryp_id.unwrap() == cryp_id)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
if targeted >= max_targets as usize {
|
||||||
|
return Err(format_err!("cryp target of maximum number of skills ({:?})", max_targets));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// targets can only be added by the owner of the team
|
// targets can only be added by the owner of the team
|
||||||
fn add_target(&mut self, team_id: Uuid, cryp_id: Uuid, skill_id: Uuid) -> Result<&mut Cast, Error> {
|
fn add_target(&mut self, team_id: Uuid, cryp_id: Uuid, skill_id: Uuid) -> Result<&mut Cast, Error> {
|
||||||
if self.phase != Phase::Target {
|
if self.phase != Phase::Target {
|
||||||
return Err(err_msg("game not in target phase"));
|
return Err(err_msg("game not in target phase"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
self.cryp_targetable(team_id, cryp_id)?;
|
||||||
// whose team is this?
|
|
||||||
let team = self.team_by_id(team_id);
|
|
||||||
|
|
||||||
// is the target in the team?
|
|
||||||
let cryp = team.cryp_by_id(cryp_id).ok_or(err_msg("cryp not in team"))?;
|
|
||||||
|
|
||||||
if cryp.is_ko() {
|
|
||||||
return Err(err_msg("you cannot target ko cryps"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the target
|
// set the target
|
||||||
let cast = match self.stack.iter_mut().find(|s| s.id == skill_id) {
|
let cast = match self.stack.iter_mut().find(|s| s.id == skill_id) {
|
||||||
@ -405,7 +439,7 @@ impl Game {
|
|||||||
|
|
||||||
// update the stack with the resolved skills
|
// update the stack with the resolved skills
|
||||||
self.stack = self.stack.clone().iter_mut().map(|skill| {
|
self.stack = self.stack.clone().iter_mut().map(|skill| {
|
||||||
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()).unwrap().clone();
|
let mut target = self.cryp_by_id(skill.target_cryp_id.unwrap()).unwrap().clone();
|
||||||
|
|
||||||
@ -835,235 +869,241 @@ mod tests {
|
|||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn create_2v2_test_game() -> Game {
|
fn create_2v2_test_game() -> Game {
|
||||||
// let mut i = Cryp::new()
|
let mut i = Cryp::new()
|
||||||
// .named(&"pretaliate".to_string())
|
.named(&"pretaliate".to_string())
|
||||||
// .level(8)
|
.level(8)
|
||||||
// .learn(Skill::Attack)
|
.learn(Skill::TestTouch)
|
||||||
// .create();
|
.create();
|
||||||
|
|
||||||
// let mut j = Cryp::new()
|
let mut j = Cryp::new()
|
||||||
// .named(&"poy sian".to_string())
|
.named(&"poy sian".to_string())
|
||||||
// .level(8)
|
.level(8)
|
||||||
// .learn(Skill::Attack)
|
.learn(Skill::TestTouch)
|
||||||
// .create();
|
.create();
|
||||||
|
|
||||||
// let mut x = Cryp::new()
|
let mut x = Cryp::new()
|
||||||
// .named(&"pronounced \"creeep\"".to_string())
|
.named(&"pronounced \"creeep\"".to_string())
|
||||||
// .level(8)
|
.level(8)
|
||||||
// .learn(Skill::Attack)
|
.learn(Skill::TestTouch)
|
||||||
// .create();
|
.create();
|
||||||
|
|
||||||
// let mut y = Cryp::new()
|
let mut y = Cryp::new()
|
||||||
// .named(&"lemongrass tea".to_string())
|
.named(&"lemongrass tea".to_string())
|
||||||
// .level(8)
|
.level(8)
|
||||||
// .learn(Skill::Attack)
|
.learn(Skill::TestTouch)
|
||||||
// .create();
|
.create();
|
||||||
|
|
||||||
// let mut game = Game::new();
|
let mut game = Game::new();
|
||||||
|
|
||||||
// game
|
game
|
||||||
// .set_team_num(2)
|
.set_team_num(2)
|
||||||
// .set_team_size(2)
|
.set_team_size(2)
|
||||||
// .set_pve(false);
|
.set_pve(false);
|
||||||
|
|
||||||
// let x_team_id = Uuid::new_v4();
|
let i_team_id = Uuid::new_v4();
|
||||||
// let mut x_team = Team::new(x_team_id);
|
let mut i_team = Team::new(i_team_id);
|
||||||
// x_team
|
i_team
|
||||||
// .set_cryps(vec![x]);
|
.set_cryps(vec![i,j]);
|
||||||
|
|
||||||
// let y_team_id = Uuid::new_v4();
|
let x_team_id = Uuid::new_v4();
|
||||||
// let mut y_team = Team::new(y_team_id);
|
let mut x_team = Team::new(x_team_id);
|
||||||
// y_team
|
x_team
|
||||||
// .set_cryps(vec![y]);
|
.set_cryps(vec![x,y]);
|
||||||
|
|
||||||
// game
|
game
|
||||||
// .team_add(x_team).unwrap()
|
.team_add(i_team).unwrap()
|
||||||
// .team_add(y_team).unwrap();
|
.team_add(x_team).unwrap();
|
||||||
|
|
||||||
// assert!(game.can_start());
|
assert!(game.can_start());
|
||||||
|
|
||||||
// game.start();
|
game.start();
|
||||||
|
|
||||||
// return game;
|
return game;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn phase_test() {
|
||||||
|
// let mut game = create_test_game();
|
||||||
|
|
||||||
|
// let x_team = game.teams[0].clone();
|
||||||
|
// let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
// let x_cryp = x_team.cryps[0].clone();
|
||||||
|
// let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
// let x_attack_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::Attack).unwrap();
|
||||||
|
// let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::Attack).unwrap();
|
||||||
|
|
||||||
|
// assert!(game.skill_phase_finished());
|
||||||
|
|
||||||
|
// game.target_phase_start();
|
||||||
|
|
||||||
|
// game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
||||||
|
// game.add_target(y_team.id, y_cryp.id, x_attack_id).unwrap();
|
||||||
|
|
||||||
|
// assert!(game.target_phase_finished());
|
||||||
|
|
||||||
|
// game.resolve_phase_start();
|
||||||
|
|
||||||
|
// assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn stun_test() {
|
||||||
|
// let mut game = create_test_game();
|
||||||
|
|
||||||
|
// let x_team = game.teams[0].clone();
|
||||||
|
// let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
// let x_cryp = x_team.cryps[0].clone();
|
||||||
|
// let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
// let x_stun_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestStun).unwrap();
|
||||||
|
// let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
|
// assert!(game.skill_phase_finished());
|
||||||
|
// game.target_phase_start();
|
||||||
|
|
||||||
|
// game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
||||||
|
// game.add_target(y_team.id, y_cryp.id, x_stun_id).unwrap();
|
||||||
|
|
||||||
|
// assert!(game.target_phase_finished());
|
||||||
|
// game.resolve_phase_start();
|
||||||
|
|
||||||
|
// // should auto progress back to skill phase
|
||||||
|
// assert!(game.phase == Phase::Skill);
|
||||||
|
|
||||||
|
// assert!(game.team_by_id(y_team.id).cryps[0].is_stunned());
|
||||||
|
// assert!(game.team_by_id(y_team.id).skills_required() == 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn cooldown_test() {
|
||||||
|
// let mut game = create_test_game();
|
||||||
|
|
||||||
|
// let x_team = game.teams[0].clone();
|
||||||
|
// let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
// let x_cryp = x_team.cryps[0].clone();
|
||||||
|
// let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
// let x_stun_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestTouch).unwrap();
|
||||||
|
// let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
|
// game.target_phase_start();
|
||||||
|
// game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
||||||
|
// game.add_target(y_team.id, y_cryp.id, x_stun_id).unwrap();
|
||||||
|
|
||||||
|
// game.resolve_phase_start();
|
||||||
|
|
||||||
|
// // should auto progress back to skill phase
|
||||||
|
// assert!(game.phase == Phase::Skill);
|
||||||
|
|
||||||
|
// // after 1 turn block should be off cooldown
|
||||||
|
// assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
||||||
|
// assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
||||||
|
|
||||||
|
// // second round
|
||||||
|
// // now we block and it should go back on cd
|
||||||
|
// let _x_block_id = game.add_skill(x_team.id, x_cryp.id, None, Skill::Block).unwrap();
|
||||||
|
// let _y_block_id = game.add_skill(y_team.id, y_cryp.id, None, Skill::Block).unwrap();
|
||||||
|
|
||||||
|
// game.target_phase_start();
|
||||||
|
|
||||||
|
// assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_some());
|
||||||
|
// assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_some());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn block_test() {
|
||||||
|
// let mut game = create_test_game();
|
||||||
|
|
||||||
|
// let x_team = game.teams[0].clone();
|
||||||
|
// let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
// let x_cryp = x_team.cryps[0].clone();
|
||||||
|
// let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
// // ensure that you can't pass a target for a block
|
||||||
|
// assert!(game.add_skill(x_team.id, x_cryp.id, Some(y_cryp.id), Skill::TestBlock).is_err());
|
||||||
|
|
||||||
|
// let x_block_id = game.add_skill(x_team.id, x_cryp.id, None, Skill::TestBlock).unwrap();
|
||||||
|
// let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestStun).unwrap();
|
||||||
|
|
||||||
|
// game.target_phase_start();
|
||||||
|
|
||||||
|
// // ensure you can't target a self targeting skill
|
||||||
|
// assert!(game.add_target(y_team.id, y_cryp.id, x_block_id).is_err());
|
||||||
|
|
||||||
|
// // ensure you can't target another team's skills
|
||||||
|
// assert!(game.add_target(x_team.id, y_cryp.id, y_attack_id).is_err());
|
||||||
|
|
||||||
|
// game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
||||||
|
|
||||||
|
// game.resolve_phase_start();
|
||||||
|
|
||||||
|
// // should not be stunned because of block
|
||||||
|
// assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn drain_test() {
|
||||||
|
// let mut game = create_test_game();
|
||||||
|
|
||||||
|
// let x_team = game.teams[0].clone();
|
||||||
|
// let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
// let x_cryp = x_team.cryps[0].clone();
|
||||||
|
// let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
// let x_drain_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestDrain).unwrap();
|
||||||
|
// let y_touch_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
|
// game.target_phase_start();
|
||||||
|
|
||||||
|
// game.add_target(x_team.id, x_cryp.id, y_touch_id).unwrap();
|
||||||
|
// game.add_target(y_team.id, y_cryp.id, x_drain_id).unwrap();
|
||||||
|
|
||||||
|
// 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.target_phase_start();
|
||||||
|
|
||||||
|
// assert!(game.resolved.iter().any(|r| r.skill == Skill::DrainTick));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn phase_test() {
|
|
||||||
let mut game = create_test_game();
|
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
|
||||||
let y_team = game.teams[1].clone();
|
|
||||||
|
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
|
||||||
|
|
||||||
let x_attack_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::Attack).unwrap();
|
|
||||||
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::Attack).unwrap();
|
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
|
||||||
|
|
||||||
game.target_phase_start();
|
|
||||||
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
|
||||||
game.add_target(y_team.id, y_cryp.id, x_attack_id).unwrap();
|
|
||||||
|
|
||||||
assert!(game.target_phase_finished());
|
|
||||||
|
|
||||||
game.resolve_phase_start();
|
|
||||||
|
|
||||||
assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn stun_test() {
|
|
||||||
let mut game = create_test_game();
|
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
|
||||||
let y_team = game.teams[1].clone();
|
|
||||||
|
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
|
||||||
|
|
||||||
let x_stun_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestStun).unwrap();
|
|
||||||
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
|
||||||
game.target_phase_start();
|
|
||||||
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
|
||||||
game.add_target(y_team.id, y_cryp.id, x_stun_id).unwrap();
|
|
||||||
|
|
||||||
assert!(game.target_phase_finished());
|
|
||||||
game.resolve_phase_start();
|
|
||||||
|
|
||||||
// should auto progress back to skill phase
|
|
||||||
assert!(game.phase == Phase::Skill);
|
|
||||||
|
|
||||||
assert!(game.team_by_id(y_team.id).cryps[0].is_stunned());
|
|
||||||
assert!(game.team_by_id(y_team.id).skills_required() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cooldown_test() {
|
|
||||||
let mut game = create_test_game();
|
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
|
||||||
let y_team = game.teams[1].clone();
|
|
||||||
|
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
|
||||||
|
|
||||||
let x_stun_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestTouch).unwrap();
|
|
||||||
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
|
||||||
|
|
||||||
game.target_phase_start();
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
|
||||||
game.add_target(y_team.id, y_cryp.id, x_stun_id).unwrap();
|
|
||||||
|
|
||||||
game.resolve_phase_start();
|
|
||||||
|
|
||||||
// should auto progress back to skill phase
|
|
||||||
assert!(game.phase == Phase::Skill);
|
|
||||||
|
|
||||||
// after 1 turn block should be off cooldown
|
|
||||||
assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
|
||||||
assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
|
||||||
|
|
||||||
// second round
|
|
||||||
// now we block and it should go back on cd
|
|
||||||
let _x_block_id = game.add_skill(x_team.id, x_cryp.id, None, Skill::Block).unwrap();
|
|
||||||
let _y_block_id = game.add_skill(y_team.id, y_cryp.id, None, Skill::Block).unwrap();
|
|
||||||
|
|
||||||
game.target_phase_start();
|
|
||||||
|
|
||||||
assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_some());
|
|
||||||
assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_some());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn block_test() {
|
|
||||||
let mut game = create_test_game();
|
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
|
||||||
let y_team = game.teams[1].clone();
|
|
||||||
|
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
|
||||||
|
|
||||||
// ensure that you can't pass a target for a block
|
|
||||||
assert!(game.add_skill(x_team.id, x_cryp.id, Some(y_cryp.id), Skill::TestBlock).is_err());
|
|
||||||
|
|
||||||
let x_block_id = game.add_skill(x_team.id, x_cryp.id, None, Skill::TestBlock).unwrap();
|
|
||||||
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestStun).unwrap();
|
|
||||||
|
|
||||||
game.target_phase_start();
|
|
||||||
|
|
||||||
// ensure you can't target a self targeting skill
|
|
||||||
assert!(game.add_target(y_team.id, y_cryp.id, x_block_id).is_err());
|
|
||||||
|
|
||||||
// ensure you can't target another team's skills
|
|
||||||
assert!(game.add_target(x_team.id, y_cryp.id, y_attack_id).is_err());
|
|
||||||
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
|
||||||
|
|
||||||
game.resolve_phase_start();
|
|
||||||
|
|
||||||
// should not be stunned because of block
|
|
||||||
assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn drain_test() {
|
|
||||||
let mut game = create_test_game();
|
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
|
||||||
let y_team = game.teams[1].clone();
|
|
||||||
|
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
|
||||||
|
|
||||||
let x_drain_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestDrain).unwrap();
|
|
||||||
let y_touch_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
|
||||||
|
|
||||||
game.target_phase_start();
|
|
||||||
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_touch_id).unwrap();
|
|
||||||
game.add_target(y_team.id, y_cryp.id, x_drain_id).unwrap();
|
|
||||||
|
|
||||||
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.target_phase_start();
|
|
||||||
|
|
||||||
assert!(game.resolved.iter().any(|r| r.skill == Skill::DrainTick));
|
|
||||||
|
|
||||||
println!("{:#?}", game);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ko_pve_test() {
|
fn ko_pve_test() {
|
||||||
let mut game = create_test_game();
|
let mut game = create_2v2_test_game();
|
||||||
|
|
||||||
let x_team = game.teams[0].clone();
|
let i_team = game.teams[0].clone();
|
||||||
let y_team = game.teams[1].clone();
|
let x_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
let i_cryp = i_team.cryps[0].clone();
|
||||||
|
let j_cryp = i_team.cryps[1].clone();
|
||||||
let x_cryp = x_team.cryps[0].clone();
|
let x_cryp = x_team.cryps[0].clone();
|
||||||
let y_cryp = y_team.cryps[0].clone();
|
let y_cryp = x_team.cryps[1].clone();
|
||||||
|
|
||||||
|
let i_attack_id = game.add_skill(i_team.id, i_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let j_attack_id = game.add_skill(i_team.id, j_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let x_attack_id = game.add_skill(x_team.id, x_cryp.id, Some(i_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let y_attack_id = game.add_skill(x_team.id, y_cryp.id, Some(i_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
let x_attack_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::Attack).unwrap();
|
|
||||||
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::Attack).unwrap();
|
|
||||||
|
|
||||||
assert!(game.skill_phase_finished());
|
assert!(game.skill_phase_finished());
|
||||||
|
|
||||||
game.target_phase_start();
|
game.target_phase_start();
|
||||||
|
|
||||||
game.add_target(x_team.id, x_cryp.id, y_attack_id).unwrap();
|
game.add_target(i_team.id, i_cryp.id, x_attack_id).unwrap();
|
||||||
game.add_target(y_team.id, y_cryp.id, x_attack_id).unwrap();
|
assert!(game.add_target(i_team.id, i_cryp.id, y_attack_id).is_err());
|
||||||
|
game.add_target(i_team.id, j_cryp.id, y_attack_id).unwrap();
|
||||||
|
|
||||||
|
game.add_target(x_team.id, x_cryp.id, i_attack_id).unwrap();
|
||||||
|
game.add_target(x_team.id, y_cryp.id, j_attack_id).unwrap();
|
||||||
|
|
||||||
assert!(game.target_phase_finished());
|
assert!(game.target_phase_finished());
|
||||||
|
|
||||||
@ -1071,8 +1111,30 @@ mod tests {
|
|||||||
|
|
||||||
assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
assert!([Phase::Skill, Phase::Finish].contains(&game.phase));
|
||||||
|
|
||||||
|
// kill a cryp
|
||||||
|
game.team_by_id(i_team.id).cryp_by_id(i_cryp.id).unwrap().hp.reduce(u64::max_value());
|
||||||
|
|
||||||
|
// add some more skills
|
||||||
|
// let i_attack_id = game.add_skill(i_team.id, i_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let j_attack_id = game.add_skill(i_team.id, j_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let x_attack_id = game.add_skill(x_team.id, x_cryp.id, Some(i_team.id), Skill::TestTouch).unwrap();
|
||||||
|
let y_attack_id = game.add_skill(x_team.id, y_cryp.id, Some(i_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
|
assert!(game.skill_phase_finished());
|
||||||
|
game.target_phase_start();
|
||||||
|
|
||||||
|
assert!(game.team_by_id(i_team.id).skills_required() == 1);
|
||||||
|
assert!(game.cryp_targetable(i_team.id, i_cryp.id).is_err());
|
||||||
|
assert!(game.cryp_targetable(i_team.id, j_cryp.id).is_ok());
|
||||||
|
|
||||||
|
assert!(game.add_target(i_team.id, i_cryp.id, x_attack_id).is_err());
|
||||||
|
game.add_target(i_team.id, j_cryp.id, x_attack_id).unwrap();
|
||||||
|
game.add_target(i_team.id, j_cryp.id, y_attack_id).unwrap();
|
||||||
|
|
||||||
|
game.add_target(x_team.id, x_cryp.id, j_attack_id).unwrap();
|
||||||
|
game.add_target(x_team.id, y_cryp.id, j_attack_id).unwrap();
|
||||||
|
|
||||||
|
assert!(game.target_phase_finished());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -669,7 +669,10 @@ impl Skill {
|
|||||||
|
|
||||||
Skill::TestBlock => 1,
|
Skill::TestBlock => 1,
|
||||||
Skill::TestStun => 2,
|
Skill::TestStun => 2,
|
||||||
_ => panic!("{:?} does not have a duration", self),
|
_ => {
|
||||||
|
println!("{:?} does not have a duration", self);
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user