From 115ce76b5acf4a517583cfc36101d8bd811621e2 Mon Sep 17 00:00:00 2001 From: Aleksey Date: Tue, 6 Oct 2020 17:59:23 +0300 Subject: [PATCH] Anvil crafting --- .../betterend/compat/REIAlloyingDisplay.java | 2 +- .../ru/betterend/compat/REIAnvilCategory.java | 85 +++++++++++++++++++ .../ru/betterend/compat/REIAnvilDisplay.java | 71 ++++++++++++++++ .../ru/betterend/compat/REIContainer.java | 1 - .../java/ru/betterend/compat/REIPlugin.java | 21 ++++- .../mixin/client/ClientRecipeBookMixin.java | 1 + .../mixin/common/AnvilScreenHandlerMixin.java | 69 +++++++++------ .../ru/betterend/recipe/AlloyingRecipe.java | 4 +- .../betterend/recipe/AnvilSmithingRecipe.java | 62 ++++++++------ .../ru/betterend/registry/ItemRegistry.java | 2 +- .../betterend/registry/ItemTagRegistry.java | 2 + .../data/fabric/tags/items/hammers.json | 11 +++ 12 files changed, 270 insertions(+), 61 deletions(-) create mode 100644 src/main/java/ru/betterend/compat/REIAnvilCategory.java create mode 100644 src/main/java/ru/betterend/compat/REIAnvilDisplay.java create mode 100644 src/main/resources/data/fabric/tags/items/hammers.json diff --git a/src/main/java/ru/betterend/compat/REIAlloyingDisplay.java b/src/main/java/ru/betterend/compat/REIAlloyingDisplay.java index d94e1ca8..0320ec67 100644 --- a/src/main/java/ru/betterend/compat/REIAlloyingDisplay.java +++ b/src/main/java/ru/betterend/compat/REIAlloyingDisplay.java @@ -99,7 +99,7 @@ public class REIAlloyingDisplay implements TransferRecipeDisplay { @Override public List> getOrganisedInputEntries(ContainerInfo containerInfo, ScreenHandler container) { - return input; + return this.input; } static { diff --git a/src/main/java/ru/betterend/compat/REIAnvilCategory.java b/src/main/java/ru/betterend/compat/REIAnvilCategory.java new file mode 100644 index 00000000..3af6c5d5 --- /dev/null +++ b/src/main/java/ru/betterend/compat/REIAnvilCategory.java @@ -0,0 +1,85 @@ +package ru.betterend.compat; + +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.Lists; + +import it.unimi.dsi.fastutil.ints.IntList; + +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.api.TransferRecipeCategory; +import me.shedaniel.rei.api.widgets.Widgets; +import me.shedaniel.rei.gui.entries.RecipeEntry; +import me.shedaniel.rei.gui.entries.SimpleRecipeEntry; +import me.shedaniel.rei.gui.widget.Widget; + +import net.minecraft.block.Blocks; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Identifier; + +import ru.betterend.recipe.AnvilSmithingRecipe; +import ru.betterend.util.LangUtil; + +public class REIAnvilCategory implements TransferRecipeCategory { + + @Override + public @NotNull Identifier getIdentifier() { + return AnvilSmithingRecipe.ID; + } + + @Override + public @NotNull String getCategoryName() { + return LangUtil.translate(Blocks.ANVIL.getTranslationKey()); + } + + @Override + public @NotNull EntryStack getLogo() { + return REIPlugin.ANVIL; + } + + @Override + public @NotNull List setupDisplay(REIAnvilDisplay display, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 41, bounds.y + 10); + List widgets = Lists.newArrayList(); + widgets.add(Widgets.createRecipeBase(bounds)); + int x = startPoint.x + 10; + int y = startPoint.y; + widgets.add(Widgets.createResultSlotBackground(new Point(x + 61, y + 9))); + List> inputEntries = display.getInputEntries(); + widgets.add(Widgets.createArrow(new Point(x + 24, y + 8))); + widgets.add(Widgets.createSlot(new Point(x - 20, y + 8)).entries(inputEntries.get(0)).markInput()); + widgets.add(Widgets.createSlot(new Point(x + 1, y + 8)).entries(inputEntries.get(1)).markInput()); + widgets.add(Widgets.createSlot(new Point(x + 61, y + 9)).entries(display.getResultingEntries().get(0)).disableBackground().markOutput()); + return widgets; + } + + @Override + public void renderRedSlots(MatrixStack matrices, List widgets, Rectangle bounds, REIAnvilDisplay display, + IntList redSlots) { + Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 27); + matrices.push(); + matrices.translate(0, 0, 400); + if (redSlots.contains(0)) { + DrawableHelper.fill(matrices, startPoint.x - 20, startPoint.y + 8, startPoint.x - 20 + 16, startPoint.y + 8 + 16, 1090453504); + DrawableHelper.fill(matrices, startPoint.x + 1, startPoint.y + 8, startPoint.x + 1 + 16, startPoint.y + 8 + 16, 1090453504); + } + matrices.pop(); + } + + @Override + public @NotNull RecipeEntry getSimpleRenderer(REIAnvilDisplay recipe) { + return SimpleRecipeEntry.from(Collections.singletonList(recipe.getInputEntries().get(0)), recipe.getResultingEntries()); + } + + @Override + public int getDisplayHeight() { + return 49; + } + +} diff --git a/src/main/java/ru/betterend/compat/REIAnvilDisplay.java b/src/main/java/ru/betterend/compat/REIAnvilDisplay.java new file mode 100644 index 00000000..b620f339 --- /dev/null +++ b/src/main/java/ru/betterend/compat/REIAnvilDisplay.java @@ -0,0 +1,71 @@ +package ru.betterend.compat; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import org.jetbrains.annotations.NotNull; + +import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.api.TransferRecipeDisplay; +import me.shedaniel.rei.server.ContainerInfo; + +import net.minecraft.recipe.Recipe; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.util.Identifier; + +import ru.betterend.recipe.AnvilSmithingRecipe; + +public class REIAnvilDisplay implements TransferRecipeDisplay { + + private AnvilSmithingRecipe recipe; + private List> input; + private List output; + + public REIAnvilDisplay(AnvilSmithingRecipe recipe) { + this.recipe = recipe; + this.input = EntryStack.ofIngredients(recipe.getPreviewInputs()); + this.output = Collections.singletonList(EntryStack.create(recipe.getOutput())); + } + + @Override + public @NotNull Optional getRecipeLocation() { + return Optional.ofNullable(recipe).map(Recipe::getId); + } + + @Override + public @NotNull List> getInputEntries() { + return this.input; + } + + @Override + public @NotNull List> getResultingEntries() { + return Collections.singletonList(output); + } + + @Override + public @NotNull Identifier getRecipeCategory() { + return AnvilSmithingRecipe.ID; + } + + @Override + public @NotNull List> getRequiredEntries() { + return this.input; + } + + @Override + public int getWidth() { + return 2; + } + + @Override + public int getHeight() { + return 1; + } + + @Override + public List> getOrganisedInputEntries(ContainerInfo containerInfo, + ScreenHandler container) { + return this.input; + } +} diff --git a/src/main/java/ru/betterend/compat/REIContainer.java b/src/main/java/ru/betterend/compat/REIContainer.java index 9dbed06c..0b660343 100644 --- a/src/main/java/ru/betterend/compat/REIContainer.java +++ b/src/main/java/ru/betterend/compat/REIContainer.java @@ -11,5 +11,4 @@ public class REIContainer implements Runnable { public void run() { ContainerInfoHandler.registerContainerInfo(AlloyingRecipe.ID, CraftingContainerInfoWrapper.create(EndStoneSmelterScreenHandler.class)); } - } diff --git a/src/main/java/ru/betterend/compat/REIPlugin.java b/src/main/java/ru/betterend/compat/REIPlugin.java index 5a769ace..4fca6ad3 100644 --- a/src/main/java/ru/betterend/compat/REIPlugin.java +++ b/src/main/java/ru/betterend/compat/REIPlugin.java @@ -3,19 +3,28 @@ package ru.betterend.compat; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.api.RecipeHelper; import me.shedaniel.rei.api.plugins.REIPluginV0; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; + +import net.minecraft.block.Blocks; import net.minecraft.recipe.BlastingRecipe; import net.minecraft.util.Identifier; + import ru.betterend.BetterEnd; import ru.betterend.recipe.AlloyingRecipe; +import ru.betterend.recipe.AnvilSmithingRecipe; import ru.betterend.registry.BlockRegistry; @Environment(EnvType.CLIENT) public class REIPlugin implements REIPluginV0 { public final static Identifier PLUGIN_ID = BetterEnd.makeID("rei_plugin"); + public final static Identifier ALLOING = AlloyingRecipe.ID; + public final static Identifier SMITHING = AlloyingRecipe.ID; + public final static EntryStack END_STONE_SMELTER = EntryStack.create(BlockRegistry.END_STONE_SMELTER); + public final static EntryStack ANVIL = EntryStack.create(Blocks.ANVIL); @Override public Identifier getPluginIdentifier() { @@ -24,17 +33,21 @@ public class REIPlugin implements REIPluginV0 { @Override public void registerRecipeDisplays(RecipeHelper recipeHelper) { - recipeHelper.registerRecipes(AlloyingRecipe.ID, AlloyingRecipe.class, REIAlloyingDisplay::new); - recipeHelper.registerRecipes(AlloyingRecipe.ID, BlastingRecipe.class, REIAlloyingDisplay::new); + recipeHelper.registerRecipes(ALLOING, AlloyingRecipe.class, REIAlloyingDisplay::new); + recipeHelper.registerRecipes(ALLOING, BlastingRecipe.class, REIAlloyingDisplay::new); + recipeHelper.registerRecipes(SMITHING, AnvilSmithingRecipe.class, REIAnvilDisplay::new); } @Override public void registerOthers(RecipeHelper recipeHelper) { - recipeHelper.registerWorkingStations(AlloyingRecipe.ID, END_STONE_SMELTER); + recipeHelper.registerWorkingStations(ALLOING, END_STONE_SMELTER); + recipeHelper.registerWorkingStations(SMITHING, ANVIL); + recipeHelper.removeAutoCraftButton(SMITHING); } @Override public void registerPluginCategories(RecipeHelper recipeHelper) { - recipeHelper.registerCategory(new REIAlloyingCategory()); + recipeHelper.registerCategories(new REIAlloyingCategory(), + new REIAnvilCategory()); } } diff --git a/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java b/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java index 6841b21f..95f239b7 100644 --- a/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java +++ b/src/main/java/ru/betterend/mixin/client/ClientRecipeBookMixin.java @@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.recipe.Recipe; + import ru.betterend.recipe.AlloyingRecipe; @Mixin(ClientRecipeBook.class) diff --git a/src/main/java/ru/betterend/mixin/common/AnvilScreenHandlerMixin.java b/src/main/java/ru/betterend/mixin/common/AnvilScreenHandlerMixin.java index a0d3583b..31f6d483 100644 --- a/src/main/java/ru/betterend/mixin/common/AnvilScreenHandlerMixin.java +++ b/src/main/java/ru/betterend/mixin/common/AnvilScreenHandlerMixin.java @@ -1,8 +1,5 @@ package ru.betterend.mixin.common; -import java.util.List; - -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -10,16 +7,19 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import net.minecraft.block.AnvilBlock; +import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.RecipeManager; import net.minecraft.screen.AnvilScreenHandler; import net.minecraft.screen.ForgingScreenHandler; -import net.minecraft.screen.Property; import net.minecraft.screen.ScreenHandlerContext; import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.tag.BlockTags; import net.minecraft.world.World; + import ru.betterend.recipe.AnvilSmithingRecipe; @Mixin(AnvilScreenHandler.class) @@ -29,48 +29,65 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler { private final RecipeManager recipeManager = this.world.getRecipeManager(); private AnvilSmithingRecipe currentRecipe; - @Final - @Shadow - private Property levelCost; - public AnvilScreenHandlerMixin(ScreenHandlerType type, int syncId, PlayerInventory playerInventory, ScreenHandlerContext context) { super(type, syncId, playerInventory, context); } - @Inject(method = "canTakeOutput", at = @At("RETURN")) + @Shadow + public abstract void updateResult(); + + @Inject(method = "canTakeOutput", at = @At("HEAD"), cancellable = true) protected void canTakeOutput(PlayerEntity player, boolean present, CallbackInfoReturnable info) { - if (!info.getReturnValue()) { - info.setReturnValue(currentRecipe != null && !currentRecipe.craft(input, player).isEmpty()); + if (currentRecipe != null) { + ItemStack output = this.currentRecipe.craft(input, player); + if (!output.isEmpty()) { + info.setReturnValue(true); + info.cancel(); + } } } @Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true) protected void onTakeOutput(PlayerEntity player, ItemStack stack, CallbackInfoReturnable info) { if (currentRecipe != null) { - this.input.getStack(0).decrement(1); - if (!currentRecipe.matches(input)) { - this.currentRecipe = null; - } + this.input.getStack(1).decrement(1); + this.updateResult(); + this.context.run((world, blockPos) -> { + BlockState anvilState = world.getBlockState(blockPos); + if (!player.abilities.creativeMode && anvilState.isIn(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) { + BlockState landingState = AnvilBlock.getLandingState(anvilState); + if (landingState == null) { + world.removeBlock(blockPos, false); + world.syncWorldEvent(1029, blockPos, 0); + } else { + world.setBlockState(blockPos, landingState, 2); + world.syncWorldEvent(1030, blockPos, 0); + } + } else { + world.syncWorldEvent(1030, blockPos, 0); + } + + }); + info.setReturnValue(stack); info.cancel(); } } @Inject(method = "updateResult", at = @At("HEAD"), cancellable = true) - public void updateResult(CallbackInfo info) { - this.currentRecipe = null; - List recipes = this.recipeManager.listAllOfType(AnvilSmithingRecipe.TYPE); - for (AnvilSmithingRecipe entry : recipes) { - if (entry.matches(input)) { - this.currentRecipe = entry; - break; - } - } + public void updateOutput(CallbackInfo info) { + this.currentRecipe = this.recipeManager.getFirstMatch(AnvilSmithingRecipe.TYPE, input, world).orElse(null); if (currentRecipe != null) { - this.levelCost.set(0); - this.output.setStack(0, currentRecipe.getOutput()); + this.output.setStack(0, currentRecipe.craft(input)); this.sendContentUpdates(); info.cancel(); } } + + @Inject(method = "setNewItemName", at = @At("HEAD"), cancellable = true) + public void setNewItemName(String string, CallbackInfo info) { + if (currentRecipe != null) { + info.cancel(); + } + } } diff --git a/src/main/java/ru/betterend/recipe/AlloyingRecipe.java b/src/main/java/ru/betterend/recipe/AlloyingRecipe.java index cf44ca5d..9ff27de7 100644 --- a/src/main/java/ru/betterend/recipe/AlloyingRecipe.java +++ b/src/main/java/ru/betterend/recipe/AlloyingRecipe.java @@ -28,7 +28,7 @@ public class AlloyingRecipe implements Recipe { public final static String GROUP = "alloying"; public final static RecipeType TYPE = EndRecipeManager.registerType(GROUP); public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new Serializer()); - public final static Identifier ID = BetterEnd.makeID("alloying"); + public final static Identifier ID = BetterEnd.makeID(GROUP); protected final RecipeType type; protected final Identifier id; @@ -38,7 +38,6 @@ public class AlloyingRecipe implements Recipe { protected final String group; protected final float experience; protected final int smeltTime; - public AlloyingRecipe(Identifier id, String group, Ingredient primaryInput, Ingredient secondaryInput, ItemStack output, float experience, int smeltTime) { this.group = group; @@ -59,6 +58,7 @@ public class AlloyingRecipe implements Recipe { return this.smeltTime; } + @Override public DefaultedList getPreviewInputs() { DefaultedList defaultedList = DefaultedList.of(); defaultedList.add(primaryInput); diff --git a/src/main/java/ru/betterend/recipe/AnvilSmithingRecipe.java b/src/main/java/ru/betterend/recipe/AnvilSmithingRecipe.java index 110146fb..9c8ab572 100644 --- a/src/main/java/ru/betterend/recipe/AnvilSmithingRecipe.java +++ b/src/main/java/ru/betterend/recipe/AnvilSmithingRecipe.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; + import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; @@ -15,14 +16,19 @@ import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeType; import net.minecraft.util.Identifier; import net.minecraft.util.JsonHelper; +import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; + +import ru.betterend.BetterEnd; import ru.betterend.registry.ItemTagRegistry; public class AnvilSmithingRecipe implements Recipe { - public final static RecipeType TYPE = EndRecipeManager.registerType("smithing"); - public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer("smithing", new Serializer()); + public final static String GROUP = "smithing"; + public final static RecipeType TYPE = EndRecipeManager.registerType(GROUP); + public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new Serializer()); + public final static Identifier ID = BetterEnd.makeID(GROUP); private final Identifier id; private final Ingredient input; @@ -43,14 +49,9 @@ public class AnvilSmithingRecipe implements Recipe { return SERIALIZER; } - @Override - public boolean isIgnoredInRecipeBook() { - return false; - } - @Override public ItemStack getOutput() { - return ItemStack.EMPTY; + return this.output; } @Override @@ -60,35 +61,39 @@ public class AnvilSmithingRecipe implements Recipe { @Override public ItemStack craft(Inventory craftingInventory) { - if (!matches(craftingInventory)) return ItemStack.EMPTY; - ItemStack hammer = craftingInventory.getStack(1); - int damage = hammer.getDamage() + this.damage; - if (damage >= hammer.getMaxDamage()) return ItemStack.EMPTY; - hammer.setDamage(damage); return this.output.copy(); } public ItemStack craft(Inventory craftingInventory, PlayerEntity player) { - if (!matches(craftingInventory)) return ItemStack.EMPTY; - - ItemStack hammer = craftingInventory.getStack(1); - int damage = hammer.getDamage() + this.damage; - if (damage >= hammer.getMaxDamage()) return ItemStack.EMPTY; - - hammer.damage(this.damage, player, ((entity) -> { - entity.sendEquipmentBreakStatus(null); - })); - return this.output.copy(); + if (!player.isCreative()) { + ItemStack hammer = craftingInventory.getStack(0); + int damage = hammer.getDamage() + this.damage; + if (damage >= hammer.getMaxDamage()) return ItemStack.EMPTY; + hammer.damage(this.damage, player, entity -> { + entity.sendEquipmentBreakStatus(null); + }); + } + return this.craft(craftingInventory); } public boolean matches(Inventory craftingInventory) { - ItemStack hammer = craftingInventory.getStack(1); - System.out.println(ItemTagRegistry.HAMMERS.values()); + ItemStack hammer = craftingInventory.getStack(0); if (hammer.isEmpty() || !ItemTagRegistry.HAMMERS.contains(hammer.getItem())) { return false; } int level = ((ToolItem) hammer.getItem()).getMaterial().getMiningLevel(); - return level >= this.level && this.input.test(craftingInventory.getStack(0)); + return level >= this.level && this.input.test(craftingInventory.getStack(1)); + } + + @Override + public DefaultedList getPreviewInputs() { + DefaultedList defaultedList = DefaultedList.of(); + defaultedList.add(Ingredient.ofStacks(ItemTagRegistry.HAMMERS.values().stream().filter(hammer -> { + return ((ToolItem) hammer).getMaterial().getMiningLevel() >= level; + }).map(ItemStack::new))); + defaultedList.add(input); + + return defaultedList; } @Override @@ -106,6 +111,11 @@ public class AnvilSmithingRecipe implements Recipe { public RecipeType getType() { return TYPE; } + + @Override + public boolean isIgnoredInRecipeBook() { + return true; + } public static class Serializer implements RecipeSerializer { @Override diff --git a/src/main/java/ru/betterend/registry/ItemRegistry.java b/src/main/java/ru/betterend/registry/ItemRegistry.java index b07cf8b2..80b6e733 100644 --- a/src/main/java/ru/betterend/registry/ItemRegistry.java +++ b/src/main/java/ru/betterend/registry/ItemRegistry.java @@ -70,7 +70,7 @@ public class ItemRegistry { public static ToolItem IRON_HAMMER = registerTool("iron_hammer", new EndHammer(ToolMaterials.IRON, 5.0F, -3.2F, 0.2D, makeSettings())); public static ToolItem GOLDEN_HAMMER = registerTool("golden_hammer", new EndHammer(ToolMaterials.GOLD, 4.5F, -3.4F, 0.3D, makeSettings())); public static ToolItem DIAMOND_HAMMER = registerTool("diamond_hammer", new EndHammer(ToolMaterials.DIAMOND, 5.5F, -3.1F, 0.2D, makeSettings())); - public static ToolItem NETHERITE_HAMMER = registerTool("netherite_hammer", new EndHammer(ToolMaterials.DIAMOND, 6.0F, -3.0F, 0.2D, makeSettings())); + public static ToolItem NETHERITE_HAMMER = registerTool("netherite_hammer", new EndHammer(ToolMaterials.NETHERITE, 5.0F, -3.0F, 0.2D, makeSettings())); protected static Item registerItem(String name, Item item) { if (item != Items.AIR) { diff --git a/src/main/java/ru/betterend/registry/ItemTagRegistry.java b/src/main/java/ru/betterend/registry/ItemTagRegistry.java index 727520c4..c15ec1e6 100644 --- a/src/main/java/ru/betterend/registry/ItemTagRegistry.java +++ b/src/main/java/ru/betterend/registry/ItemTagRegistry.java @@ -5,9 +5,11 @@ import java.util.Arrays; import net.fabricmc.fabric.api.tag.TagRegistry; import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl; import net.fabricmc.fabric.impl.tool.attribute.handlers.ModdedToolsVanillaBlocksToolHandler; + import net.minecraft.item.Item; import net.minecraft.tag.Tag; import net.minecraft.util.Identifier; + import ru.betterend.BetterEnd; public class ItemTagRegistry { diff --git a/src/main/resources/data/fabric/tags/items/hammers.json b/src/main/resources/data/fabric/tags/items/hammers.json new file mode 100644 index 00000000..db00d6af --- /dev/null +++ b/src/main/resources/data/fabric/tags/items/hammers.json @@ -0,0 +1,11 @@ +{ + "replace": false, + "values": [ + "betterend:iron_hammer", + "betterend:golden_hammer", + "betterend:diamond_hammer", + "betterend:netherite_hammer", + "betterend:terminite_hammer", + "betterend:aeternium_hammer" + ] +} \ No newline at end of file