Skip to main content

steel_registry/
chicken_variant.rs

1use crate::biome::BiomeRef;
2use crate::shared_structs::pick_spawn_conditioned_entry;
3use crate::shared_structs::{SpawnConditionEntry, insert_spawn_conditions};
4use rustc_hash::FxHashMap;
5use simdnbt::ToNbtTag;
6use simdnbt::owned::NbtTag;
7use steel_utils::Identifier;
8use steel_utils::random::Random;
9
10/// Represents a full chicken variant definition from a data pack JSON file.
11#[derive(Debug)]
12pub struct ChickenVariant {
13    pub key: Identifier,
14    pub asset_id: Identifier,
15    pub baby_asset_id: Identifier,
16    pub model: ChickenModelType,
17    pub spawn_conditions: &'static [SpawnConditionEntry],
18}
19
20/// The model type for the chicken, which can affect its shape.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
22pub enum ChickenModelType {
23    #[default]
24    Normal,
25    Cold,
26}
27
28impl ToNbtTag for &ChickenVariant {
29    fn to_nbt_tag(self) -> NbtTag {
30        use simdnbt::owned::{NbtCompound, NbtTag};
31        let mut compound = NbtCompound::new();
32        compound.insert("asset_id", self.asset_id.clone());
33        compound.insert("baby_asset_id", self.baby_asset_id.clone());
34        compound.insert(
35            "model",
36            match self.model {
37                ChickenModelType::Normal => "normal",
38                ChickenModelType::Cold => "cold",
39            },
40        );
41        insert_spawn_conditions(&mut compound, self.spawn_conditions);
42        NbtTag::Compound(compound)
43    }
44}
45
46pub type ChickenVariantRef = &'static ChickenVariant;
47
48pub struct ChickenVariantRegistry {
49    chicken_variants_by_id: Vec<ChickenVariantRef>,
50    chicken_variants_by_key: FxHashMap<Identifier, usize>,
51    allows_registering: bool,
52}
53
54impl ChickenVariantRegistry {
55    #[must_use]
56    pub fn new() -> Self {
57        Self {
58            chicken_variants_by_id: Vec::new(),
59            chicken_variants_by_key: FxHashMap::default(),
60            allows_registering: true,
61        }
62    }
63
64    #[must_use]
65    pub fn select_spawn_variant(
66        &self,
67        biome: BiomeRef,
68        random: &mut impl Random,
69    ) -> Option<ChickenVariantRef> {
70        // Mirrors vanilla conditioned variant selection against the spawn biome.
71        pick_spawn_conditioned_entry(
72            self.iter().map(|(_, variant)| variant),
73            |variant| variant.spawn_conditions,
74            biome,
75            random,
76        )
77    }
78}
79
80crate::impl_standard_methods!(
81    ChickenVariantRegistry,
82    ChickenVariantRef,
83    chicken_variants_by_id,
84    chicken_variants_by_key,
85    allows_registering
86);
87
88crate::impl_registry!(
89    ChickenVariantRegistry,
90    ChickenVariant,
91    chicken_variants_by_id,
92    chicken_variants_by_key,
93    chicken_variants
94);