chiark / gitweb /
dice: Prevent flipping during cooldown
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 15 Apr 2022 23:31:50 +0000 (00:31 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 15 Apr 2022 23:31:50 +0000 (00:31 +0100)
This involves a new hook for the piece trait.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
src/dice.rs
src/error.rs
src/gamestate.rs

index 2e9d0c66da3020b4a5c5665b1d7aae921d91f5c7..94092cb3473b04d5a096032eda1b2ee26498bbf1 100644 (file)
@@ -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 ?
index 349b6945b93b6824fb47c019c1d3aff4b95a356c..8fcc6132a620c61969f8e7af85a82823342b86d3 100644 (file)
@@ -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) {
index c133a2b3c1154faceaf0546a44348de24d65ddda..f84c966150c71e1c97c44c3bf0802dfdf4ec3dae 100644 (file)
@@ -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,
index 70971e5bb6e290a945336f88707244ad30ec908a..cf92b98535391710e8ad1e2b33da2a70cfc41d7c 100644 (file)
@@ -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>;