summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-01-08 01:42:51 +0100
committerGravatar Uko Kokņevičs2024-01-08 01:42:51 +0100
commit52f8874f81116bd6767c6f9247347c30a3820e51 (patch)
tree7c5398dc0e02bec54af7def5e1e11a7b733c034e
parentBuild script improvements (diff)
downloadmc-eris-alchemy-52f8874f81116bd6767c6f9247347c30a3820e51.tar.gz
mc-eris-alchemy-52f8874f81116bd6767c6f9247347c30a3820e51.tar.xz
mc-eris-alchemy-52f8874f81116bd6767c6f9247347c30a3820e51.zip
Created the EMC system
-rw-r--r--README.md4
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/EMC.java568
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java22
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/SubAxe.java18
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralBlockMixin.java20
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralFanBlockMixin.java20
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralPlantBlockMixin.java20
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralWallFanBlockMixin.java20
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java15
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/RecipeMixin.java29
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/mixin/SmithingTransformRecipeMixin.java28
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/BlockUtils.java13
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/CoralUtils.java42
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/DyeUtils.java60
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/ItemUtils.java13
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/RecipeUtils.java23
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/utils/TagUtils.java14
-rw-r--r--src/main/resources/assets/eris_alchemy/patchouli_books/guide_book/en_us/entries/root/covalence_dusts.json2
-rw-r--r--src/main/resources/data/eris_alchemy/recipes/medium_covalence_repair.json2
-rw-r--r--src/main/resources/eris_alchemy.mixins.json11
20 files changed, 919 insertions, 25 deletions
diff --git a/README.md b/README.md
index 81bc79c..34c9b35 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,6 @@
2 2
3## TODO 3## TODO
4 4
5- custom model for guide book \ No newline at end of file 5- custom model for guide book
6
7When upgrading minecraft `grep` for `UPGRADE`, update content and bracketed version. \ No newline at end of file
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/EMC.java b/src/main/java/lv/enes/mc/eris_alchemy/EMC.java
new file mode 100644
index 0000000..4f2c5e4
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/EMC.java
@@ -0,0 +1,568 @@
1package lv.enes.mc.eris_alchemy;
2
3import jakarta.annotation.Nullable;
4import lv.enes.mc.eris_alchemy.utils.CoralUtils;
5import lv.enes.mc.eris_alchemy.utils.DyeUtils;
6import lv.enes.mc.eris_alchemy.utils.ItemUtils;
7import lv.enes.mc.eris_alchemy.utils.RecipeUtils;
8import net.minecraft.core.RegistryAccess;
9import net.minecraft.core.registries.BuiltInRegistries;
10import net.minecraft.tags.BlockTags;
11import net.minecraft.tags.ItemTags;
12import net.minecraft.tags.TagKey;
13import net.minecraft.world.item.*;
14import net.minecraft.world.item.crafting.Ingredient;
15import net.minecraft.world.item.crafting.Recipe;
16import net.minecraft.world.level.ItemLike;
17import net.minecraft.world.level.Level;
18import net.minecraft.world.level.block.Block;
19import vazkii.patchouli.common.item.PatchouliItems;
20
21import java.util.*;
22import java.util.stream.Stream;
23
24public class EMC {
25 private record SimplifiedRecipe(ItemStack output, List<ItemStack> remainder, List<Ingredient> inputs) {
26 public SimplifiedRecipe(ItemLike output, Ingredient... inputs) {
27 this(new ItemStack(output), List.of(), List.of(inputs));
28 }
29
30 public SimplifiedRecipe(ItemLike output, ItemLike... inputs) {
31 this(new ItemStack(output), List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
32 }
33
34 public SimplifiedRecipe(ItemLike output, ItemStack... inputs) {
35 this(new ItemStack(output), List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
36 }
37
38 public SimplifiedRecipe(ItemLike output, List<ItemStack> remainder, ItemLike... inputs) {
39 this(new ItemStack(output), remainder, Arrays.stream(inputs).map(Ingredient::of).toList());
40 }
41
42 public SimplifiedRecipe(ItemStack output, ItemLike... inputs) {
43 this(output, List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
44 }
45
46 public SimplifiedRecipe(ItemStack output, ItemStack... inputs) {
47 this(output, List.of(), Arrays.stream(inputs).map(Ingredient::of).toList());
48 }
49
50 public SimplifiedRecipe(Recipe<?> recipe, RegistryAccess registryAccess) {
51 this(
52 RecipeUtils.getOutput(recipe, registryAccess),
53 List.of(), // TODO:
54 RecipeUtils.getIngredients(recipe).stream().filter(ingredient -> !ingredient.isEmpty()).toList()
55 );
56 }
57 }
58
59 private static final Map<Item, Double> ITEM_COMMON_MAP = new HashMap<>();
60 private static final Map<TagKey<Item>, Double> ITEM_TAG_COMMON_MAP = new HashMap<>();
61 private static final Map<TagKey<Block>, Double> BLOCK_TAG_COMMON_MAP = new HashMap<>();
62 private static final List<SimplifiedRecipe> FAKE_RECIPES = new ArrayList<>();
63
64 private static final EMC defaultInstance = new EMC(null);
65 private static final Map<Level, EMC> instances = Collections.synchronizedMap(new WeakHashMap<>());
66
67 public static EMC getInstance(Level world) {
68 if (world == null) {
69 return defaultInstance;
70 }
71
72 if (instances.containsKey(world)) {
73 return instances.get(world);
74 }
75
76 var instance = new EMC(world);
77 instances.put(world, instance);
78 return instance;
79 }
80
81 private final Map<Item, Double> data;
82
83 private EMC(@Nullable Level world) {
84 data = Collections.synchronizedMap(new HashMap<>(ITEM_COMMON_MAP));
85 ITEM_TAG_COMMON_MAP.forEach(
86 (tag, emcValue) -> BuiltInRegistries.ITEM
87 .getTagOrEmpty(tag)
88 .forEach(holder -> data.putIfAbsent(holder.value(), emcValue))
89 );
90 BLOCK_TAG_COMMON_MAP.forEach(
91 (tag, emcValue) -> BuiltInRegistries.BLOCK
92 .getTagOrEmpty(tag)
93 .forEach(holder -> data.putIfAbsent(holder.value().asItem(), emcValue))
94 );
95
96 ErisAlchemy.LOGGER.info("Getting recipes...");
97 var recipes = getRecipes(world);
98 var configured = new HashSet<>(data.keySet());
99 ErisAlchemy.LOGGER.info("Calculating EMC values...");
100 BuiltInRegistries.ITEM.forEach(item -> {
101 configEmc(recipes, configured, item);
102 if (world != null && !data.containsKey(item)) {
103 ErisAlchemy.LOGGER.warn("No EMC value for '{}' known", item);
104 }
105 });
106 }
107
108 public OptionalDouble get(Item item) {
109 var value = data.get(item);
110 if (value == null || value <= 0) {
111 return OptionalDouble.empty();
112 }
113 return OptionalDouble.of(value);
114 }
115
116 private List<SimplifiedRecipe> getRecipes(@Nullable Level world) {
117 Stream<SimplifiedRecipe> recipes = Stream.concat(
118 FAKE_RECIPES.stream(),
119 SubAxe.getStrippables()
120 .entrySet()
121 .stream()
122 .map(entry -> new SimplifiedRecipe(entry.getValue(), Ingredient.of(entry.getKey())))
123 );
124
125 if (world != null) {
126 recipes = Stream.concat(
127 recipes,
128 world.getRecipeManager()
129 .getRecipes()
130 .stream()
131 .map(recipe -> new SimplifiedRecipe(recipe, world.registryAccess()))
132 );
133 }
134
135 return recipes.toList();
136 }
137
138 private OptionalDouble configEmc(List<SimplifiedRecipe> recipes, Set<Item> configured, Item item) {
139 var res = get(item);
140 if (res.isPresent() || configured.contains(item)) {
141 return res;
142 }
143
144 configured.add(item);
145
146 res = recipes.stream()
147 .filter(recipe -> recipe.output.is(item))
148 .map(recipe -> calculateEmcForRecipe(recipes, configured, recipe))
149 .filter(OptionalDouble::isPresent)
150 .mapToDouble(OptionalDouble::getAsDouble)
151 .average();
152 res.ifPresent(emc -> data.put(item, emc));
153 if (res.isPresent() && res.getAsDouble() <= 0) {
154 res = OptionalDouble.empty();
155 }
156 return res;
157 }
158
159 private OptionalDouble calculateEmcForRecipe(List<SimplifiedRecipe> recipes, Set<Item> configured, SimplifiedRecipe recipe) {
160 try {
161 if (recipe.inputs.isEmpty()) {
162 return OptionalDouble.empty();
163 }
164
165 var inputEmc = recipe.inputs
166 .stream()
167 .map(ingredient -> calculateEmcForIngredient(recipes, configured, ingredient))
168 .mapToDouble(OptionalDouble::orElseThrow)
169 .sum();
170
171 if (inputEmc <= 0) {
172 return OptionalDouble.empty();
173 }
174
175 var remainderEmc = recipe.remainder
176 .stream()
177 .map(remainder -> configEmc(recipes, configured, remainder.getItem()))
178 .mapToDouble(OptionalDouble::orElseThrow)
179 .sum();
180
181 if (remainderEmc > inputEmc) {
182 ErisAlchemy.LOGGER.warn("Recipe generating {} creates too much EMC out of thin air!", recipe.output);
183 return OptionalDouble.empty();
184 } else if (remainderEmc < 0) {
185 return OptionalDouble.empty();
186 }
187
188 var outputDivisor = (double) recipe.output.getCount();
189
190 return OptionalDouble.of((inputEmc - remainderEmc) / outputDivisor);
191 } catch (NoSuchElementException e) {
192 return OptionalDouble.empty();
193 }
194 }
195
196 private OptionalDouble calculateEmcForIngredient(List<SimplifiedRecipe> recipes, Set<Item> configured, Ingredient ingredient) {
197 return Arrays.stream(ingredient.getItems())
198 .map(stack -> configEmc(recipes, configured, stack.getItem()).stream()
199 .map(x -> x * stack.getCount())
200 .findFirst())
201 .filter(OptionalDouble::isPresent)
202 .mapToDouble(OptionalDouble::getAsDouble)
203 .filter(x -> x > 0)
204 .average();
205 }
206
207 static {
208 ITEM_COMMON_MAP.putAll(Map.<Item, Double>ofEntries(
209 Map.entry(Items.AIR, -1.0),
210 Map.entry(Items.AMETHYST_CLUSTER, -1.0),
211 Map.entry(Items.AMETHYST_SHARD, 1024.0),
212 Map.entry(Items.ANCIENT_DEBRIS, -1.0),
213 Map.entry(Items.APPLE, 128.0),
214 Map.entry(Items.BAMBOO, 2.0),
215 Map.entry(Items.BARRIER, -1.0),
216 Map.entry(Items.BEDROCK, -1.0),
217 Map.entry(Items.BEEF, 64.0),
218 Map.entry(Items.BEETROOT, 24.0),
219 Map.entry(Items.BEETROOT_SEEDS, 16.0),
220 Map.entry(Items.BIG_DRIPLEAF, 1.0),
221 Map.entry(Items.BLAZE_ROD, 1536.0),
222 Map.entry(Items.BONE, 96.0),
223 Map.entry(Items.BROWN_MUSHROOM, 32.0),
224 Map.entry(Items.BROWN_MUSHROOM_BLOCK, -1.0),
225 Map.entry(Items.BUDDING_AMETHYST, -1.0),
226 Map.entry(Items.CACTUS, 8.0),
227 Map.entry(Items.CARROT, 24.0),
228 Map.entry(Items.CALCITE, 1.0),
229 Map.entry(Items.CHAIN_COMMAND_BLOCK, -1.0),
230 Map.entry(Items.CHICKEN, 64.0),
231 Map.entry(Items.CHORUS_FLOWER, 32.0),
232 Map.entry(Items.CHORUS_FRUIT, 32.0),
233 Map.entry(Items.CHORUS_PLANT, 24.0),
234 Map.entry(Items.CLAY_BALL, 64.0),
235 Map.entry(Items.COAL, 128.0),
236 Map.entry(Items.COBWEB, 12.0),
237 Map.entry(Items.COBBLESTONE, 1.0),
238 Map.entry(Items.COBBLED_DEEPSLATE, 1.0),
239 Map.entry(Items.COCOA_BEANS, 8.0),
240 Map.entry(Items.COMMAND_BLOCK, -1.0),
241 Map.entry(Items.COMMAND_BLOCK_MINECART, -1.0),
242 Map.entry(Items.COPPER_INGOT, 85.0),
243 Map.entry(Items.CREEPER_HEAD, 34816.0),
244 Map.entry(Items.CRIMSON_FUNGUS, 24.0),
245 Map.entry(Items.CRIMSON_ROOTS, 1.0),
246 Map.entry(Items.CRYING_OBSIDIAN, 64.0),
247 Map.entry(Items.DEAD_BUSH, 1.0),
248 Map.entry(Items.DEBUG_STICK, -1.0),
249 Map.entry(Items.DIAMOND, 8192.0),
250 Map.entry(Items.DIRT_PATH, 1.0),
251 Map.entry(Items.DRAGON_BREATH, 34816.0),
252 Map.entry(Items.DRAGON_EGG, 139264.0),
253 Map.entry(Items.DRAGON_HEAD, 34816.0),
254 Map.entry(Items.ECHO_SHARD, 128.0),
255 Map.entry(Items.EGG, 32.0),
256 Map.entry(Items.ELYTRA, 8196.0),
257 Map.entry(Items.EMERALD, 1024.0),
258 Map.entry(Items.ENCHANTED_BOOK, -1.0),
259 Map.entry(Items.END_PORTAL_FRAME, -1.0),
260 Map.entry(Items.END_STONE, 1.0),
261 Map.entry(Items.ENDER_PEARL, 1024.0),
262 Map.entry(Items.EXPERIENCE_BOTTLE, -1.0),
263 Map.entry(Items.FARMLAND, -1.0),
264 Map.entry(Items.FEATHER, 48.0),
265 Map.entry(Items.FERN, 1.0),
266 Map.entry(Items.FIREWORK_STAR, -1.0),
267 Map.entry(Items.FLINT, 4.0),
268 Map.entry(Items.FROGSPAWN, -1.0),
269 Map.entry(Items.GHAST_TEAR, 4096.0),
270 Map.entry(Items.GLOW_BERRIES, 8.0),
271 Map.entry(Items.GLOW_LICHEN, 8.0),
272 Map.entry(Items.GLOWSTONE_DUST, 384.0),
273 Map.entry(Items.GOAT_HORN, 32.0),
274 Map.entry(Items.GOLD_INGOT, 2048.0),
275 Map.entry(Items.GOLD_NUGGET, 2048.0/9),
276 Map.entry(Items.GRASS, 1.0),
277 Map.entry(Items.GRAVEL, 4.0),
278 Map.entry(Items.GUNPOWDER, 192.0),
279 Map.entry(Items.HANGING_ROOTS, 1.0),
280 Map.entry(Items.HEART_OF_THE_SEA, 4096.0),
281 Map.entry(Items.HONEYCOMB, 24.0),
282 Map.entry(Items.ICE, 1.0),
283 Map.entry(Items.INFESTED_CHISELED_STONE_BRICKS, -1.0),
284 Map.entry(Items.INFESTED_COBBLESTONE, -1.0),
285 Map.entry(Items.INFESTED_CRACKED_STONE_BRICKS, -1.0),
286 Map.entry(Items.INFESTED_DEEPSLATE, -1.0),
287 Map.entry(Items.INFESTED_MOSSY_STONE_BRICKS, -1.0),
288 Map.entry(Items.INFESTED_STONE, -1.0),
289 Map.entry(Items.INFESTED_STONE_BRICKS, -1.0),
290 Map.entry(Items.IRON_INGOT, 256.0),
291 Map.entry(Items.IRON_NUGGET, 256.0/9),
292 Map.entry(Items.JIGSAW, -1.0),
293 Map.entry(Items.KELP, 32.0),
294 Map.entry(Items.KNOWLEDGE_BOOK, -1.0),
295 Map.entry(Items.LAPIS_LAZULI, 864.0),
296 Map.entry(Items.LARGE_AMETHYST_BUD, -1.0),
297 Map.entry(Items.LARGE_FERN, 1.0),
298 Map.entry(Items.LEATHER, 64.0),
299 Map.entry(Items.LIGHT, -1.0),
300 Map.entry(Items.LILY_PAD, 16.0),
301 Map.entry(Items.LINGERING_POTION, -1.0),
302 Map.entry(Items.MANGROVE_ROOTS, 1.0),
303 Map.entry(Items.MEDIUM_AMETHYST_BUD, -1.0),
304 Map.entry(Items.MELON_SLICE, 144.0),
305 Map.entry(Items.MUD, 1.0),
306 Map.entry(Items.MUSHROOM_STEM, -1.0),
307 Map.entry(Items.MUTTON, 64.0),
308 Map.entry(Items.NAME_TAG, -1.0),
309 Map.entry(Items.NAUTILUS_SHELL, 64.0),
310 Map.entry(Items.NETHER_QUARTZ_ORE, -1.0),
311 Map.entry(Items.NETHER_SPROUTS, 1.0),
312 Map.entry(Items.NETHER_STAR, 139264.0),
313 Map.entry(Items.NETHER_WART, 24.0),
314 Map.entry(Items.NETHERITE_SCRAP, 16384.0),
315 Map.entry(Items.OBSIDIAN, 64.0),
316 Map.entry(Items.PHANTOM_MEMBRANE, 96.0),
317 Map.entry(Items.PIGLIN_HEAD, 34816.0),
318 Map.entry(Items.PITCHER_POD, 8.0),
319 Map.entry(Items.PLAYER_HEAD, 34816.0),
320 Map.entry(Items.POINTED_DRIPSTONE, 0.25),
321 Map.entry(Items.PORKCHOP, 64.0),
322 Map.entry(Items.POTATO, 24.0),
323 Map.entry(Items.POTION, -1.0),
324 Map.entry(Items.PRISMARINE_CRYSTALS, 384.0),
325 Map.entry(Items.PRISMARINE_SHARD, 0.25),
326 Map.entry(Items.PUMPKIN, 144.0),
327 Map.entry(Items.QUARTZ, 64.0),
328 Map.entry(Items.RABBIT, 64.0),
329 Map.entry(Items.RABBIT_HIDE, 64.0),
330 Map.entry(Items.RAW_COPPER, -1.0),
331 Map.entry(Items.RAW_COPPER_BLOCK, -1.0),
332 Map.entry(Items.RAW_GOLD, -1.0),
333 Map.entry(Items.RAW_GOLD_BLOCK, -1.0),
334 Map.entry(Items.RAW_IRON, -1.0),
335 Map.entry(Items.RAW_IRON_BLOCK, -1.0),
336 Map.entry(Items.RED_MUSHROOM, 32.0),
337 Map.entry(Items.RED_MUSHROOM_BLOCK, -1.0),
338 Map.entry(Items.REDSTONE, 64.0),
339 Map.entry(Items.REINFORCED_DEEPSLATE, -1.0),
340 Map.entry(Items.REPEATING_COMMAND_BLOCK, -1.0),
341 Map.entry(Items.ROTTEN_FLESH, 24.0),
342 Map.entry(Items.SADDLE, 192.0),
343 Map.entry(Items.SCULK, 1.0),
344 Map.entry(Items.SCULK_CATALYST, 16.0),
345 Map.entry(Items.SCULK_SENSOR, 32.0),
346 Map.entry(Items.SCULK_SHRIEKER, 16.0),
347 Map.entry(Items.SCULK_VEIN, 1.0),
348 Map.entry(Items.SCUTE, 32.0),
349 Map.entry(Items.SEA_PICKLE, 1.0),
350 Map.entry(Items.SEAGRASS, 1.0),
351 Map.entry(Items.SHULKER_SHELL, 256.0),
352 Map.entry(Items.SKELETON_SKULL, 34816.0),
353 Map.entry(Items.SLIME_BALL, 24.0),
354 Map.entry(Items.SMALL_AMETHYST_BUD, -1.0),
355 Map.entry(Items.SMALL_DRIPLEAF, 1.0),
356 Map.entry(Items.SNIFFER_EGG, 32.0),
357 Map.entry(Items.SNOWBALL, 1.0),
358 Map.entry(Items.SOUL_SAND, 49.0),
359 Map.entry(Items.SOUL_SOIL, 49.0),
360 Map.entry(Items.SPAWNER, -1.0),
361 Map.entry(Items.SPIDER_EYE, 128.0),
362 Map.entry(Items.SPLASH_POTION, -1.0),
363 Map.entry(Items.SPONGE, 48.0),
364 Map.entry(Items.SPORE_BLOSSOM, 1.0),
365 Map.entry(Items.STICK, 4.0),
366 Map.entry(Items.STRING, 12.0),
367 Map.entry(Items.STRUCTURE_BLOCK, -1.0),
368 Map.entry(Items.STRUCTURE_VOID, -1.0),
369 Map.entry(Items.SUGAR_CANE, 32.0),
370 Map.entry(Items.SUSPICIOUS_GRAVEL, 4.0),
371 Map.entry(Items.SWEET_BERRIES, 8.0),
372 Map.entry(Items.TALL_GRASS, 1.0),
373 Map.entry(Items.TIPPED_ARROW, -1.0),
374 Map.entry(Items.TORCHFLOWER_SEEDS, 8.0),
375 Map.entry(Items.TOTEM_OF_UNDYING, 4096.0),
376 Map.entry(Items.TURTLE_EGG, 32.0),
377 Map.entry(Items.TWISTING_VINES, 8.0),
378 Map.entry(Items.VINE, 8.0),
379 Map.entry(Items.WARPED_FUNGUS, 24.0),
380 Map.entry(Items.WARPED_ROOTS, 1.0),
381 Map.entry(Items.WARPED_WART_BLOCK, 1.0),
382 Map.entry(Items.WEEPING_VINES, 8.0),
383 Map.entry(Items.WET_SPONGE, 48.0),
384 Map.entry(Items.WHEAT, 24.0),
385 Map.entry(Items.WHEAT_SEEDS, 16.0),
386 Map.entry(Items.WITHER_SKELETON_SKULL, 34816.0),
387 Map.entry(Items.WRITTEN_BOOK, -1.0),
388 Map.entry(Items.ZOMBIE_HEAD, 34816.0),
389
390 Map.entry(PatchouliItems.BOOK, -1.0)
391 ));
392
393 SpawnEggItem.eggs().forEach(spawnEgg -> ITEM_COMMON_MAP.put(spawnEgg, -1.0));
394
395 CoralUtils.streamAllCoralBlocks().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
396 CoralUtils.streamAllDeadCoralBlocks().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
397 CoralUtils.streamAllCorals().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
398 CoralUtils.streamAllDeadCorals().forEach(block -> ITEM_COMMON_MAP.put(block.asItem(), 1.0));
399
400 BLOCK_TAG_COMMON_MAP.putAll(Map.ofEntries(
401 Map.entry(BlockTags.BASE_STONE_NETHER, 1.0),
402 Map.entry(BlockTags.BASE_STONE_OVERWORLD, 1.0),
403 Map.entry(BlockTags.NYLIUM, 1.0)
404 ));
405
406 ITEM_TAG_COMMON_MAP.putAll(Map.ofEntries(
407 Map.entry(ItemTags.COAL_ORES, -1.0),
408 Map.entry(ItemTags.COPPER_ORES, -1.0),
409 Map.entry(ItemTags.DIAMOND_ORES, -1.0),
410 Map.entry(ItemTags.DIRT, 1.0),
411 Map.entry(ItemTags.MUSIC_DISCS, 4096.0),
412 Map.entry(ItemTags.EMERALD_ORES, -1.0),
413 Map.entry(ItemTags.FISHES, 64.0),
414 Map.entry(ItemTags.FLOWERS, 16.0),
415 Map.entry(ItemTags.GOLD_ORES, -1.0),
416 Map.entry(ItemTags.IRON_ORES, -1.0),
417 Map.entry(ItemTags.LAPIS_ORES, -1.0),
418 Map.entry(ItemTags.LEAVES, 1.0),
419 Map.entry(ItemTags.LOGS, 32.0),
420 Map.entry(ItemTags.REDSTONE_ORES, -1.0),
421 Map.entry(ItemTags.SAND, 1.0),
422 Map.entry(ItemTags.SAPLINGS, 32.0),
423 Map.entry(ItemTags.WOOL, 48.0)
424 ));
425
426 FAKE_RECIPES.addAll(List.of(
427 // more oxidised coppers are worth less
428 new SimplifiedRecipe(new ItemStack(Items.EXPOSED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 3)),
429 new SimplifiedRecipe(new ItemStack(Items.WEATHERED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 2)),
430 new SimplifiedRecipe(new ItemStack(Items.OXIDIZED_COPPER, 4), new ItemStack(Items.COPPER_BLOCK, 1)),
431
432 new SimplifiedRecipe(new ItemStack(Items.WAXED_EXPOSED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 3)),
433 new SimplifiedRecipe(new ItemStack(Items.WAXED_WEATHERED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 2)),
434 new SimplifiedRecipe(new ItemStack(Items.WAXED_OXIDIZED_COPPER, 4), new ItemStack(Items.WAXED_COPPER_BLOCK, 1)),
435
436 // more damaged anvils are worth less
437 new SimplifiedRecipe(new ItemStack(Items.CHIPPED_ANVIL, 3), new ItemStack(Items.ANVIL, 2)),
438 new SimplifiedRecipe(new ItemStack(Items.DAMAGED_ANVIL, 3), new ItemStack(Items.ANVIL, 1)),
439
440 // old oak slabs are the same value as modern ones
441 new SimplifiedRecipe(Items.PETRIFIED_OAK_SLAB, Items.OAK_SLAB),
442
443 // chainmail armour is worth the same as normal iron armor
444 new SimplifiedRecipe(Items.CHAINMAIL_HELMET, Items.IRON_HELMET),
445 new SimplifiedRecipe(Items.CHAINMAIL_CHESTPLATE, Items.IRON_CHESTPLATE),
446 new SimplifiedRecipe(Items.CHAINMAIL_LEGGINGS, Items.IRON_LEGGINGS),
447 new SimplifiedRecipe(Items.CHAINMAIL_BOOTS, Items.IRON_BOOTS),
448
449 // enchanted golden apple is worth uhh 16 times the non-enchanted one :3
450 new SimplifiedRecipe(Items.ENCHANTED_GOLDEN_APPLE, new ItemStack(Items.GOLDEN_APPLE, 16)),
451
452 // carving a pumpkin with shears
453 new SimplifiedRecipe(Items.CARVED_PUMPKIN, List.of(new ItemStack(Items.PUMPKIN_SEEDS, 4)), Items.PUMPKIN),
454
455 // gathering honey
456 new SimplifiedRecipe(Items.HONEY_BOTTLE, Items.HONEYCOMB, Items.GLASS_BOTTLE),
457
458 // smithing template duplicating recipes but -1 templates on both sides
459 new SimplifiedRecipe(Items.COAST_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
460 new SimplifiedRecipe(Items.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.SANDSTONE)),
461 new SimplifiedRecipe(Items.EYE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.END_STONE)),
462 new SimplifiedRecipe(Items.HOST_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
463 new SimplifiedRecipe(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.NETHERRACK)),
464 new SimplifiedRecipe(Items.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
465 new SimplifiedRecipe(Items.RIB_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.NETHERRACK)),
466 new SimplifiedRecipe(Items.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
467 new SimplifiedRecipe(Items.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
468 new SimplifiedRecipe(Items.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLED_DEEPSLATE)),
469 new SimplifiedRecipe(Items.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.BLACKSTONE)),
470 new SimplifiedRecipe(Items.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.PURPUR_BLOCK)),
471 new SimplifiedRecipe(Items.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.PRISMARINE)),
472 new SimplifiedRecipe(Items.VEX_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLESTONE)),
473 new SimplifiedRecipe(Items.WARD_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.COBBLED_DEEPSLATE)),
474 new SimplifiedRecipe(Items.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.TERRACOTTA)),
475 new SimplifiedRecipe(Items.WILD_ARMOR_TRIM_SMITHING_TEMPLATE, new ItemStack(Items.DIAMOND, 7), new ItemStack(Items.MOSSY_COBBLESTONE)),
476
477 // water bucket = bucket + water, water assumed to be same value as cobblestone
478 new SimplifiedRecipe(Items.WATER_BUCKET, Items.BUCKET, Items.COBBLESTONE),
479
480 // lava bucket = bucket + lava, lava assumed to be same value as obsidian
481 new SimplifiedRecipe(Items.LAVA_BUCKET, Items.BUCKET, Items.OBSIDIAN),
482
483 // powder snow bucket = bucket + snow
484 new SimplifiedRecipe(Items.POWDER_SNOW_BUCKET, Items.BUCKET, Items.SNOW_BLOCK),
485
486 // milk bucket = bucket + milk, milk assumed to be same value as wheat
487 new SimplifiedRecipe(Items.MILK_BUCKET, Items.BUCKET, Items.WHEAT),
488
489 // [fish] bucket = bucket + [fish]
490 new SimplifiedRecipe(Items.COD_BUCKET, Items.BUCKET, Items.COD),
491 new SimplifiedRecipe(Items.PUFFERFISH_BUCKET, Items.BUCKET, Items.PUFFERFISH),
492 new SimplifiedRecipe(Items.SALMON_BUCKET, Items.BUCKET, Items.SALMON),
493 new SimplifiedRecipe(Items.TROPICAL_FISH_BUCKET, Items.BUCKET, Items.TROPICAL_FISH),
494
495 // yep
496 new SimplifiedRecipe(Items.AXOLOTL_BUCKET, Items.TROPICAL_FISH_BUCKET),
497 new SimplifiedRecipe(Items.TADPOLE_BUCKET, Items.AXOLOTL_BUCKET),
498
499 // dye value is the canon
500 new SimplifiedRecipe(Items.INK_SAC, Items.BLACK_DYE),
501
502 // disc value is the canon
503 new SimplifiedRecipe(new ItemStack(Items.DISC_FRAGMENT_5, 9), Items.MUSIC_DISC_5),
504
505 // glowing ink sac is more expensive than an ink sac
506 new SimplifiedRecipe(Items.GLOW_INK_SAC, new ItemStack(Items.INK_SAC, 4)),
507
508 // activated maps cost the same as unactivated ones
509 new SimplifiedRecipe(Items.FILLED_MAP, Items.MAP),
510
511 // poisonous potato costs less than a normal one
512 new SimplifiedRecipe(new ItemStack(Items.POISONOUS_POTATO, 2), Items.POTATO),
513
514 // rabbits foot costs more than rabbit meat
515 new SimplifiedRecipe(Items.RABBIT_FOOT, new ItemStack(Items.RABBIT, 8)),
516
517 // [X] horse armor == [X] leggings
518 // wtf, why? see how much leather is used by leather horse armor
519 new SimplifiedRecipe(Items.IRON_HORSE_ARMOR, Items.IRON_LEGGINGS),
520 new SimplifiedRecipe(Items.GOLDEN_HORSE_ARMOR, Items.GOLDEN_LEGGINGS),
521 new SimplifiedRecipe(Items.DIAMOND_HORSE_ARMOR, Items.DIAMOND_LEGGINGS),
522
523 // Trident = 1.5 * iron sword
524 new SimplifiedRecipe(new ItemStack(Items.TRIDENT, 2), new ItemStack(Items.IRON_SWORD, 3)),
525
526 // an actual recipe but it's special, minecraft:crafting_special_suspiciousstew
527 new SimplifiedRecipe(Items.SUSPICIOUS_STEW, Items.BOWL, Items.BROWN_MUSHROOM, Items.RED_MUSHROOM, Items.POPPY),
528
529 // obvious
530 new SimplifiedRecipe(Items.GLOBE_BANNER_PATTERN, Items.CREEPER_BANNER_PATTERN),
531 new SimplifiedRecipe(Items.PIGLIN_BANNER_PATTERN, Items.CREEPER_BANNER_PATTERN),
532
533 // the vibes fit
534 new SimplifiedRecipe(Items.BELL, Items.SPYGLASS),
535
536 // light sources, shroomlight has no crafting uses but is brighter
537 new SimplifiedRecipe(Items.SHROOMLIGHT, Items.GLOWSTONE),
538
539 // bee nest = honeycomb block
540 new SimplifiedRecipe(Items.BEE_NEST, new ItemStack(Items.HONEYCOMB, 9)),
541
542 // gilded blackstone = blackstone with gold nuggets
543 new SimplifiedRecipe(Items.GILDED_BLACKSTONE, new ItemStack(Items.BLACKSTONE), new ItemStack(Items.GOLD_NUGGET, 4)),
544
545 // froglight = eaten magma cube
546 new SimplifiedRecipe(Items.OCHRE_FROGLIGHT, Items.MAGMA_CREAM),
547 new SimplifiedRecipe(Items.PEARLESCENT_FROGLIGHT, Items.MAGMA_CREAM),
548 new SimplifiedRecipe(Items.VERDANT_FROGLIGHT, Items.MAGMA_CREAM),
549
550 // UPGRADE[1.20.1]: currently experimental stuff
551 new SimplifiedRecipe(Items.BUNDLE, new ItemStack(Items.RABBIT_HIDE, 6), new ItemStack(Items.STRING, 2))
552 ));
553
554 // pot sherds can be replaced with bricks when making decorated pots
555 ItemUtils.streamTag(ItemTags.DECORATED_POT_SHERDS).forEach(sherd -> FAKE_RECIPES.add(new SimplifiedRecipe(sherd, Items.BRICK)));
556
557 for (var color : DyeColor.values()) {
558 ITEM_COMMON_MAP.put(DyeUtils.getDye(color), 8.0);
559 FAKE_RECIPES.addAll(List.of(
560 // putting concrete powder in water
561 new SimplifiedRecipe(DyeUtils.getConcrete(color), DyeUtils.getConcretePowder(color)),
562
563 // an actual recipe but it's special, minecraft:crafting_special_shulkerboxcoloring
564 new SimplifiedRecipe(DyeUtils.getShulkerBox(color), Items.SHULKER_BOX, DyeUtils.getDye(color))
565 ));
566 }
567 }
568}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java
index 724b9c4..a4368fc 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemy.java
@@ -8,6 +8,7 @@ import net.minecraft.resources.ResourceLocation;
8import net.minecraft.world.item.CreativeModeTab; 8import net.minecraft.world.item.CreativeModeTab;
9import net.minecraft.world.item.Item; 9import net.minecraft.world.item.Item;
10import net.minecraft.world.item.ItemStack; 10import net.minecraft.world.item.ItemStack;
11import net.minecraft.world.item.Rarity;
11import org.quiltmc.loader.api.ModContainer; 12import org.quiltmc.loader.api.ModContainer;
12import org.quiltmc.qsl.base.api.entrypoint.ModInitializer; 13import org.quiltmc.qsl.base.api.entrypoint.ModInitializer;
13import org.quiltmc.qsl.item.setting.api.QuiltItemSettings; 14import org.quiltmc.qsl.item.setting.api.QuiltItemSettings;
@@ -18,24 +19,9 @@ public class ErisAlchemy implements ModInitializer {
18 public static final String ID = "eris_alchemy"; 19 public static final String ID = "eris_alchemy";
19 public static final Logger LOGGER = LoggerFactory.getLogger(ID); 20 public static final Logger LOGGER = LoggerFactory.getLogger(ID);
20 21
21 // Aside from crafting recipe inputs, covalence dusts can be used to repair equipment via shapeless crafting 22 public static final Item LOW_COVALENCE_DUST = new Item(new QuiltItemSettings().rarity(Rarity.COMMON));
22 // Low covalence dust: 23 public static final Item MEDIUM_COVALENCE_DUST = new Item(new QuiltItemSettings().rarity(Rarity.UNCOMMON));
23 // - wooden and stone tools 24 public static final Item HIGH_COVALENCE_DUST = new Item(new QuiltItemSettings().rarity(Rarity.RARE));
24 // - leather armour
25 // - fishing rods
26 // - wooden bows
27 // - turtle shells
28 // Medium covalence dust:
29 // - iron, gold, bronze, ruby, sapphire, and green sapphire tools and armour
30 // - flints & steels
31 // - shears
32 // - elytras
33 // High covalence dust:
34 // - diamond and netherite tools and armour
35 // 8 dusts are enough to repair 100% :3
36 public static final Item LOW_COVALENCE_DUST = new Item(new QuiltItemSettings());
37 public static final Item MEDIUM_COVALENCE_DUST = new Item(new QuiltItemSettings());
38 public static final Item HIGH_COVALENCE_DUST = new Item(new QuiltItemSettings());
39 25
40 public static final CreativeModeTab ITEM_GROUP = FabricItemGroup.builder() 26 public static final CreativeModeTab ITEM_GROUP = FabricItemGroup.builder()
41 .icon(() -> new ItemStack(LOW_COVALENCE_DUST)) 27 .icon(() -> new ItemStack(LOW_COVALENCE_DUST))
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/SubAxe.java b/src/main/java/lv/enes/mc/eris_alchemy/SubAxe.java
new file mode 100644
index 0000000..045a5a1
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/SubAxe.java
@@ -0,0 +1,18 @@
1package lv.enes.mc.eris_alchemy;
2
3import net.minecraft.world.item.AxeItem;
4import net.minecraft.world.item.Tier;
5import net.minecraft.world.level.block.Block;
6
7import java.util.Map;
8
9/** The only reason this exists is to read STRIPPABLES property from AxeItem :3 */
10public abstract class SubAxe extends AxeItem {
11 public static Map<Block, Block> getStrippables() {
12 return STRIPPABLES;
13 }
14
15 private SubAxe(Tier material, float attackDamage, float attackSpeed, Properties settings) {
16 super(material, attackDamage, attackSpeed, settings);
17 }
18}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralBlockMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralBlockMixin.java
new file mode 100644
index 0000000..d8024c9
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralBlockMixin.java
@@ -0,0 +1,20 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.CoralUtils;
4import net.minecraft.world.level.block.Block;
5import net.minecraft.world.level.block.CoralBlock;
6import org.spongepowered.asm.mixin.Final;
7import org.spongepowered.asm.mixin.Mixin;
8import org.spongepowered.asm.mixin.Shadow;
9
10@Mixin(CoralBlock.class)
11public abstract class CoralBlockMixin implements CoralUtils.CoralSuper {
12 @Final
13 @Shadow
14 private Block deadBlock;
15
16 @Override
17 public Block lv_enes_mc$getDead() {
18 return deadBlock;
19 }
20}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralFanBlockMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralFanBlockMixin.java
new file mode 100644
index 0000000..86ab8f6
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralFanBlockMixin.java
@@ -0,0 +1,20 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.CoralUtils;
4import net.minecraft.world.level.block.Block;
5import net.minecraft.world.level.block.CoralFanBlock;
6import org.spongepowered.asm.mixin.Final;
7import org.spongepowered.asm.mixin.Mixin;
8import org.spongepowered.asm.mixin.Shadow;
9
10@Mixin(CoralFanBlock.class)
11public abstract class CoralFanBlockMixin implements CoralUtils.CoralSuper {
12 @Final
13 @Shadow
14 private Block deadBlock;
15
16 @Override
17 public Block lv_enes_mc$getDead() {
18 return deadBlock;
19 }
20}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralPlantBlockMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralPlantBlockMixin.java
new file mode 100644
index 0000000..a5614f9
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralPlantBlockMixin.java
@@ -0,0 +1,20 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.CoralUtils;
4import net.minecraft.world.level.block.Block;
5import net.minecraft.world.level.block.CoralPlantBlock;
6import org.spongepowered.asm.mixin.Final;
7import org.spongepowered.asm.mixin.Mixin;
8import org.spongepowered.asm.mixin.Shadow;
9
10@Mixin(CoralPlantBlock.class)
11public abstract class CoralPlantBlockMixin implements CoralUtils.CoralSuper {
12 @Final
13 @Shadow
14 private Block deadBlock;
15
16 @Override
17 public Block lv_enes_mc$getDead() {
18 return deadBlock;
19 }
20}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralWallFanBlockMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralWallFanBlockMixin.java
new file mode 100644
index 0000000..8ffa07e
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/CoralWallFanBlockMixin.java
@@ -0,0 +1,20 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.CoralUtils;
4import net.minecraft.world.level.block.Block;
5import net.minecraft.world.level.block.CoralWallFanBlock;
6import org.spongepowered.asm.mixin.Final;
7import org.spongepowered.asm.mixin.Mixin;
8import org.spongepowered.asm.mixin.Shadow;
9
10@Mixin(CoralWallFanBlock.class)
11public abstract class CoralWallFanBlockMixin implements CoralUtils.CoralSuper {
12 @Final
13 @Shadow
14 private Block deadBlock;
15
16 @Override
17 public Block lv_enes_mc$getDead() {
18 return deadBlock;
19 }
20}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java
index 54a2fd0..aa6270b 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ItemMixin.java
@@ -1,21 +1,32 @@
1package lv.enes.mc.eris_alchemy.mixin; 1package lv.enes.mc.eris_alchemy.mixin;
2 2
3import lv.enes.mc.eris_alchemy.EMC;
3import net.minecraft.network.chat.Component; 4import net.minecraft.network.chat.Component;
4import net.minecraft.world.item.Item; 5import net.minecraft.world.item.Item;
5import net.minecraft.world.item.ItemStack; 6import net.minecraft.world.item.ItemStack;
6import net.minecraft.world.item.TooltipFlag; 7import net.minecraft.world.item.TooltipFlag;
7import net.minecraft.world.level.Level; 8import net.minecraft.world.level.Level;
8import org.spongepowered.asm.mixin.Mixin; 9import org.spongepowered.asm.mixin.Mixin;
10import org.spongepowered.asm.mixin.Unique;
9import org.spongepowered.asm.mixin.injection.At; 11import org.spongepowered.asm.mixin.injection.At;
10import org.spongepowered.asm.mixin.injection.Inject; 12import org.spongepowered.asm.mixin.injection.Inject;
11import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
12 14
15import java.text.DecimalFormat;
13import java.util.List; 16import java.util.List;
14 17
15@Mixin(Item.class) 18@Mixin(Item.class)
16public class ItemMixin { 19public abstract class ItemMixin {
20 @Unique
21 private static final DecimalFormat doubleFormat = new DecimalFormat("0");
22
23 static {
24 doubleFormat.setMaximumFractionDigits(1);
25 }
26
17 @Inject(method = "appendHoverText", at = @At("RETURN")) 27 @Inject(method = "appendHoverText", at = @At("RETURN"))
18 public void onAppendHoverText(ItemStack stack, Level world, List<Component> tooltip, TooltipFlag context, CallbackInfo ci) { 28 public void onAppendHoverText(ItemStack stack, Level world, List<Component> tooltip, TooltipFlag context, CallbackInfo ci) {
19 tooltip.add(Component.literal("EMC ???")); 29 var emc = EMC.getInstance(world).get(stack.getItem());
30 emc.ifPresent(value -> tooltip.add(Component.literal("EMC %s".formatted(doubleFormat.format(value)))));
20 } 31 }
21} 32}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/RecipeMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/RecipeMixin.java
new file mode 100644
index 0000000..43051e4
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/RecipeMixin.java
@@ -0,0 +1,29 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.RecipeUtils;
4import net.minecraft.core.NonNullList;
5import net.minecraft.core.RegistryAccess;
6import net.minecraft.world.item.ItemStack;
7import net.minecraft.world.item.crafting.Ingredient;
8import net.minecraft.world.item.crafting.Recipe;
9import org.spongepowered.asm.mixin.Mixin;
10import org.spongepowered.asm.mixin.Shadow;
11
12@Mixin(Recipe.class)
13public interface RecipeMixin extends RecipeUtils.RecipeSuper {
14 @Shadow
15 NonNullList<Ingredient> getIngredients();
16
17 @Shadow
18 ItemStack getResultItem(RegistryAccess registryAccess);
19
20 @Override
21 default NonNullList<Ingredient> lv_enes_mc$getIngredients() {
22 return getIngredients();
23 }
24
25 @Override
26 default ItemStack lv_enes_mc$getOutput(RegistryAccess registryAccess) {
27 return getResultItem(registryAccess);
28 }
29}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/SmithingTransformRecipeMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/SmithingTransformRecipeMixin.java
new file mode 100644
index 0000000..bcf49b0
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/SmithingTransformRecipeMixin.java
@@ -0,0 +1,28 @@
1package lv.enes.mc.eris_alchemy.mixin;
2
3import lv.enes.mc.eris_alchemy.utils.RecipeUtils;
4import net.minecraft.world.item.crafting.Ingredient;
5import net.minecraft.world.item.crafting.SmithingTransformRecipe;
6import org.spongepowered.asm.mixin.Final;
7import org.spongepowered.asm.mixin.Mixin;
8import org.spongepowered.asm.mixin.Shadow;
9
10import java.util.List;
11
12@Mixin(SmithingTransformRecipe.class)
13public abstract class SmithingTransformRecipeMixin implements RecipeUtils.RecipeSuper {
14 @Final
15 @Shadow
16 Ingredient template;
17 @Final
18 @Shadow
19 Ingredient base;
20 @Final
21 @Shadow
22 Ingredient addition;
23
24 @Override
25 public List<Ingredient> lv_enes_mc$getIngredients() {
26 return List.of(template, base, addition);
27 }
28}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/BlockUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/BlockUtils.java
new file mode 100644
index 0000000..74b6069
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/BlockUtils.java
@@ -0,0 +1,13 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.core.registries.BuiltInRegistries;
4import net.minecraft.tags.TagKey;
5import net.minecraft.world.level.block.Block;
6
7import java.util.stream.Stream;
8
9public class BlockUtils {
10 public static Stream<Block> streamTag(TagKey<Block> tag) {
11 return TagUtils.stream(BuiltInRegistries.BLOCK, tag);
12 }
13}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/CoralUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/CoralUtils.java
new file mode 100644
index 0000000..c9203c6
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/CoralUtils.java
@@ -0,0 +1,42 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.tags.BlockTags;
4import net.minecraft.world.level.block.*;
5
6import java.util.stream.Stream;
7
8public class CoralUtils {
9 /**
10 * @see lv.enes.mc.eris_alchemy.mixin.CoralBlockMixin
11 * @see lv.enes.mc.eris_alchemy.mixin.CoralFanBlockMixin
12 * @see lv.enes.mc.eris_alchemy.mixin.CoralPlantBlockMixin
13 * @see lv.enes.mc.eris_alchemy.mixin.CoralWallFanBlockMixin
14 */
15 public interface CoralSuper {
16 Block lv_enes_mc$getDead();
17 }
18
19 public static Stream<CoralBlock> streamAllCoralBlocks() {
20 return BlockUtils.streamTag(BlockTags.CORAL_BLOCKS).map(b -> (CoralBlock)b);
21 }
22
23 public static Stream<BaseCoralPlantTypeBlock> streamAllCorals() {
24 return BlockUtils.streamTag(BlockTags.CORALS).map(b -> (BaseCoralPlantTypeBlock)b);
25 }
26
27 public static Stream<Block> streamAllDeadCoralBlocks() {
28 return streamAllCoralBlocks().map(CoralUtils::getDeadCoralBlock);
29 }
30
31 public static Stream<Block> streamAllDeadCorals() {
32 return streamAllCorals().map(CoralUtils::getDeadCoral);
33 }
34
35 public static Block getDeadCoral(BaseCoralPlantTypeBlock live ) {
36 return ((CoralSuper)live).lv_enes_mc$getDead();
37 }
38
39 public static Block getDeadCoralBlock(CoralBlock live) {
40 return ((CoralSuper)live).lv_enes_mc$getDead();
41 }
42}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/DyeUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/DyeUtils.java
new file mode 100644
index 0000000..83c8e04
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/DyeUtils.java
@@ -0,0 +1,60 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.world.item.DyeColor;
4import net.minecraft.world.item.DyeItem;
5import net.minecraft.world.level.block.Block;
6import net.minecraft.world.level.block.Blocks;
7import net.minecraft.world.level.block.ConcretePowderBlock;
8import net.minecraft.world.level.block.ShulkerBoxBlock;
9
10public class DyeUtils {
11 public static Block getConcrete(DyeColor color) {
12 return switch (color) {
13 case BLACK -> Blocks.BLACK_CONCRETE;
14 case BLUE -> Blocks.BLUE_CONCRETE;
15 case BROWN -> Blocks.BROWN_CONCRETE;
16 case CYAN -> Blocks.CYAN_CONCRETE;
17 case GRAY -> Blocks.GRAY_CONCRETE;
18 case GREEN -> Blocks.GREEN_CONCRETE;
19 case LIGHT_BLUE -> Blocks.LIGHT_BLUE_CONCRETE;
20 case LIGHT_GRAY -> Blocks.LIGHT_GRAY_CONCRETE;
21 case LIME -> Blocks.LIME_CONCRETE;
22 case MAGENTA -> Blocks.MAGENTA_CONCRETE;
23 case ORANGE -> Blocks.ORANGE_CONCRETE;
24 case PINK -> Blocks.PINK_CONCRETE;
25 case PURPLE -> Blocks.PURPLE_CONCRETE;
26 case RED -> Blocks.RED_CONCRETE;
27 case WHITE -> Blocks.WHITE_CONCRETE;
28 case YELLOW -> Blocks.YELLOW_CONCRETE;
29 };
30 }
31
32 public static ConcretePowderBlock getConcretePowder(DyeColor color) {
33 return (ConcretePowderBlock)switch (color) {
34 case BLACK -> Blocks.BLACK_CONCRETE_POWDER;
35 case BLUE -> Blocks.BLUE_CONCRETE_POWDER;
36 case BROWN -> Blocks.BROWN_CONCRETE_POWDER;
37 case CYAN -> Blocks.CYAN_CONCRETE_POWDER;
38 case GRAY -> Blocks.GRAY_CONCRETE_POWDER;
39 case GREEN -> Blocks.GREEN_CONCRETE_POWDER;
40 case LIGHT_BLUE -> Blocks.LIGHT_BLUE_CONCRETE_POWDER;
41 case LIGHT_GRAY -> Blocks.LIGHT_GRAY_CONCRETE_POWDER;
42 case LIME -> Blocks.LIME_CONCRETE_POWDER;
43 case MAGENTA -> Blocks.MAGENTA_CONCRETE_POWDER;
44 case ORANGE -> Blocks.ORANGE_CONCRETE_POWDER;
45 case PINK -> Blocks.PINK_CONCRETE_POWDER;
46 case PURPLE -> Blocks.PURPLE_CONCRETE_POWDER;
47 case RED -> Blocks.RED_CONCRETE_POWDER;
48 case WHITE -> Blocks.WHITE_CONCRETE_POWDER;
49 case YELLOW -> Blocks.YELLOW_CONCRETE_POWDER;
50 };
51 }
52
53 public static DyeItem getDye(DyeColor color) {
54 return DyeItem.byColor(color);
55 }
56
57 public static ShulkerBoxBlock getShulkerBox(DyeColor color) {
58 return (ShulkerBoxBlock)ShulkerBoxBlock.getBlockByColor(color);
59 }
60}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/ItemUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/ItemUtils.java
new file mode 100644
index 0000000..2f7c8b2
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/ItemUtils.java
@@ -0,0 +1,13 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.core.registries.BuiltInRegistries;
4import net.minecraft.tags.TagKey;
5import net.minecraft.world.item.Item;
6
7import java.util.stream.Stream;
8
9public class ItemUtils {
10 public static Stream<Item> streamTag(TagKey<Item> tag) {
11 return TagUtils.stream(BuiltInRegistries.ITEM, tag);
12 }
13}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/RecipeUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/RecipeUtils.java
new file mode 100644
index 0000000..53ceaab
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/RecipeUtils.java
@@ -0,0 +1,23 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.core.RegistryAccess;
4import net.minecraft.world.item.ItemStack;
5import net.minecraft.world.item.crafting.Ingredient;
6import net.minecraft.world.item.crafting.Recipe;
7
8import java.util.List;
9
10public class RecipeUtils {
11 public interface RecipeSuper {
12 List<Ingredient> lv_enes_mc$getIngredients();
13 ItemStack lv_enes_mc$getOutput(RegistryAccess registryAccess);
14 }
15
16 public static List<Ingredient> getIngredients(Recipe<?> recipe) {
17 return ((RecipeSuper)recipe).lv_enes_mc$getIngredients();
18 }
19
20 public static ItemStack getOutput(Recipe<?> recipe, RegistryAccess registryAccess) {
21 return ((RecipeSuper)recipe).lv_enes_mc$getOutput(registryAccess);
22 }
23}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/TagUtils.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/TagUtils.java
new file mode 100644
index 0000000..bb923ba
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/TagUtils.java
@@ -0,0 +1,14 @@
1package lv.enes.mc.eris_alchemy.utils;
2
3import net.minecraft.core.Holder;
4import net.minecraft.core.Registry;
5import net.minecraft.tags.TagKey;
6
7import java.util.stream.Stream;
8import java.util.stream.StreamSupport;
9
10public class TagUtils {
11 public static <T> Stream<T> stream(Registry<T> registry, TagKey<T> tag) {
12 return StreamSupport.stream(registry.getTagOrEmpty(tag).spliterator(), false).map(Holder::value);
13 }
14}
diff --git a/src/main/resources/assets/eris_alchemy/patchouli_books/guide_book/en_us/entries/root/covalence_dusts.json b/src/main/resources/assets/eris_alchemy/patchouli_books/guide_book/en_us/entries/root/covalence_dusts.json
index 09c10ca..a55ae50 100644
--- a/src/main/resources/assets/eris_alchemy/patchouli_books/guide_book/en_us/entries/root/covalence_dusts.json
+++ b/src/main/resources/assets/eris_alchemy/patchouli_books/guide_book/en_us/entries/root/covalence_dusts.json
@@ -24,7 +24,7 @@
24 "text": "$(item)Low Covalence Dust$() can be used to repair$(li)$(thing)Wooden tools$(),$(li)$(thing)Stone tools$(),$(li)$(thing)Leather armour$(),$(li)$(thing)Turtle shell armour$(),$(li)$(item)Fishing rods$(), and$(li)$(item)Bows$()." 24 "text": "$(item)Low Covalence Dust$() can be used to repair$(li)$(thing)Wooden tools$(),$(li)$(thing)Stone tools$(),$(li)$(thing)Leather armour$(),$(li)$(thing)Turtle shell armour$(),$(li)$(item)Fishing rods$(), and$(li)$(item)Bows$()."
25 }, { 25 }, {
26 "type": "patchouli:text", 26 "type": "patchouli:text",
27 "text": "$(item)Medium Covalence Dust$() can be used to repair$(li)$(thing)Iron tools and armour$(),$(li)$(thing)Gold tools and armour$(),$(li)$(thing)Bronze tools and armour$() (if you have any),$(li)$(thing)Ruby tools and armour$() (if you have any),$(li)$(thing)Sapphire tools and armour$() (if you have any),$(li)$(thing)Green sapphire tools and armour$() (if you have any),$(li)$(item)Elytras$(),$(li)$(item)Flint and Steel$(), and$(li)$(item)Shears$()." 27 "text": "$(item)Medium Covalence Dust$() can be used to repair$(li)$(thing)Chainmail tools and armour$(),$(li)$(thing)Iron tools and armour$(),$(li)$(thing)Gold tools and armour$(),$(li)$(thing)Bronze tools and armour$() (if you have any),$(li)$(thing)Ruby tools and armour$() (if you have any),$(li)$(thing)Sapphire tools and armour$() (if you have any),$(li)$(thing)Green sapphire tools and armour$() (if you have any),$(li)$(item)Elytras$(),$(li)$(item)Flint and Steel$(),$(li)$(item)Shears$(), and$(li)$(item)Tridents$()."
28 }, { 28 }, {
29 "type": "patchouli:text", 29 "type": "patchouli:text",
30 "text": "$(item)High Covalence Dust$() can be used to repair$(li)$(thing)Diamond tools and armour$() and$(li)$(thing)Netherite tools and armour$()." 30 "text": "$(item)High Covalence Dust$() can be used to repair$(li)$(thing)Diamond tools and armour$() and$(li)$(thing)Netherite tools and armour$()."
diff --git a/src/main/resources/data/eris_alchemy/recipes/medium_covalence_repair.json b/src/main/resources/data/eris_alchemy/recipes/medium_covalence_repair.json
index a75bf89..a7c70ad 100644
--- a/src/main/resources/data/eris_alchemy/recipes/medium_covalence_repair.json
+++ b/src/main/resources/data/eris_alchemy/recipes/medium_covalence_repair.json
@@ -22,5 +22,7 @@
22 "item": "minecraft:flint_and_steel" 22 "item": "minecraft:flint_and_steel"
23 }, { 23 }, {
24 "item": "minecraft:shears" 24 "item": "minecraft:shears"
25 }, {
26 "item": "minecraft:trident"
25 }] 27 }]
26} \ No newline at end of file 28} \ No newline at end of file
diff --git a/src/main/resources/eris_alchemy.mixins.json b/src/main/resources/eris_alchemy.mixins.json
index 88e1a8c..1fdb6bd 100644
--- a/src/main/resources/eris_alchemy.mixins.json
+++ b/src/main/resources/eris_alchemy.mixins.json
@@ -3,9 +3,14 @@
3 "minVersion": "0.8", 3 "minVersion": "0.8",
4 "package": "lv.enes.mc.eris_alchemy.mixin", 4 "package": "lv.enes.mc.eris_alchemy.mixin",
5 "compatibilityLevel": "JAVA_17", 5 "compatibilityLevel": "JAVA_17",
6 "mixins": [], 6 "mixins": [
7 "client": [ 7 "CoralBlockMixin",
8 "ItemMixin" 8 "CoralFanBlockMixin",
9 "CoralPlantBlockMixin",
10 "CoralWallFanBlockMixin",
11 "ItemMixin",
12 "RecipeMixin",
13 "SmithingTransformRecipeMixin"
9 ], 14 ],
10 "injectors": { 15 "injectors": {
11 "defaultRequire": 1 16 "defaultRequire": 1