From 9f095f2bb27e68048ebb59131c590b6ed248e047 Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:43:55 +0400 Subject: [PATCH 1/7] Smithing recipe helpers --- .../data/recipe/VanillaRecipeHelper.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java index ee3b7ff2257..c70ed2155f0 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java @@ -10,10 +10,12 @@ import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialEntry; import com.gregtechceu.gtceu.api.data.chemical.material.stack.MaterialStack; import com.gregtechceu.gtceu.api.data.tag.TagPrefix; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.item.tool.ToolHelper; import com.gregtechceu.gtceu.data.recipe.builder.*; import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; @@ -22,12 +24,16 @@ import net.minecraft.world.level.ItemLike; import com.tterrag.registrate.util.entry.ItemProviderEntry; -import it.unimi.dsi.fastutil.chars.*; +import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap; +import it.unimi.dsi.fastutil.chars.CharArraySet; +import it.unimi.dsi.fastutil.chars.CharSet; import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; +import static com.tterrag.registrate.providers.RegistrateRecipeProvider.has; + public class VanillaRecipeHelper { public static void addSmeltingRecipe(Consumer provider, @NotNull String regName, TagKey input, @@ -581,6 +587,36 @@ public static void addShapelessRecipe(Consumer provider, @NotNul builder.save(provider); } + public static void addSmithingTransformRecipe(Consumer provider, @NotNull ResourceLocation regName, + @NotNull Item result, @NotNull ItemLike baseInput, + @NotNull ItemLike template, @NotNull ItemLike addition, + @NotNull RecipeCategory category) { + net.minecraft.data.recipes.SmithingTransformRecipeBuilder + .smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result) + .unlocks(String.format("has_%s", baseInput), has(baseInput)) + .save(provider, regName); + } + + public static void addSmithingTransformRecipe(Consumer provider, @NotNull String regName, + @NotNull Item result, @NotNull ItemLike baseInput, + @NotNull ItemLike template, @NotNull ItemLike addition) { + addSmithingTransformRecipe(provider, GTCEu.id(regName), result, baseInput, template, addition, + RecipeCategory.MISC); + } + + public static void addToolUpgradingRecipe(@NotNull Consumer provider, @NotNull GTToolType tool, + @NotNull Material upgradeMaterial, @NotNull Material baseMaterial, + @NotNull ItemLike template, @NotNull ItemLike addition) { + ItemStack upgradeToolStack = ToolHelper.get(tool, upgradeMaterial); + ItemStack baseToolStack = ToolHelper.get(tool, baseMaterial); + + VanillaRecipeHelper.addSmithingTransformRecipe(provider, + String.format("%s_%s_smithing_transform_from_%s", upgradeMaterial.getName(), tool.name, + baseMaterial.getName()), + upgradeToolStack.getItem(), baseToolStack.getItem(), + template, addition); + } + /** * @param material the material to check * @return if the material is a wood From c76fd07699c558a7c3a5376ad9476d969182cc80 Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:44:01 +0400 Subject: [PATCH 2/7] Netherite tools --- .../data/recipe/generated/ToolRecipeHandler.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java index d67aa688dd7..bc8e227050e 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java @@ -195,6 +195,8 @@ private static void processTool(@NotNull Consumer provider, @Not GTCEu.LOGGER.warn("Did not find rod for " + material.getName() + ", skipping wirecutter, butchery knife, screwdriver, crowbar recipes"); } + + GTToolType.getTypes().forEach((s, gtToolType) -> addNetheriteToolRecipe(provider, gtToolType)); } private static void processElectricTool(@NotNull Consumer provider, @NotNull ToolProperty property, @@ -347,6 +349,16 @@ public static void addToolRecipe(@NotNull Consumer provider, @No } } + public static void addNetheriteToolRecipe(@NotNull Consumer provider, @NotNull GTToolType tool) { + ItemStack netheriteTool = ToolHelper.get(tool, GTMaterials.Netherite); + ItemStack diamondTool = ToolHelper.get(tool, GTMaterials.Diamond); + + if (netheriteTool.isEmpty() || diamondTool.isEmpty()) return; + + VanillaRecipeHelper.addToolUpgradingRecipe(provider, tool, GTMaterials.Netherite, GTMaterials.Diamond, + Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, ChemicalHelper.get(ingot, GTMaterials.Netherite).getItem()); + } + public static void addArmorRecipe(Consumer provider, @NotNull Material material, @NotNull ArmorItem.Type armor, Object... recipe) { ItemStack armorStack = ToolHelper.getArmor(armor, material); From d05a576e02cd082cda54e15f4d0033656ab1c367 Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Wed, 24 Dec 2025 11:10:20 +0400 Subject: [PATCH 3/7] Move tool existing check to VanillaRecipeHelper#addToolUpgradingRecipe --- .../gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java | 2 ++ .../gtceu/data/recipe/generated/ToolRecipeHandler.java | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java index c70ed2155f0..24d8f08c845 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java @@ -610,6 +610,8 @@ public static void addToolUpgradingRecipe(@NotNull Consumer prov ItemStack upgradeToolStack = ToolHelper.get(tool, upgradeMaterial); ItemStack baseToolStack = ToolHelper.get(tool, baseMaterial); + if (upgradeToolStack.isEmpty() || baseToolStack.isEmpty()) return; + VanillaRecipeHelper.addSmithingTransformRecipe(provider, String.format("%s_%s_smithing_transform_from_%s", upgradeMaterial.getName(), tool.name, baseMaterial.getName()), diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java index bc8e227050e..ae40026f7ea 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/ToolRecipeHandler.java @@ -350,11 +350,6 @@ public static void addToolRecipe(@NotNull Consumer provider, @No } public static void addNetheriteToolRecipe(@NotNull Consumer provider, @NotNull GTToolType tool) { - ItemStack netheriteTool = ToolHelper.get(tool, GTMaterials.Netherite); - ItemStack diamondTool = ToolHelper.get(tool, GTMaterials.Diamond); - - if (netheriteTool.isEmpty() || diamondTool.isEmpty()) return; - VanillaRecipeHelper.addToolUpgradingRecipe(provider, tool, GTMaterials.Netherite, GTMaterials.Diamond, Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, ChemicalHelper.get(ingot, GTMaterials.Netherite).getItem()); } From 758d205398d32d9a9d1bb7c9ffac465cace5bab9 Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Wed, 24 Dec 2025 16:19:30 +0400 Subject: [PATCH 4/7] Mixin to transform GT tools' NBT properly --- .../mixins/SmithingTransformRecipeMixin.java | 50 +++++++++++++++++++ src/main/resources/gtceu.mixins.json | 1 + 2 files changed, 51 insertions(+) create mode 100644 src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java new file mode 100644 index 00000000000..35eed54648f --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java @@ -0,0 +1,50 @@ +package com.gregtechceu.gtceu.core.mixins; + +import com.gregtechceu.gtceu.api.item.IGTTool; +import com.gregtechceu.gtceu.api.item.tool.ToolHelper; +import net.minecraft.core.RegistryAccess; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.Container; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.SmithingTransformRecipe; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SmithingTransformRecipe.class) +public class SmithingTransformRecipeMixin { + @Unique + private static CompoundTag gtceu$newTag; + + @Shadow + @Final + ItemStack result; + + + @Inject(method = "assemble", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) + private void gtceu$gtToolSmithingTransform1(Container container, RegistryAccess registryAccess, CallbackInfoReturnable cir) { + gtceu$newTag = container.getItem(1).getTag().copy(); + var output = this.result.copy(); + if (output.getItem() instanceof IGTTool igtTool) { + // Remove old tool stats + gtceu$newTag.remove("GT.Tool"); + + // Copy stats from the upgraded tool + var newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial()); + var newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null; + if (newStats != null) { + gtceu$newTag.put("GT.Tool", newStats); + } + } + } + + @Redirect(method = "assemble", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) + private void gtceu$gtToolSmithingTransform2(ItemStack itemStack, CompoundTag tag) { + itemStack.setTag(gtceu$newTag); + } +} diff --git a/src/main/resources/gtceu.mixins.json b/src/main/resources/gtceu.mixins.json index 7bcc8159b12..745581a3827 100644 --- a/src/main/resources/gtceu.mixins.json +++ b/src/main/resources/gtceu.mixins.json @@ -57,6 +57,7 @@ "ServerGamePacketListenerImplAccessor", "ShapedRecipeAccessor", "SidedRedstoneConnectivityMixin", + "SmithingTransformRecipeMixin", "TagLoaderMixin", "TagManagerMixin", "TagValueAccessor", From 16f5419e45d8f3167792c40200f40af400b11d5e Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Wed, 24 Dec 2025 16:19:50 +0400 Subject: [PATCH 5/7] Import SmithingTransformRecipeBuilder in VanillaRecipeHelper --- .../gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java index 24d8f08c845..69dcd148c55 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java @@ -16,6 +16,7 @@ import net.minecraft.data.recipes.FinishedRecipe; import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.SmithingTransformRecipeBuilder; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; @@ -591,8 +592,7 @@ public static void addSmithingTransformRecipe(Consumer provider, @NotNull Item result, @NotNull ItemLike baseInput, @NotNull ItemLike template, @NotNull ItemLike addition, @NotNull RecipeCategory category) { - net.minecraft.data.recipes.SmithingTransformRecipeBuilder - .smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result) + SmithingTransformRecipeBuilder.smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result) .unlocks(String.format("has_%s", baseInput), has(baseInput)) .save(provider, regName); } From a923847881fb8b18de44d88007a196ec4f0e514c Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Wed, 24 Dec 2025 17:55:15 +0400 Subject: [PATCH 6/7] Use @Share for thread safety Thanks screret --- .../mixins/SmithingTransformRecipeMixin.java | 48 +++++++++++-------- .../data/recipe/VanillaRecipeHelper.java | 3 +- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java index 35eed54648f..f271de60675 100644 --- a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java @@ -2,15 +2,18 @@ import com.gregtechceu.gtceu.api.item.IGTTool; import com.gregtechceu.gtceu.api.item.tool.ToolHelper; + import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.SmithingTransformRecipe; + +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -18,33 +21,38 @@ @Mixin(SmithingTransformRecipe.class) public class SmithingTransformRecipeMixin { - @Unique - private static CompoundTag gtceu$newTag; @Shadow @Final ItemStack result; - - @Inject(method = "assemble", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) - private void gtceu$gtToolSmithingTransform1(Container container, RegistryAccess registryAccess, CallbackInfoReturnable cir) { - gtceu$newTag = container.getItem(1).getTag().copy(); + @Inject(method = "assemble", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) + private void gtceu$gtToolSmithingTransform1(Container container, RegistryAccess registryAccess, + CallbackInfoReturnable cir, + @Share("newTag") LocalRef sharedTag) { + var newTag = container.getItem(1).getTag().copy(); var output = this.result.copy(); - if (output.getItem() instanceof IGTTool igtTool) { - // Remove old tool stats - gtceu$newTag.remove("GT.Tool"); - - // Copy stats from the upgraded tool - var newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial()); - var newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null; - if (newStats != null) { - gtceu$newTag.put("GT.Tool", newStats); - } + if (output.getItem() instanceof IGTTool igtTool) { + // Remove old tool stats + newTag.remove("GT.Tool"); + + // Copy stats from the upgraded tool + var newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial()); + var newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null; + if (newStats != null) { + newTag.put("GT.Tool", newStats); + sharedTag.set(newTag); } + } } - @Redirect(method = "assemble", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) - private void gtceu$gtToolSmithingTransform2(ItemStack itemStack, CompoundTag tag) { - itemStack.setTag(gtceu$newTag); + @Redirect(method = "assemble", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/item/ItemStack;setTag(Lnet/minecraft/nbt/CompoundTag;)V")) + private void gtceu$gtToolSmithingTransform2(ItemStack itemStack, CompoundTag tag, + @Share("newTag") LocalRef sharedTag) { + itemStack.setTag(sharedTag.get()); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java index 69dcd148c55..88ecac554a4 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java @@ -592,7 +592,8 @@ public static void addSmithingTransformRecipe(Consumer provider, @NotNull Item result, @NotNull ItemLike baseInput, @NotNull ItemLike template, @NotNull ItemLike addition, @NotNull RecipeCategory category) { - SmithingTransformRecipeBuilder.smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result) + SmithingTransformRecipeBuilder + .smithing(Ingredient.of(template), Ingredient.of(baseInput), Ingredient.of(addition), category, result) .unlocks(String.format("has_%s", baseInput), has(baseInput)) .save(provider, regName); } From a9884c9e39b09b197896a474947aa24dac0c902d Mon Sep 17 00:00:00 2001 From: JuiceyBeans <75553966+JuiceyBeans@users.noreply.github.com> Date: Wed, 24 Dec 2025 18:42:27 +0400 Subject: [PATCH 7/7] Null safety + some other smol changes --- .../mixins/SmithingTransformRecipeMixin.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java index f271de60675..d349dc17cb2 100644 --- a/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/SmithingTransformRecipeMixin.java @@ -5,6 +5,7 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.SmithingTransformRecipe; @@ -32,19 +33,23 @@ public class SmithingTransformRecipeMixin { private void gtceu$gtToolSmithingTransform1(Container container, RegistryAccess registryAccess, CallbackInfoReturnable cir, @Share("newTag") LocalRef sharedTag) { - var newTag = container.getItem(1).getTag().copy(); - var output = this.result.copy(); - if (output.getItem() instanceof IGTTool igtTool) { - // Remove old tool stats - newTag.remove("GT.Tool"); - - // Copy stats from the upgraded tool - var newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial()); - var newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null; - if (newStats != null) { - newTag.put("GT.Tool", newStats); - sharedTag.set(newTag); - } + ItemStack output = this.result.copy(); + + if (!(output.getItem() instanceof IGTTool igtTool)) return; + + CompoundTag originalTag = container.getItem(1).getTag(); + CompoundTag newTag = originalTag != null ? originalTag.copy() : null; + if (newTag == null) return; + + // Remove old tool stats + newTag.remove("GT.Tool"); + + // Copy stats from the upgraded tool + ItemStack newStack = ToolHelper.get(igtTool.getToolType(), igtTool.getMaterial()); + Tag newStats = newStack.getTag() != null ? newStack.getTag().get("GT.Tool") : null; + if (newStats != null) { + newTag.put("GT.Tool", newStats); + sharedTag.set(newTag); } }