steel_registry/
instrument.rs1use rustc_hash::FxHashMap;
2use simdnbt::ToNbtTag;
3use simdnbt::owned::NbtTag;
4use steel_utils::Identifier;
5use text_components::TextComponent;
6
7use crate::sound_event::SoundEventRef;
8
9#[derive(Debug)]
12pub struct Instrument {
13 pub key: Identifier,
14 pub sound_event: SoundEventRef,
15 pub use_duration: f32,
16 pub range: f32,
17 pub description: TextComponent,
18}
19
20impl ToNbtTag for &Instrument {
21 fn to_nbt_tag(self) -> NbtTag {
22 use simdnbt::owned::NbtCompound;
23 let mut compound = NbtCompound::new();
24 let sound_event = self.sound_event.key.to_string();
25 compound.insert("sound_event", sound_event.as_str());
26 compound.insert("use_duration", self.use_duration);
27 compound.insert("range", self.range);
28 compound.insert("description", (&self.description).to_nbt_tag());
29 NbtTag::Compound(compound)
30 }
31}
32
33pub type InstrumentRef = &'static Instrument;
34
35pub struct InstrumentRegistry {
36 instruments_by_id: Vec<InstrumentRef>,
37 instruments_by_key: FxHashMap<Identifier, usize>,
38 tags: FxHashMap<Identifier, Vec<Identifier>>,
39 allows_registering: bool,
40}
41
42impl InstrumentRegistry {
43 #[must_use]
44 pub fn new() -> Self {
45 Self {
46 instruments_by_id: Vec::new(),
47 instruments_by_key: FxHashMap::default(),
48 tags: FxHashMap::default(),
49 allows_registering: true,
50 }
51 }
52}
53
54crate::impl_standard_methods!(
55 InstrumentRegistry,
56 InstrumentRef,
57 instruments_by_id,
58 instruments_by_key,
59 allows_registering
60);
61
62crate::impl_registry!(
63 InstrumentRegistry,
64 Instrument,
65 instruments_by_id,
66 instruments_by_key,
67 instruments
68);
69
70crate::impl_tagged_registry!(InstrumentRegistry, instruments_by_key, "instrument");
71
72#[cfg(test)]
73mod tests {
74 use simdnbt::ToNbtTag;
75 use simdnbt::owned::NbtTag;
76
77 use crate::{test_support::init_test_registry, vanilla_instruments};
78
79 #[test]
80 fn nbt_uses_sound_event_registry_key() {
81 init_test_registry();
82
83 let NbtTag::Compound(compound) = (&vanilla_instruments::PONDER_GOAT_HORN).to_nbt_tag()
84 else {
85 panic!("instrument did not serialize to a compound tag");
86 };
87
88 let Some(sound_event) = compound.string("sound_event") else {
89 panic!("instrument NBT is missing sound_event string");
90 };
91
92 assert_eq!(
93 sound_event.to_str().as_ref(),
94 "minecraft:item.goat_horn.sound.0"
95 );
96 }
97}