diff --git a/client/src/scenes/combat.cryps.js b/client/src/scenes/combat.cryps.js index 231430db..379929ab 100755 --- a/client/src/scenes/combat.cryps.js +++ b/client/src/scenes/combat.cryps.js @@ -54,6 +54,7 @@ class CrypImage extends Phaser.GameObjects.Image { class CrypSkill extends Phaser.GameObjects.Text { constructor(scene, row, iter, team, skill, cryp) { + console.log(skill, cryp); // Avatar will be a property of cryp const { CRYP_MARGIN, TEXT_MARGIN, TEAM_MARGIN, X_PADDING, Y_PADDING, @@ -151,6 +152,10 @@ function renderSkills(scene, group, cryp, game, team, iter) { }); } else if (game.phase === 'Target') { const blockSkill = game.stack.find(skill => skill.source_cryp_id === cryp.id); + + // cryp not casting this turn + if (!blockSkill) return false; + group.add(scene.add.existing(new CrypSkill(scene, 1, iter, team, blockSkill, cryp))); } } diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 3f304363..14975ed4 100755 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -5,8 +5,6 @@ # WORK WORK - * unwrap account for all functions except list - * handle unserializable cryps * Global rolls @@ -14,6 +12,7 @@ * skills * handle setting account better maybe? * ensure cryp untargetable and doesn't resolve when KO + * remove all statuses etc when KO * calculate * hp increase/decrease * private fields for opponents diff --git a/server/src/cryp.rs b/server/src/cryp.rs index d7b8f6bb..72aaa149 100755 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -360,6 +360,7 @@ pub fn cryp_spawn(params: CrypSpawnParams, tx: &mut Transaction, account: &Accou pub fn cryp_learn(params: CrypLearnParams, tx: &mut Transaction, account: &Account) -> Result { let mut cryp = cryp_get(tx, params.id, account.id)?; + // done here because i teach them a tonne of skills for tests let max_skills = 4; if cryp.skills.len() >= max_skills { return Err(format_err!("cryp at max skills ({:?})", max_skills)); diff --git a/server/src/game.rs b/server/src/game.rs index 3c72f300..8c5c546f 100755 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -31,7 +31,10 @@ impl Team { } fn skills_required(&self) -> usize { - let required = self.cryps.iter().filter(|c| c.available_skills().len() > 0).collect::>().len(); + let required = self.cryps.iter() + .filter(|c| !c.is_ko()) + .filter(|c| c.available_skills().len() > 0) + .collect::>().len(); // println!("{:?} requires {:?} skills this turn", self.id, required); return required; } @@ -218,6 +221,10 @@ impl Game { None => return Err(err_msg("cryp not in team")), }; + if cryp.is_ko() { + return Err(err_msg("cryp is ko")); + } + // check the cryp has the skill if !cryp.knows(skill) { return Err(err_msg("cryp does not have that skill")); @@ -291,11 +298,13 @@ impl Game { { let mob_team_id = Uuid::nil(); 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(); + println!("targeting {:?}", target_id); // TODO attack multiple players based on some criteria for incoming_skill_id in self.stack.clone().iter() .filter(|s| s.target_cryp_id.is_none() && s.target_team_id == mob_team_id) .map(|s| s.id) { - self.add_target(mob_team_id, mobs.cryps[0].id, incoming_skill_id).unwrap(); + self.add_target(mob_team_id, target_id, incoming_skill_id).unwrap(); } } @@ -376,6 +385,7 @@ impl Game { // update the stack with the resolved skills self.stack = self.stack.clone().iter_mut().map(|skill| { + 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()).unwrap().clone(); @@ -405,6 +415,10 @@ impl Game { for mut cryp in self.all_cryps() { // println!("progressing durations for {:?}", cryp.name); + if cryp.is_ko() { + continue; + } + // only reduce cooldowns if no cd was used // have to borrow self for the skill check { @@ -795,6 +809,59 @@ mod tests { return game; } + fn create_2v2_test_game() -> Game { + let mut i = Cryp::new() + .named(&"pretaliate".to_string()) + .level(8) + .learn(Skill::Attack) + .create(); + + let mut j = Cryp::new() + .named(&"poy sian".to_string()) + .level(8) + .learn(Skill::Attack) + .create(); + + let mut x = Cryp::new() + .named(&"pronounced \"creeep\"".to_string()) + .level(8) + .learn(Skill::Attack) + .create(); + + let mut y = Cryp::new() + .named(&"lemongrass tea".to_string()) + .level(8) + .learn(Skill::Attack) + .create(); + + let mut game = Game::new(); + + game + .set_team_num(2) + .set_team_size(2) + .set_pve(false); + + let x_team_id = Uuid::new_v4(); + let mut x_team = Team::new(x_team_id); + x_team + .set_cryps(vec![x]); + + let y_team_id = Uuid::new_v4(); + let mut y_team = Team::new(y_team_id); + y_team + .set_cryps(vec![y]); + + game + .team_add(x_team).unwrap() + .team_add(y_team).unwrap(); + + assert!(game.can_start()); + + game.start(); + + return game; + } + #[test] fn phase_test() { let mut game = create_test_game(); @@ -952,4 +1019,34 @@ mod tests { // println!("{:#?}", game); } + #[test] + fn ko_pve_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; + } + + }