1use std::sync::LazyLock;
4
5use steel_registry::items::{Item, ItemRef};
6use steel_registry::vanilla_item_tags::ItemTag;
7use steel_registry::vanilla_items;
8use steel_registry::{REGISTRY, RegistryEntry as _, RegistryExt as _, TaggedRegistryExt as _};
9use steel_utils::Identifier;
10
11pub struct FuelValues {
13 burn_durations: Vec<i32>,
14}
15
16impl FuelValues {
17 #[must_use]
19 pub fn builder() -> FuelValuesBuilder {
20 FuelValuesBuilder {
21 burn_durations: vec![0; REGISTRY.items.len()],
22 }
23 }
24
25 #[must_use]
27 pub fn is_fuel(&self, item: ItemRef) -> bool {
28 self.burn_duration(item) > 0
29 }
30
31 #[must_use]
33 pub fn burn_duration(&self, item: ItemRef) -> i32 {
34 self.burn_durations.get(item.id()).copied().unwrap_or(0)
35 }
36}
37
38pub struct FuelValuesBuilder {
40 burn_durations: Vec<i32>,
41}
42
43impl FuelValuesBuilder {
44 #[must_use]
46 pub fn add(mut self, item: ItemRef, burn_duration: i32) -> Self {
47 self.put(item, burn_duration);
48 self
49 }
50
51 #[must_use]
53 pub fn add_tag(mut self, tag: &Identifier, burn_duration: i32) -> Self {
54 for item in REGISTRY.items.iter_tag(tag) {
55 self.put(item, burn_duration);
56 }
57 self
58 }
59
60 #[must_use]
62 pub fn remove_tag(mut self, tag: &Identifier) -> Self {
63 for item in REGISTRY.items.iter_tag(tag) {
64 self.put(item, 0);
65 }
66 self
67 }
68
69 #[must_use]
71 pub fn build(self) -> FuelValues {
72 FuelValues {
73 burn_durations: self.burn_durations,
74 }
75 }
76
77 fn put(&mut self, item: &'static Item, burn_duration: i32) {
78 assert!(burn_duration >= 0, "fuel duration cannot be negative");
79 self.burn_durations[item.id()] = burn_duration;
80 }
81}
82
83pub static VANILLA_FUEL_VALUES: LazyLock<FuelValues> = LazyLock::new(|| {
85 const BASE: i32 = 200;
86
87 FuelValues::builder()
88 .add(&vanilla_items::LAVA_BUCKET, BASE * 100)
89 .add(&vanilla_items::COAL_BLOCK, BASE * 8 * 10)
90 .add(&vanilla_items::BLAZE_ROD, BASE * 12)
91 .add(&vanilla_items::COAL, BASE * 8)
92 .add(&vanilla_items::CHARCOAL, BASE * 8)
93 .add_tag(&ItemTag::LOGS, BASE * 3 / 2)
94 .add_tag(&ItemTag::BAMBOO_BLOCKS, BASE * 3 / 2)
95 .add_tag(&ItemTag::PLANKS, BASE * 3 / 2)
96 .add(&vanilla_items::BAMBOO_MOSAIC, BASE * 3 / 2)
97 .add_tag(&ItemTag::WOODEN_STAIRS, BASE * 3 / 2)
98 .add(&vanilla_items::BAMBOO_MOSAIC_STAIRS, BASE * 3 / 2)
99 .add_tag(&ItemTag::WOODEN_SLABS, BASE * 3 / 4)
100 .add(&vanilla_items::BAMBOO_MOSAIC_SLAB, BASE * 3 / 4)
101 .add_tag(&ItemTag::WOODEN_TRAPDOORS, BASE * 3 / 2)
102 .add_tag(&ItemTag::WOODEN_PRESSURE_PLATES, BASE * 3 / 2)
103 .add_tag(&ItemTag::WOODEN_SHELVES, BASE * 3 / 2)
104 .add_tag(&ItemTag::WOODEN_FENCES, BASE * 3 / 2)
105 .add_tag(&ItemTag::FENCE_GATES, BASE * 3 / 2)
106 .add(&vanilla_items::NOTE_BLOCK, BASE * 3 / 2)
107 .add(&vanilla_items::BOOKSHELF, BASE * 3 / 2)
108 .add(&vanilla_items::CHISELED_BOOKSHELF, BASE * 3 / 2)
109 .add(&vanilla_items::LECTERN, BASE * 3 / 2)
110 .add(&vanilla_items::JUKEBOX, BASE * 3 / 2)
111 .add(&vanilla_items::CHEST, BASE * 3 / 2)
112 .add(&vanilla_items::TRAPPED_CHEST, BASE * 3 / 2)
113 .add(&vanilla_items::CRAFTING_TABLE, BASE * 3 / 2)
114 .add(&vanilla_items::DAYLIGHT_DETECTOR, BASE * 3 / 2)
115 .add_tag(&ItemTag::BANNERS, BASE * 3 / 2)
116 .add(&vanilla_items::BOW, BASE * 3 / 2)
117 .add(&vanilla_items::FISHING_ROD, BASE * 3 / 2)
118 .add(&vanilla_items::LADDER, BASE * 3 / 2)
119 .add_tag(&ItemTag::SIGNS, BASE)
120 .add_tag(&ItemTag::HANGING_SIGNS, BASE * 4)
121 .add(&vanilla_items::WOODEN_SHOVEL, BASE)
122 .add(&vanilla_items::WOODEN_SWORD, BASE)
123 .add(&vanilla_items::WOODEN_SPEAR, BASE)
124 .add(&vanilla_items::WOODEN_HOE, BASE)
125 .add(&vanilla_items::WOODEN_AXE, BASE)
126 .add(&vanilla_items::WOODEN_PICKAXE, BASE)
127 .add_tag(&ItemTag::WOODEN_DOORS, BASE)
128 .add_tag(&ItemTag::BOATS, BASE * 6)
129 .add_tag(&ItemTag::WOOL, BASE / 2)
130 .add_tag(&ItemTag::WOODEN_BUTTONS, BASE / 2)
131 .add(&vanilla_items::STICK, BASE / 2)
132 .add_tag(&ItemTag::SAPLINGS, BASE / 2)
133 .add(&vanilla_items::BOWL, BASE / 2)
134 .add_tag(&ItemTag::WOOL_CARPETS, 1 + BASE / 3)
135 .add(&vanilla_items::DRIED_KELP_BLOCK, 1 + BASE * 20)
136 .add(&vanilla_items::CROSSBOW, BASE * 3 / 2)
137 .add(&vanilla_items::BAMBOO, BASE / 4)
138 .add(&vanilla_items::DEAD_BUSH, BASE / 2)
139 .add(&vanilla_items::SHORT_DRY_GRASS, BASE / 2)
140 .add(&vanilla_items::TALL_DRY_GRASS, BASE / 2)
141 .add(&vanilla_items::SCAFFOLDING, BASE / 4)
142 .add(&vanilla_items::LOOM, BASE * 3 / 2)
143 .add(&vanilla_items::BARREL, BASE * 3 / 2)
144 .add(&vanilla_items::CARTOGRAPHY_TABLE, BASE * 3 / 2)
145 .add(&vanilla_items::FLETCHING_TABLE, BASE * 3 / 2)
146 .add(&vanilla_items::SMITHING_TABLE, BASE * 3 / 2)
147 .add(&vanilla_items::COMPOSTER, BASE * 3 / 2)
148 .add(&vanilla_items::AZALEA, BASE / 2)
149 .add(&vanilla_items::FLOWERING_AZALEA, BASE / 2)
150 .add(&vanilla_items::MANGROVE_ROOTS, BASE * 3 / 2)
151 .add(&vanilla_items::LEAF_LITTER, BASE / 2)
152 .remove_tag(&ItemTag::NON_FLAMMABLE_WOOD)
153 .build()
154});
155
156#[cfg(test)]
157mod tests {
158 use steel_registry::{init_vanilla_registry, vanilla_items};
159
160 use super::VANILLA_FUEL_VALUES;
161
162 #[test]
163 fn vanilla_fuels_respect_specific_values_and_non_flammable_wood_removal() {
164 init_vanilla_registry();
165
166 assert_eq!(
167 VANILLA_FUEL_VALUES.burn_duration(&vanilla_items::COAL),
168 1600
169 );
170 assert_eq!(
171 VANILLA_FUEL_VALUES.burn_duration(&vanilla_items::STICK),
172 100
173 );
174 assert_eq!(
175 VANILLA_FUEL_VALUES.burn_duration(&vanilla_items::CRIMSON_PLANKS),
176 0
177 );
178 }
179}