3 #[mt_derive(to = "clt", repr = "u8")]
9 #[mt_derive(to = "clt", repr = "u8")]
26 #[mt_derive(to = "clt", repr = "u8")]
48 #[mt_derive(to = "clt", repr = "u8")]
56 #[mt_derive(to = "clt", repr = "u8")]
63 #[mt_derive(to = "clt", repr = "u8")]
66 Mask, // either fully opaque or transparent
71 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
79 aspect_ratio: [u8; 2],
84 #[mt_derive(to = "clt", repr = "u8")]
91 #[mt_derive(to = "clt", enumset, custom)]
98 #[mt_derive(to = "clt", repr = "u16", enumset)]
99 enum TileFlagInternal {
108 #[mt_derive(to = "clt", custom)]
110 // #[mt(const_before = "6u8")]
112 pub animation: TileAnim,
113 pub flags: EnumSet<TileFlag>,
114 pub color: Option<[u8; 3]>,
115 pub scale: Option<u8>,
116 pub align: Option<TileAlign>,
119 #[cfg(feature = "server")]
120 impl MtSerialize for TileDef {
121 fn mt_serialize<C: MtCfg>(
123 writer: &mut impl std::io::Write,
124 ) -> Result<(), mt_ser::SerializeError> {
125 6u8.mt_serialize::<DefCfg>(writer)?;
126 self.texture.mt_serialize::<DefCfg>(writer)?;
127 self.animation.mt_serialize::<DefCfg>(writer)?;
129 let mut flags: EnumSet<TileFlagInternal> = self
133 TileFlag::BackfaceCull => TileFlagInternal::BackfaceCull,
134 TileFlag::TileHorizontal => TileFlagInternal::TileHorizontal,
135 TileFlag::TileVertical => TileFlagInternal::TileVertical,
139 if self.color.is_some() {
140 flags.insert(TileFlagInternal::Color);
143 if self.scale.is_some() {
144 flags.insert(TileFlagInternal::Scale);
147 if self.align.is_some() {
148 flags.insert(TileFlagInternal::Align);
151 flags.mt_serialize::<DefCfg>(writer)?;
152 self.color.mt_serialize::<DefCfg>(writer)?;
153 self.scale.mt_serialize::<DefCfg>(writer)?;
154 self.align.mt_serialize::<DefCfg>(writer)?;
160 #[cfg(feature = "client")]
161 impl MtDeserialize for TileDef {
162 fn mt_deserialize<C: MtCfg>(
163 reader: &mut impl std::io::Read,
164 ) -> Result<Self, mt_ser::DeserializeError> {
165 let const6u8 = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
167 return Err(mt_ser::DeserializeError::InvalidConst(
173 let texture = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
174 let animation = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
176 let flags_internal = EnumSet::<TileFlagInternal>::mt_deserialize::<DefCfg>(reader)?;
178 let color = if flags_internal.contains(TileFlagInternal::Color) {
179 Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
184 let scale = if flags_internal.contains(TileFlagInternal::Scale) {
185 Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
190 let align = if flags_internal.contains(TileFlagInternal::Align) {
191 Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
196 let flags = flags_internal
198 .flat_map(|f| match f {
199 TileFlagInternal::BackfaceCull => Some(TileFlag::BackfaceCull),
200 TileFlagInternal::TileHorizontal => Some(TileFlag::TileHorizontal),
201 TileFlagInternal::TileVertical => Some(TileFlag::TileVertical),
217 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
218 #[mt(const_before = "6u8")]
222 fixed: Vec<RangeInclusive<[f32; 3]>>,
225 wall_top: RangeInclusive<[f32; 3]>,
226 wall_bottom: RangeInclusive<[f32; 3]>,
227 wall_sides: RangeInclusive<[f32; 3]>,
230 fixed: Vec<RangeInclusive<[f32; 3]>>,
233 fixed: Vec<RangeInclusive<[f32; 3]>>,
234 connect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
235 disconnect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
236 disconnect_all: Vec<RangeInclusive<[f32; 3]>>,
237 disconnect_sides: Vec<RangeInclusive<[f32; 3]>>,
241 #[mt_derive(to = "clt")]
244 // TODO: impl Default
245 #[mt(const_before = "13u8")]
247 pub groups: HashMap<String, u16>,
248 pub param1_type: Param1Type,
249 pub param2_type: Param2Type,
250 pub draw_type: DrawType,
253 #[mt(const_before = "6u8")]
254 pub tiles: [TileDef; 6],
255 pub overlay_tiles: [TileDef; 6],
256 #[mt(const_before = "6u8")]
257 pub special_tiles: [TileDef; 6],
261 pub connect_sides: u8,
262 pub connect_to: Vec<u16>,
263 pub inside_tint: Color,
264 pub level: u8, // FIXME: must be below 128
265 pub translucent: bool, // sunlight scattering
266 pub transparent: bool,
267 pub light_source: u8, // FIXME: max: 14 (?)
268 pub ground_content: bool,
273 pub replaceable: bool,
274 pub has_on_right_click: bool,
275 pub damage_per_second: i32,
277 pub flowing_alt: String,
278 pub source_alt: String,
279 pub viscosity: u8, // FIXME: 0-7
280 pub liquid_renewable: bool,
282 pub drown_damage: u8,
284 pub draw_box: NodeBox,
285 pub collision_box: NodeBox,
286 pub selection_box: NodeBox,
287 pub footstep_sound: SoundDef,
288 pub digging_sound: SoundDef,
289 pub dug_sound: SoundDef,
290 pub legacy_face_dir: bool,
291 pub legacy_mounted: bool,
292 pub dig_predict: String,
295 pub move_resistance: u8,
296 pub liquid_move_physics: bool,
299 #[mt_derive(to = "clt", custom)]
300 pub struct NodeDefs(pub HashMap<u16, NodeDef>);
302 // stupid bullshit ahead
304 #[cfg(feature = "server")]
305 impl MtSerialize for NodeDefs {
306 fn mt_serialize<C: MtCfg>(
308 writer: &mut impl std::io::Write,
309 ) -> Result<(), mt_ser::SerializeError> {
310 DefCfg::write_len(self.0.len(), writer)?;
312 let mut buf = Vec::new();
313 self.0.mt_serialize::<()>(&mut buf)?;
314 buf.mt_serialize::<u32>(writer)?;
320 #[cfg(feature = "client")]
321 impl MtDeserialize for NodeDefs {
322 fn mt_deserialize<C: MtCfg>(
323 reader: &mut impl std::io::Read,
324 ) -> Result<Self, mt_ser::DeserializeError> {
327 let len = DefCfg::read_len(reader)?;
328 let mut reader = u32::read_len(reader)?.take(mt_ser::WrapRead(reader));
330 mt_ser::mt_deserialize_sized_seq::<DefCfg, _>(&len, &mut reader)?.try_collect()?;
336 /* TODO: Rustify this
338 func BuiltinNodeDefs(n int) map[Content]NodeDef {
339 defs := make(map[Content]NodeDef, 3+n)
340 defs[Unknown] = NodeDef{
345 DrawType: DrawNothing,
353 defs[Ignore] = NodeDef{
355 DrawType: DrawNothing,
363 #[mt_derive(to = "clt")]
364 pub struct ToolGroupCap {
365 pub uses: i16, // 32to16
368 pub times: HashMap<i16, f32>,
371 #[mt_derive(to = "clt")]
372 pub struct ToolCaps {
373 #[mt(const_before = "5u8")]
374 pub attack_cooldown: f32,
375 pub max_drop_level: i16,
377 pub group_caps: HashMap<String, ToolGroupCap>,
379 pub dmg_groups: HashMap<String, u16>,
380 pub punch_uses: u16, // 32tou16
383 #[mt_derive(to = "clt", repr = "u8")]
391 #[mt_derive(to = "clt", repr = "u8")]
392 pub enum SoundSource {
398 #[mt_derive(to = "clt")]
399 pub struct SoundDef {
406 #[mt_derive(to = "clt")]
409 #[mt(const_before = "6u8")]
410 #[serde(rename = "type")]
411 pub item_type: ItemType,
413 pub description: String,
414 pub inventory_image: String,
415 pub wield_image: String,
416 pub wield_scale: [f32; 3],
419 pub can_point_liquids: bool,
421 pub tool_caps: Option<ToolCaps>,
422 pub groups: HashMap<String, u16>,
423 pub place_predict: String,
424 pub place_sound: SoundDef,
425 pub place_fail_sound: SoundDef,
426 pub point_range: f32,
429 pub inventory_overlay: String,
430 pub wield_overlay: String,
431 pub short_description: String,
432 pub place_param2: u8,