use bevy::reflect::Reflect;
use serde::{de::Visitor, Deserialize, Serialize};
use crate::ldtk::sprite::{NineSliceBorders, TileRenderMode};
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct Definitions {
pub entities: Vec<EntityDef>,
pub enums: Vec<EnumDef>,
pub external_enums: Vec<EnumDef>,
pub layers: Vec<LayerDef>,
pub tilesets: Vec<TilesetDef>,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct LayerDef {
#[serde(rename = "__type")]
pub ty: LayerType,
pub auto_source_layer_def_uid: Option<i32>,
pub display_opacity: f32,
pub grid_size: i32,
pub identifier: String,
pub int_grid_values: Vec<IntGridValue>,
pub int_grid_values_groups: Vec<IntGroupValueGroup>,
pub parallax_factor_x: f32,
pub parallax_factor_y: f32,
pub parallax_scaling: bool,
pub px_offset_x: i32,
pub px_offset_y: i32,
pub tileset_def_uid: Option<i32>,
pub uid: i32,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum LayerType {
IntGrid,
Entities,
Tiles,
AutoLayer,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct IntGridValue {
pub color: String,
pub group_uid: i32,
pub identifier: Option<String>,
pub tile: Option<TilesetRect>,
pub value: i32,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct IntGroupValueGroup {
pub color: Option<String>,
pub identifier: Option<String>,
pub uid: i32,
}
#[derive(Serialize, Deserialize, Debug, Clone, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct EntityDef {
pub color: String,
pub identifier: String,
pub nine_slice_borders: NineSliceBorders,
pub pivot_x: f32,
pub pivot_y: f32,
pub tile_rect: Option<TilesetRect>,
pub tile_render_mode: TileRenderMode,
pub tileset_id: Option<i32>,
pub ui_tile_rect: Option<TilesetRect>,
pub uid: i32,
pub width: i32,
pub height: i32,
}
impl<'de> Deserialize<'de> for NineSliceBorders {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(NineSliceBordersVisitor)
}
}
pub struct NineSliceBordersVisitor;
impl<'de> Visitor<'de> for NineSliceBordersVisitor {
type Value = NineSliceBorders;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an array of [top, right, bottom, left] values")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut borders = NineSliceBorders {
is_valid: false,
up: 0,
right: 0,
down: 0,
left: 0,
};
if let Some(x) = seq.next_element()? {
borders.up = x;
borders.is_valid = true;
} else {
return Ok(borders);
}
borders.right = seq.next_element()?.unwrap();
borders.down = seq.next_element()?.unwrap();
borders.left = seq.next_element()?.unwrap();
Ok(borders)
}
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct TilesetDef {
#[serde(rename = "__cHei")]
pub c_hei: i32,
#[serde(rename = "__cWid")]
pub c_wid: i32,
pub custom_data: Vec<CustomData>,
pub embed_atlas: Option<String>,
pub enum_tags: Vec<EnumTag>,
pub identifier: String,
pub padding: i32,
pub px_hei: i32,
pub px_wid: i32,
pub rel_path: Option<String>,
pub spacing: i32,
pub tags: Vec<String>,
pub tags_source_enum_uid: Option<i32>,
pub tile_grid_size: i32,
pub uid: i32,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct CustomData {
pub data: String,
pub tile_id: i32,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct EnumTag {
pub enum_value_id: String,
pub tile_ids: Vec<i32>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct TilesetRect {
pub tileset_uid: i32,
#[serde(rename = "x")]
pub x_pos: i32,
#[serde(rename = "y")]
pub y_pos: i32,
#[serde(rename = "w")]
pub width: i32,
#[serde(rename = "h")]
pub height: i32,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct EnumTagValue {
pub tile_ids: Vec<i32>,
pub enum_value_id: String,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct EnumDef {
pub external_rel_path: Option<String>,
pub icon_tileset_uid: Option<i32>,
pub identifier: String,
pub tags: Vec<String>,
pub uid: i32,
pub values: Vec<EnumValue>,
}
#[derive(Serialize, Deserialize, Debug, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct EnumValue {
pub color: i32,
pub id: String,
pub tile_rect: Option<TilesetRect>,
}