Skip to main content

steel_registry/
cat_variant.rs

1use rustc_hash::FxHashMap;
2use simdnbt::ToNbtTag;
3use simdnbt::owned::NbtTag;
4use steel_utils::Identifier;
5
6/// Represents a full cat variant definition from a data pack JSON file.
7#[derive(Debug)]
8pub struct CatVariant {
9    pub key: Identifier,
10    pub asset_id: Identifier,
11    pub baby_asset_id: Identifier,
12    pub spawn_conditions: &'static [SpawnConditionEntry],
13}
14
15/// A single entry in the list of spawn conditions.
16#[derive(Debug)]
17pub struct SpawnConditionEntry {
18    pub priority: i32,
19    pub condition: Option<SpawnCondition>,
20}
21
22/// Defines various spawn conditions for cat variants.
23#[derive(Debug)]
24pub enum SpawnCondition {
25    Structure { structures: &'static str },
26    MoonBrightness { min: Option<f32>, max: Option<f32> },
27    Biome { biomes: &'static str },
28}
29
30impl ToNbtTag for &CatVariant {
31    fn to_nbt_tag(self) -> NbtTag {
32        use simdnbt::owned::{NbtCompound, NbtList, NbtTag};
33        let mut compound = NbtCompound::new();
34        compound.insert("asset_id", self.asset_id.clone());
35        compound.insert("baby_asset_id", self.baby_asset_id.clone());
36        let conditions: Vec<NbtCompound> = self
37            .spawn_conditions
38            .iter()
39            .map(|entry| {
40                let mut e = NbtCompound::new();
41                e.insert("priority", entry.priority);
42                if let Some(cond) = &entry.condition {
43                    let mut c = NbtCompound::new();
44                    match cond {
45                        SpawnCondition::Structure { structures } => {
46                            c.insert("type", "minecraft:in_structure");
47                            c.insert("structures", *structures);
48                        }
49                        SpawnCondition::MoonBrightness { min, max } => {
50                            c.insert("type", "minecraft:moon_brightness");
51                            if let Some(min) = min {
52                                c.insert("min", *min);
53                            }
54                            if let Some(max) = max {
55                                c.insert("max", *max);
56                            }
57                        }
58                        SpawnCondition::Biome { biomes } => {
59                            c.insert("type", "minecraft:biome");
60                            c.insert("biomes", *biomes);
61                        }
62                    }
63                    e.insert("condition", NbtTag::Compound(c));
64                }
65                e
66            })
67            .collect();
68        compound.insert(
69            "spawn_conditions",
70            NbtTag::List(NbtList::Compound(conditions)),
71        );
72        NbtTag::Compound(compound)
73    }
74}
75
76pub type CatVariantRef = &'static CatVariant;
77
78pub struct CatVariantRegistry {
79    cat_variants_by_id: Vec<CatVariantRef>,
80    cat_variants_by_key: FxHashMap<Identifier, usize>,
81    allows_registering: bool,
82}
83
84impl CatVariantRegistry {
85    #[must_use]
86    pub fn new() -> Self {
87        Self {
88            cat_variants_by_id: Vec::new(),
89            cat_variants_by_key: FxHashMap::default(),
90            allows_registering: true,
91        }
92    }
93}
94
95crate::impl_registry!(
96    CatVariantRegistry,
97    CatVariant,
98    cat_variants_by_id,
99    cat_variants_by_key,
100    cat_variants
101);
102
103crate::impl_standard_methods!(
104    CatVariantRegistry,
105    CatVariantRef,
106    cat_variants_by_id,
107    cat_variants_by_key,
108    allows_registering
109);