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);
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);
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);
// ========== 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<PieceRenderInstructions> {
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(
gpl: &mut GPlayer,
piece: PieceId, pc: &GPiece, p: &dyn PieceTrait,
did: &str,
-) -> (Vec<LogEntry>, Html) {
+) -> (Vec<LogEntry>, Option<Html>) {
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(
pc: &mut GPiece,
p: &Box<dyn PieceTrait>,
op: PieceUpdateOp<(),()>,
- pri: &PieceRenderInstructions)
- -> PreparedPieceUpdate
+ pri: &Option<PieceRenderInstructions>)
+ -> Option<PreparedPieceUpdate>
{
+ let pri = match pri { Some(pri) => pri, None => return None };
+
max_z.update_max(&pc.zlevel.z);
let op = op.try_map(
}
)?;
- PreparedPieceUpdate {
+ Some(PreparedPieceUpdate {
piece: pri.vpid,
op,
- }
+ })
}
&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 {