diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx
index 9fd5b07a..f251770a 100644
--- a/client/src/components/game.ctrl.jsx
+++ b/client/src/components/game.ctrl.jsx
@@ -23,8 +23,13 @@ const addState = connect(
return ws.sendInstanceState(game.instance);
}
+ function sendGameSkillClear() {
+ return ws.sendGameSkillClear(game.id);
+ }
+
return {
game,
+ sendGameSkillClear,
sendReady,
account,
getInstanceState,
@@ -48,9 +53,10 @@ function Controls(args) {
account,
game,
animating,
+ sendGameSkillClear,
sendReady,
- quit,
getInstanceState,
+ quit,
} = args;
if (!game) return false;
@@ -98,7 +104,7 @@ function Controls(args) {
{game.phase === 'Finish' ? quitBtn : readyBtn}
-
+
);
diff --git a/client/src/components/player.box.jsx b/client/src/components/player.box.jsx
index 4b626171..62184f3f 100644
--- a/client/src/components/player.box.jsx
+++ b/client/src/components/player.box.jsx
@@ -3,9 +3,9 @@ const preact = require('preact');
function Scoreboard(args) {
const {
isPlayer,
- ready,
player,
-
+ isGame,
+ clear,
leave,
} = args;
@@ -37,7 +37,10 @@ function Scoreboard(args) {
-
+
+ {(isPlayer && isGame) ? : null}
+
+
{leave ? : null}
diff --git a/client/src/socket.jsx b/client/src/socket.jsx
index d3f91ff4..a2ab9217 100644
--- a/client/src/socket.jsx
+++ b/client/src/socket.jsx
@@ -108,6 +108,11 @@ function createSocket(events) {
events.setActiveSkill(null);
}
+ function sendGameSkillClear(gameId) {
+ send(['GameSkillClear', { game_id: gameId }]);
+ events.setActiveSkill(null);
+ }
+
function sendGameTarget(gameId, constructId, skillId) {
send(['GameTarget', { game_id: gameId, construct_id: constructId, skill_id: skillId }]);
events.setActiveSkill(null);
@@ -316,6 +321,7 @@ function createSocket(events) {
sendGameState,
sendGameReady,
sendGameSkill,
+ sendGameSkillClear,
sendGameTarget,
sendInstanceReady,
diff --git a/server/src/game.rs b/server/src/game.rs
index 5b2191c4..6e5207dd 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -322,6 +322,17 @@ impl Game {
return Ok(self);
}
+ fn clear_skill(&mut self, player_id: Uuid) -> Result<&mut Game, Error> {
+ self.player_by_id(player_id)?;
+ if self.phase != Phase::Skill {
+ return Err(err_msg("game not in skill phase"));
+ }
+ let mut game_state = self.clone();
+ self.stack.retain(|s| game_state.construct_by_id(s.source_construct_id).unwrap().account == player_id);
+
+ return Ok(self);
+ }
+
fn player_ready(&mut self, player_id: Uuid) -> Result<&mut Game, Error> {
if self.phase != Phase::Skill {
return Err(err_msg("game not in skill phase"));
@@ -877,6 +888,20 @@ pub fn game_skill(tx: &mut Transaction, account: &Account, game_id: Uuid, constr
Ok(game)
}
+pub fn game_skill_clear(tx: &mut Transaction, account: &Account, game_id: Uuid) -> Result {
+ let mut game = game_get(tx, game_id)?;
+
+ game.clear_skill(account.id)?;
+
+ if game.skill_phase_finished() {
+ game = game.resolve_phase_start();
+ }
+
+ game_update(tx, &game)?;
+
+ Ok(game)
+}
+
pub fn game_ready(tx: &mut Transaction, account: &Account, id: Uuid) -> Result {
let mut game = game_get(tx, id)?;
diff --git a/server/src/rpc.rs b/server/src/rpc.rs
index 54408bd2..d8ce6405 100644
--- a/server/src/rpc.rs
+++ b/server/src/rpc.rs
@@ -20,7 +20,7 @@ use account::{Account};
use account;
use construct::{Construct};
use events::{Event};
-use game::{Game, game_state, game_skill, game_ready};
+use game::{Game, game_state, game_skill, game_skill_clear, game_ready};
use instance::{Instance, instance_state, instance_practice, instance_ready};
use item::{Item, ItemInfoCtr, item_info};
use mtx;
@@ -75,6 +75,7 @@ enum RpcRequest {
GameState { id: Uuid },
GameReady { id: Uuid },
GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Option, skill: Skill },
+ GameSkillClear { game_id: Uuid },
AccountState {},
AccountShop {},
@@ -169,6 +170,9 @@ impl Connection {
RpcRequest::GameSkill { game_id, construct_id, target_construct_id, skill } =>
Ok(RpcMessage::GameState(game_skill(&mut tx, account, game_id, construct_id, target_construct_id, skill)?)),
+ RpcRequest::GameSkillClear { game_id } =>
+ Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_id)?)),
+
RpcRequest::GameReady { id } =>
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),