Skip to main content

steel_registry/
dialog.rs

1use rustc_hash::FxHashMap;
2use simdnbt::ToNbtTag;
3use simdnbt::owned::NbtTag;
4use steel_utils::Identifier;
5use text_components::TextComponent;
6
7/// Represents a dialog defined in data packs.
8#[derive(Debug)]
9pub struct Dialog {
10    pub key: Identifier,
11    pub button_width: i32,
12    pub columns: i32,
13    pub exit_action: ExitAction,
14    pub external_title: TextComponent,
15    pub title: TextComponent,
16    pub variant: DialogVariant,
17}
18
19/// The variant-specific data for a dialog.
20#[derive(Debug)]
21pub enum DialogVariant {
22    /// A dialog that displays a list of other dialogs.
23    DialogList { dialogs: &'static str },
24    /// A dialog that displays server links.
25    ServerLinks,
26}
27
28/// Represents an exit action with a label and width.
29#[derive(Debug)]
30pub struct ExitAction {
31    pub label: TextComponent,
32    pub width: i32,
33}
34
35impl ToNbtTag for &Dialog {
36    fn to_nbt_tag(self) -> NbtTag {
37        use simdnbt::owned::NbtCompound;
38        let mut compound = NbtCompound::new();
39        compound.insert(
40            "type",
41            match &self.variant {
42                DialogVariant::DialogList { .. } => "minecraft:dialog_list",
43                DialogVariant::ServerLinks => "minecraft:server_links",
44            },
45        );
46        compound.insert("title", (&self.title).to_nbt_tag());
47        compound.insert("external_title", (&self.external_title).to_nbt_tag());
48        compound.insert("button_width", self.button_width);
49        compound.insert("columns", self.columns);
50        let mut exit_action = NbtCompound::new();
51        exit_action.insert("label", (&self.exit_action.label).to_nbt_tag());
52        exit_action.insert("width", self.exit_action.width);
53        compound.insert("exit_action", NbtTag::Compound(exit_action));
54        if let DialogVariant::DialogList { dialogs } = &self.variant {
55            compound.insert("dialogs", *dialogs);
56        }
57        NbtTag::Compound(compound)
58    }
59}
60
61pub type DialogRef = &'static Dialog;
62
63pub struct DialogRegistry {
64    dialogs_by_id: Vec<DialogRef>,
65    dialogs_by_key: FxHashMap<Identifier, usize>,
66    tags: FxHashMap<Identifier, Vec<Identifier>>,
67    allows_registering: bool,
68}
69
70impl DialogRegistry {
71    #[must_use]
72    pub fn new() -> Self {
73        Self {
74            dialogs_by_id: Vec::new(),
75            dialogs_by_key: FxHashMap::default(),
76            tags: FxHashMap::default(),
77            allows_registering: true,
78        }
79    }
80}
81
82crate::impl_standard_methods!(
83    DialogRegistry,
84    DialogRef,
85    dialogs_by_id,
86    dialogs_by_key,
87    allows_registering
88);
89
90crate::impl_registry!(
91    DialogRegistry,
92    Dialog,
93    dialogs_by_id,
94    dialogs_by_key,
95    dialogs
96);
97crate::impl_tagged_registry!(DialogRegistry, dialogs_by_key, "dialog");