ソースを参照

Fixes Bugs

Close #13
Close #15
Close #18
Unknown 6 年 前
コミット
e7ba883bee
29 ファイル変更295 行追加295 行削除
  1. 3 3
      build.gradle
  2. 4 0
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  3. 5 2
      src/main/java/me/shedaniel/rei/api/IRecipeCategory.java
  4. 4 0
      src/main/java/me/shedaniel/rei/api/SpeedCraftAreaSupplier.java
  5. 6 7
      src/main/java/me/shedaniel/rei/client/ClientHelper.java
  6. 24 10
      src/main/java/me/shedaniel/rei/client/GuiHelper.java
  7. 34 29
      src/main/java/me/shedaniel/rei/client/RecipeHelper.java
  8. 18 31
      src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java
  9. 3 5
      src/main/java/me/shedaniel/rei/gui/widget/CraftableToggleButtonWidget.java
  10. 9 1
      src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java
  11. 19 21
      src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java
  12. 11 18
      src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java
  13. 3 1
      src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java
  14. 32 75
      src/main/java/me/shedaniel/rei/gui/widget/RecipeViewingWidget.java
  15. 45 0
      src/main/java/me/shedaniel/rei/gui/widget/SpeedCraftingButtonWidget.java
  16. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java
  17. 0 3
      src/main/java/me/shedaniel/rei/listeners/IMixinContainerGui.java
  18. 6 10
      src/main/java/me/shedaniel/rei/mixin/MixinBrewingRecipeRegistry.java
  19. 10 17
      src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java
  20. 4 5
      src/main/java/me/shedaniel/rei/plugin/DefaultBlastingCategory.java
  21. 12 8
      src/main/java/me/shedaniel/rei/plugin/DefaultBrewingCategory.java
  22. 3 4
      src/main/java/me/shedaniel/rei/plugin/DefaultCampfireCategory.java
  23. 3 4
      src/main/java/me/shedaniel/rei/plugin/DefaultCraftingCategory.java
  24. 24 23
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  25. 4 5
      src/main/java/me/shedaniel/rei/plugin/DefaultSmeltingCategory.java
  26. 4 5
      src/main/java/me/shedaniel/rei/plugin/DefaultSmokingCategory.java
  27. 3 5
      src/main/java/me/shedaniel/rei/plugin/DefaultStoneCuttingCategory.java
  28. 0 1
      src/main/java/me/shedaniel/rei/plugin/DefaultStoneCuttingDisplay.java
  29. 1 1
      src/main/resources/fabric.mod.json

+ 3 - 3
build.gradle

@@ -6,11 +6,11 @@ sourceCompatibility = 1.8
 targetCompatibility = 1.8
 
 archivesBaseName = "RoughlyEnoughItems"
-version = "2.1.0.45"
+version = "2.2.0.46"
 
 def minecraftVersion = "19w04a"
 def yarnVersion = "19w04a.2"
-def fabricVersion = "0.1.4.79"
+def fabricVersion = "0.1.5.83"
 def pluginLoaderVersion = "1.14-1.0.6-8"
 
 minecraft {
@@ -30,7 +30,7 @@ repositories {
 dependencies {
 	minecraft "com.mojang:minecraft:${minecraftVersion}"
 	mappings "net.fabricmc:yarn:${yarnVersion}"
-	modCompile "net.fabricmc:fabric-loader:0.3.3.101"
+	modCompile "net.fabricmc:fabric-loader:0.3.3.102"
 
 	// Fabric API. This is technically optional, but you probably want it anyway.
 	modCompile "net.fabricmc:fabric:${fabricVersion}"

+ 4 - 0
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -4,11 +4,13 @@ import com.google.common.collect.Maps;
 import me.shedaniel.rei.api.IRecipePlugin;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.ConfigHelper;
+import me.shedaniel.rei.client.GuiHelper;
 import me.shedaniel.rei.client.RecipeHelper;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.api.ModInitializer;
 import net.fabricmc.api.loader.Loader;
+import net.fabricmc.fabric.events.client.ClientTickEvent;
 import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
@@ -71,6 +73,8 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
             registerPlugin(new Identifier("roughlyenoughitems", "default_plugin"), new DefaultPlugin());
         }
         configHelper = new ConfigHelper();
+        
+        ClientTickEvent.CLIENT.register(GuiHelper::onTick);
     }
     
     @Override

+ 5 - 2
src/main/java/me/shedaniel/rei/api/IRecipeCategory.java

@@ -4,7 +4,6 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
 import me.shedaniel.rei.gui.widget.RecipeViewingWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Drawable;
 import net.minecraft.client.render.GuiLighting;
@@ -28,7 +27,7 @@ public interface IRecipeCategory<T extends IRecipeDisplay> {
         return false;
     }
     
-    default public List<IWidget> setupDisplay(IMixinContainerGui containerGui, T recipeDisplay, Rectangle bounds) {
+    default public List<IWidget> setupDisplay(T recipeDisplay, Rectangle bounds) {
         return Arrays.asList(new RecipeBaseWidget(bounds));
     }
     
@@ -41,4 +40,8 @@ public interface IRecipeCategory<T extends IRecipeDisplay> {
         }.drawTexturedRect((int) bounds.getX(), (int) bounds.getY(), 0, 0, (int) bounds.getWidth(), (int) bounds.getHeight());
     }
     
+    default public boolean checkTags() {
+        return false;
+    }
+    
 }

+ 4 - 0
src/main/java/me/shedaniel/rei/api/SpeedCraftAreaSupplier.java

@@ -6,4 +6,8 @@ public interface SpeedCraftAreaSupplier {
     
     public Rectangle get(Rectangle bounds);
     
+    default String getButtonText() {
+        return "+";
+    }
+    
 }

+ 6 - 7
src/main/java/me/shedaniel/rei/client/ClientHelper.java

@@ -9,7 +9,6 @@ import me.shedaniel.rei.api.IRecipeDisplay;
 import me.shedaniel.rei.gui.ContainerGuiOverlay;
 import me.shedaniel.rei.gui.widget.ConfigWidget;
 import me.shedaniel.rei.gui.widget.RecipeViewingWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
@@ -116,17 +115,17 @@ public class ClientHelper implements ClientModInitializer {
         }
     }
     
-    public static boolean executeRecipeKeyBind(ContainerGuiOverlay overlay, ItemStack stack, IMixinContainerGui parent) {
-        Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getRecipesFor(stack);
+    public static boolean executeRecipeKeyBind(ContainerGuiOverlay overlay, ItemStack stack) {
+        Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getInstance().getRecipesFor(stack);
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, parent, map));
+            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, map));
         return map.keySet().size() > 0;
     }
     
-    public static boolean executeUsageKeyBind(ContainerGuiOverlay overlay, ItemStack stack, IMixinContainerGui parent) {
-        Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getUsagesFor(stack);
+    public static boolean executeUsageKeyBind(ContainerGuiOverlay overlay, ItemStack stack) {
+        Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getInstance().getUsagesFor(stack);
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, parent, map));
+            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, map));
         return map.keySet().size() > 0;
     }
     

+ 24 - 10
src/main/java/me/shedaniel/rei/client/GuiHelper.java

@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
 import me.shedaniel.rei.gui.ContainerGuiOverlay;
 import me.shedaniel.rei.gui.widget.TextFieldWidget;
 import me.shedaniel.rei.listeners.IMixinContainerGui;
+import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.ContainerGui;
 import net.minecraft.item.ItemStack;
 
