chiark / gitweb /
hidden, etc.: pass ioccults and ipc everywhere
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Mar 2021 12:24:26 +0000 (12:24 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Mar 2021 12:24:26 +0000 (12:24 +0000)
Big internal API changes.

No functional change.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
daemon/cmdlistener.rs
daemon/session.rs
src/gamestate.rs
src/global.rs
src/hidden.rs
src/updates.rs

index 4729a6cc5a888034557aef1ff5e2370c45ce0cf1..d311ca2024032510bc412de5ea84ec4cf9bed33e 100644 (file)
@@ -110,6 +110,7 @@ fn api_piece_op<O: op::Complex>(form: Json<ApiPiece<O>>)
   cl.lastseen = Instant::now();
   let player = cl.player;
   let gs = &mut g.gs;
+  let ioccults = &g.ioccults;
   let ipieces = &g.ipieces;
   let iplayers = &g.iplayers;
   let _ = iplayers.byid(player)?;
@@ -119,7 +120,7 @@ fn api_piece_op<O: op::Complex>(form: Json<ApiPiece<O>>)
   use ApiPieceOpError::*;
 
   match (||{
-    let p = ipieces.get(piece).ok_or(OnlineError::PieceGone)?;
+    let ipc = ipieces.get(piece).ok_or(OnlineError::PieceGone)?;
     let gpc = gs.pieces.byid_mut(piece)?;
 
     let q_gen = form.gen;
@@ -133,8 +134,7 @@ fn api_piece_op<O: op::Complex>(form: Json<ApiPiece<O>>)
     form.op.check_held(gpc,player)?;
     let update =
       form.op.op_complex(ApiPieceOpArgs {
-        gs, player, piece, ipieces,
-        p: p.as_ref(),
+        ioccults, gs, player, piece, ipieces, ipc,
       })?;
     Ok::<_,ApiPieceOpError>(update)
   })() {
@@ -227,12 +227,12 @@ api_route!{
   as:
   #[throws(ApiPieceOpError)]
   fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
-    let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+    let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
     let gpl = gs.players.byid_mut(player)?;
     let gpc = gs.pieces.byid_mut(piece)?;
 
     let logents = log_did_to_piece(
-      &gs.occults, player, gpl, piece, gpc, p,
+      ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
       "grasped"
     )?;
 
@@ -259,7 +259,7 @@ api_route!{
   impl op::Simple as {
     #[throws(ApiPieceOpError)]
     fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
-      let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+      let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
       let gpc = gs.pieces.byid_mut(piece)?;
       let players = &mut gs.players;
       let was = gpc.held;
@@ -267,10 +267,10 @@ 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, gpc, &p)
+      let pri = piece_pri(ioccults, &gs.occults, player, gpl, piece, gpc, ipc)
         .ok_or(OE::PieceGone)?;
 
-      let pcs = pri.describe(gpc, &p).0;
+      let pcs = pri.describe(ioccults, gpc, ipc).0;
 
       gpc.held = Some(player);
 
@@ -297,12 +297,12 @@ api_route!{
   as:
   #[throws(ApiPieceOpError)]
   fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
-    let ApiPieceOpArgs { gs,player,piece,p,ipieces, .. } = a;
+    let ApiPieceOpArgs { gs,ioccults,player,piece,ipc,ipieces, .. } = a;
     let gpl = gs.players.byid_mut(player).unwrap();
     let gpc = gs.pieces.byid_mut(piece).unwrap();
 
     let (logents, who_by) = log_did_to_piece_whoby(
-      &gs.occults, player, gpl, piece, gpc, p,
+      ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
       "released"
     )?;
     let who_by = who_by.ok_or(OE::PieceGone)?;
@@ -394,11 +394,11 @@ api_route!{
   as:
   #[throws(ApiPieceOpError)]
   fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
-    let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+    let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
     let gpc = gs.pieces.byid_mut(piece).unwrap();
     let gpl = gs.players.byid_mut(player).unwrap();
     let logents = log_did_to_piece(
-      &gs.occults, player, gpl, piece, gpc, p,
+      ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
       "rotated"
     )?;
     gpc.angle = PieceAngle::Compass(self.0);
@@ -415,11 +415,11 @@ api_route!{
   as:
   #[throws(ApiPieceOpError)]
   fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
-    let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+    let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
     let gpc = gs.pieces.byid_mut(piece).unwrap();
     let gpl = gs.players.byid_mut(player).unwrap();
     let logents = log_did_to_piece(
-      &gs.occults, player, gpl, piece, gpc, p,
+      ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
       if gpc.pinned { "pinned" } else { "unpinned" },
     )?;
     forbid_piece_involved_in_occultation(&gpc)?;
@@ -443,7 +443,7 @@ api_route!{
   impl op::Complex as {
     #[throws(ApiPieceOpError)]
     fn op_complex(&self, mut a: ApiPieceOpArgs) -> UpdateFromOpComplex {
-      let ApiPieceOpArgs { player,piece,p, .. } = a;
+      let ApiPieceOpArgs { ioccults,player,piece,ipc, .. } = a;
       let gs = &mut a.gs;
       '_normal_global_ops__not_loop: loop {
         let gpc = gs.pieces.byid_mut(piece)?;
@@ -451,9 +451,9 @@ api_route!{
         let _: Void = match (self.opname.as_str(), self.wrc) {
 
           ("flip", wrc@ WRC::UpdateSvg) => {
-            let nfaces = p.nfaces();
+            let nfaces = ipc.p.nfaces();
             let logents = log_did_to_piece(
-              &gs.occults, player, gpl, piece, gpc, p,
+              ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
               "flipped"
             )?;
             gpc.face = ((RawFaceId::from(gpc.face) + 1) % nfaces).into();
@@ -475,7 +475,7 @@ api_route!{
         };
       }
 
-      p.ui_operation(a, &self.opname, self.wrc)?
+      ipc.p.ui_operation(a, &self.opname, self.wrc)?
     }
   }
 }
index 368d60017f83069243bab312c8e359afe9968fce..a39bc99303b9e94b38cb52b1025f8e05eab24a8b 100644 (file)
@@ -375,25 +375,26 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
     },
 
     MGI::ListPieces => readonly(cs,ag,ig, &[TP::ViewNotSecret], |ig|{
+      let ioccults = &ig.ioccults;
       let pieces = ig.gs.pieces.iter().filter_map(
         |(piece,gpc)| (|| Ok::<_,MgmtError>(if_chain!{
           let &GPiece { pos, face, .. } = gpc;
-          if let Some(p) = ig.ipieces.get(piece);
+          if let Some(ipc) = ig.ipieces.get(piece);
           let visible = if ! piece_at_all_occulted(gpc) {
             // todo: something more sophisticated would be nice
             let pri = PieceRenderInstructions::new_visible(
               // visible id is internal one here
               VisiblePieceId(piece.data())
             );
-            let bbox = p.bbox_approx()?;
-            let desc_html = pri.describe(gpc, p);
+            let bbox = ipc.p.bbox_approx()?;
+            let desc_html = pri.describe(ioccults, gpc, ipc);
             Some(MgmtGamePieceVisibleInfo {
               pos, face, desc_html, bbox
             })
           } else {
             None
           };
-          let itemname = p.itemname().to_string();
+          let itemname = ipc.p.itemname().to_string();
           then {
             Some(MgmtGamePieceInfo {
               piece, itemname,
@@ -558,26 +559,28 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
     },
 
     MGI::DeletePiece(piece) => {
-      let (ig, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
-      let IPiece { p, occilk } = ig.ipieces.as_mut(modperm)
+      let (ig_g, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
+      let ig = &mut **ig_g;
+      let ipc = ig.ipieces.as_mut(modperm)
         .remove(piece).ok_or(ME::PieceNotFound)?;
+      let ioccults = &ig.ioccults;
       let gs = &mut ig.gs;
       let gpc = gs.pieces.as_mut(modperm).remove(piece);
       let desc_html = if let Some(gpc) = &gpc {
         let pri = PieceRenderInstructions::new_visible(default());
-        pri.describe(gpc, &p)
+        pri.describe(ioccults, gpc, &ipc)
       } else {
         Html::lit("<piece partially missing from game state!>")
       };
-      if let Some(gpc) = gpc { p.delete_hook(&gpc, gs); }
-      if let Some(occilk) = occilk { ig.ioccults.ilks.dispose(occilk); }
+      if let Some(gpc) = gpc { ipc.p.delete_hook(&gpc, gs); }
+      if let Some(occilk) = ipc.occilk { ig.ioccults.ilks.dispose(occilk); }
       (U{ pcs: vec![(piece, PieceUpdateOp::Delete())],
           log: vec![ LogEntry {
             html: Html(format!("A piece {} was removed from the game",
                           desc_html.0)),
           }],
           raw: None },
-       Fine, ig)
+       Fine, ig_g)
     },
 
     MGI::AddPieces(PiecesSpec{ pos,posd,count,face,pinned,angle,info }) => {
index b3246ad950ca1aaba5fe951b17d70486dae66c42..d09f441850b31dd24757b871a04c4a22e43586a2 100644 (file)
@@ -87,6 +87,7 @@ fn session_inner(form: Json<SessionForm>,
     let ctoken = record_token(&mut ig, ciad)?;
     ig.save_game_later(); // in case we changed anything eg gpl.layout
     let ig = &mut *ig;
+    let ioccults = &ig.ioccults;
 
     let mut uses = vec![];
     let mut alldefs = vec![];
@@ -111,15 +112,16 @@ fn session_inner(form: Json<SessionForm>,
     pieces.sort_by_key(|(_,pr)| &pr.zlevel);
 
     for (piece, gpc) in pieces {
-      let p = if let Some(pto) = ig.ipieces.get(piece) { pto }
+      let ipc = if let Some(pto) = ig.ipieces.get(piece) { pto }
       else { continue /* was deleted */ };
 
-      let pri = piece_pri(&ig.gs.occults, player, gpl, piece, gpc, p);
+      let pri = piece_pri(ioccults, &ig.gs.occults, player, gpl,
+                          piece, gpc, ipc);
       let pri = if let Some(pri) = pri { pri } else { continue /*invisible*/};
 
-      let defs = pri.make_defs(gpc, p)?;
+      let defs = pri.make_defs(ioccults, gpc, ipc)?;
       alldefs.push((pri.vpid, defs));
-      let desc = pri.describe(&gpc, p);
+      let desc = pri.describe(ioccults, &gpc, ipc);
 
       let vangle = pri.angle(gpc).to_compass();
 
@@ -130,7 +132,7 @@ fn session_inner(form: Json<SessionForm>,
         pinned: gpc.pinned,
         angle: vangle,
         desc,
-        uos: &pri.ui_operations(gpc, p.as_ref())?,
+        uos: &pri.ui_operations(gpc, ipc.p.as_ref())?,
       };
 
       let for_piece = SessionPieceContext {
index 41fc3ea93e7aec27301cfbe82998d6925d260ed0..7ae73ac779b7967a86df0cb858ec226ab42ca648 100644 (file)
@@ -175,9 +175,10 @@ pub trait OccultedPieceTrait: OutlineTrait + 'static {
 pub struct ApiPieceOpArgs<'a> {
   pub gs: &'a mut GameState,
   pub ipieces: &'a IPieces,
+  pub ioccults: &'a IOccults,
   pub player: PlayerId,
   pub piece: PieceId,
-  pub p: &'a dyn PieceTrait,
+  pub ipc: &'a IPiece,
 }
 
 #[derive(Debug)]
@@ -285,17 +286,18 @@ impl VisiblePieceAngle {
 
 impl GPiece {
   #[throws(IE)]
-  pub fn prep_piecestate(&self, p: &dyn PieceTrait, pri: &PieceRenderInstructions)
+  pub fn prep_piecestate(&self, ioccults: &IOccults,
+                         ipc: &IPiece, pri: &PieceRenderInstructions)
                      -> PreparedPieceState {
     PreparedPieceState {
       pos        : self.pos,
       held       : self.held,
-      svg        : pri.make_defs(self, &p)?,
+      svg        : pri.make_defs(ioccults, self, ipc)?,
       z          : self.zlevel.z.clone(),
       zg         : self.zlevel.zg,
       angle      : pri.angle(self).to_compass(),
       pinned     : self.pinned,
-      uos        : pri.ui_operations(self, p)?,
+      uos        : pri.ui_operations(self, ipc.p.borrow())?,
     }
   }
 
@@ -379,14 +381,14 @@ impl PieceRenderInstructions {
   }
 
   #[throws(IE)]
-  fn instead<'p>(&self, p: &'p dyn PieceTrait)
+  fn instead<'p>(&self, _ioccults: &'p IOccults, p: &'p IPiece)
                  -> Option<&'p dyn OccultedPieceTrait>
   {
     match self.occulted {
       PriOcculted::Visible                              => None,
       PriOcculted::Occulted | PriOcculted::Displaced(_) => {
         Some(
-          p.occultable()
+          p.p.occultable()
             .ok_or_else(|| internal_logic_error(format!(
               "occulted non-occultable {:?}", p)))?
         )
@@ -403,17 +405,18 @@ impl PieceRenderInstructions {
 
 
   #[throws(IE)]
-  pub fn make_defs<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
-    where P:Borrow<dyn PieceTrait>
+  pub fn make_defs<'p>(&self, ioccults: &IOccults,
+                         gpc: &GPiece, ipc: &IPiece) -> Html
   {
     #[throws(IE)]
-    fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+    fn inner(pri: &PieceRenderInstructions, ioccults: &IOccults,
+             gpc: &GPiece, ipc: &IPiece)
              -> Html
   {
-    let instead = pri.instead(p)?;
+    let instead = pri.instead(ioccults, ipc)?;
 
     let o: &dyn OutlineTrait = match instead {
-      None => p.dyn_upcast(),
+      None => Borrow::<dyn PieceTrait>::borrow(&ipc.p).dyn_upcast(),
       Some(i) => i.dyn_upcast(),
     };
 
@@ -434,7 +437,7 @@ impl PieceRenderInstructions {
 
     match instead {
       None => {
-        p.svg_piece(&mut defs, gpc, pri.vpid)?;
+        ipc.p.svg_piece(&mut defs, gpc, pri.vpid)?;
       },
       Some(i) => {
         i.svg(&mut defs, pri.vpid)?;
@@ -447,28 +450,29 @@ impl PieceRenderInstructions {
            pri.vpid, o.surround_path()?.0)?;
     defs
   }
-  inner(self, gpc, p.borrow())?
+  inner(self, ioccults, gpc, ipc)?
   }
 
-  pub fn describe<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
-    where P:Borrow<dyn PieceTrait>
+  pub fn describe(&self, ioccults: &IOccults,
+                  gpc: &GPiece, ipc: &IPiece) -> Html
   {
-    fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
-             -> Html
+    fn inner(pri: &PieceRenderInstructions, ioccults: &IOccults,
+             gpc: &GPiece, ipc: &IPiece) -> Html
   {
-    pri.describe_fallible(gpc, p)
+    pri.describe_fallible(ioccults, gpc, ipc)
       .unwrap_or_else(|e| {
         error!("error describing piece: {:?}", e);
         Html::lit("<internal error describing piece>")
       })
   }
-  inner(self, gpc, p.borrow())
+  inner(self, ioccults, gpc, ipc)
   }
 
   #[throws(IE)]
-  pub fn describe_fallible(&self, gpc: &GPiece, p: &dyn PieceTrait) -> Html {
-    match self.instead(p)? {
-      None => p.describe_html(gpc)?,
+  pub fn describe_fallible(&self, ioccults: &IOccults,
+                           gpc: &GPiece, ipc: &IPiece) -> Html {
+    match self.instead(ioccults, ipc)? {
+      None => ipc.p.describe_html(gpc)?,
       Some(i) => i.describe_html()?,
     }
   }
index af8aec63830ebac0cc724575a5f5f416d9c200d8..a1ec77c166266c4331f86a47c950030ccc1350ad 100644 (file)
@@ -1263,11 +1263,7 @@ pub fn process_all_players_for_account<
 // ========== instance pieces data access ==========
 
 impl IPieces {
-  pub fn get(&self, piece: PieceId) -> Option<&Box<dyn PieceTrait>> {
-    Some(&self.0.get(piece)?.p)
-  }
-
-  pub fn get_ipc(&self, piece: PieceId) -> Option<&IPiece> {
+  pub fn get(&self, piece: PieceId) -> Option<&IPiece> {
     self.0.get(piece)
   }
 
index 2652e47496c59a953c71e9354dbbbb37dcf6f8c6..48a12f592f850fd525a7cd072554f3e8ee2f7ad3 100644 (file)
@@ -462,16 +462,18 @@ pub use vpid::{PerPlayerIdMap, NotchNumber, Notch, Notches};
 // ========== public entrypoints ==========
 
 /// None => do not render at all
-pub fn piece_pri<P:Borrow<dyn PieceTrait>>(
+pub fn piece_pri(
+  ioccults: &IOccults,
   occults: &GameOccults,
   player: PlayerId, gpl: &mut GPlayer,
-  piece: PieceId, gpc: &GPiece, p: &P,
+  piece: PieceId, gpc: &GPiece, ipc: &IPiece,
 ) -> Option<PieceRenderInstructions>
 {
 fn inner(
+  _ioccults: &IOccults,
   occults: &GameOccults,
   player: PlayerId, gpl: &mut GPlayer,
-  piece: PieceId, gpc: &GPiece, _p: &dyn PieceTrait,
+  piece: PieceId, gpc: &GPiece, _ipc: &IPiece,
 ) -> Option<PieceRenderInstructions>
 {
   let occk = if_chain! {
@@ -503,7 +505,7 @@ fn inner(
   trace_dbg!("piece_pri", gpc, occk, vpid, occulted);
   Some(PieceRenderInstructions { vpid, occulted })
 }
-  inner(occults, player, gpl, piece, gpc, p.borrow())
+  inner(ioccults, occults, player, gpl, piece, gpc, ipc)
 }
 
 pub fn piece_at_all_occulted(gpc: &GPiece) -> bool {
@@ -621,7 +623,7 @@ fn recalculate_occultation_general<
             // prevent occulting pieces being occulted
             // (also prevents reflexive occultation)
             return None
-          } else if ipc.occultable().is_none() {
+          } else if ipc.p.occultable().is_none() {
             // if we cannot make it look identical to the others, we
             // cannot occult it beause we can't hide its identity
             return None
@@ -701,7 +703,7 @@ fn recalculate_occultation_general<
       let bad = || internal_error_bydebug(&("missing", opiece, h.occid));
       let oipc = ipieces.get(opiece).ok_or_else(bad)?;
       let ogpc = gpieces.get(opiece).ok_or_else(bad)?;
-      Ok::<_,IE>(oipc.describe_html(ogpc)?)
+      Ok::<_,IE>(oipc.p.describe_html(ogpc)?)
     };
 
     let most_obscure = most_obscure.unwrap_or(&OccK::Visible); // no players!
@@ -718,8 +720,8 @@ fn recalculate_occultation_general<
         log_visible
       }
       OccK::Scrambled | OccK::Displaced{..} => {
-        let _face = ipc.nfaces() - 1; // xxx use other thing entirely
-        let show = ipc.describe_html(gpc)?;
+        let _face = ipc.p.nfaces() - 1; // xxx use other thing entirely
+        let show = ipc.p.describe_html(gpc)?;
         call_log_callback(Some(&show))?
       },
       OccK::Invisible => {
index b6aa823e96951e10715f5b852b23ac7bc4d4ef42..cfda540b5f696b96a0b15896d7d32229dd06eba2 100644 (file)
@@ -201,34 +201,36 @@ struct FormattedLogEntry<'u> {
 
 #[throws(OE)]
 pub fn log_did_to_piece_whoby(
+  ioccults: &IOccults,
   occults: &GameOccults,
   player: PlayerId,
   gpl: &mut GPlayer,
-  piece: PieceId, gpc: &GPiece, p: &dyn PieceTrait,
+  piece: PieceId, gpc: &GPiece, ipc: &IPiece,
   did: &str,
 ) -> (Vec<LogEntry>, Option<Html>) {
   let who_by = Html(htmlescape::encode_minimal(&gpl.nick));
-  let pri = piece_pri(occults, player, gpl, piece, gpc, &p)
+  let pri = piece_pri(ioccults, occults, player, gpl, piece, gpc, ipc)
     .ok_or(OE::PieceGone)?;
 
   let log = vec![ LogEntry { html: Html(format!(
     "{} {} {}",
     &who_by.0,
     did,
-    pri.describe(gpc, &p).0,
+    pri.describe(ioccults, gpc, ipc).0,
   ))}];
   (log, Some(who_by))
 }
 
 #[throws(OE)]
 pub fn log_did_to_piece(
+  ioccults: &IOccults,
   occults: &GameOccults,
   player: PlayerId,
   gpl: &mut GPlayer,
-  piece: PieceId, gpc: &GPiece, p: &dyn PieceTrait,
+  piece: PieceId, gpc: &GPiece, ipc: &IPiece,
   did: &str,
 ) -> Vec<LogEntry> {
-  log_did_to_piece_whoby(occults,player,gpl,piece,gpc,p,did)?.0
+  log_did_to_piece_whoby(ioccults,occults,player,gpl,piece,gpc,ipc,did)?.0
 }
 
 // ---------- prepared updates, queued in memory ----------
@@ -491,9 +493,10 @@ impl<'r> PrepareUpdatesBuffer<'r> {
   }
 
   #[throws(InternalError)]
-  fn piece_update_player(max_z: &mut ZCoord,
+  fn piece_update_player(ioccults: &IOccults,
+                         max_z: &mut ZCoord,
                          pc: &mut GPiece,
-                         p: &Box<dyn PieceTrait>,
+                         ipc: &IPiece,
                          op: PieceUpdateOp<(),()>,
                          pri: &Option<PieceRenderInstructions>)
                          -> Option<PreparedPieceUpdate>
@@ -504,7 +507,7 @@ impl<'r> PrepareUpdatesBuffer<'r> {
 
     let op = op.try_map(
       |()|{
-        let mut ns = pc.prep_piecestate(p.as_ref(), pri)?;
+        let mut ns = pc.prep_piecestate(ioccults, ipc, pri)?;
         massage_prep_piecestate(pri, &mut ns);
         <Result<_,InternalError>>::Ok(ns)
       },
@@ -529,9 +532,10 @@ impl<'r> PrepareUpdatesBuffer<'r> {
   {
     let gen = self.gen();
     let gs = &mut self.g.gs;
+    let ioccults = &self.g.ioccults;
 
     let mut gpc = gs.pieces.byid_mut(piece).ok();
-    let p = self.g.ipieces.get(piece);
+    let ipc = self.g.ipieces.get(piece);
 
     if let Some(ref mut gpc) = gpc {
       gen_update(gpc, gen, &self.by_client);
@@ -545,11 +549,12 @@ impl<'r> PrepareUpdatesBuffer<'r> {
           None => continue,
         }
       };
-      let op = match (&mut gpc, p) {
-        (Some(gpc), Some(p)) => {
-          let pri = piece_pri(&gs.occults, player, gpl, piece, *gpc, p);
+      let op = match (&mut gpc, ipc) {
+        (Some(gpc), Some(ipc)) => {
+          let pri = piece_pri(ioccults, &gs.occults, player,
+                              gpl, piece, *gpc, ipc);
           Self::piece_update_player(
-            &mut gs.max_z, gpc, p, ops, &pri
+            ioccults, &mut gs.max_z, gpc, ipc, ops, &pri
           )?
         }
         _ => gpl.idmap.fwd(piece).map(