of library pieces overhauled. ``size`` is now the in-game
size, and the SVG size is obtained from the SVG.
Library catalogues must be overhauled.
+ - Handling of the ``angle`` parameter in game specs is now
+ much more sensible, and also accurately documented.
* - ``1``
- 0.x - `1.0.0 <https://www.chiark.greenend.org.uk/~ianmdlvl/otter/1.0.0/docs/README.html>`_
pin and unpin pieces during the game; this is the initial state.
[boolean]
- * ``angle``: Initial orientation of the piece. The
- specified value is multiplied by 45 degrees, increasing values
- rotating anticlockwise. So for example ``6`` would mean to rotate
- 90 degrees clockwise. [integer 0..7]
+ * ``angle``: Initial orientation of the piece. Only 45-degree
+ angles are supported.
+ [number, degrees, clockwise; or string, "N", "NE" etc.]
Common parameters
pub use crate::shapelib::{ItemEnquiryData, LibraryEnquiryData};
pub use crate::shapelib::{LibraryLoadError};
pub use crate::spec::*;
-pub use crate::spec::imp::ColourSpecExt as _;
+pub use crate::spec::imp::{ColourSpecExt as _, OptionPieceAngleSpecExt as _};
pub use crate::spec::piece_specs::{FaceColourSpecs, SimpleCommon};
pub use crate::updates::*;
pub use crate::utils::*;
pub count: Option<u32>,
pub face: Option<FaceId>,
pub pinned: Option<bool>,
- #[serde(default)] pub angle: PieceAngle,
+ #[serde(default)] pub angle: Option<PieceAngleSpec>,
#[serde(flatten)]
pub info: Box<dyn PieceSpec>,
}
+#[derive(Debug,Clone,Serialize,Deserialize)]
+#[serde(untagged)]
+pub enum PieceAngleSpec {
+ Compass(String),
+ Degrees(i32),
+}
+
#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
pub enum PieceAngle {
Compass(CompassAngle),
}
}
+ #[ext(pub)]
+ impl Option<PieceAngleSpec> {
+ #[throws(SpecError)]
+ fn resolve(&self) -> PieceAngle {
+ use PieceAngleSpec as PAS;
+ let i = match self {
+ None => return default(),
+ Some(PAS::Compass(s)) => {
+ let (i,_) = [
+ "N" , "NE", "E" , "SE", "S" , "SW", "W" , "NW",
+ ].iter().enumerate().find(|(_i,&exp)| s == exp)
+ .ok_or_else(|| SpE::CompassAngleInvalid)?;
+ i as u8
+ },
+ Some(PAS::Degrees(deg)) => {
+ let deg = deg.rem_euclid(360);
+ if deg % 45 != 0 { throw!(SpE::CompassAngleInvalid) }
+ (deg / 45) as u8
+ },
+ };
+ PieceAngle::Compass(i.try_into()?)
+ }
+ }
+
impl UrlSpec {
const MAX_LEN: usize = 200;
}