clientside rounds changes
This commit is contained in:
parent
1f5fba80f1
commit
6e513e3da7
@ -446,7 +446,7 @@ header {
|
|||||||
flex: 1 1 50%;
|
flex: 1 1 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-form input {
|
.create-form .login-input {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,8 @@ document.fonts.load('16pt "Jura"').then(() => {
|
|||||||
setupKeys(store);
|
setupKeys(store);
|
||||||
|
|
||||||
const ws = createSocket(events);
|
const ws = createSocket(events);
|
||||||
store.dispatch(actions.setWs(ws));
|
|
||||||
ws.connect();
|
ws.connect();
|
||||||
|
events.setWs(ws);
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|||||||
@ -65,7 +65,7 @@ function Instance(args) {
|
|||||||
<tr key={i}
|
<tr key={i}
|
||||||
className={p.ready ? 'ready' : ''}>
|
className={p.ready ? 'ready' : ''}>
|
||||||
<td>{p.name}</td>
|
<td>{p.name}</td>
|
||||||
<td>{p.score.wins} / {p.score.losses}</td>
|
<td>{p.wins} / {p.losses}</td>
|
||||||
<td>{pText}</td>
|
<td>{pText}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,9 +6,9 @@ const addState = connect(
|
|||||||
function receiveState(state) {
|
function receiveState(state) {
|
||||||
const { ws, team } = state;
|
const { ws, team } = state;
|
||||||
|
|
||||||
function sendInstanceNew(sConstructs, name, players) {
|
function sendInstanceNew(sConstructs, name, pve) {
|
||||||
if (sConstructs.length) {
|
if (sConstructs.length) {
|
||||||
return ws.sendInstanceNew(sConstructs, name, players);
|
return ws.sendInstanceNew(sConstructs, name, pve);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -24,19 +24,19 @@ class InstanceCreateForm extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = { players: 2, name: '' };
|
this.state = { pve: false, name: '' };
|
||||||
|
|
||||||
const { sendInstanceNew } = props;
|
const { sendInstanceNew } = props;
|
||||||
|
|
||||||
this.sendInstanceNew = sendInstanceNew.bind(this);
|
this.sendInstanceNew = sendInstanceNew.bind(this);
|
||||||
|
|
||||||
this.nameInput = this.nameInput.bind(this);
|
this.nameInput = this.nameInput.bind(this);
|
||||||
this.playersChange = this.playersChange.bind(this);
|
this.pveChange = this.pveChange.bind(this);
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
playersChange(event) {
|
pveChange() {
|
||||||
this.setState({ players: Number(event.target.value) });
|
this.setState({ pve: !this.state.pve });
|
||||||
}
|
}
|
||||||
|
|
||||||
nameInput(event) {
|
nameInput(event) {
|
||||||
@ -45,8 +45,8 @@ class InstanceCreateForm extends Component {
|
|||||||
|
|
||||||
handleSubmit(event) {
|
handleSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.sendInstanceNew(this.props.team, this.state.name, this.state.players);
|
this.sendInstanceNew(this.props.team, this.state.name, this.state.pve);
|
||||||
this.setState({ name: '', players: 2 });
|
this.setState({ name: '', pve: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -62,21 +62,17 @@ class InstanceCreateForm extends Component {
|
|||||||
type="text"
|
type="text"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={this.state.name}
|
value={this.state.name}
|
||||||
placeholder="name"
|
placeholder="game name"
|
||||||
onInput={this.nameInput}
|
onInput={this.nameInput}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="playerSelect">players</label>
|
<label htmlFor="pveSelect">vs CPU</label>
|
||||||
<select id="playerSelect"
|
<input id="pveSelect"
|
||||||
|
type="checkbox"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={this.state.players}
|
checked={this.state.pve}
|
||||||
onChange={this.playersChange}
|
onChange={this.pveChange}
|
||||||
>
|
>
|
||||||
<option value={1}>pve</option>
|
</input>
|
||||||
<option value={2}>2</option>
|
|
||||||
<option value={4}>4</option>
|
|
||||||
<option value={8}>8</option>
|
|
||||||
<option value={16}>16</option>
|
|
||||||
</select>
|
|
||||||
</form>
|
</form>
|
||||||
<button
|
<button
|
||||||
onClick={this.handleSubmit}
|
onClick={this.handleSubmit}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ function List(args) {
|
|||||||
const instancePanels = instanceList.map(instance => {
|
const instancePanels = instanceList.map(instance => {
|
||||||
const player = instance.players.find(p => p.id === account.id);
|
const player = instance.players.find(p => p.id === account.id);
|
||||||
const scoreText = player
|
const scoreText = player
|
||||||
? `${player.score.wins} : ${player.score.losses}`
|
? `${player.wins} : ${player.losses}`
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
function instanceClick() {
|
function instanceClick() {
|
||||||
|
|||||||
@ -125,8 +125,8 @@ function createSocket(events) {
|
|||||||
send({ method: 'instance_join', params: { instance_id: instanceId, construct_ids: constructs } });
|
send({ method: 'instance_join', params: { instance_id: instanceId, construct_ids: constructs } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendInstanceNew(constructs, name, players) {
|
function sendInstanceNew(constructs, name, pve) {
|
||||||
send({ method: 'instance_new', params: { construct_ids: constructs, name, players } });
|
send({ method: 'instance_new', params: { construct_ids: constructs, name, pve } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendInstanceReady(instanceId) {
|
function sendInstanceReady(instanceId) {
|
||||||
@ -284,6 +284,7 @@ function createSocket(events) {
|
|||||||
if (account) {
|
if (account) {
|
||||||
events.setAccount(account);
|
events.setAccount(account);
|
||||||
sendAccountInstances();
|
sendAccountInstances();
|
||||||
|
sendInstanceList();
|
||||||
sendAccountConstructs();
|
sendAccountConstructs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,18 +38,23 @@ enum Format {
|
|||||||
|
|
||||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||||
struct Round {
|
struct Round {
|
||||||
player_ids: Vec<Uuid>,
|
|
||||||
game_id: Option<Uuid>,
|
game_id: Option<Uuid>,
|
||||||
finished: bool,
|
finished: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Round {
|
||||||
|
fn new() -> Round {
|
||||||
|
Round { game_id: None, finished: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
players: Vec<Player>,
|
players: Vec<Player>,
|
||||||
rounds: Vec<Vec<Round>>,
|
rounds: Vec<Round>,
|
||||||
|
|
||||||
open: bool,
|
open: bool,
|
||||||
max_players: usize,
|
max_players: usize,
|
||||||
@ -72,13 +77,13 @@ impl Instance {
|
|||||||
phase: InstancePhase::Lobby,
|
phase: InstancePhase::Lobby,
|
||||||
open: true,
|
open: true,
|
||||||
max_players: 2,
|
max_players: 2,
|
||||||
max_rounds: 16,
|
max_rounds: 5,
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
password: None,
|
password: None,
|
||||||
phase_end: Utc::now(),
|
phase_end: Utc::now(),
|
||||||
phase_start: Utc::now(),
|
phase_start: Utc::now(),
|
||||||
|
|
||||||
format: Format::RoundRobin,
|
format: Format::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ impl Instance {
|
|||||||
phase: InstancePhase::InProgress,
|
phase: InstancePhase::InProgress,
|
||||||
open: false,
|
open: false,
|
||||||
max_players: 0,
|
max_players: 0,
|
||||||
max_rounds: 1,
|
max_rounds: 5,
|
||||||
name: "Global Matchmaking".to_string(),
|
name: "Global Matchmaking".to_string(),
|
||||||
password: None,
|
password: None,
|
||||||
phase_start: Utc::now(),
|
phase_start: Utc::now(),
|
||||||
@ -108,7 +113,6 @@ impl Instance {
|
|||||||
self.players
|
self.players
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| !p.ready)
|
.filter(|p| !p.ready)
|
||||||
.filter(|p| self.current_game_id(p.id).is_none())
|
|
||||||
.map(|p| p.id)
|
.map(|p| p.id)
|
||||||
.collect::<Vec<Uuid>>()
|
.collect::<Vec<Uuid>>()
|
||||||
}
|
}
|
||||||
@ -131,15 +135,6 @@ impl Instance {
|
|||||||
(self, new_games)
|
(self, new_games)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_max_players(mut self, max: usize) -> Result<Instance, Error> {
|
|
||||||
if max > 16 || max % 2 != 0 {
|
|
||||||
return Err(err_msg("max players must be divisible by 2 and less than 16"));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.max_players = max;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_name(mut self, name: String) -> Result<Instance, Error> {
|
fn set_name(mut self, name: String) -> Result<Instance, Error> {
|
||||||
if name.len() == 0 {
|
if name.len() == 0 {
|
||||||
return Err(err_msg("name must have a length"));
|
return Err(err_msg("name must have a length"));
|
||||||
@ -156,15 +151,17 @@ impl Instance {
|
|||||||
|
|
||||||
fn add_bots(mut self) -> Instance {
|
fn add_bots(mut self) -> Instance {
|
||||||
self.open = false;
|
self.open = false;
|
||||||
self.players = iter::repeat_with(|| {
|
iter::repeat_with(|| {
|
||||||
let bot_id = Uuid::new_v4();
|
let bot_id = Uuid::new_v4();
|
||||||
let constructs = instance_mobs(bot_id);
|
let constructs = instance_mobs(bot_id);
|
||||||
let mut p = Player::new(bot_id, &name(), constructs).set_bot(true);
|
let mut p = Player::new(bot_id, &name(), constructs).set_bot(true);
|
||||||
p.set_ready(true);
|
p.set_ready(true);
|
||||||
p
|
p
|
||||||
})
|
})
|
||||||
.take(15)
|
// .take(self.max_players - self.players.len())
|
||||||
.collect::<Vec<Player>>();
|
.take(1)
|
||||||
|
.for_each(|p| self.players.push(p));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,52 +220,47 @@ impl Instance {
|
|||||||
// create a game object if both players are ready
|
// create a game object if both players are ready
|
||||||
// this should only happen once
|
// this should only happen once
|
||||||
|
|
||||||
let all_ready = self.round_ready_check(player_id);
|
let all_ready = self.round_ready_check();
|
||||||
|
|
||||||
if !all_ready {
|
if !all_ready {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let game = self.create_round_game(player_id);
|
let game = self.create_round_game();
|
||||||
|
|
||||||
{
|
let current_round = self.rounds
|
||||||
let round_num = self.rounds.len() - 1;
|
.last_mut()
|
||||||
let current_round = self.rounds[round_num]
|
.expect("instance does not have any rounds");
|
||||||
.iter_mut()
|
|
||||||
.find(|g| g.player_ids.contains(&player_id))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
current_round.game_id = Some(game.id);
|
current_round.game_id = Some(game.id);
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Some(game));
|
return Ok(Some(game));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn round_ready_check(&mut self, player_id: Uuid) -> bool {
|
fn round_ready_check(&mut self) -> bool {
|
||||||
let current_round = self.current_round(player_id);
|
|
||||||
self.players
|
self.players
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| current_round.player_ids.contains(&p.id))
|
|
||||||
.all(|p| p.ready)
|
.all(|p| p.ready)
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe just embed the games in the instance
|
// maybe just embed the games in the instance
|
||||||
// but seems hella inefficient
|
// but seems hella inefficient
|
||||||
fn create_round_game(&self, player_id: Uuid) -> Game {
|
fn create_round_game(&mut self) -> Game {
|
||||||
let current_round = self.current_round(player_id);
|
let current_round = self.rounds
|
||||||
|
.last_mut()
|
||||||
|
.expect("instance does not have any rounds");
|
||||||
|
|
||||||
|
|
||||||
let mut game = Game::new();
|
let mut game = Game::new();
|
||||||
|
current_round.game_id = Some(game.id);
|
||||||
|
|
||||||
game
|
game
|
||||||
.set_player_num(2)
|
.set_player_num(2)
|
||||||
.set_player_constructs(3)
|
.set_player_constructs(3)
|
||||||
.set_instance(self.id);
|
.set_instance(self.id);
|
||||||
|
|
||||||
// create the initiators player
|
for player in self.players.clone().into_iter() {
|
||||||
for player in self.players
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.filter(|p| current_round.player_ids.contains(&p.id)) {
|
|
||||||
game.player_add(player).unwrap();
|
game.player_add(player).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +295,7 @@ impl Instance {
|
|||||||
p.vbox.fill();
|
p.vbox.fill();
|
||||||
});
|
});
|
||||||
|
|
||||||
self.generate_rounds();
|
self.rounds.push(Round::new());
|
||||||
self.bot_round_actions();
|
self.bot_round_actions();
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -313,7 +305,9 @@ impl Instance {
|
|||||||
match self.format {
|
match self.format {
|
||||||
// bo5 standard
|
// bo5 standard
|
||||||
// OR condition is for forfeitures
|
// OR condition is for forfeitures
|
||||||
Format::Standard => self.players.iter().any(|p| p.score.wins > 2) || self.rounds.len() == 5,
|
Format::Standard =>
|
||||||
|
self.players.iter().any(|p| p.wins as usize >= self.max_rounds / 2 + 1)
|
||||||
|
|| self.rounds.len() == self.max_rounds,
|
||||||
|
|
||||||
// everybody plays each other once
|
// everybody plays each other once
|
||||||
Format::RoundRobin => self.rounds.len() == self.players.len() - 1,
|
Format::RoundRobin => self.rounds.len() == self.players.len() - 1,
|
||||||
@ -353,54 +347,14 @@ impl Instance {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_rounds(&mut self) -> &mut Instance {
|
fn current_game_id(&self) -> Option<Uuid> {
|
||||||
let round_num = self.rounds.len();
|
|
||||||
let mut matched_players = self.players
|
|
||||||
.iter()
|
|
||||||
.map(|p| p.id)
|
|
||||||
.collect::<Vec<Uuid>>();
|
|
||||||
|
|
||||||
let np = matched_players.len();
|
|
||||||
|
|
||||||
if round_num > 0 {
|
|
||||||
matched_players.rotate_right(round_num % np);
|
|
||||||
matched_players.swap(0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// only set up for even player numbers atm
|
|
||||||
// no byes
|
|
||||||
let current_round = matched_players[0..(np / 2)]
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, id)| Round {
|
|
||||||
player_ids: vec![*id, matched_players[np - (i + 1)]],
|
|
||||||
game_id: None,
|
|
||||||
finished: false,
|
|
||||||
})
|
|
||||||
.collect::<Vec<Round>>();
|
|
||||||
|
|
||||||
self.rounds.push(current_round);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_round(&self, player_id: Uuid) -> &Round {
|
|
||||||
let round_num = self.rounds.len() - 1;
|
|
||||||
|
|
||||||
let current_round = self.rounds[round_num]
|
|
||||||
.iter()
|
|
||||||
.find(|g| g.player_ids.contains(&player_id))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
current_round
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_game_id(&self, player_id: Uuid) -> Option<Uuid> {
|
|
||||||
if self.phase == InstancePhase::Lobby {
|
if self.phase == InstancePhase::Lobby {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_round = self.current_round(player_id);
|
let current_round = self.rounds
|
||||||
|
.last()
|
||||||
|
.expect("instance does not have any rounds");
|
||||||
|
|
||||||
if current_round.finished || current_round.game_id.is_none() {
|
if current_round.finished || current_round.game_id.is_none() {
|
||||||
return None;
|
return None;
|
||||||
@ -410,13 +364,17 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn game_finished(&mut self, game: &Game) -> Result<&mut Instance, Error> {
|
fn game_finished(&mut self, game: &Game) -> Result<&mut Instance, Error> {
|
||||||
let round_num = self.rounds.len() - 1;
|
{
|
||||||
self.rounds[round_num]
|
let current_round = self.rounds
|
||||||
.iter_mut()
|
.last_mut()
|
||||||
.filter(|r| r.game_id.is_some())
|
.expect("instance does not have any rounds");
|
||||||
.find(|r| r.game_id.unwrap() == game.id)
|
|
||||||
.ok_or(err_msg("could not find matchup in current round"))?
|
if current_round.game_id.unwrap() != game.id {
|
||||||
.finished = true;
|
return Err(err_msg("instance does not have a round for this game"));
|
||||||
|
}
|
||||||
|
|
||||||
|
current_round.finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
// if you don't win, you lose
|
// if you don't win, you lose
|
||||||
// ties can happen if both players forfeit
|
// ties can happen if both players forfeit
|
||||||
@ -446,7 +404,7 @@ impl Instance {
|
|||||||
|
|
||||||
fn all_games_finished(&self) -> bool {
|
fn all_games_finished(&self) -> bool {
|
||||||
match self.rounds.last() {
|
match self.rounds.last() {
|
||||||
Some(r) => r.iter().all(|g| g.finished),
|
Some(r) => r.finished,
|
||||||
None => true,
|
None => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,10 +418,15 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_action_allowed(&self, account: Uuid) -> Result<(), Error> {
|
pub fn vbox_action_allowed(&self, account: Uuid) -> Result<(), Error> {
|
||||||
|
if self.players.iter().find(|p| p.id == account).is_none() {
|
||||||
|
return Err(err_msg("player not in this instance"));
|
||||||
|
}
|
||||||
|
|
||||||
if self.phase == InstancePhase::Lobby {
|
if self.phase == InstancePhase::Lobby {
|
||||||
return Err(err_msg("game not yet started"));
|
return Err(err_msg("game not yet started"));
|
||||||
}
|
}
|
||||||
if self.current_game_id(account).is_some() {
|
|
||||||
|
if self.current_game_id().is_some() {
|
||||||
return Err(err_msg("you cannot perform vbox actions while in a game"));
|
return Err(err_msg("you cannot perform vbox actions while in a game"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,20 +616,13 @@ pub fn instances_need_upkeep(tx: &mut Transaction) -> Result<Vec<Instance>, Erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn instance_new(params: InstanceLobbyParams, tx: &mut Transaction, account: &Account) -> Result<Instance, Error> {
|
pub fn instance_new(params: InstanceLobbyParams, tx: &mut Transaction, account: &Account) -> Result<Instance, Error> {
|
||||||
let mut instance = match params.players {
|
let mut instance = match params.pve {
|
||||||
1 => Instance::new()
|
true => Instance::new()
|
||||||
.set_max_players(16)?
|
|
||||||
.set_name(params.name)?
|
.set_name(params.name)?
|
||||||
.add_bots(),
|
.add_bots(),
|
||||||
|
|
||||||
2 => Instance::new()
|
false => Instance::new()
|
||||||
.set_max_players(params.players)?
|
|
||||||
.set_name(params.name)?
|
.set_name(params.name)?
|
||||||
.set_format(Format::Standard),
|
|
||||||
|
|
||||||
_ => Instance::new()
|
|
||||||
.set_max_players(params.players)?
|
|
||||||
.set_name(params.name)?,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
instance = instance_create(tx, instance)?;
|
instance = instance_create(tx, instance)?;
|
||||||
@ -705,10 +661,10 @@ pub fn instance_ready(params: InstanceReadyParams, tx: &mut Transaction, account
|
|||||||
instance_update(tx, instance)
|
instance_update(tx, instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, account: &Account) -> Result<RpcResult, Error> {
|
pub fn instance_state(params: InstanceStateParams, tx: &mut Transaction, _account: &Account) -> Result<RpcResult, Error> {
|
||||||
let instance = instance_get(tx, params.instance_id)?;
|
let instance = instance_get(tx, params.instance_id)?;
|
||||||
|
|
||||||
if let Some(game_id) = instance.current_game_id(account.id) {
|
if let Some(game_id) = instance.current_game_id() {
|
||||||
let game = game_get(tx, game_id)?;
|
let game = game_get(tx, game_id)?;
|
||||||
|
|
||||||
// return the game until it's finished
|
// return the game until it's finished
|
||||||
@ -736,24 +692,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instance_pve_test() {
|
fn instance_pve_test() {
|
||||||
let mut instance = Instance::new()
|
let mut instance = Instance::new().add_bots();
|
||||||
.set_max_players(16).expect("unable to set max players")
|
|
||||||
.set_format(Format::RoundRobin)
|
|
||||||
.add_bots();
|
|
||||||
|
|
||||||
let player_account = Uuid::new_v4();
|
let player_account = Uuid::new_v4();
|
||||||
let constructs = instance_mobs(player_account);
|
let constructs = instance_mobs(player_account);
|
||||||
let player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true);
|
let player = Player::new(player_account, &"test".to_string(), constructs).set_bot(true);
|
||||||
let player_id = player.id;
|
|
||||||
|
|
||||||
instance.add_player(player).expect("could not add player");
|
instance.add_player(player).expect("could not add player");
|
||||||
|
|
||||||
assert_eq!(instance.phase, InstancePhase::Lobby);
|
assert_eq!(instance.phase, InstancePhase::Lobby);
|
||||||
instance.player_ready(player_id).unwrap();
|
instance.player_ready(player_account).unwrap();
|
||||||
|
|
||||||
assert_eq!(instance.phase, InstancePhase::Finished);
|
assert_eq!(instance.phase, InstancePhase::Finished);
|
||||||
assert_eq!(instance.rounds[0].len(), 8);
|
assert!(instance.players.iter().any(|p| p.wins as usize == instance.max_rounds / 2 + 1));
|
||||||
assert_eq!(instance.rounds.len(), 15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -766,9 +717,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instance_start_test() {
|
fn instance_start_test() {
|
||||||
let mut instance = Instance::new()
|
let mut instance = Instance::new();
|
||||||
.set_max_players(2)
|
|
||||||
.expect("could not create instance");
|
|
||||||
|
|
||||||
assert_eq!(instance.max_players, 2);
|
assert_eq!(instance.max_players, 2);
|
||||||
|
|
||||||
@ -807,9 +756,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instance_upkeep_test() {
|
fn instance_upkeep_test() {
|
||||||
let mut instance = Instance::new()
|
let mut instance = Instance::new();
|
||||||
.set_max_players(2).expect("could not create instance")
|
|
||||||
.set_format(Format::Standard);
|
|
||||||
|
|
||||||
let player_account = Uuid::new_v4();
|
let player_account = Uuid::new_v4();
|
||||||
let constructs = instance_mobs(player_account);
|
let constructs = instance_mobs(player_account);
|
||||||
|
|||||||
@ -14,22 +14,17 @@ use skill::{Effect};
|
|||||||
|
|
||||||
const DISCARD_COST: u16 = 5;
|
const DISCARD_COST: u16 = 5;
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
|
|
||||||
pub struct Score {
|
|
||||||
pub wins: u8,
|
|
||||||
pub losses: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub vbox: Vbox,
|
pub vbox: Vbox,
|
||||||
pub score: Score,
|
|
||||||
pub constructs: Vec<Construct>,
|
pub constructs: Vec<Construct>,
|
||||||
pub bot: bool,
|
pub bot: bool,
|
||||||
pub ready: bool,
|
pub ready: bool,
|
||||||
pub warnings: u8,
|
pub warnings: u8,
|
||||||
|
pub wins: u8,
|
||||||
|
pub losses: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
@ -38,7 +33,8 @@ impl Player {
|
|||||||
id: account,
|
id: account,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
vbox: Vbox::new(),
|
vbox: Vbox::new(),
|
||||||
score: Score { wins: 0, losses: 0 },
|
wins: 0,
|
||||||
|
losses: 0,
|
||||||
constructs,
|
constructs,
|
||||||
bot: false,
|
bot: false,
|
||||||
ready: false,
|
ready: false,
|
||||||
@ -69,13 +65,13 @@ impl Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_win(&mut self) -> &mut Player {
|
pub fn add_win(&mut self) -> &mut Player {
|
||||||
self.score.wins += 1;
|
self.wins += 1;
|
||||||
self.vbox.balance_add(12);
|
self.vbox.balance_add(12);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_loss(&mut self) -> &mut Player {
|
pub fn add_loss(&mut self) -> &mut Player {
|
||||||
self.score.losses += 1;
|
self.losses += 1;
|
||||||
self.vbox.balance_add(9);
|
self.vbox.balance_add(9);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,6 @@ use game::{Game, game_state, game_skill, game_ready};
|
|||||||
use account::{Account, account_create, account_login, account_from_token, account_constructs, account_instances};
|
use account::{Account, account_create, account_login, account_from_token, account_constructs, account_instances};
|
||||||
use skill::{Skill};
|
use skill::{Skill};
|
||||||
use spec::{Spec};
|
use spec::{Spec};
|
||||||
use player::{Score};
|
|
||||||
use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join};
|
use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join};
|
||||||
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
||||||
use item::{Item, ItemInfoCtr, item_info};
|
use item::{Item, ItemInfoCtr, item_info};
|
||||||
@ -389,9 +388,6 @@ pub enum RpcResult {
|
|||||||
ConstructList(Vec<Construct>),
|
ConstructList(Vec<Construct>),
|
||||||
GameState(Game),
|
GameState(Game),
|
||||||
ItemInfo(ItemInfoCtr),
|
ItemInfo(ItemInfoCtr),
|
||||||
InstanceScores(Vec<(String, Score)>),
|
|
||||||
// ZoneState(Zone),
|
|
||||||
// ZoneClose(()),
|
|
||||||
|
|
||||||
InstanceList(Vec<Instance>),
|
InstanceList(Vec<Instance>),
|
||||||
InstanceState(Instance),
|
InstanceState(Instance),
|
||||||
@ -528,7 +524,7 @@ struct InstanceLobbyMsg {
|
|||||||
pub struct InstanceLobbyParams {
|
pub struct InstanceLobbyParams {
|
||||||
pub construct_ids: Vec<Uuid>,
|
pub construct_ids: Vec<Uuid>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub players: usize,
|
pub pve: bool,
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user