From be22671d6e383960ac2d58276bb82d10ed1dfc46 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 16 Apr 2022 00:31:50 +0100 Subject: [PATCH] dice: Prevent flipping during cooldown This involves a new hook for the piece trait. Signed-off-by: Ian Jackson --- daemon/api.rs | 5 ++++- src/dice.rs | 17 ++++++++++++++++- src/error.rs | 1 + src/gamestate.rs | 6 ++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/daemon/api.rs b/daemon/api.rs index 2e9d0c66..94092cb3 100644 --- a/daemon/api.rs +++ b/daemon/api.rs @@ -595,7 +595,10 @@ api_route!{ let gpl = gs.players.byid_mut(player)?; let _: Void = match (self.opname.as_str(), self.wrc) { - ("flip", wrc@ WRC::UpdateSvg) => { + ("flip", wrc@ WRC::UpdateSvg) + if ipc.show(y).ui_permit_flip(gpc)? + => + { let nfaces = ipc.show(y).nfaces(); gpc.face = ((RawFaceId::from(gpc.face) + 1) % nfaces).into(); // todo: name the most visible aspect in the log ? diff --git a/src/dice.rs b/src/dice.rs index 349b6945..8fcc6132 100644 --- a/src/dice.rs +++ b/src/dice.rs @@ -247,10 +247,15 @@ impl Die { self.cooldown_time .as_secs_f64() } + #[throws(IE)] + pub fn cooldown_running(&self, state: &State) -> bool { + self.cooldown_remaining(state)? != Duration::default() + } + /// Possible stores None, saving us calling Instant::now in the future #[throws(IE)] pub fn cooldown_cleanup(&self, state: &mut State) { - if self.cooldown_remaining(state)? == Duration::default() { + if ! self.cooldown_running(state)? { state.cooldown_expires = None; } } @@ -312,6 +317,16 @@ impl PieceTrait for Die { } } + #[throws(ApiPieceOpError)] + fn ui_permit_flip(&self, gpc: &GPiece) -> bool { + let state: &State = gpc.xdata.get_exp()?; + if self.cooldown_running(state)? { + throw!(Inapplicable::DieCooldown) + } else { + true + } + } + #[throws(IE)] fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _: &GameState, vpid: VisiblePieceId) { diff --git a/src/error.rs b/src/error.rs index c133a2b3..f84c9661 100644 --- a/src/error.rs +++ b/src/error.rs @@ -181,6 +181,7 @@ pub enum Inapplicable { #[error("occulter already rotated")] OcculterAlreadyRotated, #[error("overfull, cannot organise")] OrganisedPlacementOverfull, #[error("overlapping occultation(s)")] OverlappingOccultation, + #[error("die was recently rolled, cannot flip or roll")] DieCooldown, #[error("UI operation not recognised")] BadUiOperation, #[error("UI operation not valid in the curret piece state")] BadPieceStateForOperation, diff --git a/src/gamestate.rs b/src/gamestate.rs index 70971e5b..cf92b985 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -205,6 +205,12 @@ pub trait PieceTrait: PieceBaseTrait + Send + Debug + 'static { throw!(Ia::BadUiOperation) } + /// Can return `false` to mean "I will handle it in ui_operation" + #[throws(ApiPieceOpError)] + fn ui_permit_flip(&self, _gpc: &GPiece) -> bool { + true + } + // #[throws] doesn't work here - fehler #todo fn svg_piece(&self, f: &mut Html, gpc: &GPiece, gs: &GameState, id: VisiblePieceId) -> Result<(),IE>; -- 2.30.2