chiark / gitweb /
rotateable: wip plumbing
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 7 Apr 2021 17:19:42 +0000 (18:19 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 7 Apr 2021 18:38:48 +0000 (19:38 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
daemon/cmdlistener.rs
daemon/session.rs
src/error.rs
src/gamestate.rs
src/pcrender.rs
src/updates.rs
templates/script.ts

index afa09dde717bbd3b97bbd6e0f7b85e86657b1f35..962ca70de1a6f11bf664f799ea3bafc5092199d7 100644 (file)
@@ -510,6 +510,9 @@ api_route!{
   fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
     let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
     let gpc = gs.pieces.byid_mut(piece).unwrap();
+    if ! gpc.rotateable() || gpc.occult.is_active() {
+      throw!(POE::PieceUnrotateable)
+    }
     let gpl = gs.players.byid_mut(player).unwrap();
     let logents = log_did_to_piece(
       ioccults,&gs.occults,gpl,gpc,ipc,
index eb4a25be1136cc3ae251de218d67a73f58f4f017..aaf002f076e99d142698471feec93d016e7136e2 100644 (file)
@@ -762,6 +762,7 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
           pos, face,
           xdata: None,
           moveable: default(),
+          rotateable: true,
         };
         let PieceSpecLoaded { p, loaded_via_alias, occultable } =
           info.load(piece_i as usize, &mut gpc, &ig.pcaliases, &gref)?;
index bf651ded5eaa1c5b1c70751b0b12768473135af7..174e25f5645e205fc4d2bf9df10da10d1070deb6 100644 (file)
@@ -49,6 +49,7 @@ struct SessionPieceLoadJson<'r> {
   desc: Html,
   uos: &'r [UoDescription],
   moveable: PieceMoveable,
+  rotateable: bool,
   occregion: Option<JsonString<&'r Region>>,
   pub bbox: &'r Rect,
 }
@@ -158,6 +159,7 @@ fn session_inner(form: Json<SessionForm>,
         desc,
         bbox: &bbox,
         moveable: gpc.moveable(),
+        rotateable: gpc.rotateable(),
         uos: &pri.ui_operations(&ig.gs, gpc, ipc)?,
         occregion,
       };
index 504a8112904e6d76d78e7d2896393c8ed3a36675..784465b868b6b12ddd612213b99148c77eaa26d3 100644 (file)
@@ -180,6 +180,7 @@ pub enum PieceOpError {
   PosOffTable,
   PieceGone,
   Occultation,
+  PieceUnrotateable,
   OrganisedPlacementOverfull,
 }
 display_as_debug!{PieceOpError}
index 544a84e70a3aa71bc8afeadfb217f7015201c445..f5aed30dc51fb5bbd78d57861d7e22d3e6d7967c 100644 (file)
@@ -74,6 +74,7 @@ pub struct GPiece {  // usual variable: gpc
   pub gen_before_lastclient: Generation,
   pub xdata: PieceXDataState,
   pub moveable: PieceMoveable,
+  #[serde(default)] pub rotateable: bool,
 }
 
 pub type PieceXDataState = Option<Box<dyn PieceXData>>;
@@ -368,6 +369,10 @@ impl GPiece {
     if self.occult.is_active() { PieceMoveable::No }
     else { self.moveable }
   }
+  pub fn rotateable(&self) -> bool {
+    if self.occult.is_active() { false }
+    else { self.rotateable }
+  }
 
   pub fn dummy() -> Self {
     let gen_dummy = Generation(1);
@@ -384,6 +389,7 @@ impl GPiece {
       gen_before_lastclient: gen_dummy,
       xdata: None,
       moveable: default(),
+      rotateable: true,
     }
   }
 }
index 5adb59611f8c42f9506ac2c59d730b3adad708f5..0e74b7828d6779917596fd1dd41fc8663fcccb1c 100644 (file)
@@ -129,6 +129,7 @@ impl PieceRenderInstructions {
       zg         : zlevel.zg,
       angle      : pri.angle(gpc).to_compass(),
       pinned     : gpc.pinned,
+      rotateable : gpc.rotateable(),
       uos        : pri.ui_operations(gs, gpc, ipc)?,
       moveable   : gpc.moveable(),
       facehint   : pri.facehint(gpc),
index ec76b0d60b148fef2a2741e2c49e73701f0c648b..6307dc4570f432b6ae98e6491b4174a58a707338 100644 (file)
@@ -110,6 +110,7 @@ pub struct PreparedPieceState {
   pub angle: CompassAngle,
   pub pinned: bool,
   pub moveable: PieceMoveable,
+  pub rotateable: bool,
   pub uos: Vec<UoDescription>,
   pub occregion: Option<JsonString<Region>>,
   pub bbox: Rect,
index 9a57048436efeda1e7f86f4e2b619104f5cc52a4..66bcf57577621598b7d87a61992e35ba69645caf 100644 (file)
@@ -74,6 +74,7 @@ type PieceInfo = {
   angle: CompassAngle,
   pinned: boolean,
   moveable: PieceMoveable,
+  rotateable: boolean,
   uos : UoDescription[],
   uelem : SVGGraphicsElement,
   delem : SVGGraphicsElement,
@@ -300,20 +301,27 @@ function recompute_keybindings() {
     };
   };
   if (all_targets.length) {
-    add_uo(all_targets, {
-      def_key: 'l',
-      kind: 'Client',
-      wrc: 'Predictable',
-      opname: "left",
-      desc: "rotate left",
-    });
-    add_uo(all_targets, {
-      def_key: 'r',
-      kind: 'Client',
-      wrc: 'Predictable',
-      opname: "right",
-      desc: "rotate right",
-    });
+    let got_rotateable = false;
+    for (let t of all_targets) {
+      if (pieces[t]!.rotateable)
+       got_rotateable = true;
+    }
+    if (got_rotateable) {
+      add_uo(all_targets, {
+       def_key: 'l',
+       kind: 'Client',
+       wrc: 'Predictable',
+       opname: "left",
+       desc: "rotate left",
+      });
+      add_uo(all_targets, {
+       def_key: 'r',
+       kind: 'Client',
+       wrc: 'Predictable',
+       opname: "right",
+       desc: "rotate right",
+      });
+    }
     add_uo(all_targets, {
       def_key: 'b',
       kind: 'Client',
@@ -524,6 +532,7 @@ keyops_local['right'] = function (uo: UoRecord) { rotate_targets(uo, -1); }
 function rotate_targets(uo: UoRecord, dangle: number): boolean {
   for (let piece of uo.targets!) {
     let p = pieces[piece]!;
+    if (!p.rotateable) continue;
     p.angle += dangle + 8;
     p.angle %= 8;
     let transform = wasm_bindgen.angle_transform(p.angle);
@@ -1412,6 +1421,7 @@ type PreparedPieceState = {
   angle: number,
   uos: UoDescription[],
   moveable: PieceMoveable,
+  rotateable: boolean,
   occregion: string | null,
   bbox: Rect,
 }
@@ -1496,6 +1506,7 @@ function piece_modify_core(piece: PieceId, p: PieceInfo,
   p.held_us_raising = false;
   p.pinned = info.pinned;
   p.moveable = info.moveable;
+  p.rotateable = info.rotateable;
   p.angle = info.angle;
   p.bbox = info.bbox;
   piece_set_zlevel_from(piece,p,info);