steel_registry/
pig_variant.rs1use steel_utils::random::Random;
2
3use crate::biome::BiomeRef;
4use crate::shared_structs::{
5 SpawnConditionEntry, insert_spawn_conditions, pick_spawn_conditioned_entry,
6};
7use rustc_hash::FxHashMap;
8use simdnbt::ToNbtTag;
9use simdnbt::owned::NbtTag;
10use steel_utils::Identifier;
11
12#[derive(Debug)]
14pub struct PigVariant {
15 pub key: Identifier,
16 pub asset_id: Identifier,
17 pub baby_asset_id: Identifier,
18 pub model: PigModelType,
19 pub spawn_conditions: &'static [SpawnConditionEntry],
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
24pub enum PigModelType {
25 #[default]
26 Normal,
27 Cold,
28}
29
30impl ToNbtTag for &PigVariant {
31 fn to_nbt_tag(self) -> NbtTag {
32 use simdnbt::owned::{NbtCompound, 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 compound.insert(
37 "model",
38 match self.model {
39 PigModelType::Normal => "normal",
40 PigModelType::Cold => "cold",
41 },
42 );
43 insert_spawn_conditions(&mut compound, self.spawn_conditions);
44 NbtTag::Compound(compound)
45 }
46}
47
48pub type PigVariantRef = &'static PigVariant;
49
50pub struct PigVariantRegistry {
51 pig_variants_by_id: Vec<PigVariantRef>,
52 pig_variants_by_key: FxHashMap<Identifier, usize>,
53 allows_registering: bool,
54}
55
56impl PigVariantRegistry {
57 #[must_use]
58 pub fn new() -> Self {
59 Self {
60 pig_variants_by_id: Vec::new(),
61 pig_variants_by_key: FxHashMap::default(),
62 allows_registering: true,
63 }
64 }
65
66 #[must_use]
67 pub fn select_spawn_variant(
68 &self,
69 biome: BiomeRef,
70 random: &mut impl Random,
71 ) -> Option<PigVariantRef> {
72 pick_spawn_conditioned_entry(
73 self.iter().map(|(_, variant)| variant),
74 |variant| variant.spawn_conditions,
75 biome,
76 random,
77 )
78 }
79}
80
81crate::impl_standard_methods!(
82 PigVariantRegistry,
83 PigVariantRef,
84 pig_variants_by_id,
85 pig_variants_by_key,
86 allows_registering
87);
88
89crate::impl_registry!(
90 PigVariantRegistry,
91 PigVariant,
92 pig_variants_by_id,
93 pig_variants_by_key,
94 pig_variants
95);
96
97#[cfg(test)]
98mod tests {
99 use steel_utils::random::legacy_random::LegacyRandom;
100
101 use crate::{REGISTRY, init_vanilla_registry, vanilla_biomes, vanilla_pig_variants};
102
103 #[test]
104 fn select_spawn_variant_uses_highest_matching_biome_priority() {
105 init_vanilla_registry();
106
107 let mut random = LegacyRandom::from_seed(0);
108 assert_eq!(
109 REGISTRY
110 .pig_variants
111 .select_spawn_variant(&vanilla_biomes::DESERT, &mut random)
112 .map(|variant| &variant.key),
113 Some(&vanilla_pig_variants::WARM.key)
114 );
115
116 let mut random = LegacyRandom::from_seed(0);
117 assert_eq!(
118 REGISTRY
119 .pig_variants
120 .select_spawn_variant(&vanilla_biomes::SNOWY_PLAINS, &mut random)
121 .map(|variant| &variant.key),
122 Some(&vanilla_pig_variants::COLD.key)
123 );
124
125 let mut random = LegacyRandom::from_seed(0);
126 assert_eq!(
127 REGISTRY
128 .pig_variants
129 .select_spawn_variant(&vanilla_biomes::PLAINS, &mut random)
130 .map(|variant| &variant.key),
131 Some(&vanilla_pig_variants::TEMPERATE.key)
132 );
133 }
134}