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")]
75 n_frames: Vector2<u16>,
79 aspect_ratio: Vector2<u8>,
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 trait BsAabb: Sized {
218 fn ser(&self) -> Self;
219 fn des(&self) -> Self;
222 impl BsAabb for Aabb3<f32> {
223 fn ser(&self) -> Self {
224 collision::Aabb::mul_s(self, BS)
227 fn des(&self) -> Self {
228 collision::Aabb::mul_s(self, BS)
232 impl<T: BsAabb> BsAabb for Vec<T> {
233 fn ser(&self) -> Self {
234 self.iter().map(BsAabb::ser).collect()
237 fn des(&self) -> Self {
238 self.iter().map(BsAabb::des).collect()
242 impl<T: BsAabb, const N: usize> BsAabb for [T; N] {
243 fn ser(&self) -> Self {
244 std::array::from_fn(|i| self[i].ser())
247 fn des(&self) -> Self {
248 std::array::from_fn(|i| self[i].des())
252 #[cfg(feature = "server")]
253 fn ser_bs_aabb<T: BsAabb>(aabb: &T) -> Result<T, mt_ser::SerializeError> {
257 #[cfg(feature = "client")]
258 fn des_bs_aabb<T: BsAabb>(aabb: T) -> Result<T, mt_ser::DeserializeError> {
262 #[mt_derive(to = "clt")]
263 pub struct MountedNodeBox {
264 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
265 wall_top: Aabb3<f32>,
266 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
267 wall_bottom: Aabb3<f32>,
268 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
269 wall_sides: Aabb3<f32>,
272 #[mt_derive(to = "clt")]
273 pub struct ConnectedNodeBox {
274 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
275 fixed: Vec<Aabb3<f32>>,
276 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
277 connect_dirs: [Vec<Aabb3<f32>>; 6],
278 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
279 disconnect_dirs: [Vec<Aabb3<f32>>; 6],
280 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
281 disconnect_all: Vec<Aabb3<f32>>,
282 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
283 disconnect_sides: Vec<Aabb3<f32>>,
286 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
287 #[mt(const_before = "6u8")]
291 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
292 fixed: Vec<Aabb3<f32>>,
294 Mounted(Box<MountedNodeBox>),
296 #[mt(map_ser = "ser_bs_aabb", map_des = "des_bs_aabb")]
297 fixed: Vec<Aabb3<f32>>,
299 Connected(Box<ConnectedNodeBox>),
302 #[mt_derive(to = "clt")]
305 // TODO: impl Default
306 #[mt(const_before = "13u8")]
308 pub groups: HashMap<String, u16>,
309 pub param1_type: Param1Type,
310 pub param2_type: Param2Type,
311 pub draw_type: DrawType,
314 #[mt(const_before = "6u8")]
315 pub tiles: [TileDef; 6],
316 pub overlay_tiles: [TileDef; 6],
317 #[mt(const_before = "6u8")]
318 pub special_tiles: [TileDef; 6],
322 pub connect_sides: u8,
323 pub connect_to: Vec<u16>,
324 pub inside_tint: Color,
325 pub level: u8, // FIXME: must be below 128
326 pub translucent: bool, // sunlight scattering
327 pub transparent: bool,
328 pub light_source: u8, // FIXME: max: 14 (?)
329 pub ground_content: bool,
334 pub replaceable: bool,
335 pub has_on_right_click: bool,
336 pub damage_per_second: i32,
338 pub flowing_alt: String,
339 pub source_alt: String,
340 pub viscosity: u8, // FIXME: 0-7
341 pub liquid_renewable: bool,
343 pub drown_damage: u8,
345 pub draw_box: NodeBox,
346 pub collision_box: NodeBox,
347 pub selection_box: NodeBox,
348 pub footstep_sound: SoundDef,
349 pub digging_sound: SoundDef,
350 pub dug_sound: SoundDef,
351 pub legacy_face_dir: bool,
352 pub legacy_mounted: bool,
353 pub dig_predict: String,
356 pub move_resistance: u8,
357 pub liquid_move_physics: bool,
360 #[mt_derive(to = "clt", custom)]
361 pub struct NodeDefs(pub HashMap<u16, NodeDef>);
363 // stupid bullshit ahead
365 #[cfg(feature = "server")]
366 impl MtSerialize for NodeDefs {
367 fn mt_serialize<C: MtCfg>(
369 writer: &mut impl std::io::Write,
370 ) -> Result<(), mt_ser::SerializeError> {
371 DefCfg::write_len(self.0.len(), writer)?;
373 let mut buf = Vec::new();
374 self.0.mt_serialize::<()>(&mut buf)?;
375 buf.mt_serialize::<u32>(writer)?;
381 #[cfg(feature = "client")]
382 impl MtDeserialize for NodeDefs {
383 fn mt_deserialize<C: MtCfg>(
384 reader: &mut impl std::io::Read,
385 ) -> Result<Self, mt_ser::DeserializeError> {
388 let len = DefCfg::read_len(reader)?;
389 let mut reader = u32::read_len(reader)?.take(mt_ser::WrapRead(reader));
391 mt_ser::mt_deserialize_sized_seq::<DefCfg, _>(&len, &mut reader)?.try_collect()?;
397 /* TODO: Rustify this
399 func BuiltinNodeDefs(n int) map[Content]NodeDef {
400 defs := make(map[Content]NodeDef, 3+n)
401 defs[Unknown] = NodeDef{
406 DrawType: DrawNothing,
414 defs[Ignore] = NodeDef{
416 DrawType: DrawNothing,
424 #[mt_derive(to = "clt")]
425 pub struct ToolGroupCap {
426 pub uses: i16, // 32to16
429 pub times: HashMap<i16, f32>,
432 #[mt_derive(to = "clt")]
433 pub struct ToolCaps {
434 #[mt(const_before = "5u8")]
435 pub attack_cooldown: f32,
436 pub max_drop_level: i16,
438 pub group_caps: HashMap<String, ToolGroupCap>,
440 pub dmg_groups: HashMap<String, u16>,
441 pub punch_uses: u16, // 32tou16
444 #[mt_derive(to = "clt", repr = "u8")]
452 #[mt_derive(to = "clt", repr = "u8")]
453 pub enum SoundSource {
459 #[mt_derive(to = "clt")]
460 pub struct SoundDef {
467 #[mt_derive(to = "clt")]
470 #[mt(const_before = "6u8")]
471 #[serde(rename = "type")]
472 pub item_type: ItemType,
474 pub description: String,
475 pub inventory_image: String,
476 pub wield_image: String,
477 pub wield_scale: Vector3<f32>,
480 pub can_point_liquids: bool,
482 pub tool_caps: Option<ToolCaps>,
483 pub groups: HashMap<String, u16>,
484 pub place_predict: String,
485 pub place_sound: SoundDef,
486 pub place_fail_sound: SoundDef,
487 pub point_range: f32,
490 pub inventory_overlay: String,
491 pub wield_overlay: String,
492 pub short_description: String,
493 pub place_param2: u8,