resolved log

This commit is contained in:
ntr 2018-10-26 19:08:00 +11:00
parent fbf02c26e1
commit 12d30fbc82
4 changed files with 150 additions and 42 deletions

View File

@ -4,30 +4,19 @@
* Prove something * Prove something
# WORK WORK # WORK WORK
* QOL
* auto login
* cryp list on spawn
* ws reconnect ✔
* Levelling ✔ * move rpc functions out
* unwrap account for all functions except list
* Global rolls * Global rolls
* Logins ✔️
* Cryp Ownership ✔
* Matchmaking
* Lobbies
* Create
* Join
* Resolve
* Stats * Stats
* Scrabble grid * Scrabble grid
* skills * skills
* offensive -> choose target ✔ * offensive -> choose target ✔
* private fields for opponents * private fields for opponents
* cooldowns reduce each turn
* teach cyps skills * teach cyps skills
* can you attack yourself? * can you attack yourself?
* fetch existing battles * fetch existing battles
@ -50,6 +39,17 @@
* Cryp Generation * Cryp Generation
* *
* ws reconnect ✔
* Levelling ✔
* Logins ✔️
* Cryp Ownership ✔
* Matchmaking ✔
* Lobbies ✔
* Create ✔
* Join ✔
* Resolve ✔
# Db maintenance # Db maintenance
* delete games when a cryp is deleted * delete games when a cryp is deleted
* does this need to happen? can have historical games * does this need to happen? can have historical games

View File

@ -26,7 +26,9 @@ impl CrypSkill {
Skill::Block => Some(1), Skill::Block => Some(1),
Skill::Dodge => Some(1), Skill::Dodge => Some(1),
Skill::Heal => Some(2), Skill::Heal => Some(2),
Skill::Stun => None, Skill::Stun => Some(2),
Skill::TestTouch => None,
Skill::TestStun => None,
}; };
CrypSkill { CrypSkill {
@ -190,12 +192,12 @@ impl Cryp {
self.skills.iter().any(|s| s.skill == skill) self.skills.iter().any(|s| s.skill == skill)
} }
pub fn skill_on_cd(&self, skill: Skill) -> bool { pub fn skill_on_cd(&self, skill: Skill) -> Option<&CrypSkill> {
self.skills.iter().any(|s| s.skill == skill && s.cd.is_some()) self.skills.iter().find(|s| s.skill == skill && s.cd.is_some())
} }
pub fn skill_can_cast(&self, skill: Skill) -> bool { pub fn skill_can_cast(&self, skill: Skill) -> bool {
self.skills.iter().any(|s| s.skill == skill && !s.can_cast(self)) self.skills.iter().any(|s| s.skill == skill && s.can_cast(self))
} }
pub fn rez(&mut self) -> &mut Cryp { pub fn rez(&mut self) -> &mut Cryp {
@ -213,6 +215,10 @@ impl Cryp {
Skill::Stun => self.str, Skill::Stun => self.str,
Skill::Dodge => self.agi, Skill::Dodge => self.agi,
Skill::Heal => self.int, Skill::Heal => self.int,
// test skills
Skill::TestTouch => self.int,
Skill::TestStun => self.str,
}; };
let mut roll = Roll { base, result: base }; let mut roll = Roll { base, result: base };

View File

@ -18,6 +18,7 @@ pub struct Team {
cryps: Vec<Cryp>, cryps: Vec<Cryp>,
skills: Vec<Cast>, skills: Vec<Cast>,
incoming: Vec<Cast>, incoming: Vec<Cast>,
resolved: Vec<Cast>,
} }
impl Team { impl Team {
@ -27,6 +28,7 @@ impl Team {
cryps: vec![], cryps: vec![],
skills: vec![], skills: vec![],
incoming: vec![], incoming: vec![],
resolved: vec![]
}; };
} }
@ -41,6 +43,13 @@ impl Team {
self self
} }
fn update_cryp(&mut self, updated: Cryp) -> &mut Team {
let index = self.cryps.iter().position(|c| c.id == updated.id).unwrap();
self.cryps.remove(index);
self.cryps.push(updated);
self
}
pub fn cryp_by_id(&mut self, id: Uuid) -> Option<&mut Cryp> { pub fn cryp_by_id(&mut self, id: Uuid) -> Option<&mut Cryp> {
self.cryps.iter_mut().find(|c| c.id == id) self.cryps.iter_mut().find(|c| c.id == id)
} }
@ -129,26 +138,15 @@ impl Game {
panic!("cryp not in game"); panic!("cryp not in game");
} }
// fn update_team(&mut self, updated: Team) -> &mut Game { fn update_team(&mut self, updated: &mut Team) -> &mut Game {
// match self.teams.iter().position(|t| t.id == updated.id) { match self.teams.iter().position(|t| t.id == updated.id) {
// Some(index) => { Some(index) => {
// self.teams.remove(index); self.teams.remove(index);
// self.teams.push(updated); self.teams.push(updated.clone());
// self self
// }
// None => panic!("team not in game"),
// }
// }
fn update_cryp(&mut self, updated: Cryp) -> &mut Game {
for team in self.teams.iter_mut() {
if let Some(index) = team.cryps.iter().position(|c| c.id == updated.id) {
team.cryps.remove(index);
team.cryps.push(updated);
break;
} }
None => panic!("team not in game"),
} }
self
} }
fn can_start(&self) -> bool { fn can_start(&self) -> bool {
@ -214,15 +212,16 @@ impl Game {
return Err(err_msg("cryp does not have that skill")); return Err(err_msg("cryp does not have that skill"));
} }
if cryp.skill_on_cd(skill) { if cryp.skill_on_cd(skill).is_some() {
return Err(err_msg("abiltity on cooldown")); return Err(err_msg("abiltity on cooldown"));
} }
if cryp.skill_can_cast(skill) { if !cryp.skill_can_cast(skill) {
return Err(err_msg("cryp cannot cast spell")); return Err(err_msg("cryp cannot cast spell"));
} }
} }
// replace cryp skill // replace cryp skill
if let Some(s) = team.skills.iter_mut().position(|s| s.cryp_id == cryp_id) { if let Some(s) = team.skills.iter_mut().position(|s| s.cryp_id == cryp_id) {
team.skills.remove(s); team.skills.remove(s);
@ -333,11 +332,13 @@ impl Game {
// they better fuckin be there // they better fuckin be there
let mut cryp = self.cryp_by_id(incoming.cryp_id).clone(); let mut cryp = self.cryp_by_id(incoming.cryp_id).clone();
let mut target_cryp = self.cryp_by_id(incoming.target_cryp_id.unwrap()).clone(); let mut target_cryp = self.cryp_by_id(incoming.target_cryp_id.unwrap()).clone();
println!("{:?} is attacking {:?}", cryp.name, target_cryp.name); let resolution = incoming.resolve(&mut cryp, &mut target_cryp);
incoming.resolve(&mut cryp, &mut target_cryp); team.resolved.push(*resolution);
self.update_cryp(target_cryp); team.update_cryp(target_cryp);
self.update_team(team);
} }
} }
self self
} }
@ -638,6 +639,55 @@ mod tests {
use game::*; use game::*;
use cryp::*; use cryp::*;
fn create_test_game() -> Game {
let x = Cryp::new()
.named(&"pronounced \"creeep\"".to_string())
.level(8)
.learn(Skill::TestStun)
.learn(Skill::TestTouch)
.learn(Skill::Block)
.create();
let _x_id = x.id;
let y = Cryp::new()
.named(&"lemongrass tea".to_string())
.level(8)
.learn(Skill::TestStun)
.learn(Skill::TestTouch)
.learn(Skill::Block)
.create();
let _y_id = y.id;
let mut game = Game::new();
game
.set_team_num(2)
.set_team_size(1)
.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
.add_team(x_team).unwrap()
.add_team(y_team).unwrap();
assert!(game.can_start());
game.start();
return game;
}
#[test] #[test]
fn game_test() { fn game_test() {
let x = Cryp::new() let x = Cryp::new()
@ -701,4 +751,39 @@ mod tests {
return; return;
} }
#[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, y_team.id, Skill::TestStun).unwrap();
let y_attack_id = game.add_skill(y_team.id, y_cryp.id, 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.damage_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);
// should be on cooldown now
assert!(game.add_skill(x_team.id, x_cryp.id, y_team.id, Skill::Stun).is_err());
println!("{:#?}", game);
// 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());
}
} }

