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)?
}
#[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,
// 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,
// 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());
// 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> {