Maraiah/source/map/poly.rs

196 lines
5.1 KiB
Rust

//! `Polygon` type.
use super::pnts;
use crate::{bin::OptU16, err::*, fixed::Unit, xfer::TransferMode};
use bitflags::bitflags;
use std::convert::TryFrom;
/// 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 = PolyType::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 = PolyType::new_old(ptype, pdata)?;
Ok((Polygon{ptype, ..poly}, 128))
}
impl PolyType
{
/// Creates a `PolyType` from a `n`/`pdata` pair.
pub fn new(n: u16, pdata: u16) -> Result<Self, ReprError>
{
match n {
0 => Ok(PolyType::Normal),
1 => Ok(PolyType::ImpassItem),
2 => Ok(PolyType::ImpassMons),
3 => Ok(PolyType::Hill),
4 => Ok(PolyType::Base),
5 => Ok(PolyType::Platform(pdata)),
6 => Ok(PolyType::TrigLightOn(pdata)),
7 => Ok(PolyType::TrigPlatOn(pdata)),
8 => Ok(PolyType::TrigLightOff(pdata)),
9 => Ok(PolyType::TrigPlatOff(pdata)),
10 => Ok(PolyType::Teleporter(pdata)),
11 => Ok(PolyType::ZoneBorder),
12 => Ok(PolyType::Goal),
13 => Ok(PolyType::TrigMonsVis),
14 => Ok(PolyType::TrigMonsInv),
15 => Ok(PolyType::TrigMonsDual),
16 => Ok(PolyType::TrigItems),
17 => Ok(PolyType::MustExplore),
18 => Ok(PolyType::AutoExit),
19 => Ok(PolyType::OuchMinor),
20 => Ok(PolyType::OuchMajor),
21 => Ok(PolyType::Glue),
22 => Ok(PolyType::GlueTrigger(pdata)),
23 => Ok(PolyType::GlueSuper),
n => Err(ReprError::new(n)),
}
}
/// Creates a `PolyType` from a Marathon 1 compatible `n`/`pdata` pair.
fn new_old(n: u16, pdata: u16) -> Result<Self, ReprError>
{
match n {
0 => Ok(PolyType::Normal),
1 => Ok(PolyType::ImpassItem),
2 => Ok(PolyType::ImpassMons),
3 => Ok(PolyType::OuchMinor),
4 => Ok(PolyType::OuchMajor),
5 => Ok(PolyType::Platform(pdata)),
6 => Ok(PolyType::TrigLightOn(pdata)),
7 => Ok(PolyType::TrigPlatOn(pdata)),
8 => Ok(PolyType::TrigLightOff(pdata)),
9 => Ok(PolyType::TrigPlatOff(pdata)),
10 => Ok(PolyType::Teleporter(pdata)),
11 => Ok(PolyType::Glue),
12 => Ok(PolyType::GlueTrigger(pdata)),
13 => Ok(PolyType::GlueSuper),
14 => Ok(PolyType::MustExplore),
15 => Ok(PolyType::AutoExit),
n => Err(ReprError::new(n)),
}
}
}
impl Default for PolyType
{
fn default() -> Self {PolyType::Normal}
}
/// A polygon segment.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Default, Eq, PartialEq)]
pub struct Polygon
{
pub ptype: PolyType,
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(Debug, Eq, PartialEq)]
pub enum PolyType
{
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 PolyFlags: u16
{
const DETACHED = 1 << 14;
}
}
// EOF