From: Ian Jackson Date: Sun, 4 Apr 2021 23:44:36 +0000 (+0100) Subject: Autoraise on ungrab, where applicable X-Git-Tag: otter-0.5.0~193 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=45aa395a5e052a5a81163d446d7963c4f6ff1ee9;p=otter.git Autoraise on ungrab, where applicable Signed-off-by: Ian Jackson --- diff --git a/daemon/api.rs b/daemon/api.rs index e72991f1..7a066157 100644 --- a/daemon/api.rs +++ b/daemon/api.rs @@ -342,6 +342,7 @@ api_route!{ api_route!{ api_ungrab, "/_/api/ungrab", struct ApiPieceUngrab { + #[serde(default)] autoraise: bool, } as: @@ -351,6 +352,45 @@ api_route!{ 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( @@ -362,10 +402,16 @@ api_route!{ 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 diff --git a/templates/script.ts b/templates/script.ts index 6c4e8be2..f9d9c0e3 100644 --- a/templates/script.ts +++ b/templates/script.ts @@ -81,6 +81,7 @@ type PieceInfo = { 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, } @@ -966,16 +967,19 @@ function ungrab_all() { 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) { @@ -1090,6 +1094,7 @@ function drag_mousemove(e: MouseEvent) { 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); @@ -1478,6 +1483,7 @@ function piece_modify_core(piece: PieceId, p: PieceInfo, 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;