api_route!{
api_ungrab, "/_/api/ungrab",
struct ApiPieceUngrab {
+ #[serde(default)] autoraise: bool,
}
as:
gs,ioccults,player,piece,ipc,ipieces,to_recalculate, ..
} = a;
let gpl = gs.players.byid_mut(player).unwrap();
+
+ let new_z = if_chain! {
+
+ if self.autoraise;
+ let tgpc = gs.pieces.byid(piece)?;
+ if gs.max_z > tgpc.zlevel;
+
+ let use_region = |rpiece: PieceId, rgpc: &GPiece| if_chain!{
+ if let Some(rvis) = rgpc.fully_visible_to_everyone();
+ if let Some(ripc) = wants!( ipieces.get(rpiece), ?rpiece );
+ if let Some(rregion) = wantok!( ripc.show(rvis).abs_bbox(rgpc) );
+ then { Some(rregion) }
+ else { None }
+ };
+
+ if gs.pieces.iter().find(|&(opiece, ogpc)| {
+
+ if ogpc.zlevel < tgpc.zlevel { return false }
+
+ let cannot_overlap = if_chain! {
+ if let Some(tregion) = use_region( piece, tgpc);
+ if let Some(oregion) = use_region(opiece, ogpc);
+ if ! tregion.overlaps(&oregion);
+ then { true }
+ else { false }
+ };
+ return ! cannot_overlap;
+ })
+ .is_some();
+
+ then {
+ let z = gs.max_z.z.clone_mut().increment().map_err(
+ |e| APOE::ReportViaResponse(IE::from(e).into()))?;
+ Some(ZLevel { z, zg: gs.gen })
+ }
+ else { None }
+
+ };
+
let gpc = gs.pieces.byid_mut(piece).unwrap();
let (logents, who_by) = log_did_to_piece_whoby(
if gpc.held != Some(player) { throw!(OnlineError::PieceHeld) }
gpc.held = None;
+ let wrc = if let Some(zlevel) = new_z {
+ gpc.zlevel = zlevel;
+ WhatResponseToClientOp::Unpredictable
+ } else {
+ WhatResponseToClientOp::Predictable
+ };
+
let update = PieceUpdateOp::Modify(());
- let vanilla = (WhatResponseToClientOp::Predictable,
- update,
- logents);
+
+ let vanilla = (wrc, update, logents);
if let Some(occid) = gpc.occult.passive_occid() {
// if piece is occulted, definitely repermute its occultation
queued_moves : number,
last_seen_moved : DOMHighResTimeStamp | null, // non-0 means halo'd
held_us_inoccult: boolean,
+ held_us_raising: boolean,
bbox: Rect,
drag_delta: number,
}
function set_grab_us(piece: PieceId, p: PieceInfo) {
p.held = us;
+ p.held_us_raising = false;
p.drag_delta = 0;
redisplay_ancillaries(piece,p);
recompute_keybindings();
}
function do_ungrab(piece: PieceId, p: PieceInfo) {
+ let autoraise = p.held_us_raising;
p.held = null;
+ p.held_us_raising = false;
p.drag_delta = 0;
redisplay_ancillaries(piece,p);
recompute_keybindings();
- api_piece(api, 'ungrab', piece,p, { });
+ api_piece(api, 'ungrab', piece,p, { autoraise });
}
function clear_halo(piece: PieceId, p: PieceInfo) {
if (dragraise > 0 && ddr2 >= dragraise*dragraise) {
dragging |= DRAGGING.RAISED;
console.log('CHECK RAISE ', dragraise, dragraise*dragraise, ddr2);
+ p.held_us_raising = true;
piece_set_zlevel(piece,p, (oldtop_piece) => {
let oldtop_p = pieces[oldtop_piece]!;
let z = wasm_bindgen.increment(oldtop_p.z);
p.uelem.setAttributeNS(null, "x", info.pos[0]+"");
p.uelem.setAttributeNS(null, "y", info.pos[1]+"");
p.held = info.held;
+ p.held_us_raising = false;
p.pinned = info.pinned;
p.moveable = info.moveable;
p.angle = info.angle;