@@ -15,6 +16,8 @@ public class GuiHelper {
     private static boolean overlayVisible = true;
     private static ContainerGuiOverlay overlay;
     public static List<ItemStack> inventoryStacks = Lists.newArrayList();
+    private static ContainerGui lastContainerGui;
+    private static IMixinContainerGui lastMixinContainerGui;
     
     public static boolean isOverlayVisible() {
         return overlayVisible;
@@ -24,14 +27,6 @@ public class GuiHelper {
         overlayVisible = !overlayVisible;
     }
     
-    public static ContainerGuiOverlay getOverlay(IMixinContainerGui lastGui) {
-        if (overlay == null) {
-            overlay = new ContainerGuiOverlay(lastGui);
-            overlay.onInitialized();
-        }
-        return overlay;
-    }
-    
     public static ContainerGuiOverlay getLastOverlay() {
         return overlay;
     }
@@ -41,8 +36,27 @@ public class GuiHelper {
         overlay.onInitialized();
     }
     
-    public static void resetOverlay() {
-        overlay = null;
+    public static void onTick(MinecraftClient client) {
+        if (client.currentGui instanceof ContainerGui && lastContainerGui != client.currentGui) {
+            GuiHelper.lastContainerGui = (ContainerGui) client.currentGui;
+            GuiHelper.lastMixinContainerGui = (IMixinContainerGui) lastContainerGui;
+        }
+    }
+    
+    public static ContainerGui getLastContainerGui() {
+        return lastContainerGui;
+    }
+    
+    public static IMixinContainerGui getLastMixinContainerGui() {
+        return lastMixinContainerGui;
+    }
+    
+    public static void setLastContainerGui(ContainerGui lastContainerGui) {
+        GuiHelper.lastContainerGui = lastContainerGui;
+    }
+    
+    public static void setLastMixinContainerGui(IMixinContainerGui lastMixinContainerGui) {
+        GuiHelper.lastMixinContainerGui = lastMixinContainerGui;
     }
     
 }

+ 34 - 29
src/main/java/me/shedaniel/rei/client/RecipeHelper.java

@@ -15,20 +15,17 @@ import java.util.stream.Collectors;
 
 public class RecipeHelper {
     
-    private static Map<Identifier, List<IRecipeDisplay>> recipeCategoryListMap;
-    private static List<IRecipeCategory> categories;
-    private static RecipeManager recipeManager;
-    private static Map<Identifier, SpeedCraftAreaSupplier> speedCraftAreaSupplierMap;
-    private static Map<Identifier, List<SpeedCraftFunctional>> speedCraftFunctionalMap;
-    
-    public RecipeHelper() {
-        this.recipeCategoryListMap = Maps.newHashMap();
-        this.categories = Lists.newArrayList();
-        this.speedCraftAreaSupplierMap = Maps.newHashMap();
-        this.speedCraftFunctionalMap = Maps.newHashMap();
+    private final Map<Identifier, List<IRecipeDisplay>> recipeCategoryListMap = Maps.newHashMap();
+    private final List<IRecipeCategory> categories = Lists.newArrayList();
+    private final Map<Identifier, SpeedCraftAreaSupplier> speedCraftAreaSupplierMap = Maps.newHashMap();
+    private final Map<Identifier, List<SpeedCraftFunctional>> speedCraftFunctionalMap = Maps.newHashMap();
+    private RecipeManager recipeManager;
+    
+    public static RecipeHelper getInstance() {
+        return RoughlyEnoughItemsCore.getRecipeHelper();
     }
     
-    public static List<ItemStack> findCraftableByItems(List<ItemStack> inventoryItems) {
+    public List<ItemStack> findCraftableByItems(List<ItemStack> inventoryItems) {
         List<ItemStack> craftables = new ArrayList<>();
         for(List<IRecipeDisplay> value : recipeCategoryListMap.values())
             for(IRecipeDisplay recipeDisplay : value) {
@@ -57,25 +54,27 @@ public class RecipeHelper {
         return craftables.stream().distinct().collect(Collectors.toList());
     }
     
-    public static void registerCategory(IRecipeCategory category) {
+    public void registerCategory(IRecipeCategory category) {
         categories.add(category);
         recipeCategoryListMap.put(category.getIdentifier(), Lists.newArrayList());
     }
     
-    public static void registerRecipe(Identifier categoryIdentifier, IRecipeDisplay display) {
+    public void registerRecipe(Identifier categoryIdentifier, IRecipeDisplay display) {
         if (!recipeCategoryListMap.containsKey(categoryIdentifier))
             return;
         recipeCategoryListMap.get(categoryIdentifier).add(display);
     }
     
-    public static Map<IRecipeCategory, List<IRecipeDisplay>> getRecipesFor(ItemStack stack) {
+    public Map<IRecipeCategory, List<IRecipeDisplay>> getRecipesFor(ItemStack stack) {
         Map<Identifier, List<IRecipeDisplay>> categoriesMap = new HashMap<>();
         categories.forEach(f -> categoriesMap.put(f.getIdentifier(), new LinkedList<>()));
-        for(List<IRecipeDisplay> value : recipeCategoryListMap.values())
-            for(IRecipeDisplay recipeDisplay : value)
+        for(Map.Entry<Identifier, List<IRecipeDisplay>> entry : recipeCategoryListMap.entrySet()) {
+            IRecipeCategory category = getCategory(entry.getKey());
+            for(IRecipeDisplay recipeDisplay : entry.getValue())
                 for(ItemStack outputStack : (List<ItemStack>) recipeDisplay.getOutput())
-                    if (ItemStack.areEqualIgnoreTags(stack, outputStack))
+                    if (category.checkTags() ? ItemStack.areEqual(stack, outputStack) : ItemStack.areEqualIgnoreTags(stack, outputStack))
                         categoriesMap.get(recipeDisplay.getRecipeCategory()).add(recipeDisplay);
+        }
         categoriesMap.keySet().removeIf(f -> categoriesMap.get(f).isEmpty());
         Map<IRecipeCategory, List<IRecipeDisplay>> recipeCategoryListMap = Maps.newHashMap();
         categories.forEach(category -> {
@@ -85,19 +84,24 @@ public class RecipeHelper {
         return recipeCategoryListMap;
     }
     
-    public static RecipeManager getRecipeManager() {
+    private IRecipeCategory getCategory(Identifier identifier) {
+        return categories.stream().filter(category -> category.getIdentifier().equals(identifier)).findFirst().orElse(null);
+    }
+    
+    public RecipeManager getRecipeManager() {
         return recipeManager;
     }
     
-    public static Map<IRecipeCategory, List<IRecipeDisplay>> getUsagesFor(ItemStack stack) {
+    public Map<IRecipeCategory, List<IRecipeDisplay>> getUsagesFor(ItemStack stack) {
         Map<Identifier, List<IRecipeDisplay>> categoriesMap = new HashMap<>();
         categories.forEach(f -> categoriesMap.put(f.getIdentifier(), new LinkedList<>()));
-        for(List<IRecipeDisplay> value : recipeCategoryListMap.values())
-            for(IRecipeDisplay recipeDisplay : value) {
+        for(Map.Entry<Identifier, List<IRecipeDisplay>> entry : recipeCategoryListMap.entrySet()) {
+            IRecipeCategory category = getCategory(entry.getKey());
+            for(IRecipeDisplay recipeDisplay : entry.getValue()) {
                 boolean found = false;
                 for(List<ItemStack> input : (List<List<ItemStack>>) recipeDisplay.getInput()) {
                     for(ItemStack itemStack : input) {
-                        if (ItemStack.areEqualIgnoreTags(itemStack, stack)) {
+                        if (category.checkTags() ? ItemStack.areEqual(itemStack, stack) : ItemStack.areEqualIgnoreTags(itemStack, stack)) {
                             categoriesMap.get(recipeDisplay.getRecipeCategory()).add(recipeDisplay);
                             found = true;
                             break;
@@ -107,6 +111,7 @@ public class RecipeHelper {
                         break;
                 }
             }
+        }
         categoriesMap.keySet().removeIf(f -> categoriesMap.get(f).isEmpty());
         Map<IRecipeCategory, List<IRecipeDisplay>> recipeCategoryListMap = Maps.newHashMap();
         categories.forEach(category -> {
@@ -116,11 +121,11 @@ public class RecipeHelper {
         return recipeCategoryListMap;
     }
     
-    public static List<IRecipeCategory> getCategories() {
-        return categories;
+    public List<IRecipeCategory> getCategories() {
+        return new LinkedList<>(categories);
     }
     
-    public static SpeedCraftAreaSupplier getSpeedCraftButtonArea(IRecipeCategory category) {
+    public SpeedCraftAreaSupplier getSpeedCraftButtonArea(IRecipeCategory category) {
         if (!speedCraftAreaSupplierMap.containsKey(category.getIdentifier()))
             return bounds -> {
                 return new Rectangle((int) bounds.getMaxX() - 16, (int) bounds.getMaxY() - 16, 10, 10);
@@ -128,17 +133,17 @@ public class RecipeHelper {
         return speedCraftAreaSupplierMap.get(category.getIdentifier());
     }
     
-    public static void registerSpeedCraftButtonArea(Identifier category, SpeedCraftAreaSupplier rectangle) {
+    public void registerSpeedCraftButtonArea(Identifier category, SpeedCraftAreaSupplier rectangle) {
         speedCraftAreaSupplierMap.put(category, rectangle);
     }
     
-    public static List<SpeedCraftFunctional> getSpeedCraftFunctional(IRecipeCategory category) {
+    public List<SpeedCraftFunctional> getSpeedCraftFunctional(IRecipeCategory category) {
         if (speedCraftFunctionalMap.get(category.getIdentifier()) == null)
             return Lists.newArrayList();
         return speedCraftFunctionalMap.get(category.getIdentifier());
     }
     
-    public static void registerSpeedCraftFunctional(Identifier category, SpeedCraftFunctional functional) {
+    public void registerSpeedCraftFunctional(Identifier category, SpeedCraftFunctional functional) {
         List<SpeedCraftFunctional> list = speedCraftFunctionalMap.containsKey(category) ? new LinkedList<>(speedCraftFunctionalMap.get(category)) : Lists.newLinkedList();
         list.add(functional);
         speedCraftFunctionalMap.put(category, list);

+ 18 - 31
src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java

@@ -1,11 +1,11 @@
 package me.shedaniel.rei.gui;
 
+import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.GuiHelper;
 import me.shedaniel.rei.gui.widget.*;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.ContainerGui;
 import net.minecraft.client.gui.Gui;
@@ -17,7 +17,6 @@ import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.MathHelper;
 
 import java.awt.*;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -25,34 +24,25 @@ import java.util.stream.Collectors;
 
 public class ContainerGuiOverlay extends Gui {
     
+    private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
     public static String searchTerm = "";
     private static int page = 0;
     private static ItemListOverlay itemListOverlay;
-    private final List<IWidget> widgets;
-    private final List<QueuedTooltip> queuedTooltips;
+    private final List<IWidget> widgets = Lists.newArrayList();
     private Rectangle rectangle;
-    private IMixinContainerGui containerGui;
     private Window window;
     private ButtonWidget buttonLeft, buttonRight;
     private int lastLeft;
     
-    public ContainerGuiOverlay(IMixinContainerGui containerGui) {
-        this.queuedTooltips = new ArrayList<>();
-        this.containerGui = containerGui;
-        this.widgets = new ArrayList<>();
-    }
-    
     public void onInitialized() {
         //Update Variables
         this.widgets.clear();
         this.window = MinecraftClient.getInstance().window;
-        if (MinecraftClient.getInstance().currentGui instanceof ContainerGui)
-            this.containerGui = (IMixinContainerGui) MinecraftClient.getInstance().currentGui;
         this.rectangle = calculateBoundary();
-        widgets.add(this.itemListOverlay = new ItemListOverlay(containerGui, page));
         this.lastLeft = getLeft();
-        
+        widgets.add(this.itemListOverlay = new ItemListOverlay(page));
         this.itemListOverlay.updateList(getItemListArea(), page, searchTerm);
+        
         widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, "<") {
             @Override
             public void onPressed(int button, double mouseX, double mouseY) {
@@ -87,7 +77,7 @@ public class ContainerGuiOverlay extends Gui {
         widgets.add(new ButtonWidget(10, 35, 40, 20, I18n.translate("text.rei.config")) {
             @Override
             public void onPressed(int button, double mouseX, double mouseY) {
-                ClientHelper.openConfigWindow(containerGui.getContainerGui());
+                ClientHelper.openConfigWindow(GuiHelper.getLastContainerGui());
             }
         });
         this.widgets.add(new LabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, "") {
@@ -117,7 +107,7 @@ public class ContainerGuiOverlay extends Gui {
         this.widgets.add(GuiHelper.searchField);
         GuiHelper.searchField.setText(searchTerm);
         if (RoughlyEnoughItemsCore.getConfigHelper().showCraftableOnlyButton())
-            this.widgets.add(new CraftableToggleButtonWidget(containerGui, getCraftableToggleArea()) {
+            this.widgets.add(new CraftableToggleButtonWidget(getCraftableToggleArea()) {
                 @Override
                 public void onPressed(int button, double mouseX, double mouseY) {
                     RoughlyEnoughItemsCore.getConfigHelper().toggleCraftableOnly();
@@ -125,6 +115,7 @@ public class ContainerGuiOverlay extends Gui {
                 }
             });
         
+        this.itemListOverlay.updateList(getItemListArea(), page, searchTerm);
         this.listeners.addAll(widgets);
     }
     
@@ -136,7 +127,7 @@ public class ContainerGuiOverlay extends Gui {
             RecipeViewingWidget widget = (RecipeViewingWidget) MinecraftClient.getInstance().currentGui;
             return new Rectangle(widget.getBounds().x, window.getScaledHeight() - 22, widget.getBounds().width - widthRemoved, 18);
         }
-        return new Rectangle(containerGui.getContainerLeft(), window.getScaledHeight() - 22, containerGui.getContainerWidth() - widthRemoved, 18);
+        return new Rectangle(GuiHelper.getLastMixinContainerGui().getContainerLeft(), window.getScaledHeight() - 22, GuiHelper.getLastMixinContainerGui().getContainerWidth() - widthRemoved, 18);
     }
     
     private Rectangle getCraftableToggleArea() {
@@ -170,8 +161,8 @@ public class ContainerGuiOverlay extends Gui {
         GuiLighting.disable();
         this.draw(mouseX, mouseY, partialTicks);
         GuiLighting.disable();
-        queuedTooltips.forEach(queuedTooltip -> containerGui.getContainerGui().drawTooltip(queuedTooltip.text, queuedTooltip.mouse.x, queuedTooltip.mouse.y));
-        queuedTooltips.clear();
+        QUEUED_TOOLTIPS.stream().filter(queuedTooltip -> queuedTooltip != null).forEach(queuedTooltip -> MinecraftClient.getInstance().currentGui.drawTooltip(queuedTooltip.text, queuedTooltip.mouse.x, queuedTooltip.mouse.y));
+        QUEUED_TOOLTIPS.clear();
         GuiLighting.disable();
     }
     
@@ -190,12 +181,8 @@ public class ContainerGuiOverlay extends Gui {
         return lastString.equals(currentString);
     }
     
-    public void setContainerGui(IMixinContainerGui containerGui) {
-        this.containerGui = containerGui;
-    }
-    
     public void addTooltip(QueuedTooltip queuedTooltip) {
-        queuedTooltips.add(queuedTooltip);
+        QUEUED_TOOLTIPS.add(queuedTooltip);
     }
     
     @Override
@@ -213,7 +200,7 @@ public class ContainerGuiOverlay extends Gui {
     }
     
     private Rectangle calculateBoundary() {
-        int startX = containerGui.getContainerLeft() + containerGui.getContainerWidth() + 10;
+        int startX = GuiHelper.getLastMixinContainerGui().getContainerLeft() + GuiHelper.getLastMixinContainerGui().getContainerWidth() + 10;
         int width = window.getScaledWidth() - startX;
         if (MinecraftClient.getInstance().currentGui instanceof RecipeViewingWidget) {
             RecipeViewingWidget widget = (RecipeViewingWidget) MinecraftClient.getInstance().currentGui;
@@ -228,7 +215,7 @@ public class ContainerGuiOverlay extends Gui {
             RecipeViewingWidget widget = (RecipeViewingWidget) MinecraftClient.getInstance().currentGui;
             return widget.getBounds().x;
         }
-        return containerGui.getContainerLeft();
+        return GuiHelper.getLastMixinContainerGui().getContainerLeft();
     }
     
     private int getTotalPage() {
@@ -273,13 +260,13 @@ public class ContainerGuiOverlay extends Gui {
                 }
         }
         if (itemStack == null && MinecraftClient.getInstance().currentGui instanceof ContainerGui)
-            if (containerGui.getHoveredSlot() != null)
-                itemStack = containerGui.getHoveredSlot().getStack();
+            if (GuiHelper.getLastMixinContainerGui().getHoveredSlot() != null)
+                itemStack = GuiHelper.getLastMixinContainerGui().getHoveredSlot().getStack();
         if (itemStack != null && !itemStack.isEmpty()) {
             if (ClientHelper.RECIPE.matchesKey(int_1, int_2))
-                return ClientHelper.executeRecipeKeyBind(this, itemStack, containerGui);
+                return ClientHelper.executeRecipeKeyBind(this, itemStack);
             else if (ClientHelper.USAGE.matchesKey(int_1, int_2))
-                return ClientHelper.executeUsageKeyBind(this, itemStack, containerGui);
+                return ClientHelper.executeUsageKeyBind(this, itemStack);
         }
         if (ClientHelper.HIDE.matchesKey(int_1, int_2)) {
             GuiHelper.toggleOverlayVisible();

+ 3 - 5
src/main/java/me/shedaniel/rei/gui/widget/CraftableToggleButtonWidget.java

@@ -4,7 +4,6 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.GuiHelper;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -20,14 +19,13 @@ public abstract class CraftableToggleButtonWidget extends ButtonWidget {
     
     protected static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private ItemRenderer itemRenderer;
-    private IMixinContainerGui containerGui;
     
-    public CraftableToggleButtonWidget(IMixinContainerGui containerGui, Rectangle rectangle) {
-        this(containerGui, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+    public CraftableToggleButtonWidget(Rectangle rectangle) {
+        this(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
         this.itemRenderer = MinecraftClient.getInstance().getItemRenderer();
     }
     
-    public CraftableToggleButtonWidget(IMixinContainerGui containerGui, int x, int y, int width, int height) {
+    public CraftableToggleButtonWidget(int x, int y, int width, int height) {
         super(x, y, width, height, "");
         this.itemRenderer = MinecraftClient.getInstance().getItemRenderer();
     }

+ 9 - 1
src/main/java/me/shedaniel/rei/gui/widget/HighlightableWidget.java

@@ -7,7 +7,15 @@ public interface HighlightableWidget extends IWidget {
     public Rectangle getBounds();
     
     default boolean isHighlighted(int mouseX, int mouseY) {
-        return getBounds().contains(new Point(mouseX, mouseY));
+        return getBounds().contains(mouseX, mouseY);
+    }
+    
+    default boolean isHighlighted(Point point) {
+        return this.isHighlighted(point.x, point.y);
+    }
+    
+    default boolean isHighlighted(double mouseX, double mouseY) {
+        return this.isHighlighted((int) mouseX, (int) mouseY);
     }
     
 }

+ 19 - 21
src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java

@@ -3,7 +3,6 @@ package me.shedaniel.rei.gui.widget;
 import com.google.common.collect.Lists;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.client.*;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Drawable;
 import net.minecraft.client.item.TooltipOptions;
@@ -23,15 +22,13 @@ import java.util.stream.Stream;
 
 public class ItemListOverlay extends Drawable implements IWidget {
     
-    private IMixinContainerGui containerGui;
     private List<IWidget> widgets = new ArrayList<>();
     private int width, height, page;
-    private Rectangle rectangle;
+    private Rectangle rectangle, listArea;
     private List<ItemStack> currentDisplayed;
     
-    public ItemListOverlay(IMixinContainerGui containerGui, int page) {
+    public ItemListOverlay(int page) {
         this.currentDisplayed = Lists.newArrayList();
-        this.containerGui = containerGui;
         this.width = 0;
         this.height = 0;
         this.page = page;
@@ -46,28 +43,29 @@ public class ItemListOverlay extends Drawable implements IWidget {
         widgets.forEach(widget -> widget.draw(int_1, int_2, float_1));
         ClientPlayerEntity player = MinecraftClient.getInstance().player;
         if (rectangle.contains(ClientHelper.getMouseLocation()) && ClientHelper.isCheating() && !player.inventory.getCursorStack().isEmpty() && MinecraftClient.getInstance().isInSingleplayer())
-            GuiHelper.getOverlay(containerGui).addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.rei.delete_items"))));
+            GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.rei.delete_items"))));
     }
     
     public void updateList(int page, String searchTerm) {
         updateList(rectangle, page, searchTerm);
     }
     
-    public void updateList(Rectangle rect, int page, String searchTerm) {
-        this.rectangle = rect;
+    public void updateList(Rectangle bounds, int page, String searchTerm) {
+        this.rectangle = bounds;
         if (ClientHelper.getItemList().isEmpty())
             RoughlyEnoughItemsCore.getClientHelper().clientLoaded();
         currentDisplayed = processSearchTerm(searchTerm, ClientHelper.getItemList(), GuiHelper.inventoryStacks);
         this.widgets.clear();
         this.page = page;
-        calculateListSize(rect);
-        double startX = rect.getCenterX() - width * 9;
-        double startY = rect.getCenterY() - height * 9;
+        calculateListSize(rectangle);
+        double startX = rectangle.getCenterX() - width * 9;
+        double startY = rectangle.getCenterY() - height * 9;
+        this.listArea = new Rectangle((int) startX, (int) startY, width * 18, height * 18);
         for(int i = 0; i < getTotalSlotsPerPage(); i++) {
             int j = i + page * getTotalSlotsPerPage();
             if (j >= currentDisplayed.size())
                 break;
-            widgets.add(new ItemSlotWidget((int) (startX + (i % width) * 18), (int) (startY + MathHelper.floor(i / width) * 18), currentDisplayed.get(j), false, true, containerGui) {
+            ItemSlotWidget slotWidget = new ItemSlotWidget((int) (startX + (i % width) * 18), (int) (startY + MathHelper.floor(i / width) * 18), currentDisplayed.get(j), false, true) {
                 @Override
                 protected void drawToolTip(ItemStack itemStack) {
                     ClientPlayerEntity player = MinecraftClient.getInstance().player;
@@ -77,23 +75,23 @@ public class ItemListOverlay extends Drawable implements IWidget {
                 
                 @Override
                 public boolean onMouseClick(int button, double mouseX, double mouseY) {
-                    if (getBounds().contains(mouseX, mouseY)) {
+                    if (isHighlighted(mouseX, mouseY)) {
                         if (ClientHelper.isCheating()) {
                             if (getCurrentStack() != null && !getCurrentStack().isEmpty()) {
                                 ItemStack cheatedStack = getCurrentStack().copy();
                                 cheatedStack.setAmount(button == 0 ? 1 : button == 1 ? cheatedStack.getMaxAmount() : cheatedStack.getAmount());
                                 return ClientHelper.tryCheatingStack(cheatedStack);
                             }
-                        } else {
-                            if (button == 0)
-                                return ClientHelper.executeRecipeKeyBind(GuiHelper.getOverlay(containerGui), getCurrentStack().copy(), containerGui);
-                            else if (button == 1)
-                                return ClientHelper.executeUsageKeyBind(GuiHelper.getOverlay(containerGui), getCurrentStack().copy(), containerGui);
-                        }
+                        } else if (button == 0)
+                            return ClientHelper.executeRecipeKeyBind(GuiHelper.getLastOverlay(), getCurrentStack().copy());
+                        else if (button == 1)
+                            return ClientHelper.executeUsageKeyBind(GuiHelper.getLastOverlay(), getCurrentStack().copy());
                     }
                     return false;
                 }
-            });
+            };
+            if (this.rectangle.contains(slotWidget.getBounds()))
+                widgets.add(slotWidget);
         }
     }
     
@@ -139,7 +137,7 @@ public class ItemListOverlay extends Drawable implements IWidget {
             stacks.addAll(os);
         List<ItemStack> workingItems = RoughlyEnoughItemsCore.getConfigHelper().craftableOnly() && inventoryItems.size() > 0 ? new ArrayList<>() : new LinkedList<>(ol);
         if (RoughlyEnoughItemsCore.getConfigHelper().craftableOnly()) {
-            RecipeHelper.findCraftableByItems(inventoryItems).forEach(workingItems::add);
+            RecipeHelper.getInstance().findCraftableByItems(inventoryItems).forEach(workingItems::add);
             workingItems.addAll(inventoryItems);
         }
         final List<ItemStack> finalWorkingItems = workingItems;

+ 11 - 18
src/main/java/me/shedaniel/rei/gui/widget/ItemSlotWidget.java

@@ -3,7 +3,6 @@ package me.shedaniel.rei.gui.widget;
 import com.google.common.collect.Lists;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.GuiHelper;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Drawable;
 import net.minecraft.client.render.GuiLighting;
@@ -26,24 +25,22 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
     private List<ItemStack> itemList = new LinkedList<>();
     private boolean drawBackground, showToolTips, clickToMoreRecipes;
     private int x, y;
-    private IMixinContainerGui containerGui;
     
-    public ItemSlotWidget(int x, int y, ItemStack itemStack, boolean drawBackground, boolean showToolTips, IMixinContainerGui containerGui) {
-        this(x, y, Arrays.asList(itemStack), drawBackground, showToolTips, containerGui);
+    public ItemSlotWidget(int x, int y, ItemStack itemStack, boolean drawBackground, boolean showToolTips) {
+        this(x, y, Arrays.asList(itemStack), drawBackground, showToolTips);
     }
     
-    public ItemSlotWidget(int x, int y, List<ItemStack> itemList, boolean drawBackground, boolean showToolTips, IMixinContainerGui containerGui) {
+    public ItemSlotWidget(int x, int y, List<ItemStack> itemList, boolean drawBackground, boolean showToolTips) {
         this.itemList = itemList;
         this.drawBackground = drawBackground;
         this.showToolTips = showToolTips;
         this.x = x;
         this.y = y;
-        this.containerGui = containerGui;
         this.clickToMoreRecipes = false;
     }
     
-    public ItemSlotWidget(int x, int y, List<ItemStack> itemList, boolean drawBackground, boolean showToolTips, IMixinContainerGui containerGui, boolean clickToMoreRecipes) {
-        this(x, y, itemList, drawBackground, showToolTips, containerGui);
+    public ItemSlotWidget(int x, int y, List<ItemStack> itemList, boolean drawBackground, boolean showToolTips, boolean clickToMoreRecipes) {
+        this(x, y, itemList, drawBackground, showToolTips);
         this.clickToMoreRecipes = clickToMoreRecipes;
     }
     
@@ -69,11 +66,7 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
         ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
         itemRenderer.zOffset = 200.0F;
         itemRenderer.renderItemAndGlowInGui(itemStack, x, y);
-        assert containerGui != null;
-        if (containerGui.getDraggedStack().isEmpty())
-            itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y - 0, getItemCountOverlay(itemStack));
-        else
-            itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y - 8, getItemCountOverlay(itemStack));
+        itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y, getItemCountOverlay(itemStack));
         itemRenderer.zOffset = 0.0F;
         if (isHighlighted(mouseX, mouseY) && showToolTips)
             drawToolTip(itemStack);
@@ -81,7 +74,7 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
     
     protected void drawToolTip(ItemStack itemStack) {
         List<String> toolTip = getTooltip(itemStack);
-        GuiHelper.getOverlay(containerGui).addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), toolTip));
+        GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), toolTip));
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {
@@ -89,7 +82,7 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
         MinecraftClient mc = MinecraftClient.getInstance();
         List<String> toolTip = Lists.newArrayList();
         try {
-            toolTip = containerGui.getContainerGui().getStackTooltip(itemStack).stream().filter(s -> !s.equals(modString)).collect(Collectors.toList());
+            toolTip = GuiHelper.getLastOverlay().getStackTooltip(itemStack).stream().filter(s -> !s.equals(modString)).collect(Collectors.toList());
         } catch (Exception e) {
             toolTip.add(itemStack.getDisplayName().getFormattedText());
         }
@@ -118,7 +111,7 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
     
     @Override
     public Rectangle getBounds() {
-        return new Rectangle(this.x, this.y, 18, 18);
+        return new Rectangle(this.x - 1, this.y - 1, 18, 18);
     }
     
     @Override
@@ -127,9 +120,9 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
             return false;
         if (getBounds().contains(mouseX, mouseY)) {
             if (button == 0)
-                return ClientHelper.executeRecipeKeyBind(GuiHelper.getOverlay(containerGui), getCurrentStack().copy(), containerGui);
+                return ClientHelper.executeRecipeKeyBind(GuiHelper.getLastOverlay(), getCurrentStack().copy());
             else if (button == 1)
-                return ClientHelper.executeUsageKeyBind(GuiHelper.getOverlay(containerGui), getCurrentStack().copy(), containerGui);
+                return ClientHelper.executeUsageKeyBind(GuiHelper.getLastOverlay(), getCurrentStack().copy());
         }
         return false;
     }

+ 3 - 1
src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java

@@ -1,6 +1,8 @@
 package me.shedaniel.rei.gui.widget;
 
 
+import com.sun.istack.internal.NotNull;
+
 import java.awt.*;
 import java.util.LinkedList;
 import java.util.List;
@@ -10,7 +12,7 @@ public class QueuedTooltip {
     public Point mouse;
     public List<String> text;
     
-    public QueuedTooltip(Point mouse, List<String> text) {
+    public QueuedTooltip(@NotNull Point mouse, @NotNull List<String> text) {
         this.mouse = mouse;
         this.text = new LinkedList<>(text);
     }

+ 32 - 75
src/main/java/me/shedaniel/rei/gui/widget/RecipeViewingWidget.java

@@ -9,13 +9,12 @@ import me.shedaniel.rei.api.SpeedCraftFunctional;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.GuiHelper;
 import me.shedaniel.rei.client.RecipeHelper;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.audio.PositionedSoundInstance;
+import net.minecraft.client.gui.ContainerGui;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.GuiEventListener;
 import net.minecraft.client.render.GuiLighting;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.Window;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.util.Identifier;
@@ -23,14 +22,13 @@ import net.minecraft.util.math.MathHelper;
 
 import java.awt.*;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
 public class RecipeViewingWidget extends Gui {
     
-    private static final Identifier CREATIVE_INVENTORY_TABS = new Identifier("textures/gui/container/creative_inventory/tabs.png");
     public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
+    private static final Identifier CREATIVE_INVENTORY_TABS = new Identifier("textures/gui/container/creative_inventory/tabs.png");
     public final int guiWidth = 176;
     public final int guiHeight = 186;
     
@@ -41,19 +39,17 @@ public class RecipeViewingWidget extends Gui {
     private Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap;
     private List<IRecipeCategory> categories;
     private IRecipeCategory selectedCategory;
-    private IMixinContainerGui parent;
     private int page, categoryPages;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     
-    public RecipeViewingWidget(Window window, IMixinContainerGui parent, Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap) {
+    public RecipeViewingWidget(Window window, Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap) {
         this.categoryPages = 0;
-        this.parent = parent;
         this.window = window;
         this.widgets = Lists.newArrayList();
         this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, guiWidth, guiHeight);
         this.categoriesMap = categoriesMap;
         this.categories = Lists.newArrayList();
-        RecipeHelper.getCategories().forEach(category -> {
+        RecipeHelper.getInstance().getCategories().forEach(category -> {
             if (categoriesMap.containsKey(category))
                 categories.add(category);
         });
@@ -61,14 +57,18 @@ public class RecipeViewingWidget extends Gui {
         this.tabs = new ArrayList<>();
     }
     
-    public IMixinContainerGui getParent() {
-        return parent;
+    public static SpeedCraftFunctional getSpeedCraftFunctionalByCategory(ContainerGui containerGui, IRecipeCategory category) {
+        for(SpeedCraftFunctional functional : RecipeHelper.getInstance().getSpeedCraftFunctional(category))
+            for(Class aClass : functional.getFunctioningFor())
+                if (containerGui.getClass().isAssignableFrom(aClass))
+                    return functional;
+        return null;
     }
     
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if ((int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) && this.doesEscapeKeyClose()) {
-            MinecraftClient.getInstance().openGui(parent.getContainerGui());
+            MinecraftClient.getInstance().openGui(GuiHelper.getLastContainerGui());
             return true;
         }
         for(GuiEventListener listener : listeners)
@@ -82,11 +82,6 @@ public class RecipeViewingWidget extends Gui {
         return false;
     }
     
-    @Override
-    public void onClosed() {
-        GuiHelper.resetOverlay();
-    }
-    
     @Override
     protected void onInitialized() {
         super.onInitialized();
@@ -178,73 +173,35 @@ public class RecipeViewingWidget extends Gui {
                 tab.setItem(categories.get(j).getCategoryIcon(), categories.get(j).getCategoryName(), tab.getId() + categoryPages * 6 == categories.indexOf(selectedCategory));
             }
         }
-        SpeedCraftAreaSupplier supplier = RecipeHelper.getSpeedCraftButtonArea(selectedCategory);
-        final SpeedCraftFunctional[] functional0 = {null};
-        RecipeHelper.getSpeedCraftFunctional(selectedCategory).forEach(functional1 -> {
-            for(Class aClass : functional1.getFunctioningFor())
-                if (parent.getContainerGui().getClass().isAssignableFrom(aClass)) {
-                    functional0[0] = functional1;
-                    break;
-                }
-        });
-        final SpeedCraftFunctional functional = functional0[0];
+        SpeedCraftAreaSupplier supplier = RecipeHelper.getInstance().getSpeedCraftButtonArea(selectedCategory);
+        final SpeedCraftFunctional functional = getSpeedCraftFunctionalByCategory(GuiHelper.getLastContainerGui(), selectedCategory);
         if (page * getRecipesPerPage() < categoriesMap.get(selectedCategory).size()) {
-            IRecipeDisplay topDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage());
-            widgets.addAll(selectedCategory.setupDisplay(getParent(), topDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 140 : 66)));
-            if (supplier != null) {
-                ButtonWidget btn;
-                widgets.add(btn = new ButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 140 : 66)), "+") {
-                    @Override
-                    public void onPressed(int button, double mouseX, double mouseY) {
-                        MinecraftClient.getInstance().openGui(parent.getContainerGui());
-                        functional.performAutoCraft(parent.getContainerGui(), topDisplay);
-                    }
-                    
-                    @Override
-                    public void draw(int mouseX, int mouseY, float partialTicks) {
-                        super.draw(mouseX, mouseY, partialTicks);
-                        if (getBounds().contains(mouseX, mouseY))
-                            if (enabled)
-                                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.move_items"))));
-                            else
-                                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.failed_move_items"))));
-                    }
-                });
-                btn.enabled = functional != null && functional.acceptRecipe(parent.getContainerGui(), topDisplay);
-            }
+            final IRecipeDisplay topDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage());
+            widgets.addAll(selectedCategory.setupDisplay(topDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 140 : 66)));
+            if (supplier != null)
+                widgets.add(new SpeedCraftingButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 140 : 66)), supplier.getButtonText(), functional, topDisplay));
             if (!selectedCategory.usesFullPage() && page * getRecipesPerPage() + 1 < categoriesMap.get(selectedCategory).size()) {
-                IRecipeDisplay middleDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage() + 1);
-                widgets.addAll(selectedCategory.setupDisplay(getParent(), middleDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 113, 150, 66)));
-                if (supplier != null) {
-                    ButtonWidget btn;
-                    widgets.add(btn = new ButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 113, 150, 66)), "+") {
-                        @Override
-                        public void onPressed(int button, double mouseX, double mouseY) {
-                            MinecraftClient.getInstance().openGui(parent.getContainerGui());
-                            functional.performAutoCraft(parent.getContainerGui(), middleDisplay);
-                        }
-                        
-                        @Override
-                        public void draw(int mouseX, int mouseY, float partialTicks) {
-                            super.draw(mouseX, mouseY, partialTicks);
-                            if (getBounds().contains(mouseX, mouseY))
-                                if (enabled)
-                                    GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.move_items"))));
-                                else
-                                    GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.failed_move_items"))));
-                        }
-                    });
-                    btn.enabled = functional != null && functional.acceptRecipe(parent.getContainerGui(), middleDisplay);
-                }
+                final IRecipeDisplay middleDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage() + 1);
+                widgets.addAll(selectedCategory.setupDisplay(middleDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 113, 150, 66)));
+                if (supplier != null)
+                    widgets.add(new SpeedCraftingButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 113, 150, 66)), supplier.getButtonText(), functional, middleDisplay));
             }
         }
         
-        GuiHelper.getOverlay(parent).onInitialized();
+        GuiHelper.getLastOverlay().onInitialized();
         listeners.addAll(tabs);
-        listeners.add(GuiHelper.getOverlay(parent));
+        listeners.add(GuiHelper.getLastOverlay());
         listeners.addAll(widgets);
     }
     
+    public int getPage() {
+        return page;
+    }
+    
+    public int getCategoryPage() {
+        return categoryPages;
+    }
+    
     private int getRecipesPerPage() {
         if (selectedCategory.usesFullPage())
             return 1;
@@ -266,7 +223,7 @@ public class RecipeViewingWidget extends Gui {
         GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         GuiLighting.disable();
         tabs.stream().filter(TabWidget::isSelected).forEach(tabWidget -> tabWidget.draw(mouseX, mouseY, partialTicks));
-        GuiHelper.getOverlay(parent).render(mouseX, mouseY, partialTicks);
+        GuiHelper.getLastOverlay().render(mouseX, mouseY, partialTicks);
     }
     
     @Override

+ 45 - 0
src/main/java/me/shedaniel/rei/gui/widget/SpeedCraftingButtonWidget.java

@@ -0,0 +1,45 @@
+package me.shedaniel.rei.gui.widget;
+
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.api.IRecipeDisplay;
+import me.shedaniel.rei.api.SpeedCraftFunctional;
+import me.shedaniel.rei.client.ClientHelper;
+import me.shedaniel.rei.client.GuiHelper;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.item.ItemStack;
+
+import java.awt.*;
+import java.util.Arrays;
+
+public class SpeedCraftingButtonWidget extends ButtonWidget {
+    
+    private final IRecipeDisplay display;
+    private final SpeedCraftFunctional functional;
+    
+    public SpeedCraftingButtonWidget(Rectangle rectangle, String text, SpeedCraftFunctional functional, IRecipeDisplay display) {
+        super(rectangle, text);
+        this.display = display;
+        //RoughlyEnoughItemsCore.LOGGER.info("Registered %s.", ((ItemStack) this.display.getOutput().get(0)).getDisplayName().getFormattedText());
+        this.functional = functional;
+    }
+    
+    @Override
+    public void onPressed(int button, double mouseX, double mouseY) {
+        //RoughlyEnoughItemsCore.LOGGER.info("Crafting %s.", ((ItemStack) this.display.getOutput().get(0)).getDisplayName().getFormattedText());
+        MinecraftClient.getInstance().openGui(GuiHelper.getLastContainerGui());
+        functional.performAutoCraft(GuiHelper.getLastContainerGui(), display);
+    }
+    
+    @Override
+    public void draw(int mouseX, int mouseY, float partialTicks) {
+        this.enabled = functional != null && functional.acceptRecipe(GuiHelper.getLastContainerGui(), display);
+        super.draw(mouseX, mouseY, partialTicks);
+        if (getBounds().contains(mouseX, mouseY))
+            if (enabled)
+                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.move_items"))));
+            else
+                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.failed_move_items"))));
+    }
+    
+}

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java

@@ -90,7 +90,7 @@ public class TabWidget extends Drawable implements HighlightableWidget {
     }
     
     private void drawTooltip() {
-        GuiHelper.getOverlay(recipeViewingWidget.getParent()).addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(categoryName)));
+        GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(categoryName)));
     }
     
     @Override

+ 0 - 3
src/main/java/me/shedaniel/rei/listeners/IMixinContainerGui.java

@@ -1,7 +1,6 @@
 package me.shedaniel.rei.listeners;
 
 import me.shedaniel.rei.gui.ContainerGuiOverlay;
-import net.minecraft.client.gui.ContainerGui;
 import net.minecraft.container.Slot;
 import net.minecraft.item.ItemStack;
 
@@ -19,8 +18,6 @@ public interface IMixinContainerGui {
     
     public Slot getHoveredSlot();
     
-    public ContainerGui getContainerGui();
-    
     public void setOverlay(ContainerGuiOverlay overlay);
     
 }

+ 6 - 10
src/main/java/me/shedaniel/rei/mixin/MixinBrewingRecipeRegistry.java

@@ -6,7 +6,6 @@ import me.shedaniel.rei.plugin.DefaultBrewingDisplay;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemProvider;
-import net.minecraft.item.ItemStack;
 import net.minecraft.item.PotionItem;
 import net.minecraft.potion.Potion;
 import net.minecraft.potion.PotionUtil;
@@ -17,6 +16,7 @@ import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
 import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 
+import java.util.Arrays;
 import java.util.List;
 
 @Mixin(BrewingRecipeRegistry.class)
@@ -28,16 +28,14 @@ public class MixinBrewingRecipeRegistry {
     
     @Inject(method = "method_8080", at = @At("RETURN"))
     private static void method_8080(Item item_1, CallbackInfo ci) {
-        if (item_1 instanceof PotionItem) {
+        if (item_1 instanceof PotionItem)
             SELF_POTION_TYPES.add(Ingredient.ofItems(new ItemProvider[]{item_1}));
-        }
     }
     
     @Inject(method = "method_8071", at = @At("RETURN"))
     private static void method_8071(Item item_1, Item item_2, Item item_3, CallbackInfo ci) {
-        if (item_1 instanceof PotionItem && item_3 instanceof PotionItem) {
+        if (item_1 instanceof PotionItem && item_3 instanceof PotionItem)
             SELF_ITEM_RECIPES.add(new BrewingRecipe(item_1, Ingredient.ofItems(new ItemProvider[]{item_2}), item_3));
-        }
     }
     
     @Inject(method = "registerPotionRecipe", at = @At("RETURN"))
@@ -46,11 +44,9 @@ public class MixinBrewingRecipeRegistry {
             registerPotionType(potion_1);
         if (!REGISTERED_POTION_TYPES.contains(potion_2))
             registerPotionType(potion_2);
-        SELF_POTION_TYPES.forEach(ingredient -> {
-            for(ItemStack stack : ingredient.getStackArray()) {
-                DefaultPlugin.registerBrewingDisplay(new DefaultBrewingDisplay(PotionUtil.setPotion(stack.copy(), potion_1), Ingredient.ofItems(new ItemProvider[]{item_1}), PotionUtil.setPotion(stack.copy(), potion_2)));
-            }
-        });
+        SELF_POTION_TYPES.stream().map(Ingredient::getStackArray).forEach(itemStacks -> Arrays.stream(itemStacks).forEach(stack -> {
+            DefaultPlugin.registerBrewingDisplay(new DefaultBrewingDisplay(PotionUtil.setPotion(stack.copy(), potion_1), Ingredient.ofItems(new ItemProvider[]{item_1}), PotionUtil.setPotion(stack.copy(), potion_2)));
+        }));
     }
     
     private static void registerPotionType(Potion potion) {

+ 10 - 17
src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java

@@ -33,7 +33,6 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
     protected int containerHeight;
     @Shadow
     protected Slot focusedSlot;
-    private ContainerGui lastGui;
     @Shadow
     private ItemStack field_2782;
     
@@ -64,8 +63,10 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
     
     @Inject(method = "onInitialized()V", at = @At("RETURN"))
     protected void onInitialized(CallbackInfo info) {
-        GuiHelper.resetOverlay();
-        this.listeners.add(GuiHelper.getOverlay((IMixinContainerGui) lastGui));
+        GuiHelper.setLastContainerGui((ContainerGui) (Object) this);
+        GuiHelper.setLastMixinContainerGui((IMixinContainerGui) this);
+        GuiHelper.setOverlay(new ContainerGuiOverlay());
+        this.listeners.add(GuiHelper.getLastOverlay());
     }
     
     @Inject(method = "draw(IIF)V", at = @At("RETURN"))
@@ -75,9 +76,7 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
             if (tabGetter.getSelectedTab() != ItemGroup.INVENTORY.getId())
                 return;
         }
-        if (MinecraftClient.getInstance().currentGui instanceof ContainerGui)
-            this.lastGui = (ContainerGui) MinecraftClient.getInstance().currentGui;
-        GuiHelper.getOverlay((IMixinContainerGui) lastGui).render(int_1, int_2, float_1);
+        GuiHelper.getLastOverlay().render(int_1, int_2, float_1);
     }
     
     @Override
@@ -85,11 +84,6 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
         return this.field_2782;
     }
     
-    @Override
-    public ContainerGui getContainerGui() {
-        return lastGui;
-    }
-    
     @Override
     public Slot getHoveredSlot() {
         return focusedSlot;
@@ -97,7 +91,7 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
     
     @Override
     public boolean mouseScrolled(double double_1) {
-        ContainerGuiOverlay overlay = GuiHelper.getOverlay((IMixinContainerGui) lastGui);
+        ContainerGuiOverlay overlay = GuiHelper.getLastOverlay();
         if (GuiHelper.isOverlayVisible() && overlay.getRectangle().contains(ClientHelper.getMouseLocation()))
             for(GuiEventListener entry : this.getEntries())
                 if (entry.mouseScrolled(double_1))
@@ -107,11 +101,10 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
     
     @Inject(method = "keyPressed(III)Z", at = @At("HEAD"), cancellable = true)
     public void keyPressed(int int_1, int int_2, int int_3, CallbackInfoReturnable<Boolean> ci) {
-        for(GuiEventListener entry : this.getEntries())
-            if (entry.keyPressed(int_1, int_2, int_3)) {
-                ci.setReturnValue(true);
-                ci.cancel();
-            }
+        if (GuiHelper.getLastOverlay().keyPressed(int_1, int_2, int_3)) {
+            ci.setReturnValue(true);
+            ci.cancel();
+        }
     }
     
 }

+ 4 - 5
src/main/java/me/shedaniel/rei/plugin/DefaultBlastingCategory.java

@@ -5,7 +5,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -39,7 +38,7 @@ public class DefaultBlastingCategory implements IRecipeCategory<DefaultBlastingD
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultBlastingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultBlastingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -56,14 +55,14 @@ public class DefaultBlastingCategory implements IRecipeCategory<DefaultBlastingD
             }
         }));
         List<List<ItemStack>> input = recipeDisplay.getInput();
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.smelting.fuel"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, true));
         return widgets;
     }
     

+ 12 - 8
src/main/java/me/shedaniel/rei/plugin/DefaultBrewingCategory.java

@@ -5,7 +5,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -40,7 +39,7 @@ public class DefaultBrewingCategory implements IRecipeCategory<DefaultBrewingDis
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultBrewingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultBrewingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 52, (int) bounds.getCenterY() - 29);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -54,32 +53,32 @@ public class DefaultBrewingCategory implements IRecipeCategory<DefaultBrewingDis
                 drawTexturedRect(startPoint.x + 44, startPoint.y + 28, 103, 163, width, 4);
             }
         }));
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, Arrays.asList(new ItemStack(Items.BLAZE_POWDER)), false, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 63, startPoint.y + 1, recipeDisplay.getInput().get(0), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, Arrays.asList(new ItemStack(Items.BLAZE_POWDER)), false, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 63, startPoint.y + 1, recipeDisplay.getInput().get(0), false, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.brewing.input"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 40, startPoint.y + 1, recipeDisplay.getInput().get(1), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 40, startPoint.y + 1, recipeDisplay.getInput().get(1), false, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.brewing.reactant"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 40, startPoint.y + 35, recipeDisplay.getOutput(0), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 40, startPoint.y + 35, recipeDisplay.getOutput(0), false, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.brewing.result"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 63, startPoint.y + 42, recipeDisplay.getOutput(1), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 63, startPoint.y + 42, recipeDisplay.getOutput(1), false, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.brewing.result"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 86, startPoint.y + 35, recipeDisplay.getOutput(2), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 86, startPoint.y + 35, recipeDisplay.getOutput(2), false, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.brewing.result"));
@@ -88,4 +87,9 @@ public class DefaultBrewingCategory implements IRecipeCategory<DefaultBrewingDis
         return widgets;
     }
     
+    @Override
+    public boolean checkTags() {
+        return true;
+    }
+    
 }

+ 3 - 4
src/main/java/me/shedaniel/rei/plugin/DefaultCampfireCategory.java

@@ -5,7 +5,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -39,7 +38,7 @@ public class DefaultCampfireCategory implements IRecipeCategory<DefaultCampfireD
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultCampfireDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultCampfireDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -58,8 +57,8 @@ public class DefaultCampfireCategory implements IRecipeCategory<DefaultCampfireD
                 MinecraftClient.getInstance().fontRenderer.draw(text, bounds.x + bounds.width - length - 5, startPoint.y + 54 - 8, -1);
             }
         }));
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 11, recipeDisplay.getInput().get(0), true, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 11, recipeDisplay.getInput().get(0), true, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, true));
         return widgets;
     }
     

+ 3 - 4
src/main/java/me/shedaniel/rei/plugin/DefaultCraftingCategory.java

@@ -6,7 +6,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -39,7 +38,7 @@ public class DefaultCraftingCategory implements IRecipeCategory<DefaultCraftingD
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultCraftingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultCraftingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 58, (int) bounds.getCenterY() - 27);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -55,7 +54,7 @@ public class DefaultCraftingCategory implements IRecipeCategory<DefaultCraftingD
         List<ItemSlotWidget> slots = Lists.newArrayList();
         for(int y = 0; y < 3; y++)
             for(int x = 0; x < 3; x++)
-                slots.add(new ItemSlotWidget(startPoint.x + 1 + x * 18, startPoint.y + 1 + y * 18, Lists.newArrayList(), true, true, containerGui, true));
+                slots.add(new ItemSlotWidget(startPoint.x + 1 + x * 18, startPoint.y + 1 + y * 18, Lists.newArrayList(), true, true, true));
         for(int i = 0; i < input.size(); i++) {
             if (recipeDisplay instanceof DefaultShapedDisplay) {
                 if (!input.get(i).isEmpty())
@@ -64,7 +63,7 @@ public class DefaultCraftingCategory implements IRecipeCategory<DefaultCraftingD
                 slots.get(i).setItemList(input.get(i));
         }
         widgets.addAll(slots);
-        widgets.add(new ItemSlotWidget(startPoint.x + 95, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 95, startPoint.y + 19, recipeDisplay.getOutput(), false, true, true) {
             @Override
             protected String getItemCountOverlay(ItemStack currentStack) {
                 if (currentStack.getAmount() == 1)

+ 24 - 23
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -1,6 +1,7 @@
 package me.shedaniel.rei.plugin;
 
 import com.google.common.collect.Lists;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.IRecipePlugin;
 import me.shedaniel.rei.api.SpeedCraftFunctional;
 import me.shedaniel.rei.client.RecipeHelper;
@@ -42,41 +43,41 @@ public class DefaultPlugin implements IRecipePlugin {
     
     @Override
     public void registerPluginCategories() {
-        RecipeHelper.registerCategory(new DefaultCraftingCategory());
-        RecipeHelper.registerCategory(new DefaultSmeltingCategory());
-        RecipeHelper.registerCategory(new DefaultSmokingCategory());
-        RecipeHelper.registerCategory(new DefaultBlastingCategory());
-        RecipeHelper.registerCategory(new DefaultCampfireCategory());
-        RecipeHelper.registerCategory(new DefaultStoneCuttingCategory());
-        RecipeHelper.registerCategory(new DefaultBrewingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultCraftingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultSmeltingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultSmokingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultBlastingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultCampfireCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultStoneCuttingCategory());
+        RoughlyEnoughItemsCore.getRecipeHelper().registerCategory(new DefaultBrewingCategory());
     }
     
     @Override
     public void registerRecipes() {
-        for(Recipe recipe : RecipeHelper.getRecipeManager().values())
+        for(Recipe recipe : RoughlyEnoughItemsCore.getRecipeHelper().getRecipeManager().values())
             if (recipe instanceof ShapelessRecipe)
-                RecipeHelper.registerRecipe(CRAFTING, new DefaultShapelessDisplay((ShapelessRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(CRAFTING, new DefaultShapelessDisplay((ShapelessRecipe) recipe));
             else if (recipe instanceof ShapedRecipe)
-                RecipeHelper.registerRecipe(CRAFTING, new DefaultShapedDisplay((ShapedRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(CRAFTING, new DefaultShapedDisplay((ShapedRecipe) recipe));
             else if (recipe instanceof SmeltingRecipe)
-                RecipeHelper.registerRecipe(SMELTING, new DefaultSmeltingDisplay((SmeltingRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(SMELTING, new DefaultSmeltingDisplay((SmeltingRecipe) recipe));
             else if (recipe instanceof SmokingRecipe)
-                RecipeHelper.registerRecipe(SMOKING, new DefaultSmokingDisplay((SmokingRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(SMOKING, new DefaultSmokingDisplay((SmokingRecipe) recipe));
             else if (recipe instanceof BlastingRecipe)
-                RecipeHelper.registerRecipe(BLASTING, new DefaultBlastingDisplay((BlastingRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(BLASTING, new DefaultBlastingDisplay((BlastingRecipe) recipe));
             else if (recipe instanceof CampfireCookingRecipe)
-                RecipeHelper.registerRecipe(CAMPFIRE, new DefaultCampfireDisplay((CampfireCookingRecipe) recipe));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(CAMPFIRE, new DefaultCampfireDisplay((CampfireCookingRecipe) recipe));
             else if (recipe instanceof StonecuttingRecipe)
-                RecipeHelper.registerRecipe(STONE_CUTTING, new DefaultStoneCuttingDisplay((StonecuttingRecipe) recipe));
-        BREWING_DISPLAYS.forEach(display -> RecipeHelper.registerRecipe(BREWING, display));
+                RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(STONE_CUTTING, new DefaultStoneCuttingDisplay((StonecuttingRecipe) recipe));
+        BREWING_DISPLAYS.stream().forEachOrdered(display -> RoughlyEnoughItemsCore.getRecipeHelper().registerRecipe(BREWING, display));
     }
     
     @Override
     public void registerSpeedCraft() {
-        RecipeHelper.registerSpeedCraftButtonArea(DefaultPlugin.CAMPFIRE, null);
-        RecipeHelper.registerSpeedCraftButtonArea(DefaultPlugin.STONE_CUTTING, null);
-        RecipeHelper.registerSpeedCraftButtonArea(DefaultPlugin.BREWING, null);
-        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.CRAFTING, new SpeedCraftFunctional<DefaultCraftingDisplay>() {
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftButtonArea(DefaultPlugin.CAMPFIRE, null);
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftButtonArea(DefaultPlugin.STONE_CUTTING, null);
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftButtonArea(DefaultPlugin.BREWING, null);
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftFunctional(DefaultPlugin.CRAFTING, new SpeedCraftFunctional<DefaultCraftingDisplay>() {
             @Override
             public Class[] getFunctioningFor() {
                 return new Class[]{PlayerInventoryGui.class, CraftingTableGui.class};
@@ -99,7 +100,7 @@ public class DefaultPlugin implements IRecipePlugin {
                 return gui instanceof CraftingTableGui || (gui instanceof PlayerInventoryGui && recipe.getHeight() < 3 && recipe.getWidth() < 3);
             }
         });
-        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.SMELTING, new SpeedCraftFunctional<DefaultSmeltingDisplay>() {
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftFunctional(DefaultPlugin.SMELTING, new SpeedCraftFunctional<DefaultSmeltingDisplay>() {
             @Override
             public Class[] getFunctioningFor() {
                 return new Class[]{FurnaceGui.class};
@@ -120,7 +121,7 @@ public class DefaultPlugin implements IRecipePlugin {
                 return gui instanceof FurnaceGui;
             }
         });
-        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.SMOKING, new SpeedCraftFunctional<DefaultSmokingDisplay>() {
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftFunctional(DefaultPlugin.SMOKING, new SpeedCraftFunctional<DefaultSmokingDisplay>() {
             @Override
             public Class[] getFunctioningFor() {
                 return new Class[]{SmokerGui.class};
@@ -141,7 +142,7 @@ public class DefaultPlugin implements IRecipePlugin {
                 return gui instanceof SmokerGui;
             }
         });
-        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.BLASTING, new SpeedCraftFunctional<DefaultBlastingDisplay>() {
+        RoughlyEnoughItemsCore.getRecipeHelper().registerSpeedCraftFunctional(DefaultPlugin.BLASTING, new SpeedCraftFunctional<DefaultBlastingDisplay>() {
             @Override
             public Class[] getFunctioningFor() {
                 return new Class[]{BlastFurnaceGui.class};

+ 4 - 5
src/main/java/me/shedaniel/rei/plugin/DefaultSmeltingCategory.java

@@ -5,7 +5,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -39,7 +38,7 @@ public class DefaultSmeltingCategory implements IRecipeCategory<DefaultSmeltingD
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultSmeltingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultSmeltingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -56,14 +55,14 @@ public class DefaultSmeltingCategory implements IRecipeCategory<DefaultSmeltingD
             }
         }));
         List<List<ItemStack>> input = recipeDisplay.getInput();
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.smelting.fuel"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, true));
         return widgets;
     }
     

+ 4 - 5
src/main/java/me/shedaniel/rei/plugin/DefaultSmokingCategory.java

@@ -5,7 +5,6 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -39,7 +38,7 @@ public class DefaultSmokingCategory implements IRecipeCategory<DefaultSmokingDis
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultSmokingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultSmokingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -56,14 +55,14 @@ public class DefaultSmokingCategory implements IRecipeCategory<DefaultSmokingDis
             }
         }));
         List<List<ItemStack>> input = recipeDisplay.getInput();
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, containerGui, true) {
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, true) {
             @Override
             protected List<String> getExtraToolTips(ItemStack stack) {
                 return Arrays.asList(I18n.translate("category.rei.smelting.fuel"));
             }
         });
-        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, true));
         return widgets;
     }
     

+ 3 - 5
src/main/java/me/shedaniel/rei/plugin/DefaultStoneCuttingCategory.java

@@ -5,14 +5,12 @@ import me.shedaniel.rei.api.IRecipeCategory;
 import me.shedaniel.rei.gui.widget.IWidget;
 import me.shedaniel.rei.gui.widget.ItemSlotWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.Identifier;
-import net.minecraft.util.math.MathHelper;
 
 import java.awt.*;
 import java.util.Arrays;
@@ -39,7 +37,7 @@ public class DefaultStoneCuttingCategory implements IRecipeCategory<DefaultStone
     }
     
     @Override
-    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultStoneCuttingDisplay recipeDisplay, Rectangle bounds) {
+    public List<IWidget> setupDisplay(DefaultStoneCuttingDisplay recipeDisplay, Rectangle bounds) {
         Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 13);
         List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
             @Override
@@ -51,8 +49,8 @@ public class DefaultStoneCuttingCategory implements IRecipeCategory<DefaultStone
                 drawTexturedRect(startPoint.x, startPoint.y, 0, 221, 82, 26);
             }
         }));
-        widgets.add(new ItemSlotWidget(startPoint.x + 4, startPoint.y + 5, recipeDisplay.getInput().get(0), true, true, containerGui, true));
-        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 5, recipeDisplay.getOutput(), false, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 4, startPoint.y + 5, recipeDisplay.getInput().get(0), true, true, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 5, recipeDisplay.getOutput(), false, true, true));
         return widgets;
     }
     

+ 0 - 1
src/main/java/me/shedaniel/rei/plugin/DefaultStoneCuttingDisplay.java

@@ -6,7 +6,6 @@ import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.Ingredient;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.StonecuttingRecipe;
-import net.minecraft.recipe.cooking.CampfireCookingRecipe;
 import net.minecraft.util.DefaultedList;
 import net.minecraft.util.Identifier;
 

+ 1 - 1
src/main/resources/fabric.mod.json

@@ -12,7 +12,7 @@
     "me.shedaniel.rei.client.ClientHelper"
   ],
   "requires": {
-    "fabric": "0.1.4.79"
+    "fabric": "0.1.5.83"
   },
   "recommended": {
     "pluginloader": "1.0.6"