View File

@ -16,6 +16,9 @@ pub enum Skill {
Heal, Heal,
Stun, Stun,
Dodge, Dodge,
// used by tests to do no dmg
TestTouch,
TestStun,
} }
@ -26,6 +29,7 @@ pub struct Cast {
pub cryp_id: Uuid, pub cryp_id: Uuid,
pub target_cryp_id: Option<Uuid>, pub target_cryp_id: Option<Uuid>,
pub target_team_id: Uuid, pub target_team_id: Uuid,
pub roll: Option<Roll>,
} }
impl Cast { impl Cast {
@ -36,18 +40,31 @@ impl Cast {
target_cryp_id: None, target_cryp_id: None,
target_team_id, target_team_id,
skill, skill,
roll: None,
}; };
} }
pub fn resolve(&mut self, cryp: &mut Cryp, target: &mut Cryp) -> &mut Cast { pub fn resolve(&mut self, cryp: &mut Cryp, target: &mut Cryp) -> &mut Cast {
let roll = cryp.roll(self.skill); let roll = cryp.roll(self.skill);
println!("{:?} -> {:?} -> {:?}", cryp.name, self.skill, target.name);
match self.skill { match self.skill {
// the real deal
Skill::Stun => target.stun(roll), Skill::Stun => target.stun(roll),
_ => target.attack(roll), Skill::Attack => target.attack(roll),
Skill::Block => target,
Skill::Heal => target,
Skill::Dodge => target,
// Test Skills
Skill::TestStun => target.stun(roll),
Skill::TestTouch => target,
}; };
println!("{:?} gettin clapped for {:?}", target.name, roll.result); println!("{:?} gettin clapped for {:?}", target.name, roll.result);
self.roll = Some(roll);
self self
} }