instance ready rejoins

This commit is contained in:
ntr 2019-03-01 14:44:27 +11:00
parent 8abe18b0f1
commit b1be8aa3bf
2 changed files with 63 additions and 32 deletions

View File

@ -732,19 +732,19 @@ pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account)
Ok(game) Ok(game)
} }
pub fn game_instance_new(tx: &mut Transaction, player: Player, pve: bool) -> Result<Game, Error> { pub fn game_instance_new(tx: &mut Transaction, player: Player, game_id: Uuid) -> Result<Game, Error> {
// create the game // create the game
let mut game = Game::new(); let mut game = Game::new();
let game_id = game.id; game.id = game_id;
game game
.set_pve(pve) .set_pve(false)
.set_team_num(2) .set_team_num(2)
.set_team_size(3) .set_team_size(3)
.set_mode(GameMode::Pvp); .set_mode(GameMode::Pvp);
// create the initiators team // create the initiators team
let mut team = Team::new(player.id); let mut team = Team::new(player.account);
team.set_cryps(player.cryps); team.set_cryps(player.cryps);
game.team_add(team)?; game.team_add(team)?;

View File

@ -14,7 +14,7 @@ use account::Account;
use player::{Player, player_create, player_get, player_update}; use player::{Player, player_create, player_get, player_update};
use cryp::{Cryp, cryp_get}; use cryp::{Cryp, cryp_get};
use mob::{instance_mobs}; use mob::{instance_mobs};
use game::{Game, Team, game_get, game_instance_new, game_instance_join}; use game::{Game, Team, game_get, game_write, game_instance_new, game_instance_join};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
enum InstancePhase { enum InstancePhase {
@ -27,7 +27,7 @@ enum InstancePhase {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct Round { struct Round {
player_ids: Vec<Uuid>, player_ids: Vec<Uuid>,
game_id: Option<Uuid>, game_id: Uuid,
outcome: Option<(Uuid, Uuid)>, outcome: Option<(Uuid, Uuid)>,
} }
@ -87,6 +87,36 @@ impl Instance {
Ok(self) Ok(self)
} }
fn bot_vs_player_game(&self, player: &Player) -> Game {
let current_round = self.current_round(player);
let plr = self.players.clone().into_iter().find(|p| p.id == player.id).unwrap();
let bot = self.players.clone().into_iter().find(|p| p.id != player.id).unwrap();
let mut game = Game::new();
game.id = current_round.game_id;
game
.set_pve(true)
.set_team_num(2)
.set_team_size(3);
// add the players
let mut plr_team = Team::new(plr.account);
plr_team.set_cryps(plr.cryps);
let mut bot_team = Team::new(bot.account);
bot_team.set_cryps(bot.cryps);
bot_team.set_bot();
game
.team_add(plr_team).unwrap()
.team_add(bot_team).unwrap();
game.start();
game
}
fn can_start(&self) -> bool { fn can_start(&self) -> bool {
match self.pve { match self.pve {
true => self.players.len() == 16, true => self.players.len() == 16,
@ -97,6 +127,7 @@ impl Instance {
fn start(&mut self) -> &mut Instance { fn start(&mut self) -> &mut Instance {
// self.players.sort_unstable_by_key(|p| p.id); // self.players.sort_unstable_by_key(|p| p.id);
self.generate_rounds(); self.generate_rounds();
self.open = false;
self.phase = InstancePhase::Vbox; self.phase = InstancePhase::Vbox;
self.vbox_phase_start() self.vbox_phase_start()
@ -145,7 +176,7 @@ impl Instance {
fn games_phase_finished(&self) -> bool { fn games_phase_finished(&self) -> bool {
match self.rounds.last() { match self.rounds.last() {
Some(r) => r.iter().all(|g| g.game_id.is_some() && g.outcome.is_some()), Some(r) => r.iter().all(|g| g.outcome.is_some()),
None => true, None => true,
} }
} }
@ -196,8 +227,6 @@ impl Instance {
game.start(); game.start();
assert!(game.finished()); assert!(game.finished());
round.game_id = Some(game.id);
round.outcome = Some((game.winner().unwrap().id, Uuid::new_v4())); round.outcome = Some((game.winner().unwrap().id, Uuid::new_v4()));
} }
} }
@ -227,7 +256,7 @@ impl Instance {
.enumerate() .enumerate()
.map(|(i, id)| Round { .map(|(i, id)| Round {
player_ids: vec![*id, matched_players[np - (i + 1)]], player_ids: vec![*id, matched_players[np - (i + 1)]],
game_id: None, game_id: Uuid::new_v4(),
outcome: None, outcome: None,
}) })
.collect::<Vec<Round>>(); .collect::<Vec<Round>>();
@ -237,22 +266,15 @@ impl Instance {
self self
} }
fn next_game_id(&mut self, player: &Player) -> Uuid { fn current_round(&self, player: &Player) -> &Round {
let current_round = self.rounds.len() - 1; let round_num = self.rounds.len() - 1;
let next_round = self.rounds[current_round] let current_round = self.rounds[round_num]
.iter_mut() .iter()
.find(|g| g.player_ids.contains(&player.id)) .find(|g| g.player_ids.contains(&player.id))
.unwrap(); .unwrap();
match next_round.game_id { current_round
Some(id) => return id,
None => {
let id = Uuid::new_v4();
next_round.game_id = Some(id);
return id;
}
}
} }
} }
@ -278,13 +300,13 @@ pub fn instance_write(instance: Instance, tx: &mut Transaction) -> Result<Instan
let query = " let query = "
UPDATE instances UPDATE instances
SET data = $1 SET data = $1, open = $2
WHERE id = $2 WHERE id = $3
RETURNING id, data; RETURNING id, data;
"; ";
let result = tx let result = tx
.query(query, &[&instance_bytes, &instance.id])?; .query(query, &[&instance_bytes, &instance.open, &instance.id])?;
result.iter().next().ok_or(err_msg("no instance row returned"))?; result.iter().next().ok_or(err_msg("no instance row returned"))?;
@ -371,19 +393,28 @@ pub fn instance_join(params: InstanceJoinParams, tx: &mut Transaction, account:
pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> { pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let player = player_get(tx, account.id, params.instance_id)?; let player = player_get(tx, account.id, params.instance_id)?;
let mut instance = instance_get(tx, params.instance_id)? let instance = instance_get(tx, params.instance_id)?
.player_ready(player.clone())?; .player_ready(player.clone())?;
let game_id = instance.next_game_id(&player); let game_id = instance.current_round(&player).game_id;
let game = match game_get(tx, game_id) { let game = match instance.pve {
Ok(_g) => game_instance_join(tx, player.clone(), game_id)?, true => match game_get(tx, game_id) {
Err(_) => game_instance_new(tx, player.clone(), instance.pve)?, Ok(g) => g,
Err(_) => {
let game = instance.bot_vs_player_game(&player);
game_write(&game, tx)?;
game
},
},
false => match game_get(tx, game_id) {
Ok(_g) => game_instance_join(tx, player.clone(), game_id)?,
Err(_) => game_instance_new(tx, player.clone(), game_id)?,
}
}; };
instance_write(instance, tx)?;
player_update(tx, player)?; player_update(tx, player)?;
instance_write(instance, tx)?;
return Ok(game); return Ok(game);
} }