Maraiah/maraiah/map/poly.rs

195 lines
5.3 KiB
Rust

//! `Polygon` type.
use super::pnts;
use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode};
use bitflags::bitflags;
/// Reads a polygon for either M1 or M2.
pub fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
{
read_data! {
endian: BIG, buf: b, size: 128, start: 0, data {
let tex_flr = OptU16[40];
let tex_cei = OptU16[42];
let hei_flr = Unit[44];
let hei_cei = Unit[46];
let lit_flr = u16[48];
let lit_cei = u16[50];
let xfr_flr = u16[64] enum TransferMode;
let xfr_cei = u16[66] enum TransferMode;
}
}
Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr,
xfr_cei, ..Polygon::default()})
}
/// Reads a `POLY` chunk.
pub fn read(b: &[u8]) -> ResultS<(Polygon, usize)>
{
read_data! {
endian: BIG, buf: b, size: 128, start: 0, data {
let ptype = u16[0];
let pdata = u16[4];
let ori_flr = pnts::read_o[108; 4];
let ori_cei = pnts::read_o[112; 4];
let med_ind = OptU16[116];
let med_ctl = u16[118];
let snd_amb = OptU16[122];
let snd_ind = u16[120];
let snd_rnd = OptU16[124];
}
}
let poly = read_poly_inter(b)?;
let ptype = PolygonType::new(ptype, pdata)?;
Ok((Polygon{ptype, ori_flr, ori_cei, med_ind, med_ctl, snd_ind, snd_amb,
snd_rnd, ..poly}, 128))
}
/// Reads an old `POLY` chunk.
pub fn read_old(b: &[u8]) -> ResultS<(Polygon, usize)>
{
read_data! {
endian: BIG, buf: b, size: 128, start: 0, data {
let ptype = u16[0];
let pdata = u16[4];
}
}
let poly = read_poly_inter(b)?;
let ptype = PolygonType::new_old(ptype, pdata)?;
Ok((Polygon{ptype, ..poly}, 128))
}
impl PolygonType
{
/// Creates a `PolygonType` from a `n`/`pdata` pair.
pub fn new(n: u16, pdata: u16) -> Result<Self, ReprError>
{
match n {
0 => Ok(PolygonType::Normal),
1 => Ok(PolygonType::ImpassItem),
2 => Ok(PolygonType::ImpassMons),
3 => Ok(PolygonType::Hill),
4 => Ok(PolygonType::Base),
5 => Ok(PolygonType::Platform(pdata)),
6 => Ok(PolygonType::TrigLightOn(pdata)),
7 => Ok(PolygonType::TrigPlatOn(pdata)),
8 => Ok(PolygonType::TrigLightOff(pdata)),
9 => Ok(PolygonType::TrigPlatOff(pdata)),
10 => Ok(PolygonType::Teleporter(pdata)),
11 => Ok(PolygonType::ZoneBorder),
12 => Ok(PolygonType::Goal),
13 => Ok(PolygonType::TrigMonsVis),
14 => Ok(PolygonType::TrigMonsInv),
15 => Ok(PolygonType::TrigMonsDual),
16 => Ok(PolygonType::TrigItems),
17 => Ok(PolygonType::MustExplore),
18 => Ok(PolygonType::AutoExit),
19 => Ok(PolygonType::OuchMinor),
20 => Ok(PolygonType::OuchMajor),
21 => Ok(PolygonType::Glue),
22 => Ok(PolygonType::GlueTrigger(pdata)),
23 => Ok(PolygonType::GlueSuper),
n => Err(ReprError::new(n)),
}
}
/// Creates a `PolygonType` from a Marathon 1 compatible `n`/`pdata` pair.
fn new_old(n: u16, pdata: u16) -> Result<Self, ReprError>
{
match n {
0 => Ok(PolygonType::Normal),
1 => Ok(PolygonType::ImpassItem),
2 => Ok(PolygonType::ImpassMons),
3 => Ok(PolygonType::OuchMinor),
4 => Ok(PolygonType::OuchMajor),
5 => Ok(PolygonType::Platform(pdata)),
6 => Ok(PolygonType::TrigLightOn(pdata)),
7 => Ok(PolygonType::TrigPlatOn(pdata)),
8 => Ok(PolygonType::TrigLightOff(pdata)),
9 => Ok(PolygonType::TrigPlatOff(pdata)),
10 => Ok(PolygonType::Teleporter(pdata)),
11 => Ok(PolygonType::Glue),
12 => Ok(PolygonType::GlueTrigger(pdata)),
13 => Ok(PolygonType::GlueSuper),
14 => Ok(PolygonType::MustExplore),
15 => Ok(PolygonType::AutoExit),
n => Err(ReprError::new(n)),
}
}
}
impl Default for PolygonType
{
fn default() -> Self {PolygonType::Normal}
}
/// A polygon segment.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Polygon
{
pub ptype: PolygonType,
pub tex_flr: OptU16,
pub tex_cei: OptU16,
pub hei_flr: Unit,
pub hei_cei: Unit,
pub lit_flr: u16,
pub lit_cei: u16,
pub xfr_flr: TransferMode,
pub xfr_cei: TransferMode,
pub ori_flr: pnts::Point,
pub ori_cei: pnts::Point,
pub med_ind: OptU16,
pub med_ctl: u16,
pub snd_ind: u16,
pub snd_amb: OptU16,
pub snd_rnd: OptU16,
}
/// The action type of a `Polygon`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PolygonType
{
Normal,
ImpassItem,
ImpassMons,
Hill,
Base,
Platform(u16),
TrigLightOn(u16),
TrigPlatOn(u16),
TrigLightOff(u16),
TrigPlatOff(u16),
Teleporter(u16),
ZoneBorder,
Goal,
TrigMonsVis,
TrigMonsInv,
TrigMonsDual,
TrigItems,
MustExplore,
AutoExit,
OuchMinor,
OuchMajor,
Glue,
GlueTrigger(u16),
GlueSuper,
}
bitflags! {
/// Flags for `Polygon`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
pub struct PolygonFlags: u16
{
const DETACHED = 1 << 14;
}
}
// EOF