]> git.lizzy.rs Git - mt_net.git/blobdiff - src/to_clt/media.rs
Implement NodeDefs and ItemDefs
[mt_net.git] / src / to_clt / media.rs
index 1ec1fd6441304e263a7e2dc6fcf51c92a1f7dcd8..71767739f80a5592264320956076e7759c3f61f9 100644 (file)
@@ -1,5 +1,73 @@
 use super::*;
 
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Param1Type {
+    None = 0,
+    Light,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Param2Type {
+    Nibble = 0,
+    Byte,
+    Flowing,
+    FaceDir,
+    Mounted,
+    Leveled,
+    Rotation,
+    Mesh,
+    Color,
+    ColorFaceDir,
+    ColorMounted,
+    GrassLikeLevel,
+    ColorRotation,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum DrawType {
+    Cube = 0,
+    None,
+    Liquid,
+    Flowing,
+    GlassLike,
+    AllFaces,
+    AllFacesOpt,
+    Torch,
+    Sign,
+    Plant,
+    Fence,
+    Rail,
+    NodeBox,
+    GlassFrame,
+    Fire,
+    GlassFrameOpt,
+    Mesh,
+    RootedPlant,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Waving {
+    None = 0,
+    Plant,
+    Leaf,
+    Liquid,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Liquid {
+    None = 0,
+    Flowing,
+    Source,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Alpha {
+    Blend = 0,
+    Mask, // either fully opaque or transparent
+    Opaque,
+    Legacy,
+}
+
 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
 pub enum TileAnim {
     None = 0,
@@ -13,15 +81,352 @@ pub enum TileAnim {
     },
 }
 
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum TileAlign {
+    None = 0,
+    World,
+    User,
+}
+
+#[mt_derive(to = "clt", enumset, custom)]
+pub enum TileFlag {
+    BackfaceCull,
+    TileHorizontal,
+    TileVertical,
+}
+
+#[mt_derive(to = "clt", repr = "u16", enumset)]
+enum TileFlagInternal {
+    BackfaceCull,
+    TileHorizontal,
+    TileVertical,
+    Color,
+    Scale,
+    Align,
+}
+
+#[mt_derive(to = "clt", custom)]
+pub struct TileDef {
+    // #[mt(const_before = "6u8")]
+    pub texture: String,
+    pub animation: TileAnim,
+    pub flags: EnumSet<TileFlag>,
+    pub color: Option<[u8; 3]>,
+    pub scale: Option<u8>,
+    pub align: Option<TileAlign>,
+}
+
+#[cfg(feature = "server")]
+impl MtSerialize for TileDef {
+    fn mt_serialize<C: MtCfg>(
+        &self,
+        writer: &mut impl std::io::Write,
+    ) -> Result<(), mt_ser::SerializeError> {
+        6u8.mt_serialize::<DefCfg>(writer)?;
+        self.texture.mt_serialize::<DefCfg>(writer)?;
+        self.animation.mt_serialize::<DefCfg>(writer)?;
+
+        let mut flags: EnumSet<TileFlagInternal> = self
+            .flags
+            .iter()
+            .map(|f| match f {
+                TileFlag::BackfaceCull => TileFlagInternal::BackfaceCull,
+                TileFlag::TileHorizontal => TileFlagInternal::TileHorizontal,
+                TileFlag::TileVertical => TileFlagInternal::TileVertical,
+            })
+            .collect();
+
+        if self.color.is_some() {
+            flags.insert(TileFlagInternal::Color);
+        }
+
+        if self.scale.is_some() {
+            flags.insert(TileFlagInternal::Scale);
+        }
+
+        if self.align.is_some() {
+            flags.insert(TileFlagInternal::Align);
+        }
+
+        flags.mt_serialize::<DefCfg>(writer)?;
+        self.color.mt_serialize::<DefCfg>(writer)?;
+        self.scale.mt_serialize::<DefCfg>(writer)?;
+        self.align.mt_serialize::<DefCfg>(writer)?;
+
+        Ok(())
+    }
+}
+
+#[cfg(feature = "client")]
+impl MtDeserialize for TileDef {
+    fn mt_deserialize<C: MtCfg>(
+        reader: &mut impl std::io::Read,
+    ) -> Result<Self, mt_ser::DeserializeError> {
+        let const6u8 = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+        if 6u8 != const6u8 {
+            return Err(mt_ser::DeserializeError::InvalidConst(
+                Box::new(const6u8),
+                Box::new(6u8),
+            ));
+        }
+
+        let texture = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+        let animation = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+
+        let flags_internal = EnumSet::<TileFlagInternal>::mt_deserialize::<DefCfg>(reader)?;
+
+        let color = if flags_internal.contains(TileFlagInternal::Color) {
+            Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+        } else {
+            None
+        };
+
+        let scale = if flags_internal.contains(TileFlagInternal::Scale) {
+            Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+        } else {
+            None
+        };
+
+        let align = if flags_internal.contains(TileFlagInternal::Align) {
+            Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+        } else {
+            None
+        };
+
+        let flags = flags_internal
+            .iter()
+            .flat_map(|f| match f {
+                TileFlagInternal::BackfaceCull => Some(TileFlag::BackfaceCull),
+                TileFlagInternal::TileHorizontal => Some(TileFlag::TileHorizontal),
+                TileFlagInternal::TileVertical => Some(TileFlag::TileVertical),
+                _ => None,
+            })
+            .collect();
+
+        Ok(Self {
+            texture,
+            animation,
+            flags,
+            color,
+            scale,
+            align,
+        })
+    }
+}
+
+#[mt_derive(to = "clt", repr = "u8", tag = "type")]
+#[mt(const_before = "6u8")]
+pub enum NodeBox {
+    Cube = 0,
+    Fixed {
+        fixed: Vec<RangeInclusive<[f32; 3]>>,
+    },
+    Mounted {
+        wall_top: RangeInclusive<[f32; 3]>,
+        wall_bottom: RangeInclusive<[f32; 3]>,
+        wall_sides: RangeInclusive<[f32; 3]>,
+    },
+    Leveled {
+        fixed: Vec<RangeInclusive<[f32; 3]>>,
+    },
+    Connected {
+        fixed: Vec<RangeInclusive<[f32; 3]>>,
+        connect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
+        disconnect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
+        disconnect_all: Vec<RangeInclusive<[f32; 3]>>,
+        disconnect_sides: Vec<RangeInclusive<[f32; 3]>>,
+    },
+}
+
 #[mt_derive(to = "clt")]
-pub struct ItemDef; // TODO
+#[mt(size = "u16")]
+pub struct NodeDef {
+    // TODO: impl Default
+    #[mt(const_before = "13u8")]
+    pub name: String,
+    pub groups: HashMap<String, u16>,
+    pub param1_type: Param1Type,
+    pub param2_type: Param2Type,
+    pub draw_type: DrawType,
+    pub mesh: String,
+    pub scale: f32,
+    #[mt(const_before = "6u8")]
+    pub tiles: [TileDef; 6],
+    pub overlay_tiles: [TileDef; 6],
+    #[mt(const_before = "6u8")]
+    pub special_tiles: [TileDef; 6],
+    pub color: Color,
+    pub palette: String,
+    pub waving: Waving,
+    pub connect_sides: u8,
+    pub connect_to: Vec<u16>,
+    pub inside_tint: Color,
+    pub level: u8,         // FIXME: must be below 128
+    pub translucent: bool, // sunlight scattering
+    pub transparent: bool,
+    pub light_source: u8, // FIXME: max: 14 (?)
+    pub ground_content: bool,
+    pub collision: bool,
+    pub pointable: bool,
+    pub diggable: bool,
+    pub climbable: bool,
+    pub replaceable: bool,
+    pub has_on_right_click: bool,
+    pub damage_per_second: i32,
+    pub liquid: Liquid,
+    pub flowing_alt: String,
+    pub source_alt: String,
+    pub viscosity: u8, // FIXME: 0-7
+    pub liquid_renewable: bool,
+    pub flow_range: u8,
+    pub drown_damage: u8,
+    pub floodable: bool,
+    pub draw_box: NodeBox,
+    pub collision_box: NodeBox,
+    pub selection_box: NodeBox,
+    pub footstep_sound: SoundDef,
+    pub digging_sound: SoundDef,
+    pub dug_sound: SoundDef,
+    pub legacy_face_dir: bool,
+    pub legacy_mounted: bool,
+    pub dig_predict: String,
+    pub max_level: u8,
+    pub alpha: Alpha,
+    pub move_resistance: u8,
+    pub liquid_move_physics: bool,
+}
+
+#[mt_derive(to = "clt", custom)]
+pub struct NodeDefs(pub HashMap<u16, NodeDef>);
+
+// stupid bullshit ahead
+
+#[cfg(feature = "server")]
+impl MtSerialize for NodeDefs {
+    fn mt_serialize<C: MtCfg>(
+        &self,
+        writer: &mut impl std::io::Write,
+    ) -> Result<(), mt_ser::SerializeError> {
+        DefCfg::write_len(self.0.len(), writer)?;
+
+        let mut buf = Vec::new();
+        self.0.mt_serialize::<()>(&mut buf)?;
+        buf.mt_serialize::<u32>(writer)?;
+
+        Ok(())
+    }
+}
+
+#[cfg(feature = "client")]
+impl MtDeserialize for NodeDefs {
+    fn mt_deserialize<C: MtCfg>(
+        reader: &mut impl std::io::Read,
+    ) -> Result<Self, mt_ser::DeserializeError> {
+        use mt_ser::MtLen;
+
+        let len = DefCfg::read_len(reader)?;
+        let mut reader = u32::read_len(reader)?.take(mt_ser::WrapRead(reader));
+        let inner =
+            mt_ser::mt_deserialize_sized_seq::<DefCfg, _>(&len, &mut reader)?.try_collect()?;
+
+        Ok(Self(inner))
+    }
+}
+
+/* TODO: Rustify this
+
+func BuiltinNodeDefs(n int) map[Content]NodeDef {
+    defs := make(map[Content]NodeDef, 3+n)
+    defs[Unknown] = NodeDef{
+        Name: "unknown",
+    }
+    defs[Air] = NodeDef{
+        Name:        "air",
+        DrawType:    DrawNothing,
+        P1Type:      P1Light,
+        Translucent: true,
+        Transparent: true,
+        Replaceable: true,
+        Floodable:   true,
+        GndContent:  true,
+    }
+    defs[Ignore] = NodeDef{
+        Name:        "ignore",
+        DrawType:    DrawNothing,
+        Replaceable: true,
+        GndContent:  true,
+    }
+    return defs
+}
+*/
+
+#[mt_derive(to = "clt")]
+pub struct ToolGroupCap {
+    pub uses: i16, // 32to16
+    pub max_level: i16,
+    #[mt(len = "u32")]
+    pub times: HashMap<i16, f32>,
+}
 
 #[mt_derive(to = "clt")]
-pub struct NodeDef; // TODO
+pub struct ToolCaps {
+    #[mt(const_before = "5u8")]
+    pub attack_cooldown: f32,
+    pub max_drop_level: i16,
+    #[mt(len = "u32")]
+    pub group_caps: HashMap<String, ToolGroupCap>,
+    #[mt(len = "u32")]
+    pub dmg_groups: HashMap<String, u16>,
+    pub punch_uses: u16, // 32tou16
+}
 
 #[mt_derive(to = "clt", repr = "u8")]
-pub enum SoundSrcType {
+pub enum ItemType {
+    Node = 1,
+    Craft,
+    Tool,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum SoundSource {
     Nowhere = 0,
     Pos,
     Obj,
 }
+
+#[mt_derive(to = "clt")]
+pub struct SoundDef {
+    pub name: String,
+    pub gain: f32,
+    pub pitch: f32,
+    pub fade: f32,
+}
+
+#[mt_derive(to = "clt")]
+#[mt(size = "u16")]
+pub struct ItemDef {
+    #[mt(const_before = "6u8")]
+    #[serde(rename = "type")]
+    pub item_type: ItemType,
+    pub name: String,
+    pub description: String,
+    pub inventory_image: String,
+    pub wield_image: String,
+    pub wield_scale: [f32; 3],
+    pub stack_max: u16,
+    pub usable: bool,
+    pub can_point_liquids: bool,
+    #[mt(size = "u16")]
+    pub tool_caps: Option<ToolCaps>,
+    pub groups: HashMap<String, u16>,
+    pub place_predict: String,
+    pub place_sound: SoundDef,
+    pub place_fail_sound: SoundDef,
+    pub point_range: f32,
+    pub palette: String,
+    pub color: Color,
+    pub inventory_overlay: String,
+    pub wield_overlay: String,
+    pub short_description: String,
+    pub place_param2: u8,
+}