summaryrefslogtreecommitdiff
path: root/src/main/java/lv/enes/mc/eris_alchemy/EMC.java
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-01-11 23:11:27 +0100
committerGravatar Uko Kokņevičs2024-01-11 23:11:27 +0100
commitbca6a74e9a17e04de419743850f66af96a6473cc (patch)
tree6f81c0ceb615b0a85810df89ea9acafe6112eba9 /src/main/java/lv/enes/mc/eris_alchemy/EMC.java
parentMaking SheetsMixin more extensible (diff)
downloadmc-eris-alchemy-bca6a74e9a17e04de419743850f66af96a6473cc.tar.gz
mc-eris-alchemy-bca6a74e9a17e04de419743850f66af96a6473cc.tar.xz
mc-eris-alchemy-bca6a74e9a17e04de419743850f66af96a6473cc.zip
Move default emc values to JSON files in datapack
Diffstat (limited to 'src/main/java/lv/enes/mc/eris_alchemy/EMC.java')
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/EMC.java600
1 files changed, 0 insertions, 600 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/EMC.java b/src/main/java/lv/enes/mc/eris_alchemy/EMC.java
deleted file mode 100644
index 92c0624..0000000
--- a/src/main/java/lv/enes/mc/eris_alchemy/EMC.java
+++ /dev/null
@@ -1,600 +0,0 @@
1package lv.enes.mc.eris_alchemy;
2
3import jakarta.annotation.Nullable;
4import lv.enes.mc.eris_alchemy.utils.*;
5import lv.enes.mc.eris_alchemy.utils.ItemUtils;
6import net.minecraft.core.RegistryAccess;
7import net.minecraft.core.registries.BuiltInRegistries;
8import net.minecraft.tags.BlockTags;
9import net.minecraft.tags.ItemTags;
10import net.minecraft.tags.TagKey;
11import net.minecraft.world.item.*;
12import net.minecraft.world.item.crafting.Ingredient;
13import net.minecraft.world.item.crafting.Recipe;
14import net.minecraft.world.level.ItemLike;
15import net.minecraft.world.level.Level;
16import net.minecraft.world.level.block.Block;
17import vazkii.patchouli.common.item.PatchouliItems;
18
19import java.text.DecimalFormat;
20import java.util.*;
21import java.util.stream.Stream;
22
23public class EMC {
24 private record SimplifiedRecipe(ItemStack output, List<ItemStack> remainder, List<Ingredient> inputs) {
25 public SimplifiedRecipe(ItemLike output, Ingredient... inputs) {
26 this(new ItemStack(output), List.of(), List.of(inputs));
27 }
28
29 public SimplifiedRecipe(ItemLike output, ItemLike... inputs) {
30 this(new ItemStack(output), List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
31 }
32
33 public SimplifiedRecipe(ItemLike output, ItemStack... inputs) {
34 this(new ItemStack(output), List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
35 }
36
37 public SimplifiedRecipe(ItemLike output, List<ItemStack> remainder, ItemLike... inputs) {
38 this(new ItemStack(output), remainder, Arrays.stream(inputs).map(Ingredient::of).toList());
39 }
40
41 public SimplifiedRecipe(ItemStack output, ItemLike... inputs) {
42 this(output, List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
43 }
44
45 public SimplifiedRecipe(ItemStack output, ItemStack... inputs) {
46 this(output, List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
47 }
48
49 public SimplifiedRecipe(Recipe<?> recipe, RegistryAccess registryAccess) {
50 this(
51 RecipeUtils.getOutput(recipe, registryAccess),
52 List.of(), // TODO:
53 RecipeUtils.getIngredients(recipe).stream().filter(ingredient -> !ingredient.isEmpty()).toList()
54 );
55 }
56 }
57
58 private static final Map<Item, Double> ITEM_COMMON_MAP = new HashMap<>();
59 private static final Map<TagKey<Item>, Double> ITEM_TAG_COMMON_MAP = new HashMap<>();
60 private static final Map<TagKey<Block>, Double> BLOCK_TAG_COMMON_MAP = new HashMap<>();
61 private static final List<SimplifiedRecipe> FAKE_RECIPES = new ArrayList<>();
62
63 private static final EMC defaultInstance = new EMC(null);
64 private static final Map<Level, EMC> instances = Collections.synchronizedMap(new WeakHashMap<>());
65
66 private static final DecimalFormat formatter = new DecimalFormat("0");
67 static {
68 formatter.setMaximumFractionDigits(1);
69 }
70
71 public static EMC getInstance(Level world) {
72 if (world == null) {
73 return defaultInstance;
74 }
75
76 if (instances.containsKey(world)) {
77 return instances.get(world);
78 }
79
80 var instance = new EMC(world);
81 instances.put(world, instance);
82 return instance;
83 }
84
85 public static String formatEmc(double value) {
86 return formatter.format(value);
87 }
88
89 private final Map<Item, Double> data;
90
91 private EMC(@Nullable Level world) {
92 data = Collections.synchronizedMap(new HashMap<>(ITEM_COMMON_MAP));
93 ITEM_TAG_COMMON_MAP.forEach(
94 (tag, emcValue) -> BuiltInRegistries.ITEM
95 .getTagOrEmpty(tag)
96 .forEach(holder -> data.putIfAbsent(holder.value(), emcValue))
97 );
98 BLOCK_TAG_COMMON_MAP.forEach(
99 (tag, emcValue) -> BuiltInRegistries.BLOCK
100 .getTagOrEmpty(tag)
101 .forEach(holder -> data.putIfAbsent(holder.value().asItem(), emcValue))
102 );
103
104 ErisAlchemy.LOGGER.info("Calculating EMC values...");
105 var recipes = getRecipes(world);
106 var configured = new HashSet<>(data.keySet());
107 BuiltInRegistries.ITEM.forEach(item -> {
108 configEmc(recipes, configured, item);
109 if (world != null && !data.containsKey(item)) {
110 ErisAlchemy.LOGGER.warn("No EMC value for '{}' known", item);
111 }
112 });
113 }
114
115 public OptionalDouble get(ItemStack stack) {
116 if (stack.isEmpty()) {
117 return OptionalDouble.empty();
118 }
119
120 var item = stack.getItem();
121 var value = data.get(item);
122 if (value == null || value <= 0) {
123 return OptionalDouble.empty();
124 }
125
126 EmcStorage storage = null;
127 if (item instanceof EmcStorage emcStorage) {
128 storage = emcStorage;
129 } else if (item instanceof BlockItem blockItem) {
130 if (blockItem.getBlock() instanceof EmcStorage emcStorage) {
131 storage = emcStorage;
132 }
133 }
134
135 if (storage != null) {
136 value += storage.getStoredEmc(stack);
137 }
138
139 return OptionalDouble.of(value);
140 }
141
142 private List<SimplifiedRecipe> getRecipes(@Nullable Level world) {
143 Stream<SimplifiedRecipe> recipes = Stream.concat(
144 FAKE_RECIPES.stream(),
145 AxeUtils.getStrippables()
146 .entrySet()
147 .stream()
148 .map(entry -> new SimplifiedRecipe(entry.getValue(), Ingredient.of(entry.getKey())))
149 );
150
151 if (world != null) {
152 recipes = Stream.concat(
153 recipes,
154 world.getRecipeManager()
155 .getRecipes()
156 .stream()
157 .map(recipe -> new SimplifiedRecipe(recipe, world.registryAccess()))
158 );
159 }
160
161 return recipes.toList();
162 }
163
164 private OptionalDouble configEmc(List<SimplifiedRecipe> recipes, Set<Item> configured, Item item) {
165 var res = get(item.getDefaultInstance());
166 if (res.isPresent() || configured.contains(item)) {
167 return res;
168 }
169
170 configured.add(item);
171
172 res = recipes.stream()
173 .filter(recipe -> recipe.output.is(item))
174 .map(recipe -> calculateEmcForRecipe(recipes, configured, recipe))
175 .filter(OptionalDouble::isPresent)
176 .mapToDouble(OptionalDouble::getAsDouble)
177 .average();
178 res.ifPresent(emc -> data.put(item, emc));
179 if (res.isPresent() && res.getAsDouble() <= 0) {
180 res = OptionalDouble.empty();
181 }
182 return res;
183 }
184
185 private OptionalDouble calculateEmcForRecipe(
186 List<SimplifiedRecipe> recipes,
187 Set<Item> configured,
188 SimplifiedRecipe recipe
189 ) {
190 try {
191 if (recipe.inputs.isEmpty()) {
192 return OptionalDouble.empty();
193 }
194
195 var inputEmc = recipe.inputs
196 .stream()
197 .map(ingredient -> calculateEmcForIngredient(recipes, configured, ingredient))
198 .mapToDouble(OptionalDouble::orElseThrow)
199 .sum();
200
201 if (inputEmc <= 0) {
202 return OptionalDouble.empty();
203 }
204
205 var remainderEmc = recipe.remainder
206 .stream()
207 .map(remainder -> configEmc(recipes, configured, remainder.getItem()))
208 .mapToDouble(OptionalDouble::orElseThrow)
209 .sum();
210
211 if (remainderEmc > inputEmc) {
212 ErisAlchemy.LOGGER.warn("Recipe generating {} creates too much EMC out of thin air!", recipe.output);
213 return OptionalDouble.empty();
214 } else if (remainderEmc < 0) {
215 return OptionalDouble.empty();
216 }
217
218 var outputDivisor = (double) recipe.output.getCount();
219
220 return OptionalDouble.of((inputEmc - remainderEmc) / outputDivisor);
221 } catch (NoSuchElementException e) {
222 return OptionalDouble.empty();
223 }
224 }
225
226 private OptionalDouble calculateEmcForIngredient(
227 List<SimplifiedRecipe> recipes,
228 Set<Item> configured,
229 Ingredient ingredient
230 ) {
231 return Arrays.stream(ingredient.getItems())
232 .map(stack -> configEmc(recipes, configured, stack.getItem()).stream()
233 .map(x -> x * stack.getCount())
234 .findFirst())
235 .filter(OptionalDouble::isPresent)
236 .mapToDouble(OptionalDouble::getAsDouble)
237 .filter(x -> x > 0)
238 .average();
239 }
240
241 static {
242 ITEM_COMMON_MAP.putAll(Map.<Item, Double>ofEntries(
243 Map.entry(Items.AIR, -1.0),
244 Map.entry(Items.AMETHYST_CLUSTER, -1.0),
245 Map.entry(Items.AMETHYST_SHARD, 1024.0),
246 Map.entry(Items.ANCIENT_DEBRIS, -1.0),
247 Map.entry(Items.APPLE, 128.0),
248 Map.entry(Items.BAMBOO, 2.0),
249 Map.entry(Items.BARRIER, -1.0),
250 Map.entry(Items.BEDROCK, -1.0),
251 Map.entry(Items.BEEF, 64.0),
252 Map.entry(Items.BEETROOT, 24.0),
253 Map.entry(Items.BEETROOT_SEEDS, 16.0),
254 Map.entry(Items.BIG_DRIPLEAF, 1.0),
255 Map.entry(Items.BLAZE_ROD, 1536.0),
256 Map.entry(Items.BONE, 96.0),
257 Map.entry(Items.BROWN_MUSHROOM, 32.0),
258 Map.entry(Items.BROWN_MUSHROOM_BLOCK, -1.0),
259 Map.entry(Items.BUDDING_AMETHYST, -1.0),
260 Map.entry(Items.BUNDLE, -1.0),
261 Map.entry(Items.CACTUS, 8.0),
262 Map.entry(Items.CARROT, 24.0),
263 Map.entry(Items.CALCITE, 1.0),
264 Map.entry(Items.CHAIN_COMMAND_BLOCK, -1.0),
265 Map.entry(Items.CHICKEN, 64.0),
266 Map.entry(Items.CHORUS_FLOWER, 32.0),
267 Map.entry(Items.CHORUS_FRUIT, 32.0),
268 Map.entry(Items.CHORUS_PLANT, 24.0),
269 Map.entry(Items.CLAY_BALL, 64.0),
270 Map.entry(Items.COAL, 128.0),
271 Map.entry(Items.COBWEB, 12.0),
272 Map.entry(Items.COBBLESTONE, 1.0),
273 Map.entry(Items.COBBLED_DEEPSLATE, 1.0),
274 Map.entry(Items.COCOA_BEANS, 8.0),
275 Map.entry(Items.COMMAND_BLOCK, -1.0),
276 Map.entry(Items.COMMAND_BLOCK_MINECART, -1.0),
277 Map.entry(Items.COPPER_INGOT, 85.0),
278 Map.entry(Items.CREEPER_HEAD, 34816.0),
279 Map.entry(Items.CRIMSON_FUNGUS, 24.0),
280 Map.entry(Items.CRIMSON_ROOTS, 1.0),
281 Map.entry(Items.CRYING_OBSIDIAN, 64.0),
282 Map.entry(Items.DEAD_BUSH, 1.0),
283 Map.entry(Items.DEBUG_STICK, -1.0),
284 Map.entry(Items.DIAMOND, 8192.0),
285 Map.entry(Items.DIRT_PATH, 1.0),
286 Map.entry(Items.DRAGON_BREATH, 34816.0),
287 Map.entry(Items.DRAGON_EGG, 139264.0),
288 Map.entry(Items.DRAGON_HEAD, 34816.0),
289 Map.entry(Items.ECHO_SHARD, 128.0),
290 Map.entry(Items.EGG, 32.0),
291 Map.entry(Items.ELYTRA, 8196.0),
292 Map.entry(Items.EMERALD, 1024.0),
293 Map.entry(Items.ENCHANTED_BOOK, -1.0),
294 Map.entry(Items.END_PORTAL_FRAME, -1.0),
295 Map.entry(Items.END_STONE, 1.0),
296 Map.entry(Items.ENDER_PEARL, 1024.0),
297 Map.entry(Items.EXPERIENCE_BOTTLE, -1.0),
298 Map.entry(Items.FARMLAND, -1.0),
299 Map.entry(Items.FEATHER, 48.0),
300 Map.entry(Items.FERN, 1.0),
301 Map.entry(Items.FIREWORK_STAR, -1.0),
302 Map.entry(Items.FLINT, 4.0),
303 Map.entry(Items.FROGSPAWN, -1.0),
304 Map.entry(Items.GHAST_TEAR, 4096.0),
305 Map.entry(Items.GLOW_BERRIES, 8.0),
306 Map.entry(Items.GLOW_LICHEN, 8.0),
307 Map.entry(Items.GLOWSTONE_DUST, 384.0),
308 Map.entry(Items.GOAT_HORN, 32.0),
309 Map.entry(Items.GOLD_INGOT, 2048.0),
310 Map.entry(Items.GOLD_NUGGET, 2048.0/9),
311 Map.entry(Items.GRASS, 1.0),
312 Map.entry(Items.GRAVEL, 4.0),
313 Map.entry(Items.GUNPOWDER, 192.0),
314 Map.entry(Items.HANGING_ROOTS, 1.0),
315 Map.entry(Items.HEART_OF_THE_SEA, 4096.0),
316 Map.entry(Items.HONEYCOMB, 24.0),
317 Map.entry(Items.ICE, 1.0),
318 Map.entry(Items.INFESTED_CHISELED_STONE_BRICKS, -1.0),
319 Map.entry(Items.INFESTED_COBBLESTONE, -1.0),
320 Map.entry(Items.INFESTED_CRACKED_STONE_BRICKS, -1.0),
321 Map.entry(Items.INFESTED_DEEPSLATE, -1.0),
322 Map.entry(Items.INFESTED_MOSSY_STONE_BRICKS, -1.0),
323 Map.entry(Items.INFESTED_STONE, -1.0),
324 Map.entry(Items.INFESTED_STONE_BRICKS, -1.0),
325 Map.entry(Items.IRON_INGOT, 256.0),
326 Map.entry(Items.IRON_NUGGET, 256.0/9),
327 Map.entry(Items.JIGSAW, -1.0),
328 Map.entry(Items.KELP, 32.0),
329 Map.entry(Items.KNOWLEDGE_BOOK, -1.0),
330 Map.entry(Items.LAPIS_LAZULI, 864.0),
331 Map.entry(Items.LARGE_AMETHYST_BUD, -1.0),
332 Map.entry(Items.LARGE_FERN, 1.0),
333 Map.entry(Items.LEATHER, 64.0),
334 Map.entry(Items.LIGHT, -1.0),
335 Map.entry(Items.LILY_PAD, 16.0),
336 Map.entry(Items.LINGERING_POTION, -1.0),
337 Map.entry(Items.MANGROVE_ROOTS, 1.0),
338 Map.entry(Items.MEDIUM_AMETHYST_BUD, -1.0),
339 Map.entry(Items.MELON_SLICE, 144.0),
340 Map.entry(Items.MUD, 1.0),
341 Map.entry(Items.MUSHROOM_STEM, -1.0),
342 Map.entry(Items.MUTTON, 64.0),
343 Map.entry(Items.NAME_TAG, -1.0),
344 Map.entry(Items.NAUTILUS_SHELL, 64.0),
345 Map.entry(Items.NETHER_QUARTZ_ORE, -1.0),
346 Map.entry(Items.NETHER_SPROUTS, 1.0),
347 Map.entry(Items.NETHER_STAR, 139264.0),
348 Map.entry(Items.NETHER_WART, 24.0),
349 Map.entry(Items.NETHERITE_SCRAP, 16384.0),
350 Map.entry(Items.OBSIDIAN, 64.0),
351 Map.entry(Items.PHANTOM_MEMBRANE, 96.0),
352 Map.entry(Items.PIGLIN_HEAD, 34816.0),
353 Map.entry(Items.PITCHER_POD, 8.0),
354 Map.entry(Items.PLAYER_HEAD, 34816.0),
355 Map.entry(Items.POINTED_DRIPSTONE, 0.25),
356 Map.entry(Items.PORKCHOP, 64.0),
357 Map.entry(Items.POTATO, 24.0),
358 Map.entry(Items.POTION, -1.0),
359 Map.entry(Items.PRISMARINE_CRYSTALS, 384.0),
360 Map.entry(Items.PRISMARINE_SHARD, 0.25),
361 Map.entry(Items.PUMPKIN, 144.0),
362 Map.entry(Items.QUARTZ, 64.0),
363 Map.entry(Items.RABBIT, 64.0),
364 Map.entry(Items.RABBIT_HIDE, 64.0),
365 Map.entry(Items.RAW_COPPER, -1.0),
366 Map.entry(Items.RAW_COPPER_BLOCK, -1.0),
367 Map.entry(Items.RAW_GOLD, -1.0),
368 Map.entry(Items.RAW_GOLD_BLOCK, -1.0),
369 Map.entry(Items.RAW_IRON, -1.0),
370 Map.entry(Items.RAW_IRON_BLOCK, -1.0),
371 Map.entry(Items.RED_MUSHROOM, 32.0),
372 Map.entry(Items.RED_MUSHROOM_BLOCK, -1.0),
373 Map.entry(Items.REDSTONE, 64.0),
374 Map.entry(Items.REINFORCED_DEEPSLATE, -1.0),
375 Map.entry(Items.REPEATING_COMMAND_BLOCK, -1.0),
376 Map.entry(Items.ROTTEN_FLESH, 24.0),
377 Map.entry(Items.SADDLE, 192.0),
378 Map.entry(Items.SCULK, 1.0),
379 Map.entry(Items.SCULK_CATALYST, 16.0),
380 Map.entry(Items.SCULK_SENSOR, 32.0),
381 Map.entry(Items.SCULK_SHRIEKER, 16.0),
382 Map.entry(Items.SCULK_VEIN, 1.0),
383 Map.entry(Items.SCUTE, 32.0),
384 Map.entry(Items.SEA_PICKLE, 1.0),
385 Map.entry(Items.SEAGRASS, 1.0),
386 Map.entry(Items.SHULKER_SHELL, 256.0),
387 Map.entry(Items.SKELETON_SKULL, 34816.0),
388 Map.entry(Items.SLIME_BALL, 24.0),
389 Map.entry(Items.SMALL_AMETHYST_BUD, -1.0),
390 Map.entry(Items.SMALL_DRIPLEAF, 1.0),
391 Map.entry(Items.SNIFFER_EGG, 32.0),
392 Map.entry(Items.SNOWBALL, 1.0),
393 Map.entry(Items.SOUL_SAND, 49.0),
394 Map.entry(Items.SOUL_SOIL, 49.0),
395 Map.entry(Items.SPAWNER, -1.0),
396 Map.entry(Items.SPIDER_EYE, 128.0),
397 Map.entry(Items.SPLASH_POTION, -1.0),
398 Map.entry(Items.SPONGE, 48.0),
399 Map.entry(Items.SPORE_BLOSSOM, 1.0),
400 Map.entry(Items.STICK, 4.0),
401 Map.entry(Items.STRING, 12.0),
402 Map.entry(Items.STRUCTURE_BLOCK, -1.0),
403 Map.entry(Items.STRUCTURE_VOID, -1.0),
404 Map.entry(Items.SUGAR_CANE, 32.0),
405 Map.entry(Items.SUSPICIOUS_GRAVEL, 4.0),
406 Map.entry(Items.SWEET_BERRIES, 8.0),
407 Map.entry(Items.TALL_GRASS, 1.0),
408 Map.entry(Items.TIPPED_ARROW, -1.0),
409 Map.entry(Items.TORCHFLOWER_SEEDS, 8.0),
410 Map.entry(Items.TOTEM_OF_UNDYING, 4096.0),
411 Map.entry(Items.TURTLE_EGG, 32.0),
412 Map.entry(Items.TWISTING_VINES, 8.0),
413 Map.entry(Items.VINE, 8.0),
414 Map.entry(Items.WARPED_FUNGUS, 24.0),
415 Map.entry(Items.WARPED_ROOTS, 1.0),
416 Map.entry(Items.WARPED_WART_BLOCK, 1.0),
417 Map.entry(Items.WEEPING_VINES, 8.0),
418 Map.entry(Items.WET_SPONGE, 48.0),
419 Map.entry(Items.WHEAT, 24.0),
420 Map.entry(Items.WHEAT_SEEDS, 16.0),
421 Map.entry(Items.WITHER_SKELETON_SKULL, 34816.0),
422 Map.entry(Items.WRITTEN_BOOK, -1.0),
423 Map.entry(Items.ZOMBIE_HEAD, 34816.0),
424
425 Map.entry(PatchouliItems.BOOK, -1.0)
426 ));
427
428 SpawnEggItem.eggs().forEach(spawnEgg -> ITEM_COMMON_MAP.put(spawnEgg, -1.0));
429
430 CoralUtils.streamAllCoralBlocks().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
431 CoralUtils.streamAllDeadCoralBlocks().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
432 CoralUtils.streamAllCorals().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
433 CoralUtils.streamAllDeadCorals().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
434
435 BLOCK_TAG_COMMON_MAP.putAll(Map.ofEntries(
436 Map.entry(BlockTags.BASE_STONE_NETHER, 1.0),
437 Map.entry(BlockTags.BASE_STONE_OVERWORLD, 1.0),
438 Map.entry(BlockTags.NYLIUM, 1.0)
439 ));
440
441 ITEM_TAG_COMMON_MAP.putAll(Map.ofEntries(
442 Map.entry(ItemTags.COAL_ORES, -1.0),
443 Map.entry(ItemTags.COPPER_ORES, -1.0),
444 Map.entry(ItemTags.DIAMOND_ORES, -1.0),
445 Map.entry(ItemTags.DIRT, 1.0),
446 Map.entry(ItemTags.MUSIC_DISCS, 4096.0),
447 Map.entry(ItemTags.EMERALD_ORES, -1.0),
448 Map.entry(ItemTags.FISHES, 64.0),
449 Map.entry(ItemTags.FLOWERS, 16.0),
450 Map.entry(ItemTags.GOLD_ORES, -1.0),
451 Map.entry(ItemTags.IRON_ORES, -1.0),
452 Map.entry(ItemTags.LAPIS_ORES, -1.0),
453 Map.entry(ItemTags.LEAVES, 1.0),
454 Map.entry(ItemTags.LOGS, 32.0),
455 Map.entry(ItemTags.REDSTONE_ORES, -1.0),
456 Map.entry(ItemTags.SAND, 1.0),
457 Map.entry(ItemTags.SAPLINGS, 32.0),
458 Map.entry(ItemTags.WOOL, 48.0)
459 ));
460
461 FAKE_RECIPES.addAll(List.of(
462 // more oxidised coppers are worth less
463 new SimplifiedRecipe(new ItemStack(Items.EXPOSED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 3)),
464 new SimplifiedRecipe(new ItemStack(Items.WEATHERED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 2)),
465 new SimplifiedRecipe(new ItemStack(Items.OXIDIZED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 1)),
466
467 new SimplifiedRecipe(new ItemStack(Items.WAXED_EXPOSED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 3)),
468 new SimplifiedRecipe(new ItemStack(Items.WAXED_WEATHERED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 2)),
469 new SimplifiedRecipe(new ItemStack(Items.WAXED_OXIDIZED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 1)),
470
471 // more damaged anvils are worth less
472 new SimplifiedRecipe(new ItemStack(Items.CHIPPED_ANVIL, 3), new ItemStack(Items.ANVIL, 2)),
473 new SimplifiedRecipe(new ItemStack(Items.DAMAGED_ANVIL, 3), new ItemStack(Items.ANVIL, 1)),
474
475 // old oak slabs are the same value as modern ones
476 new SimplifiedRecipe(Items.PETRIFIED_OAK_SLAB, Items.OAK_SLAB),
477
478 // chainmail armour is worth the same as normal iron armor
479 new SimplifiedRecipe(Items.CHAINMAIL_HELMET, Items.IRON_HELMET),
480 new SimplifiedRecipe(Items.CHAINMAIL_CHESTPLATE, Items.IRON_CHESTPLATE),
481 new SimplifiedRecipe(Items.CHAINMAIL_LEGGINGS, Items.IRON_LEGGINGS),
482 new SimplifiedRecipe(Items.CHAINMAIL_BOOTS, Items.IRON_BOOTS),
483
484 // enchanted golden apple is worth uhh 16 times the non-enchanted one :3
485 new SimplifiedRecipe(Items.ENCHANTED_GOLDEN_APPLE, new ItemStack(Items.GOLDEN_APPLE, 16)),
486
487 // carving a pumpkin with shears
488 new SimplifiedRecipe(Items.CARVED_PUMPKIN, List.of(new ItemStack(Items.PUMPKIN_SEEDS, 4)), Items.PUMPKIN),
489
490 // gathering honey
491 new SimplifiedRecipe(Items.HONEY_BOTTLE, Items.HONEYCOMB, Items.GLASS_BOTTLE),
492
493 // smithing template duplicating recipes but -1 templates on both sides
494 new SimplifiedRecipe(Items.COAST_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
495 new SimplifiedRecipe(Items.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.SANDSTONE)),
496 new SimplifiedRecipe(Items.EYE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.END_STONE)),
497 new SimplifiedRecipe(Items.HOST_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
498 new SimplifiedRecipe(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.NETHERRACK)),
499 new SimplifiedRecipe(Items.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
500 new SimplifiedRecipe(Items.RIB_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.NETHERRACK)),
501 new SimplifiedRecipe(Items.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
502 new SimplifiedRecipe(Items.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
503 new SimplifiedRecipe(Items.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLED_DEEPSLATE)),
504 new SimplifiedRecipe(Items.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.BLACKSTONE)),
505 new SimplifiedRecipe(Items.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.PURPUR_BLOCK)),
506 new SimplifiedRecipe(Items.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.PRISMARINE)),
507 new SimplifiedRecipe(Items.VEX_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
508 new SimplifiedRecipe(Items.WARD_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLED_DEEPSLATE)),
509 new SimplifiedRecipe(Items.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
510 new SimplifiedRecipe(Items.WILD_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.MOSSY_COBBLESTONE)),
511
512 // water bucket = bucket + water, water assumed to be same value as cobblestone
513 new SimplifiedRecipe(Items.WATER_BUCKET, Items.BUCKET, Items.COBBLESTONE),
514
515 // lava bucket = bucket + lava, lava assumed to be same value as obsidian
516 new SimplifiedRecipe(Items.LAVA_BUCKET, Items.BUCKET, Items.OBSIDIAN),
517
518 // powder snow bucket = bucket + snow
519 new SimplifiedRecipe(Items.POWDER_SNOW_BUCKET, Items.BUCKET, Items.SNOW_BLOCK),
520
521 // milk bucket = bucket + milk, milk assumed to be same value as wheat
522 new SimplifiedRecipe(Items.MILK_BUCKET, Items.BUCKET, Items.WHEAT),
523
524 // [fish] bucket = bucket + [fish]
525 new SimplifiedRecipe(Items.COD_BUCKET, Items.BUCKET, Items.COD),
526 new SimplifiedRecipe(Items.PUFFERFISH_BUCKET, Items.BUCKET, Items.PUFFERFISH),
527 new SimplifiedRecipe(Items.SALMON_BUCKET, Items.BUCKET, Items.SALMON),
528 new SimplifiedRecipe(Items.TROPICAL_FISH_BUCKET, Items.BUCKET, Items.TROPICAL_FISH),
529
530 // yep
531 new SimplifiedRecipe(Items.AXOLOTL_BUCKET, Items.TROPICAL_FISH_BUCKET),
532 new SimplifiedRecipe(Items.TADPOLE_BUCKET, Items.AXOLOTL_BUCKET),
533
534 // dye value is the canon
535 new SimplifiedRecipe(Items.INK_SAC, Items.BLACK_DYE),
536
537 // disc value is the canon
538 new SimplifiedRecipe(new ItemStack(Items.DISC_FRAGMENT_5, 9), Items.MUSIC_DISC_5),
539
540 // glowing ink sac is more expensive than an ink sac
541 new SimplifiedRecipe(Items.GLOW_INK_SAC, new ItemStack(Items.INK_SAC, 4)),
542
543 // activated maps cost the same as unactivated ones
544 new SimplifiedRecipe(Items.FILLED_MAP, Items.MAP),
545
546 // poisonous potato costs less than a normal one
547 new SimplifiedRecipe(new ItemStack(Items.POISONOUS_POTATO, 2), Items.POTATO),
548
549 // rabbits foot costs more than rabbit meat
550 new SimplifiedRecipe(Items.RABBIT_FOOT, new ItemStack(Items.RABBIT, 8)),
551
552 // [X] horse armor == [X] leggings
553 // wtf, why? see how much leather is used by leather horse armor
554 new SimplifiedRecipe(Items.IRON_HORSE_ARMOR, Items.IRON_LEGGINGS),
555 new SimplifiedRecipe(Items.GOLDEN_HORSE_ARMOR, Items.GOLDEN_LEGGINGS),
556 new SimplifiedRecipe(Items.DIAMOND_HORSE_ARMOR, Items.DIAMOND_LEGGINGS),
557
558 // Trident = 1.5 * iron sword
559 new SimplifiedRecipe(new ItemStack(Items.TRIDENT, 2), new ItemStack(Items.IRON_SWORD, 3)),
560
561 // an actual recipe but it's special, minecraft:crafting_special_suspiciousstew
562 new SimplifiedRecipe(Items.SUSPICIOUS_STEW, Items.BOWL, Items.BROWN_MUSHROOM, Items.RED_MUSHROOM, Items.POPPY),
563
564 // obvious
565 new SimplifiedRecipe(Items.GLOBE_BANNER_PATTERN, Items.CREEPER_BANNER_PATTERN),
566 new SimplifiedRecipe(Items.PIGLIN_BANNER_PATTERN, Items.CREEPER_BANNER_PATTERN),
567
568 // the vibes fit
569 new SimplifiedRecipe(Items.BELL, Items.SPYGLASS),
570
571 // light sources, shroomlight has no crafting uses but is brighter
572 new SimplifiedRecipe(Items.SHROOMLIGHT, Items.GLOWSTONE),
573
574 // bee nest = honeycomb block
575 new SimplifiedRecipe(Items.BEE_NEST, new ItemStack(Items.HONEYCOMB, 9)),
576
577 // gilded blackstone = blackstone with gold nuggets
578 new SimplifiedRecipe(Items.GILDED_BLACKSTONE, new ItemStack(Items.BLACKSTONE), new ItemStack(Items.GOLD_NUGGET, 4)),
579
580 // froglight = eaten magma cube
581 new SimplifiedRecipe(Items.OCHRE_FROGLIGHT, Items.MAGMA_CREAM),
582 new SimplifiedRecipe(Items.PEARLESCENT_FROGLIGHT, Items.MAGMA_CREAM),
583 new SimplifiedRecipe(Items.VERDANT_FROGLIGHT, Items.MAGMA_CREAM)
584 ));
585
586 // pot sherds can be replaced with bricks when making decorated pots
587 ItemUtils.streamTag(ItemTags.DECORATED_POT_SHERDS).forEach(sherd -> FAKE_RECIPES.add(new SimplifiedRecipe(sherd, Items.BRICK)));
588
589 for (var color : DyeColor.values()) {
590 ITEM_COMMON_MAP.put(DyeUtils.getDye(color), 8.0);
591 FAKE_RECIPES.addAll(List.of(
592 // putting concrete powder in water
593 new SimplifiedRecipe(DyeUtils.getConcrete(color), DyeUtils.getConcretePowder(color)),
594
595 // an actual recipe but it's special, minecraft:crafting_special_shulkerboxcoloring
596 new SimplifiedRecipe(DyeUtils.getShulkerBox(color), Items.SHULKER_BOX, DyeUtils.getDye(color))
597 ));
598 }
599 }
600}