From: Ian Jackson Date: Sun, 28 Feb 2021 15:58:32 +0000 (+0000) Subject: hidden: Make it possible to completely hide a piece X-Git-Tag: otter-0.4.0~275 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=261dd534f259644060b974e6d3df515408a2fb99;p=otter.git hidden: Make it possible to completely hide a piece Signed-off-by: Ian Jackson --- diff --git a/daemon/api.rs b/daemon/api.rs index 5628af90..ba278a6a 100644 --- a/daemon/api.rs +++ b/daemon/api.rs @@ -266,7 +266,9 @@ api_route!{ let was = was.map(|was| htmlescape::encode_minimal(&was.nick)); let gpl = players.byid_mut(player)?; - let pri = piece_pri(&gs.occults, player, gpl, piece, pc); + let pri = piece_pri(&gs.occults, player, gpl, piece, pc) + .ok_or(OE::PieceGone)?; + let pcs = pri.describe(pc, &p).0; pc.held = Some(player); @@ -298,15 +300,16 @@ api_route!{ let gpl = gs.players.byid_mut(player).unwrap(); let pc = gs.pieces.byid_mut(piece).unwrap(); - if pc.held != Some(player) { throw!(OnlineError::PieceHeld) } - pc.held = None; - - let update = PieceUpdateOp::Modify(()); let (logents, who_by) = log_did_to_piece_whoby( &gs.occults, player, gpl, piece, pc, p, "released" ); + let who_by = who_by.ok_or(OE::PieceGone)?; + if pc.held != Some(player) { throw!(OnlineError::PieceHeld) } + pc.held = None; + + let update = PieceUpdateOp::Modify(()); let vanilla = (WhatResponseToClientOp::Predictable, update, logents); diff --git a/daemon/session.rs b/daemon/session.rs index 9087c281..346bc409 100644 --- a/daemon/session.rs +++ b/daemon/session.rs @@ -111,9 +111,12 @@ fn session_inner(form: Json, pieces.sort_by_key(|(_,pr)| &pr.zlevel); for (piece, gpc) in pieces { - let pri = piece_pri(&ig.gs.occults, player, gpl, piece, gpc); let pto = if let Some(pto) = ig.ipieces.get(piece) { pto } else { continue /* was deleted */ }; + + let pri = piece_pri(&ig.gs.occults, player, gpl, piece, gpc); + let pri = if let Some(pri) = pri { pri } else { continue /*invisible*/}; + let defs = pri.make_defs(gpc, pto)?; alldefs.push((pri.vpid, defs)); let desc = pri.describe(&gpc, pto); diff --git a/src/hidden.rs b/src/hidden.rs index c733edd3..830943ae 100644 --- a/src/hidden.rs +++ b/src/hidden.rs @@ -173,19 +173,20 @@ impl PerPlayerIdMap { // ========== public entrypoints ========== +/// None => do not render at all pub fn piece_pri( _occults: &GameOccults, // xxx player: PlayerId, gpl: &mut GPlayer, piece: PieceId, pc: &GPiece, -) -> PieceRenderInstructions { +) -> Option { let vpid = gpl.idmap.fwd_or_insert(piece); let angle = pc.angle; let occluded = PriOccluded::Visible; // xxx trace!("{} {:?} => {} angle={:?}", player, piece, vpid, angle); - PieceRenderInstructions { vpid, occluded } + Some(PieceRenderInstructions { vpid, occluded }) } pub fn piece_at_all_occluded( diff --git a/src/updates.rs b/src/updates.rs index d6d6da28..46441b8d 100644 --- a/src/updates.rs +++ b/src/updates.rs @@ -205,16 +205,19 @@ pub fn log_did_to_piece_whoby( gpl: &mut GPlayer, piece: PieceId, pc: &GPiece, p: &dyn PieceTrait, did: &str, -) -> (Vec, Html) { +) -> (Vec, Option) { let who_by = Html(htmlescape::encode_minimal(&gpl.nick)); - let pri = piece_pri(occults, player, gpl, piece, pc); - let log = vec![ LogEntry { html: Html(format!( - "{} {} {}", - &who_by.0, - did, - pri.describe(pc, &p).0, - ))}]; - (log, who_by) + if let Some(pri) = piece_pri(occults, player, gpl, piece, pc) { + let log = vec![ LogEntry { html: Html(format!( + "{} {} {}", + &who_by.0, + did, + pri.describe(pc, &p).0, + ))}]; + (log, Some(who_by)) + } else { + (vec![], None) + } } pub fn log_did_to_piece( @@ -491,9 +494,11 @@ impl<'r> PrepareUpdatesBuffer<'r> { pc: &mut GPiece, p: &Box, op: PieceUpdateOp<(),()>, - pri: &PieceRenderInstructions) - -> PreparedPieceUpdate + pri: &Option) + -> Option { + let pri = match pri { Some(pri) => pri, None => return None }; + max_z.update_max(&pc.zlevel.z); let op = op.try_map( @@ -507,10 +512,10 @@ impl<'r> PrepareUpdatesBuffer<'r> { } )?; - PreparedPieceUpdate { + Some(PreparedPieceUpdate { piece: pri.vpid, op, - } + }) } @@ -546,14 +551,16 @@ impl<'r> PrepareUpdatesBuffer<'r> { &mut gs.max_z, pc, p, ops, &pri )? } - _ => PreparedPieceUpdate { + _ => Some(PreparedPieceUpdate { // The piece is deleted, so we can't leak anything. piece: gpl.idmap.fwd_or_insert(piece), op: PieceUpdateOp::Delete(), - } + }) }; - out.insert(player, op); + if let Some(op) = op { + out.insert(player, op); + } } PreparedUpdateEntry_Piece {