]> git.lizzy.rs Git - mt_net.git/commitdiff
Implement NodeDefs and ItemDefs
authorLizzy Fleckenstein <eliasfleckenstein@web.de>
Wed, 15 Feb 2023 01:22:36 +0000 (02:22 +0100)
committerLizzy Fleckenstein <eliasfleckenstein@web.de>
Wed, 15 Feb 2023 01:22:36 +0000 (02:22 +0100)
Cargo.toml
src/lib.rs
src/to_clt.rs
src/to_clt/inv.rs
src/to_clt/map.rs
src/to_clt/media.rs
src/to_clt/obj.rs

index eb9d99c1f6678f3b7733be3c100cb4b49679ebbe..afbc3e4998da34ff4b76cb651608280b9232669e 100644 (file)
@@ -15,7 +15,6 @@ test = ["client", "server", "random"]
 enumset = { git = "https://github.com/Lymia/enumset" }
 generate-random = { git = "https://github.com/minetest-rust/generate-random", features = ["enumset"], optional = true }
 mt_ser = { git = "https://github.com/minetest-rust/mt_ser" }
-#mt_ser = { path = "../mt_ser" }
 rand = { version = "0.8.5", optional = true }
 serde = { version = "1.0.152", features = ["derive"], optional = true }
 serde_arrays = { version = "0.1.0", optional = true }
index 36ffec95164759e0de96237814a06d2c96a2cd5a..77538cd2943b7036e28d6b8868cc67a27c1c8973 100644 (file)
@@ -1,5 +1,6 @@
 #![feature(iterator_try_collect)]
 
+pub use enumset;
 pub use mt_ser;
 
 #[cfg(feature = "random")]
@@ -16,6 +17,7 @@ use mt_ser::mt_derive;
 use std::{
     collections::{HashMap, HashSet},
     fmt,
+    ops::RangeInclusive,
 };
 
 #[cfg(any(feature = "client", feature = "server"))]
index 9848daec3016e4c9ccdf06a0e49d7dbe7d99c0e1..3792018a305b6062952bc676e653fa4fddc36e93 100644 (file)
@@ -170,10 +170,7 @@ pub enum ToCltPkt {
         files: HashMap<String, Vec<u8>>, // name -> payload
     } = 56,
     #[mt(size = "u32", zlib)]
