]> git.lizzy.rs Git - mt_net.git/blob - src/to_clt/media.rs
c05492d55f35b438ac13769e9b4c73c119a66c40
[mt_net.git] / src / to_clt / media.rs
1 use super::*;
2
3 #[mt_derive(to = "clt", repr = "u8")]
4 pub enum Param1Type {
5     None = 0,
6     Light,
7 }
8
9 #[mt_derive(to = "clt", repr = "u8")]
10 pub enum Param2Type {
11     Nibble = 0,
12     Byte,
13     Flowing,
14     FaceDir,
15     Mounted,
16     Leveled,
17     Rotation,
18     Mesh,
19     Color,
20     ColorFaceDir,
21     ColorMounted,
22     GrassLikeLevel,
23     ColorRotation,
24 }
25
26 #[mt_derive(to = "clt", repr = "u8")]
27 pub enum DrawType {
28     Cube = 0,
29     None,
30     Liquid,
31     Flowing,
32     GlassLike,
33     AllFaces,
34     AllFacesOpt,
35     Torch,
36     Sign,
37     Plant,
38     Fence,
39     Rail,
40     NodeBox,
41     GlassFrame,
42     Fire,
43     GlassFrameOpt,
44     Mesh,
45     RootedPlant,
46 }
47
48 #[mt_derive(to = "clt", repr = "u8")]
49 pub enum Waving {
50     None = 0,
51     Plant,
52     Leaf,
53     Liquid,
54 }
55
56 #[mt_derive(to = "clt", repr = "u8")]
57 pub enum Liquid {
58     None = 0,
59     Flowing,
60     Source,
61 }
62
63 #[mt_derive(to = "clt", repr = "u8")]
64 pub enum Alpha {
65     Blend = 0,
66     Mask, // either fully opaque or transparent
67     Opaque,
68     Legacy,
69 }
70
71 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
72 pub enum TileAnim {
73     None = 0,
74     VerticalFrame {
75         n_frames: [u16; 2],
76         duration: f32,
77     },
78     SpriteSheet {
79         aspect_ratio: [u8; 2],
80         duration: f32,
81     },
82 }
83
84 #[mt_derive(to = "clt", repr = "u8")]
85 pub enum TileAlign {
86     None = 0,
87     World,
88     User,
89 }
90
91 #[mt_derive(to = "clt", enumset, custom)]
92 pub enum TileFlag {
93     BackfaceCull,
94     TileHorizontal,
95     TileVertical,
96 }
97
98 #[mt_derive(to = "clt", repr = "u16", enumset)]
99 enum TileFlagInternal {
100     BackfaceCull,
101     TileHorizontal,
102     TileVertical,
103     Color,
104     Scale,
105     Align,
106 }
107
108 #[mt_derive(to = "clt", custom)]
109 pub struct TileDef {
110     // #[mt(const_before = "6u8")]
111     pub texture: String,
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>,
117 }
118
119 #[cfg(feature = "server")]
120 impl MtSerialize for TileDef {
121     fn mt_serialize<C: MtCfg>(
122         &self,
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)?;
128
129         let mut flags: EnumSet<TileFlagInternal> = self
130             .flags
131             .iter()
132             .map(|f| match f {
133                 TileFlag::BackfaceCull => TileFlagInternal::BackfaceCull,
134                 TileFlag::TileHorizontal => TileFlagInternal::TileHorizontal,
135                 TileFlag::TileVertical => TileFlagInternal::TileVertical,
136             })
137             .collect();
138
139         if self.color.is_some() {
140             flags.insert(TileFlagInternal::Color);
141         }
142
143         if self.scale.is_some() {
144             flags.insert(TileFlagInternal::Scale);
145         }
146
147         if self.align.is_some() {
148             flags.insert(TileFlagInternal::Align);
149         }
150
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)?;
155
156         Ok(())
157     }
158 }
159
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)?;
166         if 6u8 != const6u8 {
167             return Err(mt_ser::DeserializeError::InvalidConst(
168                 Box::new(const6u8),
169                 Box::new(6u8),
170             ));
171         }
172
173         let texture = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
174         let animation = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
175
176         let flags_internal = EnumSet::<TileFlagInternal>::mt_deserialize::<DefCfg>(reader)?;
177
178         let color = if flags_internal.contains(TileFlagInternal::Color) {
179             Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
180         } else {
181             None
182         };
183
184         let scale = if flags_internal.contains(TileFlagInternal::Scale) {
185             Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
186         } else {
187             None
188         };
189
190         let align = if flags_internal.contains(TileFlagInternal::Align) {
191             Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
192         } else {
193             None
194         };
195
196         let flags = flags_internal
197             .iter()
198             .flat_map(|f| match f {
199                 TileFlagInternal::BackfaceCull => Some(TileFlag::BackfaceCull),
200                 TileFlagInternal::TileHorizontal => Some(TileFlag::TileHorizontal),
201                 TileFlagInternal::TileVertical => Some(TileFlag::TileVertical),
202                 _ => None,
203             })
204             .collect();
205
206         Ok(Self {
207             texture,
208             animation,
209             flags,
210             color,
211             scale,
212             align,
213         })
214     }
215 }
216
217 #[mt_derive(to = "clt", repr = "u8", tag = "type")]
218 #[mt(const_before = "6u8")]
219 pub enum NodeBox {
220     Cube = 0,
221     Fixed {
222         fixed: Vec<RangeInclusive<[f32; 3]>>,
223     },
224     Mounted {
225         wall_top: RangeInclusive<[f32; 3]>,
226         wall_bottom: RangeInclusive<[f32; 3]>,
227         wall_sides: RangeInclusive<[f32; 3]>,
228     },
229     Leveled {
230         fixed: Vec<RangeInclusive<[f32; 3]>>,
231     },
232     Connected {
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]>>,
238     },
239 }
240
241 #[mt_derive(to = "clt")]
242 #[mt(size = "u16")]
243 pub struct NodeDef {
244     // TODO: impl Default
245     #[mt(const_before = "13u8")]
246     pub name: String,
247     pub groups: HashMap<String, u16>,
248     pub param1_type: Param1Type,
249     pub param2_type: Param2Type,
250     pub draw_type: DrawType,
251     pub mesh: String,
252     pub scale: f32,
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],
258     pub color: Color,
259     pub palette: String,
260     pub waving: Waving,
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,
269     pub collision: bool,
270     pub pointable: bool,
271     pub diggable: bool,
272     pub climbable: bool,
273     pub replaceable: bool,
274     pub has_on_right_click: bool,
275     pub damage_per_second: i32,
276     pub liquid: Liquid,
277     pub flowing_alt: String,
278     pub source_alt: String,
279     pub viscosity: u8, // FIXME: 0-7
280     pub liquid_renewable: bool,
281     pub flow_range: u8,
282     pub drown_damage: u8,
283     pub floodable: bool,
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,
293     pub max_level: u8,
294     pub alpha: Alpha,
295     pub move_resistance: u8,
296     pub liquid_move_physics: bool,
297 }
298
299 #[mt_derive(to = "clt", custom)]
300 pub struct NodeDefs(pub HashMap<u16, NodeDef>);
301
302 // stupid bullshit ahead
303
304 #[cfg(feature = "server")]
305 impl MtSerialize for NodeDefs {
306     fn mt_serialize<C: MtCfg>(
307         &self,
308         writer: &mut impl std::io::Write,
309     ) -> Result<(), mt_ser::SerializeError> {
310         DefCfg::write_len(self.0.len(), writer)?;
311
312         let mut buf = Vec::new();
313         self.0.mt_serialize::<()>(&mut buf)?;
314         buf.mt_serialize::<u32>(writer)?;
315
316         Ok(())
317     }
318 }
319
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> {
325         use mt_ser::MtLen;
326
327         let len = DefCfg::read_len(reader)?;
328         let mut reader = u32::read_len(reader)?.take(mt_ser::WrapRead(reader));
329         let inner =
330             mt_ser::mt_deserialize_sized_seq::<DefCfg, _>(&len, &mut reader)?.try_collect()?;
331
332         Ok(Self(inner))
333     }
334 }
335
336 /* TODO: Rustify this
337
338 func BuiltinNodeDefs(n int) map[Content]NodeDef {
339     defs := make(map[Content]NodeDef, 3+n)
340     defs[Unknown] = NodeDef{
341         Name: "unknown",
342     }
343     defs[Air] = NodeDef{
344         Name:        "air",
345         DrawType:    DrawNothing,
346         P1Type:      P1Light,
347         Translucent: true,
348         Transparent: true,
349         Replaceable: true,
350         Floodable:   true,
351         GndContent:  true,
352     }
353     defs[Ignore] = NodeDef{
354         Name:        "ignore",
355         DrawType:    DrawNothing,
356         Replaceable: true,
357         GndContent:  true,
358     }
359     return defs
360 }
361 */
362
363 #[mt_derive(to = "clt")]
364 pub struct ToolGroupCap {
365     pub uses: i16, // 32to16
366     pub max_level: i16,
367     #[mt(len = "u32")]
368     pub times: HashMap<i16, f32>,
369 }
370
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,
376     #[mt(len = "u32")]
377     pub group_caps: HashMap<String, ToolGroupCap>,
378     #[mt(len = "u32")]
379     pub dmg_groups: HashMap<String, u16>,
380     pub punch_uses: u16, // 32tou16
381 }
382
383 #[mt_derive(to = "clt", repr = "u8")]
384 pub enum ItemType {
385     None = 0,
386     Node,
387     Craft,
388     Tool,
389 }
390
391 #[mt_derive(to = "clt", repr = "u8")]
392 pub enum SoundSource {
393     Nowhere = 0,
394     Pos,
395     Obj,
396 }
397
398 #[mt_derive(to = "clt")]
399 pub struct SoundDef {
400     pub name: String,
401     pub gain: f32,
402     pub pitch: f32,
403     pub fade: f32,
404 }
405
406 #[mt_derive(to = "clt")]
407 #[mt(size = "u16")]
408 pub struct ItemDef {
409     #[mt(const_before = "6u8")]
410     #[serde(rename = "type")]
411     pub item_type: ItemType,
412     pub name: String,
413     pub description: String,
414     pub inventory_image: String,
415     pub wield_image: String,
416     pub wield_scale: [f32; 3],
417     pub stack_max: u16,
418     pub usable: bool,
419     pub can_point_liquids: bool,
420     #[mt(size = "u16")]
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,
427     pub palette: String,
428     pub color: Color,
429     pub inventory_overlay: String,
430     pub wield_overlay: String,
431     pub short_description: String,
432     pub place_param2: u8,
433 }