This commit is contained in:
ntr 2019-04-29 18:42:03 +10:00
parent b2bfe8cf2a
commit 18aef974b6
4 changed files with 60 additions and 17 deletions

View File

@ -278,6 +278,11 @@ impl Cryp {
self.green_life.value == 0
}
pub fn force_ko(&mut self) -> &mut Cryp {
self.green_life.value = 0;
self
}
pub fn immune(&self, skill: Skill) -> Option<Immunity> {
// also checked in resolve stage so shouldn't happen really
if self.is_ko() {

View File

@ -22,7 +22,6 @@ use instance::{instance_game_finished, global_game_finished};
pub enum Phase {
Start,
Skill,
Target,
Resolve,
Finish,
}
@ -568,19 +567,29 @@ impl Game {
}
fn phase_timed_out(&self) -> bool {
Utc::now().signed_duration_since(self.phase_start).num_seconds() > 30
Utc::now().signed_duration_since(self.phase_start).num_seconds() > 60
}
pub fn upkeep(mut self) -> Game {
// give players a ready status
// on time out if not enough skills selected
// add a warning
// on 3 warnings forfeit
if self.phase == Phase::Skill && self.phase_timed_out() {
self = self.resolve_phase_start();
if self.phase != Phase::Skill {
panic!("{:?} game not in skill phase during upkeep", self);
}
if !self.phase_timed_out() {
return self;
}
for player in self.players.iter_mut() {
if !player.ready {
player.set_ready(true);
player.add_warning();
if player.warnings >= 3 {
player.forfeit();
}
}
}
self = self.resolve_phase_start();
self
}
}
@ -998,12 +1007,12 @@ mod tests {
let i_player_id = Uuid::new_v4();
i.account = i_player_id;
j.account = i_player_id;
let mut i_player = Player::new(i_player_id, &"ntr".to_string(), vec![i, j]);
let i_player = Player::new(i_player_id, &"ntr".to_string(), vec![i, j]);
let x_player_id = Uuid::new_v4();
x.account = x_player_id;
y.account = x_player_id;
let mut x_player = Player::new(x_player_id, &"mashy".to_string(), vec![x, y]);
let x_player = Player::new(x_player_id, &"mashy".to_string(), vec![x, y]);
game
.player_add(i_player).unwrap()
@ -1027,6 +1036,9 @@ mod tests {
game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::Attack).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::Attack).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
assert!(game.skill_phase_finished());
game = game.resolve_phase_start();
@ -1049,6 +1061,9 @@ mod tests {
let _x_stun_id = game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
assert!(game.skill_phase_finished());
game = game.resolve_phase_start();
@ -1079,6 +1094,9 @@ mod tests {
let _x_stun_id = game.add_skill(x_player.id, x_cryp.id, Some(y_cryp.id), Skill::TestStun).unwrap();
game.add_skill(y_player.id, y_cryp.id, Some(x_cryp.id), Skill::Attack).unwrap();
game.player_ready(x_player.id).unwrap();
game.player_ready(y_player.id).unwrap();
assert!(game.skill_phase_finished());
game = game.resolve_phase_start();
@ -1291,8 +1309,9 @@ mod tests {
#[test]
fn upkeep_test() {
let mut game = create_2v2_test_game();
game.phase_start = Utc::now().checked_sub_signed(Duration::seconds(31)).unwrap();
println!("{:?}", game.upkeep());
game.players[0].set_ready(true);
game.phase_start = Utc::now().checked_sub_signed(Duration::seconds(61)).unwrap();
game = game.upkeep();
assert!(game.players[1].warnings == 1);
}
}

View File

@ -230,11 +230,16 @@ impl Instance {
.ok_or(err_msg("could not find matchup in current round"))?
.finished = true;
let winner = game.winner().ok_or(err_msg("game not finished"))?;
// if you don't win, you lose
// ties can happen if both players forfeit
let winner_id = match game.winner() {
Some(w) => w.id,
None => Uuid::nil(),
};
for player in game.players.iter() {
let mut player = self.account_player(player.id)?;
match player.id == winner.id {
match player.id == winner_id {
true => player.add_win(),
false => player.add_loss(),
};
@ -663,7 +668,7 @@ pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account
}
pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
let mut instance = instance_get(tx, params.instance_id)?;
let instance = instance_get(tx, params.instance_id)?;
if let Some(game_id) = instance.current_game(account.id) {
let game = game_get(tx, game_id)?;

View File

@ -32,6 +32,7 @@ pub struct Player {
pub cryps: Vec<Cryp>,
pub bot: bool,
pub ready: bool,
pub warnings: u8,
}
impl Player {
@ -44,6 +45,7 @@ impl Player {
cryps,
bot: false,
ready: false,
warnings: 0,
}
}
@ -57,6 +59,18 @@ impl Player {
self
}
pub fn add_warning(&mut self) -> &mut Player {
self.warnings += 1;
self
}
pub fn forfeit(&mut self) -> &mut Player {
for cryp in self.cryps.iter_mut() {
cryp.force_ko();
}
self
}
pub fn add_win(&mut self) -> &mut Player {
self.score.wins += 1;
self.set_ready(false);