-    NodeDefs {
-        #[mt(const_before = "1u8")] // version
-        defs: Vec<NodeDef>,
-    } = 58,
+    NodeDefs(#[mt(const_before = "1u8")] NodeDefs) = 58,
     AnnounceMedia {
         files: HashMap<String, String>, // name -> base64 sha1 hash
         url: String,
@@ -188,7 +185,7 @@ pub enum ToCltPkt {
         id: u32,
         name: String,
         gain: f32,
-        src_type: SoundSrcType,
+        source: SoundSource,
         pos: [f32; 3],
         src_obj_id: u16,
         #[serde(rename = "loop")]
@@ -254,11 +251,11 @@ pub enum ToCltPkt {
     AddParticleSpawner {
         amount: u16,
         duration: f32,
-        pos: [[f32; 3]; 2],
-        vel: [[f32; 3]; 2],
-        acc: [[f32; 3]; 2],
-        expiration_time: [f32; 2],
-        size: [f32; 2],
+        pos: RangeInclusive<[f32; 3]>,
+        vel: RangeInclusive<[f32; 3]>,
+        acc: RangeInclusive<[f32; 3]>,
+        expiration_time: RangeInclusive<f32>,
+        size: RangeInclusive<f32>,
         collide: bool,
         #[mt(len = "u32")]
         texture: String,
index 2ada0a1bcfcb5af1cef74b2e8b0e01d4280a507e..01eaa75a1edb1b860d9e6d5c6231ff472d440f2a 100644 (file)
@@ -1,18 +1,20 @@
 use super::*;
-use mt_ser::{DeserializeError, SerializeError};
-use std::io::{Read, Write};
 
 #[mt_derive(to = "clt", custom)]
 pub struct Inventory; // TODO
 
 #[cfg(feature = "server")]
 impl MtSerialize for Inventory {
-    fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
+    fn mt_serialize<C: MtCfg>(
+        &self,
+        writer: &mut impl std::io::Write,
+    ) -> Result<(), mt_ser::SerializeError> {
         "EndInventory\n".mt_serialize::<()>(writer)
     }
 }
 
-fn read_line(reader: &mut impl Read) -> Result<String, DeserializeError> {
+#[cfg(feature = "client")]
+fn read_line(reader: &mut impl std::io::Read) -> Result<String, mt_ser::DeserializeError> {
     let utf8 = mt_ser::mt_deserialize_seq::<(), u8>(reader)?
         .map_while(|x| match x {
             Ok(0x0A) => None,
@@ -21,12 +23,14 @@ fn read_line(reader: &mut impl Read) -> Result<String, DeserializeError> {
         .try_collect::<Vec<_>>()?;
 
     String::from_utf8(utf8)
-        .map_err(|e| DeserializeError::Other(format!("Invalid UTF-8: {e}").into()))
+        .map_err(|e| mt_ser::DeserializeError::Other(format!("Invalid UTF-8: {e}").into()))
 }
 
 #[cfg(feature = "client")]
 impl MtDeserialize for Inventory {
-    fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
+    fn mt_deserialize<C: MtCfg>(
+        reader: &mut impl std::io::Read,
+    ) -> Result<Self, mt_ser::DeserializeError> {
         loop {
             match read_line(reader)?.as_str() {
                 "EndInventory" => return Ok(Self),
index 296a23f0dac6b2d4a6b7cad50999ee4b6d02688c..b35f2cd62a9c78477ec24cb83eabf6807c517306 100644 (file)
@@ -1,5 +1,4 @@
 use super::*;
-use mt_ser::{DeserializeError, SerializeError};
 
 #[mt_derive(to = "clt", repr = "u8", enumset)]
 pub enum MapBlockFlag {
@@ -32,11 +31,15 @@ pub struct NodeMeta {
 #[derive(Debug)]
 pub struct NodeMetasLen;
 
+#[cfg(any(feature = "client", feature = "server"))]
 impl MtCfg for NodeMetasLen {
     type Len = <DefCfg as MtCfg>::Len;
     type Inner = <DefCfg as MtCfg>::Inner;
 
-    fn write_len(len: usize, writer: &mut impl std::io::Write) -> Result<(), SerializeError> {
+    fn write_len(
+        len: usize,
+        writer: &mut impl std::io::Write,
+    ) -> Result<(), mt_ser::SerializeError> {
         if len == 0 {
             0u8.mt_serialize::<DefCfg>(writer)
         } else {
@@ -45,11 +48,14 @@ impl MtCfg for NodeMetasLen {
         }
     }
 
-    fn read_len(reader: &mut impl std::io::Read) -> Result<Self::Len, DeserializeError> {
+    fn read_len(reader: &mut impl std::io::Read) -> Result<Self::Len, mt_ser::DeserializeError> {
         match u8::mt_deserialize::<DefCfg>(reader)? {
             0 => Ok(0),
             2 => DefCfg::read_len(reader),
-            x => Err(DeserializeError::InvalidEnum("NodeMetasLen", Box::new(x))),
+            x => Err(mt_ser::DeserializeError::InvalidEnum(
+                "NodeMetasLen",
+                Box::new(x),
+            )),
         }
     }
 }
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,
+}
index 9e88ffffa8af6fdf68dda470937cfa8031371c89..1b605cc33598a9263744daff428fa83d6b893232 100644 (file)
@@ -16,8 +16,8 @@ pub struct ObjProps {
     pub max_hp: u16, // player only
     pub collide_with_nodes: bool,
     pub weight: f32, // deprecated
-    pub collision_box: ([f32; 3], [f32; 3]),
-    pub selection_box: ([f32; 3], [f32; 3]),
+    pub collision_box: RangeInclusive<[f32; 3]>,
+    pub selection_box: RangeInclusive<[f32; 3]>,
     pub pointable: bool,
     pub visual: ObjVisual,
     pub visual_size: [f32; 3],