use super::*; pub(super) fn default_floors() -> u8 { 2 } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(default)] pub(super) struct Pos { pub x: f32, pub y: f32, } impl From for Vec2 { fn from(Pos { x, y }: Pos) -> Self { Self { x, y } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(default)] pub(super) struct UPos { pub x: u32, pub y: u32, } impl From for UVec2 { fn from(UPos { x, y }: UPos) -> Self { Self { x, y } } } #[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(default)] pub(super) struct USize { pub w: u32, pub h: u32, } impl Default for USize { fn default() -> Self { Self { w: 1, h: 1 } } } impl From for UVec2 { fn from(USize { w, h }: USize) -> Self { Self { x: w, y: h } } } #[derive(Debug, Deserialize, Serialize, Default, PartialEq, Eq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(default)] pub(super) struct USizeRect { #[serde(flatten)] pub pos: UPos, #[serde(flatten)] pub size: USize, } impl From for URect { fn from(USizeRect { pos, size: USize { w, h } }: USizeRect) -> Self { URect::from_corners(pos.into(), uvec2(pos.x + w - 1, pos.y + h - 1)) } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "lowercase")] pub(super) enum Facing { #[default] Left, Right, } impl From for bool { fn from(value: Facing) -> Self { match value { Facing::Left => true, Facing::Right => false, } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct DoorDataInner { #[serde(flatten)] pub pos: Pos, #[serde(default)] pub facing: Option, #[serde(default)] pub lock: Option, } impl From for DoorData { fn from(DoorDataInner { pos, facing, lock }: DoorDataInner) -> Self { let lock = if let Some(lock) = lock { Some(lock.into()) } else { None }; Self { pos: pos.into(), facing_left: facing.unwrap_or_default().into(), lock, } } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct StairsInnerData { #[serde(flatten)] pub pos: Pos, #[serde(default = "default_floors")] pub floors: u8, } impl From for StairsData { fn from(StairsInnerData { pos, floors }: StairsInnerData) -> Self { Self { pos: pos.into(), floors, } } } impl Default for StairsInnerData { fn default() -> Self { Self { pos: Pos::default(), floors: default_floors(), } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct ItemDataInner { pub id: String, #[serde(default, flatten)] pub pos: UPos, #[serde(default)] pub rotated: bool, } impl From for ItemData { fn from(ItemDataInner { id, pos, rotated }: ItemDataInner) -> Self { Self { id, pos: pos.into(), rotated, } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct ContainerDataInner { #[serde(flatten)] pub pos: Pos, #[serde(flatten, default)] pub size: Option, #[serde(default)] pub items: Option>, } impl From for ContainerData { fn from(ContainerDataInner { pos, size, items }: ContainerDataInner) -> Self { Self { pos: pos.into(), size: size.unwrap_or_default().into(), items: items.unwrap_or_default(), } } } pub(super) fn default_intensity() -> f32 { 2. } pub(super) fn default_radius() -> f32 { 4. } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct LampDataInner { #[serde(flatten)] pub pos: Pos, #[serde(default = "default_intensity")] pub intensity: f32, #[serde(default = "default_radius")] pub radius: f32, } impl From for LampData { fn from(LampDataInner { pos, intensity, radius }: LampDataInner) -> Self { Self { pos: pos.into(), intensity, radius, } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] pub(super) struct InteractiveInner { pub player: Pos, #[serde(default)] pub doors: Option>, #[serde(default)] pub stairs: Option>, #[serde(default)] pub containers: Option>, #[serde(default)] pub lamps: Option>, } impl From for Interactive { fn from(InteractiveInner { player, doors, stairs, containers, lamps }: InteractiveInner) -> Self { Self { player: player.into(), doors: doors.unwrap_or_default(), stairs: stairs.unwrap_or_default(), containers: containers.unwrap_or_default(), lamps: lamps.unwrap_or_default(), } } } #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, Clone, Reflect)] #[reflect(Debug, Default, Deserialize, Serialize, PartialEq, Clone)] #[serde(transparent)] pub(super) struct TilesInner(HashMap>); impl From for Tiles { fn from(TilesInner(tiles): TilesInner) -> Self { // This is probably the funniest one-liner I've ever written Tiles { tiles: tiles.into_iter().map(|(k, v)| (k, v.into_iter().map(|v| v.into()).collect())).collect() } } }