Skip to main content

steel_registry/stat/
vanilla_stat_types.rs

1//! This module defines all the stat types from Vanilla.
2
3use crate::REGISTRY;
4use crate::blocks::BlockRegistry;
5use crate::entity_type::EntityTypeRegistry;
6use crate::items::ItemRegistry;
7use crate::stat::custom::CustomStatRegistry;
8use crate::stat::registry::{StatType, StatTypeRegistry};
9use steel_utils::Identifier;
10
11pub static BLOCK_MINED: StatType<BlockRegistry> =
12    StatType::new(Identifier::vanilla_static("mined"));
13
14pub static ITEM_CRAFTED: StatType<ItemRegistry> =
15    StatType::new(Identifier::vanilla_static("crafted"));
16pub static ITEM_USED: StatType<ItemRegistry> = StatType::new(Identifier::vanilla_static("used"));
17pub static ITEM_BROKEN: StatType<ItemRegistry> =
18    StatType::new(Identifier::vanilla_static("broken"));
19pub static ITEM_PICKED_UP: StatType<ItemRegistry> =
20    StatType::new(Identifier::vanilla_static("picked_up"));
21pub static ITEM_DROPPED: StatType<ItemRegistry> =
22    StatType::new(Identifier::vanilla_static("dropped"));
23
24pub static ENTITY_KILLED: StatType<EntityTypeRegistry> =
25    StatType::new(Identifier::vanilla_static("killed"));
26pub static ENTITY_KILLED_BY: StatType<EntityTypeRegistry> =
27    StatType::new(Identifier::vanilla_static("killed_by"));
28
29pub static CUSTOM: StatType<CustomStatRegistry> =
30    StatType::new(Identifier::vanilla_static("custom"));
31
32/// Registers all vanilla stat types.
33///
34/// IMPORTANT: The registration order MUST match vanilla's Stats.java exactly,
35/// as the component's network ID is determined by its registration order.
36pub fn register_vanilla_stat_types(registry: &mut StatTypeRegistry) {
37    // 0: mined
38    registry.register(&BLOCK_MINED, || &REGISTRY.blocks);
39    // 1: crafted
40    registry.register(&ITEM_CRAFTED, || &REGISTRY.items);
41    // 2: used
42    registry.register(&ITEM_USED, || &REGISTRY.items);
43    // 3: broken
44    registry.register(&ITEM_BROKEN, || &REGISTRY.items);
45    // 4: picked_up
46    registry.register(&ITEM_PICKED_UP, || &REGISTRY.items);
47    // 5: dropped
48    registry.register(&ITEM_DROPPED, || &REGISTRY.items);
49    // 6: killed
50    registry.register(&ENTITY_KILLED, || &REGISTRY.entity_types);
51    // 7: killed_by
52    registry.register(&ENTITY_KILLED_BY, || &REGISTRY.entity_types);
53    // 8: custom
54    registry.register(&CUSTOM, || &REGISTRY.custom_stats);
55}
56
57#[cfg(test)]
58mod tests {
59    use crate::RegistryExt;
60    use crate::stat::StatTypeRegistry;
61    use crate::stat::vanilla_stat_types::register_vanilla_stat_types;
62    use serde::Deserialize;
63
64    #[derive(Deserialize)]
65    struct ExtractedStatTypeEntry {
66        id: usize,
67        key: String,
68    }
69
70    #[test]
71    fn registry_matches_extracted_stat_types() {
72        let entries: Vec<ExtractedStatTypeEntry> =
73            serde_json::from_str(include_str!("../../build_assets/stat_types.json"))
74                .expect("extracted stat types should be valid");
75
76        let mut registry = StatTypeRegistry::new();
77        register_vanilla_stat_types(&mut registry);
78
79        assert_eq!(registry.len(), entries.len());
80
81        for (expected_id, entry) in entries.into_iter().enumerate() {
82            assert_eq!(
83                entry.id, expected_id,
84                "the IDs of stat type {} don't match",
85                entry.key
86            );
87
88            let stat_entry = registry
89                .by_id(entry.id)
90                .unwrap_or_else(|| panic!("missing stat type registry ID {}", entry.id));
91
92            assert_eq!(stat_entry.key.to_string(), entry.key);
93        }
94    }
95}