chiark / gitweb /
fastsplit: Move Z check from multigrab into fastsplit impl
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 30 Apr 2022 12:28:43 +0000 (13:28 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 30 Apr 2022 14:15:30 +0000 (15:15 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
src/fastsplit.rs
src/gamestate.rs

index 9150bf4be74c424ff01d46c03c1d57b652e1fe00..6752fcd402db912b89c8e9d69ba56ca0199858a0 100644 (file)
@@ -574,7 +574,6 @@ api_route!{
       let y = pri.fully_visible().ok_or(Ia::Occultation)?;
       let gpc = a.gs.pieces.byid_mut(a.piece)?;
       if gpc.held != None { throw!(Ia::PieceHeld) }
-      if ! (self.z > gpc.zlevel.z) { throw!(Ia::BadPieceStateForOperation); }
       let new_z = api_op_set_z(gpc, a.gs.gen, &self.z)?;
       a.ipc.show(y).op_multigrab(a, y, self.n, new_z)?
     }
index 37d6ff141bbdaa2d5755669d8a32bcbe00dcac74..4a80c5ff2dc3708489a201d6c354d8363b7b1829 100644 (file)
@@ -83,7 +83,7 @@ impl InstanceGuard<'_> {
   #[throws(ApiPieceOpError)]
   pub fn fastsplit_split<I>(
     &mut self, player: PlayerId,
-    tpiece: PieceId, show: ShowUnocculted, new_z: ShouldSetZLevel,
+    tpiece: PieceId, show: ShowUnocculted, tpc_new_z: ShouldSetZLevel,
     implementation: I
   ) -> UpdateFromOpComplex
   where I: FnOnce(&IOccults, &GameOccults, &GPlayer,
@@ -113,13 +113,16 @@ impl InstanceGuard<'_> {
     // old piece's Z (but we need to give it a new generation so that
     // we don't risk having two pieces with the precise same Z).  The
     // old piece becomes the amount taken and gets the specified Z.
-    let n_zlevel = ZLevel { z: tgpc.zlevel.z.clone(), zg: ig.gs.gen };
+    let npc_z = ZLevel { z: tgpc.zlevel.z.clone(), zg: ig.gs.gen };
+    if ! (tpc_new_z.inspect() > &npc_z) {
+      throw!(Ia::BadPieceStateForOperation);
+    }
 
     let mut ngpc = GPiece {
       pos:           tgpc.pos,
       face:          tgpc.face,
       held:          None,
-      zlevel:        n_zlevel,
+      zlevel:        npc_z,
       pinned:        tgpc.pinned,
       occult:        default(),
       angle:         tgpc.angle,
@@ -150,7 +153,7 @@ impl InstanceGuard<'_> {
 
     // This is outside the infallible closure because borrowck
     // can't see that we drop tgpc before doing stuff with ig.
-    new_z.implement(tgpc);
+    tpc_new_z.implement(tgpc);
     (||{
       let nipc = IFastSplits::make_ipc(&mut ig.ioccults.ilks,
                                        fs_record.ipc.clone());
index 04d64aa7f4427b5b7d55626e9e8cedf8c936bef3..72fea48200560fabbd1fb72a16dd6fbed0c95a5a 100644 (file)
@@ -272,7 +272,10 @@ pub trait PieceTrait: PieceBaseTrait + Downcast + Send + Debug + 'static {
   // And the client can easily select a suitable ZCoord: the top
   // one will do.
   //
-  // So the multigrab operation specifies a ZCoord.
+  // So the multigrab operation specifies a ZCoord.  The client
+  // selects the top, but this is not checked centrally.  Implementations
+  // of op_multigrab that have particular requirements, like the fastsplit
+  // banknotes, must do whatever check is needed.
   fn op_multigrab(&self, _a: ApiPieceOpArgs, _show: ShowUnocculted,
                   _qty: MultigrabQty, _new_z: ShouldSetZLevel)
                   -> Result<OpOutcomeThunk,ApiPieceOpError>  {