diff options
Diffstat (limited to 'src/to_clt/media.rs')
-rw-r--r-- | src/to_clt/media.rs | 411 |
1 files changed, 408 insertions, 3 deletions
diff --git a/src/to_clt/media.rs b/src/to_clt/media.rs index 1ec1fd6..7176773 100644 --- a/src/to_clt/media.rs +++ b/src/to_clt/media.rs @@ -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, +} |