From 6cc0322aacd36bbf325d3e08b7fa0b76d2eb0e5a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 16 Apr 2024 18:32:47 +0900 Subject: Add anvil recipes, Close #1381 --- .../rei/plugin/client/DefaultClientPlugin.java | 63 ++++++++++++++++++++++ .../categories/anvil/DefaultAnvilCategory.java | 16 +++++- 2 files changed, 77 insertions(+), 2 deletions(-) (limited to 'default-plugin/src/main/java/me/shedaniel/rei/plugin/client') diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java index 239b95e2e..b3b94b9e3 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java @@ -96,6 +96,7 @@ import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.PotionUtils; import net.minecraft.world.item.crafting.*; +import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.ComposterBlock; @@ -104,11 +105,13 @@ import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.util.*; import java.util.function.Supplier; import java.util.function.UnaryOperator; +import java.util.stream.IntStream; import java.util.stream.Stream; @Environment(EnvType.CLIENT) @@ -355,6 +358,66 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin registerForgePotions(registry, this); } + for (Item item : Registry.ITEM) { + ItemStack stack = item.getDefaultInstance(); + if (!stack.isDamageableItem()) continue; + EntryIngredient repairMaterialBase = null; + if (item instanceof TieredItem tieredItem) { + Tier tier = tieredItem.getTier(); + repairMaterialBase = EntryIngredients.ofIngredient(tier.getRepairIngredient()); + } else if (item instanceof ArmorItem armorItem) { + ArmorMaterial material = armorItem.getMaterial(); + repairMaterialBase = EntryIngredients.ofIngredient(material.getRepairIngredient()); + } else if (item instanceof ShieldItem shieldItem) { + repairMaterialBase = EntryIngredients.ofItemTag(ItemTags.PLANKS); + repairMaterialBase.filter(s -> shieldItem.isValidRepairItem(stack, s.castValue())); + } else if (item instanceof ElytraItem elytraItem) { + repairMaterialBase = EntryIngredients.of(Items.PHANTOM_MEMBRANE); + repairMaterialBase.filter(s -> elytraItem.isValidRepairItem(stack, s.castValue())); + } + if (repairMaterialBase == null || repairMaterialBase.isEmpty()) continue; + for (int[] i = {1}; i[0] <= 4; i[0]++) { + ItemStack baseStack = item.getDefaultInstance(); + int toRepair = i[0] == 4 ? item.getMaxDamage() : baseStack.getMaxDamage() / 4 * i[0]; + baseStack.setDamageValue(toRepair); + EntryIngredient repairMaterial = repairMaterialBase.map(s -> { + EntryStack newStack = s.copy(); + newStack.castValue().setCount(i[0]); + return newStack; + }); + Optional> output = DefaultAnvilDisplay.calculateOutput(baseStack, repairMaterial.get(0).castValue()); + if (output.isEmpty()) continue; + registry.add(new DefaultAnvilDisplay(List.of(EntryIngredients.of(baseStack), repairMaterial), + Collections.singletonList(EntryIngredients.of(output.get().getLeft())), Optional.empty(), OptionalInt.of(output.get().getRight()))); + } + } + List> enchantmentBooks = Registry.ENCHANTMENT.stream() + .flatMap(enchantment -> { + if (enchantment.getMaxLevel() - enchantment.getMinLevel() >= 10) { + return IntStream.of(enchantment.getMinLevel(), enchantment.getMaxLevel()) + .mapToObj(lvl -> new EnchantmentInstance(enchantment, lvl)); + } else { + return IntStream.rangeClosed(enchantment.getMinLevel(), enchantment.getMaxLevel()) + .mapToObj(lvl -> new EnchantmentInstance(enchantment, lvl)); + } + }) + .map(instance -> { + return Pair.of(instance, EnchantedBookItem.createForEnchantment(instance)); + }) + .toList(); + EntryRegistry.getInstance().getEntryStacks().forEach(stack -> { + if (stack.getType() != VanillaEntryTypes.ITEM) return; + ItemStack itemStack = stack.castValue(); + if (!itemStack.isEnchantable()) return; + for (Pair pair : enchantmentBooks) { + if (!pair.getKey().enchantment.canEnchant(itemStack)) continue; + Optional> output = DefaultAnvilDisplay.calculateOutput(itemStack, pair.getValue()); + if (output.isEmpty()) continue; + registry.add(new DefaultAnvilDisplay(List.of(EntryIngredients.of(itemStack), EntryIngredients.of(pair.getValue())), + Collections.singletonList(EntryIngredients.of(output.get().getLeft())), Optional.empty(), OptionalInt.of(output.get().getRight()))); + } + }); + for (Registry reg : Registry.REGISTRY) { reg.getTags().forEach(tagPair -> registry.add(tagPair.getFirst())); } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/anvil/DefaultAnvilCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/anvil/DefaultAnvilCategory.java index f8c16278e..efcd41b1f 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/anvil/DefaultAnvilCategory.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/anvil/DefaultAnvilCategory.java @@ -34,6 +34,9 @@ import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.util.EntryStacks; import me.shedaniel.rei.plugin.common.BuiltinPlugin; import me.shedaniel.rei.plugin.common.displays.anvil.DefaultAnvilDisplay; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiComponent; import net.minecraft.network.chat.Component; import net.minecraft.world.level.block.Blocks; @@ -57,7 +60,7 @@ public class DefaultAnvilCategory implements DisplayCategory setupDisplay(DefaultAnvilDisplay display, Rectangle bounds) { - Point startPoint = new Point(bounds.getCenterX() - 31, bounds.getCenterY() - 13); + Point startPoint = new Point(bounds.getCenterX() - 31, bounds.getCenterY() - (display.getCost().isPresent() ? 20 : 13)); List widgets = Lists.newArrayList(); widgets.add(Widgets.createRecipeBase(bounds)); widgets.add(Widgets.createArrow(new Point(startPoint.x + 27, startPoint.y + 4))); @@ -65,11 +68,20 @@ public class DefaultAnvilCategory implements DisplayCategory { + Font font = Minecraft.getInstance().font; + Component component = Component.translatable("container.repair.cost", display.getCost().getAsInt()); + int x = startPoint.x + 102 - font.width(component) - 2; + GuiComponent.fill(matrices, x - 2, startPoint.y + 28, startPoint.x + 102, startPoint.y + 28 + 12, 0x4f000000); + font.drawShadow(matrices, component, x, startPoint.y + 28 + 2, 0x80ff20); + })); + } return widgets; } @Override public int getDisplayHeight() { - return 36; + return 48; } } -- cgit