From f3bafcfe3791b5b0bc6d4bd706f14449dccc016e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 22 Mar 2021 02:47:55 +0000 Subject: [PATCH] deck: Skeleton Signed-off-by: Ian Jackson --- src/deck.rs | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/spec.rs | 9 +++++ 3 files changed, 120 insertions(+) create mode 100644 src/deck.rs diff --git a/src/deck.rs b/src/deck.rs new file mode 100644 index 00000000..52adc9be --- /dev/null +++ b/src/deck.rs @@ -0,0 +1,110 @@ +// Copyright 2020-2021 Ian Jackson and contributors to Otter +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +// This is otter::hidden::magic + +use crate::prelude::*; + +pub const ACTIVE_DESC: &str = "a pickup deck (active)"; +pub const INACTIVE_DESC: &str = "a pickup deck (inactive)"; + +#[derive(Debug,Serialize,Deserialize)] +struct Deck { + shape: GenericSimpleShape<(), Outline>, +} + +#[dyn_upcast] +impl OutlineTrait for Deck { + delegate!{ + to self.shape { + fn outline_path(&self, scale: f64) -> Result; + fn thresh_dragraise(&self) -> Result,IE>; + fn bbox_approx(&self) -> Result<[Pos;2], IE>; + } + } +} + +#[typetag::serde(name="PickupDeck")] +impl PieceSpec for piece_specs::Deck { + #[throws(SpecError)] + fn load(&self, _: usize, _: &mut GPiece, _ir: &InstanceRef) + -> PieceSpecLoaded { + let common = SimpleCommon { + itemname: None, + faces: self.faces.clone(), + edges: self.edges.clone(), + edge_width: self.edge_width, + }; + let shape = GenericSimpleShape::new( + (), + self.shape.clone(), + "magic-pickupdeck", + &common)?; + if shape.count_faces() != 2 { + throw!(SpE::WrongNumberOfFaces); + } + let p = Box::new(Deck { + shape, + }) as Box; + PieceSpecLoaded { p, occultable: None } + } +} + +impl Deck { + fn active(&self, gpc: &GPiece) -> bool { + gpc.occult.is_active() + } + + fn current_face(&self, gpc: &GPiece) -> FaceId { + (self.active(gpc) as RawFaceId).into() + } +} + +#[typetag::serde] +impl PieceTrait for Deck { + fn nfaces(&self) -> RawFaceId { 1 } + #[throws(IE)] + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, + _gs: &GameState, _vpid: VisiblePieceId) { + let face = self.current_face(gpc); + self.shape.svg_piece_raw(f, face, &mut |_|Ok::<_,IE>(()))?; + } + + #[throws(IE)] + fn describe_html(&self, gpc: &GPiece) -> Html { + Html::lit( + if self.active(gpc) { ACTIVE_DESC } else { INACTIVE_DESC } + ) + } + + delegate!{ + to self.shape { + fn itemname(&self) -> &str; + } + } + + #[throws(InternalError)] + fn add_ui_operations(&self, upd: &mut Vec, + _gs: &GameState, gpc: &GPiece) { + upd.push( + if self.active(gpc) { + UoDescription { + kind: UoKind::Piece, + def_key: 'A', + opname: "activate".to_owned(), + desc: Html::lit("Enable pickup deck (to shuffle, etc.)"), + wrc: WRC::Unpredictable, + } + } else { + UoDescription { + kind: UoKind::Piece, + def_key: 'S', + opname: "deactivate".to_owned(), + desc: Html::lit("Deactivate pickup deck"), + wrc: WRC::Unpredictable, + } + } + ) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1703862c..5ddbdc10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub mod authproofs; pub mod clock; pub mod commands; pub mod config; +pub mod deck; pub mod debugreader; pub mod error; pub mod gamestate; diff --git a/src/spec.rs b/src/spec.rs index e0b4d8e4..6871ddd9 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -81,6 +81,7 @@ pub enum SpecError { CompassAngleInvalid, ZeroFaces, InconsistentFacesEdgecoloursCount, + WrongNumberOfFaces, SpecifiedWidthOfNoEdges, UnsupportedShape, NegativeTimeout, @@ -246,6 +247,14 @@ pub mod piece_specs { pub edge_width: Option, pub shape: Outline, } + + #[derive(Debug,Serialize,Deserialize)] + pub struct Deck { + pub faces: IndexVec, + #[serde(default)] pub edges: IndexVec, + pub edge_width: Option, + pub shape: Outline, + } } //---------- Pos ---------- -- 2.30.2