From d6cdaad5f93de6845ee315de44fa9ac454d81c30 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 29 Nov 2025 21:40:54 -0500 Subject: [PATCH 01/13] Reimplement `IRecipeTransferReceiver` --- .../gregtech/api/mui/GregTechGuiScreen.java | 82 ++++++++++++++++++- .../api/mui/IRecipeTransferReceiver.java | 66 +++++++++++++++ .../jei/JustEnoughItemsModule.java | 4 + 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index ad5c48449c5..a5051ffd2ec 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -1,15 +1,31 @@ package gregtech.api.mui; import gregtech.api.GTValues; +import gregtech.integration.jei.JustEnoughItemsModule; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import com.cleanroommc.modularui.integration.recipeviewer.RecipeViewerRecipeTransferHandler; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; +import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntComparators; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import org.jetbrains.annotations.NotNull; +import java.util.Map; + +@SuppressWarnings("UnstableApiUsage") @SideOnly(Side.CLIENT) -public class GregTechGuiScreen extends ModularScreen { +public class GregTechGuiScreen extends ModularScreen implements RecipeViewerRecipeTransferHandler { + + // Stores lists of higher priority recipe receivers to the left of the tree + private final Int2ObjectMap> registeredRecipeTransferReceivers = new Int2ObjectAVLTreeMap<>( + IntComparators.OPPOSITE_COMPARATOR); public GregTechGuiScreen(ModularPanel mainPanel) { this(mainPanel, GTGuiTheme.STANDARD); @@ -27,4 +43,68 @@ public GregTechGuiScreen(String owner, ModularPanel mainPanel, String themeId) { super(owner, mainPanel); useTheme(themeId); } + + @Override + public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean maxTransfer, boolean simulate) { + // Receivers are sorted high to low on registration + for (Map subMap : registeredRecipeTransferReceivers.values()) { + for (IRecipeTransferReceiver receiver : subMap.values()) { + IRecipeTransferError result = receiver.receiveRecipe(recipeLayout, maxTransfer, simulate); + if (result == IRecipeTransferReceiver.SKIP) continue; + return result; + } + } + + // No valid transfer handler was found + return JustEnoughItemsModule.transferHelper.createInternalError(); + } + + /** + * Register an {@link IRecipeTransferReceiver} to this screen.
+ * Recipe transfer handlers registered through this method will have a priority of {@code 0}.
+ * Important: if you have dynamic widgets or sync handlers, ensure that you remove this handler with + * {@link #removeRecipeTransferHandler(String)} when it's disposed of! + * + * @throws IllegalArgumentException if a receiver with the given key already exists. + */ + public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver transferReceiver, @NotNull String key) { + registerRecipeTransferHandler(transferReceiver, key, 0); + } + + /** + * Register an {@link IRecipeTransferReceiver} to this screen with a certain priority. Higher numbers will be tried + * first.
+ * Important: if you have dynamic widgets or sync handlers, ensure that you remove this handler with + * {@link #removeRecipeTransferHandler(String)} when it's disposed of! + * + * @throws IllegalArgumentException if a receiver with the given key already exists. + */ + public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver transferReceiver, @NotNull String key, + int priority) { + for (Map subMap : registeredRecipeTransferReceivers.values()) { + if (subMap.containsKey(key)) { + throw new IllegalArgumentException( + "Tried to register a recipe transfer receiver to a key that's already used!"); + } + } + + registeredRecipeTransferReceivers.computeIfAbsent(priority, $ -> new Object2ObjectOpenHashMap<>()) + .put(key, transferReceiver); + } + + /** + * Remove a registered {@link IRecipeTransferReceiver} from this screen. + * + * @throws IllegalArgumentException if no receiver exists with the given key. + */ + public void removeRecipeTransferHandler(@NotNull String key) { + for (Map subMap : registeredRecipeTransferReceivers.values()) { + if (subMap.containsKey(key)) { + subMap.remove(key); + return; + } + } + + throw new IllegalArgumentException("Tried to remove a recipe transfer receiver by a key that didn't exist!"); + } } diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java new file mode 100644 index 00000000000..259a25b5490 --- /dev/null +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -0,0 +1,66 @@ +package gregtech.api.mui; + +import gregtech.integration.jei.JustEnoughItemsModule; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * An interface for receiving a recipe from a recipe viewer to anything on the panel, such as a {@link Widget} or + * {@link SyncHandler}.
+ * Register it via {@link GregTechGuiScreen#registerRecipeTransferHandler(IRecipeTransferReceiver, String)} or + * {@link GregTechGuiScreen#registerRecipeTransferHandler(IRecipeTransferReceiver, String, int)} if you want to + * prioritize checking a certain handler first. + */ +public interface IRecipeTransferReceiver { + + IRecipeTransferError SKIP = new IRecipeTransferError() { + + @Override + public @NotNull Type getType() { + return Type.INTERNAL; + } + + @Override + public void showError(@NotNull Minecraft minecraft, int mouseX, int mouseY, @NotNull IRecipeLayout recipeLayout, + int recipeX, + int recipeY) { + // NO-OP + } + }; + + /** + * Attempt or simulate transferring a recipe from a recipe viewer like JEI or HEI.
+ * A factory for default {@link IRecipeTransferError}s is available at {@link JustEnoughItemsModule#transferHelper}. + * There are three default options for errors.
+ * - {@link IRecipeTransferHandlerHelper#createInternalError()}: mark the recipe as invalid for transferring by + * graying out the + button.
+ * - {@link IRecipeTransferHandlerHelper#createUserErrorWithTooltip(String)}: the same as above, but also display a + * message when hovering over the + button.
+ * - {@link IRecipeTransferHandlerHelper#createUserErrorForSlots(String, Collection)}: the same as above, but + * additionally highlight certain slots in the recipe to, for example, mark missing ingredients. Important: will + * throw {@link IllegalArgumentException} if the supplied {@link Collection} is empty!
+ * If you have multiple receivers on your panel and want to indicate that this receiver should be skipped and the + * next receiver in order should be tried, return {@link #SKIP}! + * + * @param recipeLayout the recipe layout that contains the recipe category, and the item and fluid stacks. + * @param maxTransfer if the receiver should try to move as many ingredients as possible to the crafting slots, ie + * a crafting table. + * @param simulate if this recipe should only simulate being transferred + * @return {@code null} if the transfer should succeed or a {@link IRecipeTransferError} if not. + */ + @Nullable + @SideOnly(Side.CLIENT) + IRecipeTransferError receiveRecipe(@NotNull IRecipeLayout recipeLayout, boolean maxTransfer, boolean simulate); +} diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 7772e0ada44..75c424483b4 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -74,6 +74,7 @@ import mezz.jei.api.recipe.IRecipeCategory; import mezz.jei.api.recipe.IRecipeCategoryRegistration; import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; import mezz.jei.config.Constants; import mezz.jei.input.IShowsRecipeFocuses; import mezz.jei.input.InputHandler; @@ -105,6 +106,7 @@ public class JustEnoughItemsModule extends IntegrationSubmodule implements IModP public static IIngredientRegistry ingredientRegistry; public static IJeiRuntime jeiRuntime; public static IGuiHelper guiHelper; + public static IRecipeTransferHandlerHelper transferHelper; @Override public void loadComplete(FMLLoadCompleteEvent event) { @@ -331,6 +333,8 @@ public void register(IModRegistry registry) { // Refresh Ore Ingredients Cache GTRecipeOreInput.refreshStackCache(); + + transferHelper = jeiHelpers.recipeTransferHandlerHelper(); } private void setupInputHandler() { From 93917c3e824ae374247d1bc6c3ff33b4f2a3a520 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 29 Nov 2025 22:48:11 -0500 Subject: [PATCH 02/13] skip on any internal error --- .../gregtech/api/mui/GregTechGuiScreen.java | 2 +- .../api/mui/IRecipeTransferReceiver.java | 25 +++---------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index a5051ffd2ec..7614fac2b0b 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -50,7 +50,7 @@ public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean m for (Map subMap : registeredRecipeTransferReceivers.values()) { for (IRecipeTransferReceiver receiver : subMap.values()) { IRecipeTransferError result = receiver.receiveRecipe(recipeLayout, maxTransfer, simulate); - if (result == IRecipeTransferReceiver.SKIP) continue; + if (result != null && result.getType() == IRecipeTransferError.Type.INTERNAL) continue; return result; } } diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java index 259a25b5490..bf7280273ef 100644 --- a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -2,7 +2,6 @@ import gregtech.integration.jei.JustEnoughItemsModule; -import net.minecraft.client.Minecraft; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -25,34 +24,18 @@ */ public interface IRecipeTransferReceiver { - IRecipeTransferError SKIP = new IRecipeTransferError() { - - @Override - public @NotNull Type getType() { - return Type.INTERNAL; - } - - @Override - public void showError(@NotNull Minecraft minecraft, int mouseX, int mouseY, @NotNull IRecipeLayout recipeLayout, - int recipeX, - int recipeY) { - // NO-OP - } - }; - /** * Attempt or simulate transferring a recipe from a recipe viewer like JEI or HEI.
* A factory for default {@link IRecipeTransferError}s is available at {@link JustEnoughItemsModule#transferHelper}. - * There are three default options for errors.
+ * There are three default options for errors:
* - {@link IRecipeTransferHandlerHelper#createInternalError()}: mark the recipe as invalid for transferring by - * graying out the + button.
+ * graying out the + button. If there are multiple registered recipe transfer receivers on the same panel, returning + * an internal error will skip this receiver and try the others.
* - {@link IRecipeTransferHandlerHelper#createUserErrorWithTooltip(String)}: the same as above, but also display a * message when hovering over the + button.
* - {@link IRecipeTransferHandlerHelper#createUserErrorForSlots(String, Collection)}: the same as above, but * additionally highlight certain slots in the recipe to, for example, mark missing ingredients. Important: will - * throw {@link IllegalArgumentException} if the supplied {@link Collection} is empty!
- * If you have multiple receivers on your panel and want to indicate that this receiver should be skipped and the - * next receiver in order should be tried, return {@link #SKIP}! + * throw {@link IllegalArgumentException} if the supplied {@link Collection} is empty! * * @param recipeLayout the recipe layout that contains the recipe category, and the item and fluid stacks. * @param maxTransfer if the receiver should try to move as many ingredients as possible to the crafting slots, ie From 01078888a3160cae0078917e577d49978dce361f Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 29 Nov 2025 23:25:28 -0500 Subject: [PATCH 03/13] Add RecipeTransferSyncHandler --- .../gregtech/api/mui/GregTechGuiScreen.java | 39 +++++++++++++------ .../api/mui/IRecipeTransferReceiver.java | 9 +++-- .../mui/sync/RecipeTransferSyncHandler.java | 36 +++++++++++++++++ 3 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index 7614fac2b0b..85dcf63636d 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -9,10 +9,12 @@ import com.cleanroommc.modularui.integration.recipeviewer.RecipeViewerRecipeTransferHandler; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntComparators; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import org.jetbrains.annotations.NotNull; @@ -24,7 +26,7 @@ public class GregTechGuiScreen extends ModularScreen implements RecipeViewerRecipeTransferHandler { // Stores lists of higher priority recipe receivers to the left of the tree - private final Int2ObjectMap> registeredRecipeTransferReceivers = new Int2ObjectAVLTreeMap<>( + private static final Int2ObjectMap> registeredRecipeTransferReceivers = new Int2ObjectAVLTreeMap<>( IntComparators.OPPOSITE_COMPARATOR); public GregTechGuiScreen(ModularPanel mainPanel) { @@ -44,6 +46,11 @@ public GregTechGuiScreen(String owner, ModularPanel mainPanel, String themeId) { useTheme(themeId); } + @Override + public void onClose() { + registeredRecipeTransferReceivers.clear(); + } + @Override public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean maxTransfer, boolean simulate) { // Receivers are sorted high to low on registration @@ -62,25 +69,31 @@ public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean m /** * Register an {@link IRecipeTransferReceiver} to this screen.
* Recipe transfer handlers registered through this method will have a priority of {@code 0}.
- * Important: if you have dynamic widgets or sync handlers, ensure that you remove this handler with - * {@link #removeRecipeTransferHandler(String)} when it's disposed of! + * Important: ensure that you remove this handler with {@link #removeRecipeTransferHandler(String)} when it's + * disposed of!
+ * Remove it by calling {@link #removeRecipeTransferHandler(String)} from {@link Widget#dispose()} for widgets and + * {@link SyncHandler#dispose()} for sync handlers. * * @throws IllegalArgumentException if a receiver with the given key already exists. */ - public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver transferReceiver, @NotNull String key) { - registerRecipeTransferHandler(transferReceiver, key, 0); + public static void registerRecipeTransferHandler(@NotNull String key, + @NotNull IRecipeTransferReceiver transferReceiver) { + registerRecipeTransferHandler(key, transferReceiver, 0); } /** * Register an {@link IRecipeTransferReceiver} to this screen with a certain priority. Higher numbers will be tried * first.
- * Important: if you have dynamic widgets or sync handlers, ensure that you remove this handler with - * {@link #removeRecipeTransferHandler(String)} when it's disposed of! + * Important: ensure that you remove this handler with {@link #removeRecipeTransferHandler(String)} when it's + * disposed of!
+ * Remove it by calling {@link #removeRecipeTransferHandler(String)} from {@link Widget#dispose()} for widgets and + * {@link SyncHandler#dispose()} for sync handlers. * * @throws IllegalArgumentException if a receiver with the given key already exists. */ - public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver transferReceiver, @NotNull String key, - int priority) { + public static void registerRecipeTransferHandler(@NotNull String key, + @NotNull IRecipeTransferReceiver transferReceiver, + int priority) { for (Map subMap : registeredRecipeTransferReceivers.values()) { if (subMap.containsKey(key)) { throw new IllegalArgumentException( @@ -88,7 +101,9 @@ public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver trans } } - registeredRecipeTransferReceivers.computeIfAbsent(priority, $ -> new Object2ObjectOpenHashMap<>()) + // Reference map so the receiver might:tm: not stick around for too long if someone forgets to unregister their + // receiver. + registeredRecipeTransferReceivers.computeIfAbsent(priority, $ -> new Object2ReferenceOpenHashMap<>()) .put(key, transferReceiver); } @@ -97,7 +112,7 @@ public void registerRecipeTransferHandler(@NotNull IRecipeTransferReceiver trans * * @throws IllegalArgumentException if no receiver exists with the given key. */ - public void removeRecipeTransferHandler(@NotNull String key) { + public static void removeRecipeTransferHandler(@NotNull String key) { for (Map subMap : registeredRecipeTransferReceivers.values()) { if (subMap.containsKey(key)) { subMap.remove(key); diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java index bf7280273ef..6137d4037f6 100644 --- a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -1,5 +1,6 @@ package gregtech.api.mui; +import gregtech.api.mui.sync.RecipeTransferSyncHandler; import gregtech.integration.jei.JustEnoughItemsModule; import net.minecraftforge.fml.relauncher.Side; @@ -18,9 +19,11 @@ /** * An interface for receiving a recipe from a recipe viewer to anything on the panel, such as a {@link Widget} or * {@link SyncHandler}.
- * Register it via {@link GregTechGuiScreen#registerRecipeTransferHandler(IRecipeTransferReceiver, String)} or - * {@link GregTechGuiScreen#registerRecipeTransferHandler(IRecipeTransferReceiver, String, int)} if you want to - * prioritize checking a certain handler first. + * Register it via {@link GregTechGuiScreen#registerRecipeTransferHandler(String, IRecipeTransferReceiver)} or + * {@link GregTechGuiScreen#registerRecipeTransferHandler(String, IRecipeTransferReceiver, int)} if you want to + * prioritize checking a certain handler first.
+ * If you're implementing this on a {@link SyncHandler}, it's recommended to extend {@link RecipeTransferSyncHandler} so + * registering and unregistering from {@link GregTechGuiScreen} is done for you. */ public interface IRecipeTransferReceiver { diff --git a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java new file mode 100644 index 00000000000..53da6eecdf3 --- /dev/null +++ b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java @@ -0,0 +1,36 @@ +package gregtech.api.mui.sync; + +import gregtech.api.mui.GregTechGuiScreen; +import gregtech.api.mui.IRecipeTransferReceiver; + +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; + +/** + * A base class for to handle implementing {@link IRecipeTransferReceiver} on a {@link SyncHandler}s to automatically + * register and unregister it from the map of valid handlers in {@link GregTechGuiScreen}. + */ +public abstract class RecipeTransferSyncHandler extends SyncHandler implements IRecipeTransferReceiver { + + @ApiStatus.OverrideOnly + @MustBeInvokedByOverriders + @Override + public void init(String key, PanelSyncManager syncManager) { + super.init(key, syncManager); + GregTechGuiScreen.registerRecipeTransferHandler(getKey(), this, getTransferHandlerPriority()); + } + + protected int getTransferHandlerPriority() { + return 0; + } + + @ApiStatus.OverrideOnly + @MustBeInvokedByOverriders + @Override + public void dispose() { + GregTechGuiScreen.removeRecipeTransferHandler(getKey()); + super.dispose(); + } +} From b8d6a3aa3bbd753c111806c8b2a80b5c5a72a07a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 29 Nov 2025 23:55:52 -0500 Subject: [PATCH 04/13] Refactor CraftingRecipeLogic to use RecipeTransferSyncHandler --- .../api/mui/GregTechGuiTransferHandler.java | 69 ------------------- .../storage/CraftingRecipeLogic.java | 44 +++++++++++- .../storage/MetaTileEntityWorkbench.java | 2 +- .../jei/JustEnoughItemsModule.java | 5 -- 4 files changed, 43 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java deleted file mode 100644 index 9332b8a9a70..00000000000 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package gregtech.api.mui; - -import gregtech.api.mui.sync.PagedWidgetSyncHandler; -import gregtech.common.metatileentities.storage.CraftingRecipeLogic; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; - -import com.cleanroommc.modularui.screen.ModularContainer; -import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import mezz.jei.api.gui.IGuiItemStackGroup; -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.recipe.transfer.IRecipeTransferError; -import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; -import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class GregTechGuiTransferHandler implements IRecipeTransferHandler { - - private final IRecipeTransferHandlerHelper handlerHelper; - - public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { - this.handlerHelper = handlerHelper; - } - - @Override - public @NotNull Class getContainerClass() { - return ModularContainer.class; - } - - @Override - public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, - @NotNull IRecipeLayout recipeLayout, - @NotNull EntityPlayer player, boolean maxTransfer, - boolean doTransfer) { - if (!container.getSyncManager().isOpen("workbench")) { - return null; - } - PanelSyncManager syncManager = container.getSyncManager().getPanelSyncManager("workbench"); - var recipeLogic = (CraftingRecipeLogic) syncManager.getSyncHandler("recipe_logic:0"); - var pageController = (PagedWidgetSyncHandler) syncManager.getSyncHandler("page_controller:0"); - - if (!doTransfer) { - // todo highlighting in JEI? - return null; - } - - var matrix = extractMatrix(recipeLayout.getItemStacks()); - recipeLogic.fillCraftingGrid(matrix); - pageController.setPage(0); - return null; - } - - private Int2ObjectMap extractMatrix(IGuiItemStackGroup stackGroup) { - var ingredients = stackGroup.getGuiIngredients(); - Int2ObjectMap matrix = new Int2ObjectArrayMap<>(9); - for (var slot : ingredients.keySet()) { - if (slot != 0) { - var ing = ingredients.get(slot).getDisplayedIngredient(); - if (ing == null) continue; - matrix.put(slot - 1, ingredients.get(slot).getDisplayedIngredient()); - } - } - return matrix; - } -} diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index eece105d06d..0314a8b23f9 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -1,12 +1,15 @@ package gregtech.common.metatileentities.storage; import gregtech.api.items.toolitem.ItemGTToolbelt; +import gregtech.api.mui.sync.PagedWidgetSyncHandler; +import gregtech.api.mui.sync.RecipeTransferSyncHandler; import gregtech.api.util.DummyContainer; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; import gregtech.common.mui.widget.workbench.CraftingInputSlot; +import gregtech.integration.jei.JustEnoughItemsModule; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IInventory; @@ -23,7 +26,6 @@ import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.network.NetworkUtils; -import com.cleanroommc.modularui.value.sync.SyncHandler; import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; import it.unimi.dsi.fastutil.ints.Int2BooleanMap; import it.unimi.dsi.fastutil.ints.Int2IntArrayMap; @@ -38,11 +40,18 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import mezz.jei.api.gui.IGuiIngredient; +import mezz.jei.api.gui.IGuiItemStackGroup; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.Map; -public class CraftingRecipeLogic extends SyncHandler { +public class CraftingRecipeLogic extends RecipeTransferSyncHandler { // client only public static final int UPDATE_INGREDIENTS = 1; @@ -120,6 +129,37 @@ public void fillCraftingGrid(Map ingredients) { updateCurrentRecipe(); } + @Override + public @Nullable IRecipeTransferError receiveRecipe(@NotNull IRecipeLayout recipeLayout, boolean maxTransfer, + boolean simulate) { + if (!recipeLayout.getRecipeCategory().getUid().equals(VanillaRecipeCategoryUid.CRAFTING)) { + JustEnoughItemsModule.transferHelper.createInternalError(); + } else if (simulate) { + // TODO: highlight missing items in recipe viewer + return null; + } + + Int2ObjectMap matrix = extractMatrix(recipeLayout.getItemStacks()); + fillCraftingGrid(matrix); + getSyncManager().findSyncHandler("page_controller", 0, PagedWidgetSyncHandler.class).setPage(0); + + return null; + } + + private Int2ObjectMap extractMatrix(IGuiItemStackGroup stackGroup) { + Map> ingredients = stackGroup.getGuiIngredients(); + Int2ObjectMap matrix = new Int2ObjectArrayMap<>(9); + for (int slot : ingredients.keySet()) { + if (slot != 0) { + ItemStack ingredient = ingredients.get(slot).getDisplayedIngredient(); + if (ingredient == null) continue; + matrix.put(slot - 1, ingredient); + } + } + + return matrix; + } + public void setInputSlot(CraftingInputSlot slot, int index) { this.inputSlots[index] = slot; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 3483c603223..c1d45fb6515 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -226,7 +226,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager, UI syncManager.syncValue("recipe_memory", this.recipeMemory); var controller = new PagedWidget.Controller(); - syncManager.syncValue("page_controller", new PagedWidgetSyncHandler(controller)); + syncManager.syncValue("page_controller", 0, new PagedWidgetSyncHandler(controller)); return GTGuis.createPanel(this, 176, 224) .child(Flow.row() diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 75c424483b4..cd578908577 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -12,7 +12,6 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; -import gregtech.api.mui.GregTechGuiTransferHandler; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.category.GTRecipeCategory; @@ -169,10 +168,6 @@ public void register(IModRegistry registry) { registry.getRecipeTransferRegistry().addRecipeTransferHandler(modularUIGuiHandler, Constants.UNIVERSAL_RECIPE_TRANSFER_UID); - // register transfer handler for crafting recipes - registry.getRecipeTransferRegistry().addRecipeTransferHandler(new GregTechGuiTransferHandler( - jeiHelpers.recipeTransferHandlerHelper()), VanillaRecipeCategoryUid.CRAFTING); - registry.addAdvancedGuiHandlers(modularUIGuiHandler); registry.addGhostIngredientHandler(modularUIGuiHandler.getGuiContainerClass(), modularUIGuiHandler); From 5ad8370f0bce7042b2c9a8003d67c750f42dd0c2 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 30 Nov 2025 00:22:49 -0500 Subject: [PATCH 05/13] Remove reference map because the fastutils reference maps don't clear entries that had their key or value GC'd unlike the WeakHashMap --- src/main/java/gregtech/api/mui/GregTechGuiScreen.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index 85dcf63636d..84bb49a661c 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -14,7 +14,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntComparators; -import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import org.jetbrains.annotations.NotNull; @@ -101,9 +101,7 @@ public static void registerRecipeTransferHandler(@NotNull String key, } } - // Reference map so the receiver might:tm: not stick around for too long if someone forgets to unregister their - // receiver. - registeredRecipeTransferReceivers.computeIfAbsent(priority, $ -> new Object2ReferenceOpenHashMap<>()) + registeredRecipeTransferReceivers.computeIfAbsent(priority, $ -> new Object2ObjectOpenHashMap<>()) .put(key, transferReceiver); } From 930935b3095864fcb21ef9d642815ef6f7c5863b Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 30 Nov 2025 00:24:54 -0500 Subject: [PATCH 06/13] Wrap (un)registration in a client-side check --- .../gregtech/api/mui/sync/RecipeTransferSyncHandler.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java index 53da6eecdf3..8943f960b84 100644 --- a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java @@ -19,7 +19,9 @@ public abstract class RecipeTransferSyncHandler extends SyncHandler implements I @Override public void init(String key, PanelSyncManager syncManager) { super.init(key, syncManager); - GregTechGuiScreen.registerRecipeTransferHandler(getKey(), this, getTransferHandlerPriority()); + if (syncManager.isClient()) { + GregTechGuiScreen.registerRecipeTransferHandler(getKey(), this, getTransferHandlerPriority()); + } } protected int getTransferHandlerPriority() { @@ -30,7 +32,9 @@ protected int getTransferHandlerPriority() { @MustBeInvokedByOverriders @Override public void dispose() { - GregTechGuiScreen.removeRecipeTransferHandler(getKey()); + if (getSyncManager().isClient()) { + GregTechGuiScreen.removeRecipeTransferHandler(getKey()); + } super.dispose(); } } From f9a10b5c656a6936995c99f08728b1795f698de6 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 30 Nov 2025 01:20:25 -0500 Subject: [PATCH 07/13] Only clear the receivers when the UI is actually being closed --- src/main/java/gregtech/api/mui/GregTechGuiScreen.java | 7 ++++++- .../gregtech/api/mui/sync/RecipeTransferSyncHandler.java | 1 + src/main/java/gregtech/client/ClientProxy.java | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index 84bb49a661c..05a346fdde3 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -1,6 +1,7 @@ package gregtech.api.mui; import gregtech.api.GTValues; +import gregtech.client.ClientProxy; import gregtech.integration.jei.JustEnoughItemsModule; import net.minecraftforge.fml.relauncher.Side; @@ -48,7 +49,11 @@ public GregTechGuiScreen(String owner, ModularPanel mainPanel, String themeId) { @Override public void onClose() { - registeredRecipeTransferReceivers.clear(); + // Only clear all registered recipe receivers when the UI is truly closing, ie not just opening JEI over it. + if (ClientProxy.isGUIClosingPermanently) { + // Clear all registered recipe receivers on UI close, just in case. + registeredRecipeTransferReceivers.clear(); + } } @Override diff --git a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java index 8943f960b84..dadb2afdd3c 100644 --- a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java @@ -28,6 +28,7 @@ protected int getTransferHandlerPriority() { return 0; } + // TODO: this method is never actually called. Either fix on our side or wait for it to get fixed in MUI. @ApiStatus.OverrideOnly @MustBeInvokedByOverriders @Override diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index f9b712309a2..fdc894c53f1 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -57,6 +57,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.GuiIngameForge; +import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.MouseEvent; @@ -86,6 +87,8 @@ @Mod.EventBusSubscriber(Side.CLIENT) public class ClientProxy extends CommonProxy { + public static boolean isGUIClosingPermanently = false; + public void onPreLoad() { super.onPreLoad(); @@ -428,4 +431,9 @@ private static void renderToolbeltHotbar(GuiIngameForge gui, ItemStack stack, It GlStateManager.disableBlend(); } } + + @SubscribeEvent + public static void onGuiChange(GuiOpenEvent event) { + isGUIClosingPermanently = (event.getGui() == null); + } } From 79403b7fd6192d2284f4b4ae48d56d35b914c62d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 6 Dec 2025 16:18:09 -0500 Subject: [PATCH 08/13] Update to MUI 3.0.5 --- dependencies.gradle | 2 +- .../java/gregtech/api/mui/GregTechGuiScreen.java | 4 ++++ .../api/mui/sync/FixedIntArraySyncValue.java | 14 ++++++++++++++ .../api/mui/sync/RecipeTransferSyncHandler.java | 1 - .../MetaTileEntityLargeCombustionEngine.java | 6 +++--- .../generator/MetaTileEntityLargeTurbine.java | 2 +- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 112c8e2d2c9..a0d91ab38d4 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,7 +40,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:3.0.4") { transitive = false } + api("com.cleanroommc:modularui:3.0.5") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } api("curse.maven:inventory-bogosorter-632327:7102721-deobf-6717233-sources-6717234") // Inventory BogoSorter − v1.5.0 api("curse.maven:key-binding-patch-928895:5951859") // Key Binding Patch v1.3.3.3, needed by Inventory BogoSorter v1.5.0+ diff --git a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java index 05a346fdde3..a938624c8f2 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiScreen.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiScreen.java @@ -27,6 +27,7 @@ public class GregTechGuiScreen extends ModularScreen implements RecipeViewerRecipeTransferHandler { // Stores lists of higher priority recipe receivers to the left of the tree + @SideOnly(Side.CLIENT) private static final Int2ObjectMap> registeredRecipeTransferReceivers = new Int2ObjectAVLTreeMap<>( IntComparators.OPPOSITE_COMPARATOR); @@ -81,6 +82,7 @@ public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean m * * @throws IllegalArgumentException if a receiver with the given key already exists. */ + @SideOnly(Side.CLIENT) public static void registerRecipeTransferHandler(@NotNull String key, @NotNull IRecipeTransferReceiver transferReceiver) { registerRecipeTransferHandler(key, transferReceiver, 0); @@ -96,6 +98,7 @@ public static void registerRecipeTransferHandler(@NotNull String key, * * @throws IllegalArgumentException if a receiver with the given key already exists. */ + @SideOnly(Side.CLIENT) public static void registerRecipeTransferHandler(@NotNull String key, @NotNull IRecipeTransferReceiver transferReceiver, int priority) { @@ -115,6 +118,7 @@ public static void registerRecipeTransferHandler(@NotNull String key, * * @throws IllegalArgumentException if no receiver exists with the given key. */ + @SideOnly(Side.CLIENT) public static void removeRecipeTransferHandler(@NotNull String key) { for (Map subMap : registeredRecipeTransferReceivers.values()) { if (subMap.containsKey(key)) { diff --git a/src/main/java/gregtech/api/mui/sync/FixedIntArraySyncValue.java b/src/main/java/gregtech/api/mui/sync/FixedIntArraySyncValue.java index c3f29ee80b5..5fe7e294604 100644 --- a/src/main/java/gregtech/api/mui/sync/FixedIntArraySyncValue.java +++ b/src/main/java/gregtech/api/mui/sync/FixedIntArraySyncValue.java @@ -25,6 +25,10 @@ public class FixedIntArraySyncValue extends ValueSyncHandler { private final Supplier getter; private final @Nullable Consumer setter; + public FixedIntArraySyncValue(@NotNull Supplier getter) { + this(getter, null); + } + public FixedIntArraySyncValue(@NotNull Supplier getter, @Nullable Consumer setter) { this.getter = Objects.requireNonNull(getter); this.setter = setter; @@ -70,6 +74,11 @@ public boolean updateCacheFromSource(boolean isFirstSync) { return false; } + @Override + public void notifyUpdate() { + setValue(this.getter.get(), false, true); + } + @Override public void write(@NotNull PacketBuffer buffer) throws IOException { for (int i : cache) { @@ -92,4 +101,9 @@ public int[] getValue() { public int getValue(int index) { return this.cache[index]; } + + @Override + public Class getValueType() { + return int[].class; + } } diff --git a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java index dadb2afdd3c..8943f960b84 100644 --- a/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/RecipeTransferSyncHandler.java @@ -28,7 +28,6 @@ protected int getTransferHandlerPriority() { return 0; } - // TODO: this method is never actually called. Either fix on our side or wait for it to get fixed in MUI. @ApiStatus.OverrideOnly @MustBeInvokedByOverriders @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 7c367d349b6..37c7f075a00 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -250,7 +250,7 @@ public int getProgressBarCount() { @Override public void registerBars(List> bars, PanelSyncManager syncManager) { - FixedIntArraySyncValue fuelValue = new FixedIntArraySyncValue(this::getFuelAmount, null); + FixedIntArraySyncValue fuelValue = new FixedIntArraySyncValue(this::getFuelAmount); syncManager.syncValue("fuel_amount", fuelValue); StringSyncValue fuelNameValue = new StringSyncValue(() -> { FluidStack stack = ((MultiblockFuelRecipeLogic) recipeMapWorkable).getInputFluidStack(); @@ -264,9 +264,9 @@ public void registerBars(List> bars, PanelSync return fluid.getName(); }); syncManager.syncValue("fuel_name", fuelNameValue); - FixedIntArraySyncValue lubricantValue = new FixedIntArraySyncValue(this::getLubricantAmount, null); + FixedIntArraySyncValue lubricantValue = new FixedIntArraySyncValue(this::getLubricantAmount); syncManager.syncValue("lubricant_amount", lubricantValue); - FixedIntArraySyncValue oxygenValue = new FixedIntArraySyncValue(this::getOxygenAmount, null); + FixedIntArraySyncValue oxygenValue = new FixedIntArraySyncValue(this::getOxygenAmount); syncManager.syncValue("oxygen_amount", oxygenValue); BooleanSyncValue boostValue = new BooleanSyncValue(this::isBoostAllowed); syncManager.syncValue("boost_allowed", boostValue); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java index 5a15302484d..ce69d58658b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeTurbine.java @@ -272,7 +272,7 @@ public int getProgressBarCount() { @Override public void registerBars(List> bars, PanelSyncManager syncManager) { - FixedIntArraySyncValue fuelValue = new FixedIntArraySyncValue(this::getFuelAmount, null); + FixedIntArraySyncValue fuelValue = new FixedIntArraySyncValue(this::getFuelAmount); StringSyncValue fuelNameValue = new StringSyncValue(() -> { FluidStack stack = ((MultiblockFuelRecipeLogic) recipeMapWorkable).getInputFluidStack(); if (stack == null) { From 80cdbb1a5246693ee0c769a3e53b13ecdca686c1 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 6 Dec 2025 16:30:53 -0500 Subject: [PATCH 09/13] Reword IRecipeTransferReceiver javadoc --- .../java/gregtech/api/mui/IRecipeTransferReceiver.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java index 6137d4037f6..32e2d3cfbd7 100644 --- a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -32,8 +32,7 @@ public interface IRecipeTransferReceiver { * A factory for default {@link IRecipeTransferError}s is available at {@link JustEnoughItemsModule#transferHelper}. * There are three default options for errors:
* - {@link IRecipeTransferHandlerHelper#createInternalError()}: mark the recipe as invalid for transferring by - * graying out the + button. If there are multiple registered recipe transfer receivers on the same panel, returning - * an internal error will skip this receiver and try the others.
+ * graying out the + button.
* - {@link IRecipeTransferHandlerHelper#createUserErrorWithTooltip(String)}: the same as above, but also display a * message when hovering over the + button.
* - {@link IRecipeTransferHandlerHelper#createUserErrorForSlots(String, Collection)}: the same as above, but @@ -44,7 +43,9 @@ public interface IRecipeTransferReceiver { * @param maxTransfer if the receiver should try to move as many ingredients as possible to the crafting slots, ie * a crafting table. * @param simulate if this recipe should only simulate being transferred - * @return {@code null} if the transfer should succeed or a {@link IRecipeTransferError} if not. + * @return {@code null} if the transfer should succeed or an {@link IRecipeTransferError} if not. If there are + * multiple registered recipe transfer receivers on the same panel, returning an error with type + * {@link IRecipeTransferError.Type#INTERNAL} will skip this and attempt the next one. */ @Nullable @SideOnly(Side.CLIENT) From 633ae5aa9932541f22452c3cf003137b7e1da15a Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sat, 6 Dec 2025 16:32:58 -0500 Subject: [PATCH 10/13] Reword IRecipeTransferReceiver javadoc pt2 --- src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java index 32e2d3cfbd7..148b6b88620 100644 --- a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -41,7 +41,7 @@ public interface IRecipeTransferReceiver { * * @param recipeLayout the recipe layout that contains the recipe category, and the item and fluid stacks. * @param maxTransfer if the receiver should try to move as many ingredients as possible to the crafting slots, ie - * a crafting table. + * shift clicking a recipe into a crafting table. * @param simulate if this recipe should only simulate being transferred * @return {@code null} if the transfer should succeed or an {@link IRecipeTransferError} if not. If there are * multiple registered recipe transfer receivers on the same panel, returning an error with type From 92436357a5bca2ea9341bf9875ecb271e7d0e88d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Thu, 11 Dec 2025 16:04:43 -0500 Subject: [PATCH 11/13] MUI 3.0.6 --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index a0d91ab38d4..f70b692ae2b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,7 +40,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:3.0.5") { transitive = false } + api("com.cleanroommc:modularui:3.0.6") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } api("curse.maven:inventory-bogosorter-632327:7102721-deobf-6717233-sources-6717234") // Inventory BogoSorter − v1.5.0 api("curse.maven:key-binding-patch-928895:5951859") // Key Binding Patch v1.3.3.3, needed by Inventory BogoSorter v1.5.0+ From 4363e27c3644872ecd7dbdaaf1b23c0bd6e0307f Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Thu, 11 Dec 2025 16:08:17 -0500 Subject: [PATCH 12/13] touch up IRecipeTransferReceiver javadoc --- .../java/gregtech/api/mui/IRecipeTransferReceiver.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java index 148b6b88620..ea963c7c3fd 100644 --- a/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java +++ b/src/main/java/gregtech/api/mui/IRecipeTransferReceiver.java @@ -22,8 +22,8 @@ * Register it via {@link GregTechGuiScreen#registerRecipeTransferHandler(String, IRecipeTransferReceiver)} or * {@link GregTechGuiScreen#registerRecipeTransferHandler(String, IRecipeTransferReceiver, int)} if you want to * prioritize checking a certain handler first.
- * If you're implementing this on a {@link SyncHandler}, it's recommended to extend {@link RecipeTransferSyncHandler} so - * registering and unregistering from {@link GregTechGuiScreen} is done for you. + * If you're implementing this on a {@link SyncHandler}, it's recommended to extend {@link RecipeTransferSyncHandler} + * instead as registering and unregistering from {@link GregTechGuiScreen} is done for you. */ public interface IRecipeTransferReceiver { @@ -36,8 +36,8 @@ public interface IRecipeTransferReceiver { * - {@link IRecipeTransferHandlerHelper#createUserErrorWithTooltip(String)}: the same as above, but also display a * message when hovering over the + button.
* - {@link IRecipeTransferHandlerHelper#createUserErrorForSlots(String, Collection)}: the same as above, but - * additionally highlight certain slots in the recipe to, for example, mark missing ingredients. Important: will - * throw {@link IllegalArgumentException} if the supplied {@link Collection} is empty! + * additionally highlight certain slots in the recipe to, for example, mark missing ingredients. Important: will + * throw {@link IllegalArgumentException} if the supplied {@link Collection} is empty! * * @param recipeLayout the recipe layout that contains the recipe category, and the item and fluid stacks. * @param maxTransfer if the receiver should try to move as many ingredients as possible to the crafting slots, ie From f6943c10aa7e7ed3c09208f181fad78e402e99b0 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 12 Dec 2025 19:04:06 -0500 Subject: [PATCH 13/13] Remove name set from panel in MultiblockUIFactory --- .../api/metatileentity/multiblock/ui/MultiblockUIFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/ui/MultiblockUIFactory.java b/src/main/java/gregtech/api/metatileentity/multiblock/ui/MultiblockUIFactory.java index bdd21a36b27..f1e70af7e1e 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/ui/MultiblockUIFactory.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/ui/MultiblockUIFactory.java @@ -234,7 +234,6 @@ public MultiblockUIFactory addScreenChildren(ScreenFunction function) { */ public @NotNull ModularPanel buildUI(PosGuiData guiData, PanelSyncManager panelSyncManager) { var panel = GTGuis.createPanel(mte, width, height) - .debugName("root_panel") .childIf(!disableDisplay, () -> createScreen(panelSyncManager)); // TODO createExtras() hook for overrides?