shedaniel 5 years ago
parent
commit
fbe735c166
46 changed files with 369 additions and 303 deletions
  1. 1 1
      gradle.properties
  2. 4 9
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  3. 24 3
      src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java
  4. 1 1
      src/main/java/me/shedaniel/rei/api/ConfigManager.java
  5. 9 7
      src/main/java/me/shedaniel/rei/api/ConfigObject.java
  6. 32 4
      src/main/java/me/shedaniel/rei/api/DisplayHelper.java
  7. 6 2
      src/main/java/me/shedaniel/rei/api/EntryStack.java
  8. 1 1
      src/main/java/me/shedaniel/rei/api/ItemStackRenderOverlayHook.java
  9. 31 6
      src/main/java/me/shedaniel/rei/api/ObjectHolder.java
  10. 1 2
      src/main/java/me/shedaniel/rei/api/annotations/Experimental.java
  11. 1 2
      src/main/java/me/shedaniel/rei/api/annotations/Internal.java
  12. 1 2
      src/main/java/me/shedaniel/rei/api/annotations/ToBeRemoved.java
  13. 14 24
      src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java
  14. 6 3
      src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java
  15. 4 4
      src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java
  16. 2 1
      src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java
  17. 3 1
      src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java
  18. 1 2
      src/main/java/me/shedaniel/rei/gui/entries/RecipeEntry.java
  19. 2 1
      src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java
  20. 26 29
      src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java
  21. 7 7
      src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java
  22. 4 2
      src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
  23. 2 2
      src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java
  24. 29 16
      src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java
  25. 1 3
      src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
  26. 8 7
      src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java
  27. 30 51
      src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java
  28. 38 3
      src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java
  29. 3 1
      src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java
  30. 6 11
      src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java
  31. 0 30
      src/main/java/me/shedaniel/rei/impl/ObjectHolderImpl.java
  32. 20 26
      src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java
  33. 1 2
      src/main/java/me/shedaniel/rei/impl/ScreenHelper.java
  34. 3 3
      src/main/java/me/shedaniel/rei/impl/SearchArgument.java
  35. 3 6
      src/main/java/me/shedaniel/rei/mixin/MixinBrewingRecipeRegistry.java
  36. 1 1
      src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java
  37. 5 3
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  38. 4 4
      src/main/java/me/shedaniel/rei/plugin/DefaultPotionEffectExclusionZones.java
  39. 4 4
      src/main/java/me/shedaniel/rei/plugin/DefaultRecipeBookExclusionZones.java
  40. 6 5
      src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java
  41. 11 3
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingCategory.java
  42. 2 1
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java
  43. 6 3
      src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java
  44. 1 2
      src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java
  45. 2 1
      src/main/java/me/shedaniel/rei/utils/CollectionUtils.java
  46. 2 1
      src/main/resources/assets/roughlyenoughitems/lang/en_us.json

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=3.2.26
+mod_version=3.2.27
 minecraft_version=1.15
 yarn_version=1.15+build.1
 fabricloader_version=0.7.2+build.174

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

@@ -8,7 +8,6 @@ package me.shedaniel.rei;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import me.shedaniel.cloth.hooks.ClothClientHooks;
-import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.annotations.Internal;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
@@ -58,14 +57,10 @@ import java.util.concurrent.atomic.AtomicLong;
 @Internal
 public class RoughlyEnoughItemsCore implements ClientModInitializer {
     
-    @Internal
-    public static final Logger LOGGER;
-    @SuppressWarnings("deprecation")
-    private static final RecipeHelper RECIPE_HELPER = new RecipeHelperImpl();
-    @SuppressWarnings("deprecation")
-    private static final EntryRegistry ENTRY_REGISTRY = new EntryRegistryImpl();
-    @SuppressWarnings("deprecation")
-    private static final DisplayHelper DISPLAY_HELPER = new DisplayHelperImpl();
+    @Internal public static final Logger LOGGER;
+    @SuppressWarnings("deprecation") private static final RecipeHelper RECIPE_HELPER = new RecipeHelperImpl();
+    @SuppressWarnings("deprecation") private static final EntryRegistry ENTRY_REGISTRY = new EntryRegistryImpl();
+    @SuppressWarnings("deprecation") private static final DisplayHelper DISPLAY_HELPER = new DisplayHelperImpl();
     private static final Map<Identifier, REIPluginEntry> plugins = Maps.newHashMap();
     private static final ExecutorService SYNC_RECIPES = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "REI-SyncRecipes"));
     private static ConfigManager configManager;

+ 24 - 3
src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java

@@ -5,11 +5,14 @@
 
 package me.shedaniel.rei.api;
 
+import com.google.common.collect.Lists;
 import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import net.minecraft.client.gui.screen.Screen;
 
 import java.util.List;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 public interface BaseBoundsHandler extends DisplayHelper.DisplayBoundsHandler<Screen> {
     /**
@@ -19,11 +22,19 @@ public interface BaseBoundsHandler extends DisplayHelper.DisplayBoundsHandler<Sc
      * @param isOnRightSide      whether the user has set the overlay to the right
      * @return the list of exclusion zones
      */
+    @Deprecated
     default List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide) {
-        return getCurrentExclusionZones(currentScreenClass, isOnRightSide, false);
+        return getExclusionZones(currentScreenClass, false);
     }
     
-    List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide, boolean sort);
+    @Deprecated
+    default List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide, boolean sort) {
+        return getExclusionZones(currentScreenClass, sort);
+    }
+    
+    List<Rectangle> getExclusionZones(Class<?> currentScreenClass, boolean sort);
+    
+    int supplierSize();
     
     /**
      * Register an exclusion zone
@@ -31,6 +42,16 @@ public interface BaseBoundsHandler extends DisplayHelper.DisplayBoundsHandler<Sc
      * @param screenClass the screen
      * @param supplier    the exclusion zone supplier, isOnRightSide -> the list of exclusion zones
      */
-    void registerExclusionZones(Class<?> screenClass, Function<Boolean, List<Rectangle>> supplier);
+    @Deprecated
+    default void registerExclusionZones(Class<?> screenClass, Function<Boolean, List<Rectangle>> supplier) {
+        RoughlyEnoughItemsCore.LOGGER.warn("[REI] Someone is registering exclusion zones with the deprecated method: " + supplier.getClass().getName());
+        registerExclusionZones(screenClass, () -> {
+            List<Rectangle> zones = Lists.newArrayList(supplier.apply(false));
+            zones.addAll(supplier.apply(true));
+            return zones;
+        });
+    }
+    
+    void registerExclusionZones(Class<?> screenClass, Supplier<List<Rectangle>> supplier);
     
 }

+ 1 - 1
src/main/java/me/shedaniel/rei/api/ConfigManager.java

@@ -27,8 +27,8 @@ public interface ConfigManager {
     /**
      * Gets the config instance
      *
-     * @deprecated Use {@link ConfigObject#getInstance()}
      * @return the config instance
+     * @deprecated Use {@link ConfigObject#getInstance()}
      */
     @Deprecated
     ConfigObject getConfig();

+ 9 - 7
src/main/java/me/shedaniel/rei/api/ConfigObject.java

@@ -43,7 +43,12 @@ public interface ConfigObject {
     
     boolean isToastDisplayedOnCopyIdentifier();
     
-    boolean doesRenderEntryExtraOverlay();
+    @Deprecated
+    default boolean doesRenderEntryExtraOverlay() {
+        return doesRenderEntryEnchantmentGlint();
+    }
+    
+    boolean doesRenderEntryEnchantmentGlint();
     
     boolean isEntryListWidgetScrolled();
     
@@ -97,17 +102,14 @@ public interface ConfigObject {
     
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
-    public @interface AddInFrontKeyCode {
-    }
+    public @interface AddInFrontKeyCode {}
     
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
-    public @interface DontApplyFieldName {
-    }
+    public @interface DontApplyFieldName {}
     
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
-    public @interface UseEnumSelectorInstead {
-    }
+    public @interface UseEnumSelectorInstead {}
     
 }

+ 32 - 4
src/main/java/me/shedaniel/rei/api/DisplayHelper.java

@@ -84,6 +84,20 @@ public interface DisplayHelper {
          */
         Rectangle getRightBounds(T screen);
         
+        /**
+         * Checks if item slot can fit the screen
+         *
+         * @param left       the left x coordinates of the stack
+         * @param top        the top y coordinates for the stack
+         * @param screen     the current screen
+         * @param fullBounds the current bounds
+         * @return whether the item slot can fit
+         * @see BaseBoundsHandler#registerExclusionZones(Class, BaseBoundsHandler.ExclusionZoneSupplier) for easier api
+         */
+        default ActionResult canItemSlotWidgetFit(int left, int top, T screen, Rectangle fullBounds) {
+            return PASS;
+        }
+        
         /**
          * Checks if item slot can fit the screen
          *
@@ -93,10 +107,11 @@ public interface DisplayHelper {
          * @param screen        the current screen
          * @param fullBounds    the current bounds
          * @return whether the item slot can fit
-         * @see BaseBoundsHandler#registerExclusionZones(Class, BaseBoundsHandler.ExclusionZoneSupplier) for easier api
+         * @deprecated use {@link #canItemSlotWidgetFit(int, int, Object, Rectangle)}
          */
+        @Deprecated
         default ActionResult canItemSlotWidgetFit(boolean isOnRightSide, int left, int top, T screen, Rectangle fullBounds) {
-            return PASS;
+            return canItemSlotWidgetFit(left, top, screen, fullBounds);
         }
         
         /**
@@ -106,8 +121,21 @@ public interface DisplayHelper {
          * @param mouseX        mouse's x coordinates
          * @param mouseY        mouse's y coordinates
          * @return whether mouse is inside the overlay
+         * @deprecated use {@link #isInZone(double, double)}
          */
+        @Deprecated
         default ActionResult isInZone(boolean isOnRightSide, double mouseX, double mouseY) {
+            return isInZone(mouseX, mouseY);
+        }
+        
+        /**
+         * Checks if mouse is inside the overlay
+         *
+         * @param mouseX mouse's x coordinates
+         * @param mouseY mouse's y coordinates
+         * @return whether mouse is inside the overlay
+         */
+        default ActionResult isInZone(double mouseX, double mouseY) {
             return PASS;
         }
         
@@ -120,10 +148,10 @@ public interface DisplayHelper {
         default Rectangle getItemListArea(Rectangle rectangle) {
             return new Rectangle(rectangle.x + 1, rectangle.y + 2 + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + (ConfigObject.getInstance().isEntryListWidgetScrolled() ? 0 : 22), rectangle.width - 2, rectangle.height - (ConfigObject.getInstance().getSearchFieldLocation() != SearchFieldLocation.CENTER ? 27 + 22 : 27) + (!ConfigObject.getInstance().isEntryListWidgetScrolled() ? 0 : 22));
         }
-    
+        
         default Rectangle getFavoritesListArea(Rectangle rectangle) {
             int offset = 31 + (ConfigObject.getInstance().doesShowUtilsButtons() ? 25 : 0);
-            return new Rectangle(rectangle.x + 1, rectangle.y + 2 + offset, rectangle.width - 2, rectangle.height - 5- offset);
+            return new Rectangle(rectangle.x + 1, rectangle.y + 2 + offset, rectangle.width - 2, rectangle.height - 5 - offset);
         }
         
         /**

+ 6 - 2
src/main/java/me/shedaniel/rei/api/EntryStack.java

@@ -167,7 +167,10 @@ public interface EntryStack {
     void render(Rectangle bounds, int mouseX, int mouseY, float delta);
     
     public static enum Type {
-        ITEM, FLUID, EMPTY, RENDER
+        ITEM,
+        FLUID,
+        EMPTY,
+        RENDER
     }
     
     public static class Settings<T> {
@@ -192,7 +195,8 @@ public interface EntryStack {
         }
         
         public static class Item {
-            public static final Settings<Supplier<Boolean>> RENDER_OVERLAY = new Settings(TRUE);
+            public static final Settings<Supplier<Boolean>> RENDER_ENCHANTMENT_GLINT = new Settings(TRUE);
+            @Deprecated public static final Settings<Supplier<Boolean>> RENDER_OVERLAY = RENDER_ENCHANTMENT_GLINT;
             
             private Item() {
             }

+ 1 - 1
src/main/java/me/shedaniel/rei/api/ItemStackRenderOverlayHook.java

@@ -6,5 +6,5 @@
 package me.shedaniel.rei.api;
 
 public interface ItemStackRenderOverlayHook {
-    void rei_setRenderOverlay(boolean b);
+    void rei_setRenderEnchantmentGlint(boolean b);
 }

+ 31 - 6
src/main/java/me/shedaniel/rei/api/ObjectHolder.java

@@ -5,18 +5,43 @@
 
 package me.shedaniel.rei.api;
 
+import me.shedaniel.rei.impl.ObjectHolderImpl;
+
 public interface ObjectHolder<T> {
-    int intValue();
+    @SuppressWarnings("deprecation")
+    static <T> ObjectHolder<T> of(T o) {
+        return new ObjectHolderImpl<>(o);
+    }
+    
+    @Deprecated
+    default int intValue() {
+        return (int) (Object) value();
+    }
     
-    long longValue();
+    @Deprecated
+    default long longValue() {
+        return (long) (Object) value();
+    }
     
-    boolean booleanValue();
+    @Deprecated
+    default boolean booleanValue() {
+        return (boolean) (Object) value();
+    }
     
-    float floatValue();
+    @Deprecated
+    default float floatValue() {
+        return (float) (Object) value();
+    }
     
-    double doubleValue();
+    @Deprecated
+    default double doubleValue() {
+        return (double) (Object) value();
+    }
     
-    String stringValue();
+    @Deprecated
+    default String stringValue() {
+        return (String) value();
+    }
     
     T value();
 }

+ 1 - 2
src/main/java/me/shedaniel/rei/api/annotations/Experimental.java

@@ -13,5 +13,4 @@ import static java.lang.annotation.ElementType.*;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(value = {CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
-public @interface Experimental {
-}
+public @interface Experimental {}

+ 1 - 2
src/main/java/me/shedaniel/rei/api/annotations/Internal.java

@@ -13,5 +13,4 @@ import static java.lang.annotation.ElementType.*;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(value = {CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
-public @interface Internal {
-}
+public @interface Internal {}

+ 1 - 2
src/main/java/me/shedaniel/rei/api/annotations/ToBeRemoved.java

@@ -13,5 +13,4 @@ import static java.lang.annotation.ElementType.*;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(value = {CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
-public @interface ToBeRemoved {
-}
+public @interface ToBeRemoved {}

+ 14 - 24
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -71,7 +71,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
         matrixStack_1.translate(0.0D, 0.0D, getBlitOffset());
         Matrix4f matrix4f_1 = matrixStack_1.peek().getModel();
-        for(int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) {
+        for (int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) {
             font.draw(tooltipLines.get(lineIndex), x, currentY, -1, true, matrix4f_1, immediate, false, 0, 15728880);
             currentY += lineIndex == 0 ? 12 : 10;
         }
@@ -253,7 +253,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                 }
             });
             int xxx = ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10;
-            for(Weather weather : Weather.values()) {
+            for (Weather weather : Weather.values()) {
                 widgets.add(new ButtonWidget(new Rectangle(xxx, 35, 20, 20), "") {
                     @Override
                     public void onPressed() {
@@ -427,7 +427,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         if (shouldReInit)
             init();
         else {
-            for(DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(minecraft.currentScreen.getClass())) {
+            for (DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(minecraft.currentScreen.getClass())) {
                 if (handler != null && handler.shouldRecalculateArea(!ConfigObject.getInstance().isLeftHandSidePanel(), rectangle)) {
                     init();
                     break;
@@ -444,7 +444,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen) {
                 ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
                 int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
-                for(Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
+                for (Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
                     if (!slot.hasStack() || !ENTRY_LIST_WIDGET.canLastSearchTermsBeAppliedTo(EntryStack.create(slot.getStack())))
                         fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
             }
@@ -455,7 +455,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         this.renderWidgets(mouseX, mouseY, delta);
         if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
-            for(RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
+            for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(mouseX - hooks.rei_getContainerLeft(), mouseY - hooks.rei_getContainerTop())) {
                         String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
@@ -473,7 +473,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         }
         Screen currentScreen = MinecraftClient.getInstance().currentScreen;
         if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
-            for(QueuedTooltip queuedTooltip : QUEUED_TOOLTIPS) {
+            for (QueuedTooltip queuedTooltip : QUEUED_TOOLTIPS) {
                 if (queuedTooltip != null)
                     renderTooltip(queuedTooltip);
             }
@@ -540,7 +540,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(i, j, amount))
                 return true;
         }
-        for(Widget widget : widgets)
+        for (Widget widget : widgets)
             if (widget != ENTRY_LIST_WIDGET && (favoritesListWidget == null || widget != favoritesListWidget) && widget.mouseScrolled(i, j, amount))
                 return true;
         return false;
@@ -551,7 +551,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         if (ScreenHelper.isOverlayVisible()) {
             if (ScreenHelper.getSearchField().keyPressed(int_1, int_2, int_3))
                 return true;
-            for(Element listener : widgets)
+            for (Element listener : widgets)
                 if (listener != ScreenHelper.getSearchField() && listener.keyPressed(int_1, int_2, int_3))
                     return true;
         }
@@ -587,7 +587,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             return false;
         if (ScreenHelper.getSearchField().charTyped(char_1, int_1))
             return true;
-        for(Element listener : widgets)
+        for (Element listener : widgets)
             if (listener != ScreenHelper.getSearchField() && listener.charTyped(char_1, int_1))
                 return true;
         return false;
@@ -604,7 +604,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             return false;
         if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
-            for(RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
+            for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(double_1 - hooks.rei_getContainerLeft(), double_2 - hooks.rei_getContainerTop())) {
                         ClientHelper.getInstance().executeViewAllRecipesFromCategories(Arrays.asList(area.getCategories()));
@@ -612,7 +612,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                         return true;
                     }
         }
-        for(Element element : widgets)
+        for (Element element : widgets)
             if (element.mouseClicked(double_1, double_2, int_1)) {
                 this.setFocused(element);
                 if (int_1 == 0)
@@ -630,22 +630,12 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     }
     
     public boolean isInside(double mouseX, double mouseY) {
-        if (!rectangle.contains(mouseX, mouseY))
-            return false;
-        for(DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
-            ActionResult in = handler.isInZone(!ConfigObject.getInstance().isLeftHandSidePanel(), mouseX, mouseY);
-            if (in != ActionResult.PASS)
-                return in == ActionResult.SUCCESS;
-        }
-        return true;
+        return rectangle.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY);
     }
     
     public boolean isNotInExclusionZones(double mouseX, double mouseY) {
-        for(DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
-            ActionResult in = handler.isInZone(true, mouseX, mouseY);
-            if (in != ActionResult.PASS)
-                return in == ActionResult.SUCCESS;
-            in = handler.isInZone(false, mouseX, mouseY);
+        for (DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
+            ActionResult in = handler.isInZone(mouseX, mouseY);
             if (in != ActionResult.PASS)
                 return in == ActionResult.SUCCESS;
         }

+ 6 - 3
src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java

@@ -35,7 +35,8 @@ public class OverlaySearchField extends TextFieldWidget {
     
     @Override
     public void setFocused(boolean boolean_1) {
-        if (isFocused() != boolean_1) addToHistory(getText());
+        if (isFocused() != boolean_1)
+            addToHistory(getText());
         super.setFocused(boolean_1);
     }
     
@@ -45,7 +46,8 @@ public class OverlaySearchField extends TextFieldWidget {
         if (!text.isEmpty()) {
             history.removeIf(str -> str.equalsIgnoreCase(text));
             history.add(text);
-            if (history.size() > 100) history.remove(0);
+            if (history.size() > 100)
+                history.remove(0);
         }
     }
     
@@ -96,7 +98,8 @@ public class OverlaySearchField extends TextFieldWidget {
                 return true;
             } else if (int_1 == 265) {
                 int i = history.indexOf(getText()) - 1;
-                if (i < -1 && getText().isEmpty()) i = history.size() - 1;
+                if (i < -1 && getText().isEmpty())
+                    i = history.size() - 1;
                 else if (i < -1) {
                     addToHistory(getText());
                     i = history.size() - 2;

+ 4 - 4
src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java

@@ -47,8 +47,7 @@ public class RecipeViewingScreen extends Screen {
     public boolean choosePageActivated;
     public RecipeChoosePageWidget recipeChoosePageWidget;
     private Rectangle bounds;
-    @Nullable
-    private CategoryBaseWidget workingStationsBaseWidget;
+    @Nullable private CategoryBaseWidget workingStationsBaseWidget;
     private RecipeCategory<RecipeDisplay> selectedCategory;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     
@@ -110,7 +109,8 @@ public class RecipeViewingScreen extends Screen {
         if (int_1 == 259) {
             if (ScreenHelper.hasLastRecipeScreen())
                 minecraft.openScreen(ScreenHelper.getLastRecipeScreen());
-            else minecraft.openScreen(ScreenHelper.getLastContainerScreen());
+            else
+                minecraft.openScreen(ScreenHelper.getLastContainerScreen());
             return true;
         }
         return super.keyPressed(int_1, int_2, int_3);
@@ -300,7 +300,7 @@ public class RecipeViewingScreen extends Screen {
             recipeChoosePageWidget = new RecipeChoosePageWidget(this, page, getTotalPages(selectedCategory));
         else
             recipeChoosePageWidget = null;
-    
+        
         workingStationsBaseWidget = null;
         List<List<EntryStack>> workingStations = RecipeHelper.getInstance().getWorkingStations(selectedCategory.getIdentifier());
         if (!workingStations.isEmpty()) {

+ 2 - 1
src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java

@@ -483,7 +483,8 @@ public class VillagerRecipeViewingScreen extends Screen {
         if (int_1 == 259) {
             if (ScreenHelper.hasLastRecipeScreen())
                 minecraft.openScreen(ScreenHelper.getLastRecipeScreen());
-            else minecraft.openScreen(ScreenHelper.getLastContainerScreen());
+            else
+                minecraft.openScreen(ScreenHelper.getLastContainerScreen());
             return true;
         }
         return super.keyPressed(int_1, int_2, int_3);

+ 3 - 1
src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java

@@ -10,7 +10,9 @@ import net.minecraft.client.resource.language.I18n;
 import java.util.Locale;
 
 public enum SearchFieldLocation {
-    CENTER, BOTTOM_SIDE, TOP_SIDE;
+    CENTER,
+    BOTTOM_SIDE,
+    TOP_SIDE;
     
     @Override
     public String toString() {

+ 1 - 2
src/main/java/me/shedaniel/rei/gui/entries/RecipeEntry.java

@@ -7,7 +7,6 @@ package me.shedaniel.rei.gui.entries;
 
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.ObjectHolder;
-import me.shedaniel.rei.impl.ObjectHolderImpl;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.util.Identifier;
 
@@ -107,7 +106,7 @@ public abstract class RecipeEntry extends DrawableHelper implements EntryStack {
     @SuppressWarnings("deprecation")
     @Override
     public <T> ObjectHolder<T> getSetting(Settings<T> settings) {
-        return new ObjectHolderImpl<>(settings.getDefaultValue());
+        return ObjectHolder.of(settings.getDefaultValue());
     }
     
     public abstract int getHeight();

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

@@ -156,7 +156,8 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
         if (errorTooltip == null) {
             if (IS_YOG.get())
                 str += I18n.translate("text.auto_craft.move_items.yog");
-            else str += I18n.translate("text.auto_craft.move_items");
+            else
+                str += I18n.translate("text.auto_craft.move_items");
         } else {
             if (errorTooltip.size() > 1)
                 str += Formatting.RED.toString() + I18n.translate("error.rei.multi.errors") + "\n";

+ 26 - 29
src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java

@@ -44,7 +44,7 @@ import java.util.stream.Collectors;
 
 public class EntryListWidget extends WidgetWithBounds {
     
-    static final Supplier<Boolean> RENDER_EXTRA_CONFIG = ConfigObject.getInstance()::doesRenderEntryExtraOverlay;
+    static final Supplier<Boolean> RENDER_ENCHANTMENT_GLINT = ConfigObject.getInstance()::doesRenderEntryEnchantmentGlint;
     @SuppressWarnings("deprecation")
     static final Comparator<? super EntryStack> ENTRY_NAME_COMPARER = Comparator.comparing(SearchArgument::tryGetEntryStackName);
     static final Comparator<? super EntryStack> ENTRY_GROUP_COMPARER = Comparator.comparingInt(stack -> {
@@ -75,11 +75,8 @@ public class EntryListWidget extends WidgetWithBounds {
     @SuppressWarnings("rawtypes")
     static boolean notSteppingOnExclusionZones(int left, int top, Rectangle listArea) {
         MinecraftClient instance = MinecraftClient.getInstance();
-        for(DisplayHelper.DisplayBoundsHandler sortedBoundsHandler : DisplayHelper.getInstance().getSortedBoundsHandlers(instance.currentScreen.getClass())) {
-            ActionResult fit = sortedBoundsHandler.canItemSlotWidgetFit(!ConfigObject.getInstance().isLeftHandSidePanel(), left, top, instance.currentScreen, listArea);
-            if (fit != ActionResult.PASS)
-                return fit == ActionResult.SUCCESS;
-            fit = sortedBoundsHandler.canItemSlotWidgetFit(ConfigObject.getInstance().isLeftHandSidePanel(), left, top, instance.currentScreen, listArea);
+        for (DisplayHelper.DisplayBoundsHandler sortedBoundsHandler : DisplayHelper.getInstance().getSortedBoundsHandlers(instance.currentScreen.getClass())) {
+            ActionResult fit = sortedBoundsHandler.canItemSlotWidgetFit(left, top, instance.currentScreen, listArea);
             if (fit != ActionResult.PASS)
                 return fit == ActionResult.SUCCESS;
         }
@@ -191,7 +188,7 @@ public class EntryListWidget extends WidgetWithBounds {
     @Override
     public void render(int mouseX, int mouseY, float delta) {
         if (ConfigObject.getInstance().isEntryListWidgetScrolled()) {
-            for(EntryListEntry entry : entries)
+            for (EntryListEntry entry : entries)
                 entry.clearStacks();
             ScissorsHandler.INSTANCE.scissor(bounds);
             int sizeForFavorites = getSlotsHeightNumberForFavorites();
@@ -202,7 +199,7 @@ public class EntryListWidget extends WidgetWithBounds {
             if (sizeForFavorites > 0) {
                 drawString(font, I18n.translate("text.rei.favorites"), innerBounds.x + 2, (int) (innerBounds.y + 8 - scroll), -1);
                 nextIndex += innerBounds.width / 18;
-                for(int i1 = 0; i1 < favorites.size(); i1++) {
+                for (int i1 = 0; i1 < favorites.size(); i1++) {
                     EntryStack stack = favorites.get(i1);
                     back1:
                     while (true) {
@@ -226,7 +223,7 @@ public class EntryListWidget extends WidgetWithBounds {
             }
             int offset = sizeForFavorites > 0 ? -12 : 0;
             back:
-            for(; i < allStacks.size(); i++) {
+            for (; i < allStacks.size(); i++) {
                 EntryStack stack = allStacks.get(i);
                 while (true) {
                     EntryListEntry entry = entries.get(nextIndex);
@@ -249,10 +246,10 @@ public class EntryListWidget extends WidgetWithBounds {
             ScissorsHandler.INSTANCE.removeLastScissor();
             renderScrollbar();
         } else {
-            for(EntryListEntry widget : entries) {
+            for (EntryListEntry widget : entries) {
                 widget.render(mouseX, mouseY, delta);
             }
-            for(Widget widget : widgets) {
+            for (Widget widget : widgets) {
                 widget.render(mouseX, mouseY, delta);
             }
         }
@@ -349,7 +346,7 @@ public class EntryListWidget extends WidgetWithBounds {
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (containsMouse(PointHelper.fromMouse()))
-            for(Widget widget : widgets)
+            for (Widget widget : widgets)
                 if (widget.keyPressed(int_1, int_2, int_3))
                     return true;
         return false;
@@ -375,8 +372,8 @@ public class EntryListWidget extends WidgetWithBounds {
             List<EntryListEntry> entries = Lists.newLinkedList();
             int width = innerBounds.width / 18;
             int height = innerBounds.height / 18;
-            for(int currentY = 0; currentY < height; currentY++) {
-                for(int currentX = 0; currentX < width; currentX++) {
+            for (int currentY = 0; currentY < height; currentY++) {
+                for (int currentX = 0; currentX < width; currentX++) {
                     if (notSteppingOnExclusionZones(currentX * 18 + innerBounds.x, currentY * 18 + innerBounds.y, innerBounds)) {
                         entries.add((EntryListEntry) new EntryListEntry(currentX * 18 + innerBounds.x, currentY * 18 + innerBounds.y).noBackground());
                     }
@@ -385,7 +382,7 @@ public class EntryListWidget extends WidgetWithBounds {
             page = Math.max(Math.min(page, getTotalPages() - 1), 0);
             int numberForFavorites = getScrollNumberForFavorites();
             List<EntryStack> subList = allStacks.stream().skip(Math.max(0, page * entries.size() - numberForFavorites)).limit(Math.max(0, entries.size() - Math.max(0, numberForFavorites - page * entries.size()))).collect(Collectors.toList());
-            for(int i = 0; i < subList.size(); i++) {
+            for (int i = 0; i < subList.size(); i++) {
                 EntryStack stack = subList.get(i);
                 entries.get(i + Math.max(0, numberForFavorites - page * entries.size())).clearStacks().entry(stack);
                 entries.get(i + Math.max(0, numberForFavorites - page * entries.size())).isFavorites = false;
@@ -400,7 +397,7 @@ public class EntryListWidget extends WidgetWithBounds {
                     j += width;
                 }
                 List<EntryStack> subFavoritesList = favorites.stream().skip(skippedFavorites).limit(Math.max(0, entries.size() - width)).collect(Collectors.toList());
-                for(int i = 0; i < subFavoritesList.size(); i++) {
+                for (int i = 0; i < subFavoritesList.size(); i++) {
                     EntryStack stack = subFavoritesList.get(i);
                     entries.get(j).clearStacks().entry(stack);
                     entries.get(j).isFavorites = true;
@@ -416,7 +413,7 @@ public class EntryListWidget extends WidgetWithBounds {
             int currentX = 0;
             int currentY = 0;
             List<EntryListEntry> entries = Lists.newLinkedList();
-            for(int i = 0; i < slotsToPrepare; i++) {
+            for (int i = 0; i < slotsToPrepare; i++) {
                 int xPos = currentX * 18 + innerBounds.x;
                 int yPos = currentY * 18 + innerBounds.y;
                 entries.add((EntryListEntry) new EntryListEntry(xPos, yPos).noBackground());
@@ -446,11 +443,11 @@ public class EntryListWidget extends WidgetWithBounds {
             List<EntryStack> list = Lists.newLinkedList();
             boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty();
             List<EntryStack> workingItems = checkCraftable ? RecipeHelper.getInstance().findCraftableEntriesByItems(CollectionUtils.map(ScreenHelper.inventoryStacks, EntryStack::create)) : null;
-            for(EntryStack stack : EntryRegistry.getInstance().getStacksList()) {
+            for (EntryStack stack : EntryRegistry.getInstance().getStacksList()) {
                 if (canLastSearchTermsBeAppliedTo(stack)) {
                     if (workingItems != null && CollectionUtils.findFirstOrNullEquals(workingItems, stack) == null)
                         continue;
-                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_OVERLAY, RENDER_EXTRA_CONFIG));
+                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
                 }
             }
             ItemListOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
@@ -466,11 +463,11 @@ public class EntryListWidget extends WidgetWithBounds {
             List<EntryStack> list = Lists.newLinkedList();
             boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty();
             List<EntryStack> workingItems = checkCraftable ? RecipeHelper.getInstance().findCraftableEntriesByItems(CollectionUtils.map(ScreenHelper.inventoryStacks, EntryStack::create)) : null;
-            for(EntryStack stack : ConfigManager.getInstance().getFavorites()) {
+            for (EntryStack stack : ConfigManager.getInstance().getFavorites()) {
                 if (canLastSearchTermsBeAppliedTo(stack)) {
                     if (workingItems != null && CollectionUtils.findFirstOrNullEquals(workingItems, stack) == null)
                         continue;
-                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_OVERLAY, RENDER_EXTRA_CONFIG));
+                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
                 }
             }
             ItemListOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
@@ -499,9 +496,9 @@ public class EntryListWidget extends WidgetWithBounds {
         if (searchArguments.isEmpty())
             return true;
         String mod = null, name = null, tooltip = null, tags[] = null;
-        for(SearchArgument.SearchArguments arguments : searchArguments) {
+        for (SearchArgument.SearchArguments arguments : searchArguments) {
             boolean applicable = true;
-            for(SearchArgument argument : arguments.getArguments()) {
+            for (SearchArgument argument : arguments.getArguments()) {
                 if (argument.getArgumentType() == SearchArgument.ArgumentType.ALWAYS)
                     return true;
                 else if (argument.getArgumentType() == SearchArgument.ArgumentType.MOD) {
@@ -530,19 +527,19 @@ public class EntryListWidget extends WidgetWithBounds {
                         if (stack.getType() == EntryStack.Type.ITEM) {
                             Identifier[] tagsFor = minecraft.getNetworkHandler().getTagManager().items().getTagsFor(stack.getItem()).toArray(new Identifier[0]);
                             tags = new String[tagsFor.length];
-                            for(int i = 0; i < tagsFor.length; i++)
+                            for (int i = 0; i < tagsFor.length; i++)
                                 tags[i] = tagsFor[i].toString();
                         } else if (stack.getType() == EntryStack.Type.FLUID) {
                             Identifier[] tagsFor = minecraft.getNetworkHandler().getTagManager().fluids().getTagsFor(stack.getFluid()).toArray(new Identifier[0]);
                             tags = new String[tagsFor.length];
-                            for(int i = 0; i < tagsFor.length; i++)
+                            for (int i = 0; i < tagsFor.length; i++)
                                 tags[i] = tagsFor[i].toString();
                         } else
                             tags = new String[0];
                     }
                     if (tags != null && tags.length > 0) {
                         boolean a = false;
-                        for(String tag : tags)
+                        for (String tag : tags)
                             if (argument.getFunction(argument.isInclude()).apply(tag))
                                 a = true;
                         if (!a) {
@@ -564,13 +561,13 @@ public class EntryListWidget extends WidgetWithBounds {
     @SuppressWarnings("deprecation")
     private List<SearchArgument.SearchArguments> processSearchTerm(String searchTerm) {
         List<SearchArgument.SearchArguments> searchArguments = Lists.newArrayList();
-        for(String split : StringUtils.splitByWholeSeparatorPreserveAllTokens(searchTerm.toLowerCase(Locale.ROOT), "|")) {
+        for (String split : StringUtils.splitByWholeSeparatorPreserveAllTokens(searchTerm.toLowerCase(Locale.ROOT), "|")) {
             String[] terms = StringUtils.split(split);
             if (terms.length == 0)
                 searchArguments.add(SearchArgument.SearchArguments.ALWAYS);
             else {
                 SearchArgument[] arguments = new SearchArgument[terms.length];
-                for(int i = 0; i < terms.length; i++) {
+                for (int i = 0; i < terms.length; i++) {
                     String term = terms[i];
                     if (term.startsWith("-@") || term.startsWith("@-")) {
                         arguments[i] = new SearchArgument(SearchArgument.ArgumentType.MOD, term.substring(2), false);
@@ -622,7 +619,7 @@ public class EntryListWidget extends WidgetWithBounds {
             }
             if (!player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
                 return false;
-            for(Widget widget : children())
+            for (Widget widget : children())
                 if (widget.mouseClicked(double_1, double_2, int_1))
                     return true;
         }

+ 7 - 7
src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java

@@ -107,7 +107,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
     
     @Override
     public void render(int mouseX, int mouseY, float delta) {
-        for(EntryListEntry entry : entries)
+        for (EntryListEntry entry : entries)
             entry.clearStacks();
         ScissorsHandler.INSTANCE.scissor(bounds);
         int skip = Math.max(0, MathHelper.floor(scroll / 18f));
@@ -115,7 +115,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
         int i = nextIndex;
         blockedCount = 0;
         back:
-        for(; i < favorites.size(); i++) {
+        for (; i < favorites.size(); i++) {
             EntryStack stack = favorites.get(i);
             while (true) {
                 EntryListEntry entry = entries.get(nextIndex);
@@ -229,7 +229,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (containsMouse(PointHelper.fromMouse()))
-            for(Widget widget : children())
+            for (Widget widget : children())
                 if (widget.keyPressed(int_1, int_2, int_3))
                     return true;
         return false;
@@ -246,11 +246,11 @@ public class FavoritesListWidget extends WidgetWithBounds {
             List<EntryStack> list = Lists.newLinkedList();
             boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty();
             List<EntryStack> workingItems = checkCraftable ? RecipeHelper.getInstance().findCraftableEntriesByItems(CollectionUtils.map(ScreenHelper.inventoryStacks, EntryStack::create)) : null;
-            for(EntryStack stack : ConfigManager.getInstance().getFavorites()) {
+            for (EntryStack stack : ConfigManager.getInstance().getFavorites()) {
                 if (listWidget.canLastSearchTermsBeAppliedTo(stack)) {
                     if (workingItems != null && CollectionUtils.findFirstOrNullEquals(workingItems, stack) == null)
                         continue;
-                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_OVERLAY, RENDER_EXTRA_CONFIG));
+                    list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
                 }
             }
             ItemListOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
@@ -273,7 +273,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
         int currentX = 0;
         int currentY = 0;
         List<EntryListEntry> entries = Lists.newLinkedList();
-        for(int i = 0; i < slotsToPrepare; i++) {
+        for (int i = 0; i < slotsToPrepare; i++) {
             int xPos = currentX * 18 + innerBounds.x;
             int yPos = currentY * 18 + innerBounds.y;
             entries.add((EntryListEntry) new EntryListEntry(xPos, yPos).noBackground());
@@ -312,7 +312,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
             }
             if (!player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
                 return false;
-            for(Widget widget : children())
+            for (Widget widget : children())
                 if (widget.mouseClicked(double_1, double_2, int_1))
                     return true;
         }

+ 4 - 2
src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java

@@ -115,11 +115,13 @@ public class LabelWidget extends WidgetWithBounds {
         if (isCentered()) {
             if (hasShadows)
                 font.drawWithShadow(text, pos.x - width / 2, pos.y, defaultColor);
-            else font.draw(text, pos.x - width / 2, pos.y, defaultColor);
+            else
+                font.draw(text, pos.x - width / 2, pos.y, defaultColor);
         } else {
             if (hasShadows)
                 font.drawWithShadow(text, pos.x, pos.y, defaultColor);
-            else font.draw(text, pos.x, pos.y, defaultColor);
+            else
+                font.draw(text, pos.x, pos.y, defaultColor);
         }
     }
     

+ 2 - 2
src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java

@@ -42,8 +42,8 @@ public abstract class AbstractEntryStack extends DrawableHelper implements Entry
     public <T> ObjectHolder<T> getSetting(Settings<T> settings) {
         Object o = this.settings.get(settings);
         if (o == null)
-            return new ObjectHolderImpl(settings.getDefaultValue());
-        return new ObjectHolderImpl(o);
+            return ObjectHolder.of(settings.getDefaultValue());
+        return ObjectHolder.of((T) o);
     }
     
     @Override

+ 29 - 16
src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java

@@ -17,7 +17,7 @@ import net.minecraft.util.Pair;
 
 import java.util.Comparator;
 import java.util.List;
-import java.util.function.Function;
+import java.util.function.Supplier;
 
 @Deprecated
 @Internal
@@ -26,7 +26,7 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     private static final Comparator<? super Rectangle> RECTANGLE_COMPARER = Comparator.comparingLong(Rectangle::hashCode);
     
     private long lastArea = -1;
-    private List<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> list = Lists.newArrayList();
+    private List<Pair<Pair<Class<?>, Float>, Supplier<List<Rectangle>>>> list = Lists.newArrayList();
     
     @Override
     public Class<?> getBaseSupportedClass() {
@@ -49,10 +49,14 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     }
     
     @Override
-    public ActionResult isInZone(boolean isOnRightSide, double mouseX, double mouseY) {
-        for (Rectangle zone : getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false))
-            if (zone.contains(mouseX, mouseY))
-                return ActionResult.FAIL;
+    public ActionResult isInZone(double mouseX, double mouseY) {
+        Class<? extends Screen> screenClass = MinecraftClient.getInstance().currentScreen.getClass();
+        for (Pair<Pair<Class<?>, Float>, Supplier<List<Rectangle>>> pair : list) {
+            if (pair.getLeft().getLeft().isAssignableFrom(screenClass))
+                for (Rectangle zone : pair.getRight().get())
+                    if (zone.contains(mouseX, mouseY))
+                        return ActionResult.FAIL;
+        }
         return ActionResult.PASS;
     }
     
@@ -67,23 +71,28 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     
     private long currentHashCode(boolean isOnRightSide) {
         DisplayHelper.DisplayBoundsHandler handler = DisplayHelper.getInstance().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
-        return areasHashCode(isOnRightSide ? handler.getRightBounds(MinecraftClient.getInstance().currentScreen) : handler.getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false));
+        return areasHashCode(isOnRightSide ? handler.getRightBounds(MinecraftClient.getInstance().currentScreen) : handler.getLeftBounds(MinecraftClient.getInstance().currentScreen), getExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), false));
     }
     
     @Override
-    public ActionResult canItemSlotWidgetFit(boolean isOnRightSide, int left, int top, Screen screen, Rectangle fullBounds) {
-        for (Rectangle currentExclusionZone : getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false))
-            if (left + 18 >= currentExclusionZone.x && top + 18 >= currentExclusionZone.y && left <= currentExclusionZone.x + currentExclusionZone.width && top <= currentExclusionZone.y + currentExclusionZone.height)
-                return ActionResult.FAIL;
+    public ActionResult canItemSlotWidgetFit(int left, int top, Screen screen, Rectangle fullBounds) {
+        Class<? extends Screen> screenClass = screen.getClass();
+        for (Pair<Pair<Class<?>, Float>, Supplier<List<Rectangle>>> pair : list) {
+            if (pair.getLeft().getLeft().isAssignableFrom(screenClass))
+                for (Rectangle zone : pair.getRight().get()) {
+                    if (left + 18 >= zone.x && top + 18 >= zone.y && left <= zone.getMaxX() && top <= zone.getMaxY())
+                        return ActionResult.FAIL;
+                }
+        }
         return ActionResult.PASS;
     }
     
     @Override
-    public List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide, boolean sort) {
+    public List<Rectangle> getExclusionZones(Class<?> currentScreenClass, boolean sort) {
         List<Rectangle> rectangles = Lists.newArrayList();
-        for (Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>> pair : list) {
+        for (Pair<Pair<Class<?>, Float>, Supplier<List<Rectangle>>> pair : list) {
             if (pair.getLeft().getLeft().isAssignableFrom(currentScreenClass))
-                rectangles.addAll(pair.getRight().apply(isOnRightSide));
+                rectangles.addAll(pair.getRight().get());
         }
         if (sort)
             rectangles.sort(RECTANGLE_COMPARER);
@@ -91,7 +100,12 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     }
     
     @Override
-    public void registerExclusionZones(Class<?> screenClass, Function<Boolean, List<Rectangle>> supplier) {
+    public int supplierSize() {
+        return list.size();
+    }
+    
+    @Override
+    public void registerExclusionZones(Class<?> screenClass, Supplier<List<Rectangle>> supplier) {
         list.add(new Pair<>(new Pair<>(screenClass, 0f), supplier));
     }
     
@@ -99,7 +113,6 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
         int hashCode = 31 + (rectangle == null ? 0 : rectangle.hashCode());
         for (Rectangle e : exclusionZones)
             hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
-        // hashCode -= (e == null ? 0 : e.hashCode());
         return hashCode;
     }
     

+ 1 - 3
src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java

@@ -76,9 +76,7 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
     
     @Override
     public FabricKeyBinding[] getREIKeyBindings() {
-        return new FabricKeyBinding[]{
-                recipe, usage, hide, previousPage, nextPage, focusSearchField, copyRecipeIdentifier
-        };
+        return new FabricKeyBinding[]{recipe, usage, hide, previousPage, nextPage, focusSearchField, copyRecipeIdentifier};
     }
     
     @Override

+ 8 - 7
src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java

@@ -13,9 +13,7 @@ import me.sargunvohra.mcmods.autoconfig1u.gui.ConfigScreenProvider;
 import me.sargunvohra.mcmods.autoconfig1u.gui.registry.GuiRegistry;
 import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer;
 import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.Jankson;
-import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.JsonObject;
 import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.JsonPrimitive;
-import me.sargunvohra.mcmods.autoconfig1u.shadowed.blue.endless.jankson.impl.SyntaxError;
 import me.shedaniel.cloth.hooks.ScreenHooks;
 import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
@@ -62,7 +60,7 @@ public class ConfigManagerImpl implements ConfigManager {
         loadFavoredEntries();
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> {
             @SuppressWarnings("rawtypes") List<AbstractConfigListEntry> entries = new ArrayList<>();
-            for(FabricKeyBinding binding : ClientHelper.getInstance().getREIKeyBindings()) {
+            for (FabricKeyBinding binding : ClientHelper.getInstance().getREIKeyBindings()) {
                 entries.add(ConfigEntryBuilder.create().fillKeybindingField(I18n.translate(binding.getId()) + ":", binding).build());
             }
             KeyCodeEntry entry = ConfigEntryBuilder.create().startKeyCodeField(i13n, getUnsafely(field, config, InputUtil.UNKNOWN_KEYCODE)).setDefaultValue(() -> getUnsafely(field, defaults)).setSaveConsumer(newValue -> setUnsafely(field, config, newValue)).build();
@@ -89,7 +87,8 @@ public class ConfigManagerImpl implements ConfigManager {
         Gson gson = new GsonBuilder().create();
         for (String entry : ((ConfigObjectImpl) getConfig()).general.favorites) {
             EntryStack stack = EntryStack.readFromJson(gson.fromJson(entry, JsonElement.class));
-            if (!stack.isEmpty()) favorites.add(stack);
+            if (!stack.isEmpty())
+                favorites.add(stack);
         }
         saveConfig();
     }
@@ -101,7 +100,8 @@ public class ConfigManagerImpl implements ConfigManager {
         object.general.favorites.clear();
         for (EntryStack stack : favorites) {
             JsonElement element = stack.toJson();
-            if (element != null) object.general.favorites.add(gson.toJson(element));
+            if (element != null)
+                object.general.favorites.add(gson.toJson(element));
         }
         ((me.sargunvohra.mcmods.autoconfig1u.ConfigManager<ConfigObjectImpl>) AutoConfig.getConfigHolder(ConfigObjectImpl.class)).save();
     }
@@ -156,7 +156,8 @@ public class ConfigManagerImpl implements ConfigManager {
                     });
                 }).setSavingRunnable(() -> {
                     saveConfig();
-                    ContainerScreenOverlay.getEntryListWidget().updateSearch(ScreenHelper.getSearchField().getText());
+                    if (ScreenHelper.getSearchField() != null)
+                        ContainerScreenOverlay.getEntryListWidget().updateSearch(ScreenHelper.getSearchField().getText());
                 }).build();
             });
             return provider.get();
@@ -169,7 +170,7 @@ public class ConfigManagerImpl implements ConfigManager {
                 renderDirtBackground(0);
                 List<String> list = minecraft.textRenderer.wrapStringToWidthAsList(I18n.translate("text.rei.config_api_failed"), width - 100);
                 int y = (int) (height / 2 - minecraft.textRenderer.fontHeight * 1.3f / 2 * list.size());
-                for(int i = 0; i < list.size(); i++) {
+                for (int i = 0; i < list.size(); i++) {
                     String s = list.get(i);
                     drawCenteredString(minecraft.textRenderer, s, width / 2, y, -1);
                     y += minecraft.textRenderer.fontHeight;

+ 30 - 51
src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java

@@ -22,22 +22,16 @@ import java.util.List;
 @Config(name = "roughlyenoughitems/config")
 public class ConfigObjectImpl implements ConfigObject, ConfigData {
     
-    @ConfigEntry.Category("!general")
-    @ConfigEntry.Gui.TransitiveObject
-    @DontApplyFieldName
+    @ConfigEntry.Category("!general") @ConfigEntry.Gui.TransitiveObject @DontApplyFieldName
     public General general = new General();
-    @ConfigEntry.Category("appearance")
-    @ConfigEntry.Gui.TransitiveObject
-    @DontApplyFieldName
+    @ConfigEntry.Category("appearance") @ConfigEntry.Gui.TransitiveObject @DontApplyFieldName
     private Appearance appearance = new Appearance();
-    @ConfigEntry.Category("modules")
-    @ConfigEntry.Gui.TransitiveObject
-    @DontApplyFieldName
+    @ConfigEntry.Category("modules") @ConfigEntry.Gui.TransitiveObject @DontApplyFieldName
     private Modules modules = new Modules();
-    @ConfigEntry.Category("technical")
-    @ConfigEntry.Gui.TransitiveObject
-    @DontApplyFieldName
+    @ConfigEntry.Category("technical") @ConfigEntry.Gui.TransitiveObject @DontApplyFieldName
     private Technical technical = new Technical();
+    @ConfigEntry.Category("performance") @ConfigEntry.Gui.TransitiveObject @DontApplyFieldName
+    private Performance performance = new Performance();
     
     @Override
     public boolean isLighterButtonHover() {
@@ -90,8 +84,8 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
     }
     
     @Override
-    public boolean doesRenderEntryExtraOverlay() {
-        return appearance.renderEntryExtraOverlay;
+    public boolean doesRenderEntryEnchantmentGlint() {
+        return performance.renderEntryEnchantmentGlint;
     }
     
     @Override
@@ -220,50 +214,33 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
     }
     
     public static class General {
-        @ConfigEntry.Gui.Excluded
-        public List<String> favorites = new ArrayList<>();
-        @Comment("Declares whether cheating mode is on.")
-        private boolean cheating = false;
-        @Comment("Declares whether REI is visible.")
-        @ConfigEntry.Gui.Excluded
-        private boolean overlayVisible = true;
+        @ConfigEntry.Gui.Excluded public List<String> favorites = new ArrayList<>();
+        @Comment("Declares whether cheating mode is on.") private boolean cheating = false;
+        @Comment("Declares whether REI is visible.") @ConfigEntry.Gui.Excluded private boolean overlayVisible = true;
         private boolean favoritesEnabled = true;
-        @AddInFrontKeyCode
-        private InputUtil.KeyCode favoriteKeybind = InputUtil.Type.KEYSYM.createFromCode(65);
+        @AddInFrontKeyCode private InputUtil.KeyCode favoriteKeybind = InputUtil.Type.KEYSYM.createFromCode(65);
     }
     
     public static class Appearance {
-        @Comment("The ordering of the items on the item panel.")
-        @UseEnumSelectorInstead
+        @Comment("The ordering of the items on the item panel.") @UseEnumSelectorInstead
         private ItemListOrderingConfig itemListOrdering = ItemListOrderingConfig.REGISTRY_ASCENDING;
-        @Comment("Declares the appearance of REI windows.")
-        private boolean darkTheme = false;
-        @Comment("Whether REI should render entry's overlay.\nExample: Enchantment Glint")
-        private boolean renderEntryExtraOverlay = true;
-        @Comment("The ordering of the items on the item panel.")
-        @UseEnumSelectorInstead
+        @Comment("Declares the appearance of REI windows.") private boolean darkTheme = false;
+        @Comment("The ordering of the items on the item panel.") @UseEnumSelectorInstead
         private RecipeScreenType recipeScreenType = RecipeScreenType.UNSET;
-        @Comment("Declares the position of the search field.")
-        @UseEnumSelectorInstead
+        @Comment("Declares the position of the search field.") @UseEnumSelectorInstead
         private SearchFieldLocation searchFieldLocation = SearchFieldLocation.CENTER;
-        @Comment("Declares the position of the item list panel.")
-        private boolean mirrorItemPanel = false;
+        @Comment("Declares the position of the item list panel.") private boolean mirrorItemPanel = false;
         @Comment("Declares the maximum amount of recipes displayed in a page if possible.")
-        @ConfigEntry.BoundedDiscrete(min = 2, max = 99)
-        private int maxRecipePerPage = 3;
+        @ConfigEntry.BoundedDiscrete(min = 2, max = 99) private int maxRecipePerPage = 3;
         @Comment("Declares whether REI should lighten the button if hovered.")
         private boolean lighterButtonHover = true;
         private boolean clickableRecipeArrows = true;
-        @UseEnumSelectorInstead
-        private ItemCheatingMode itemCheatingMode = ItemCheatingMode.REI_LIKE;
-        @Comment("Declares the appearance of recipe's border.")
-        private boolean lightGrayRecipeBorder = false;
-        @Comment("Declares whether REI should append mod names to item stacks.")
-        private boolean appendModNames = true;
+        @UseEnumSelectorInstead private ItemCheatingMode itemCheatingMode = ItemCheatingMode.REI_LIKE;
+        @Comment("Declares the appearance of recipe's border.") private boolean lightGrayRecipeBorder = false;
+        @Comment("Declares whether REI should append mod names to item stacks.") private boolean appendModNames = true;
         @Comment("Declares how the scrollbar in villager screen should act.")
         private boolean villagerScreenPermanentScrollBar = false;
-        @Comment("Declares whether if entry list widget is scrolled.")
-        private boolean scrollingEntryListWidget = false;
+        @Comment("Declares whether if entry list widget is scrolled.") private boolean scrollingEntryListWidget = false;
         private boolean snapToRows = false;
         private boolean displayFavoritesOnTheLeft = true;
         private boolean displayFavoritesTooltip = true;
@@ -276,8 +253,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         private String gamemodeCommand = "/gamemode {gamemode}";
         @Comment("Declares the command used in servers to cheat items.")
         private String giveCommand = "/give {player_name} {item_identifier}{nbt} {count}";
-        @Comment("Declares the command used to change weather.")
-        private String weatherCommand = "/weather {weather}";
+        @Comment("Declares the command used to change weather.") private String weatherCommand = "/weather {weather}";
         private boolean registerRecipesInAnotherThread = true;
     }
     
@@ -285,11 +261,14 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         @Comment("Declares whether the craftable filter button is enabled.")
         private boolean enableCraftableOnlyButton = true;
         private boolean toastDisplayedOnCopyIdentifier = true;
-        @Comment("Declares whether the utils buttons are shown.")
-        private boolean showUtilsButtons = false;
-        @Comment("Declares whether REI should remove the recipe book.")
-        private boolean disableRecipeBook = false;
+        @Comment("Declares whether the utils buttons are shown.") private boolean showUtilsButtons = false;
+        @Comment("Declares whether REI should remove the recipe book.") private boolean disableRecipeBook = false;
         @Comment("Declares whether REI should fix closing container with tab.")
         private boolean fixTabCloseContainer = false;
     }
+    
+    public static class Performance {
+        @Comment("Whether REI should render entry's enchantment glint")
+        private boolean renderEntryEnchantmentGlint = true;
+    }
 }

+ 38 - 3
src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java

@@ -7,6 +7,7 @@ package me.shedaniel.rei.impl;
 
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.EntryStack;
+import me.shedaniel.rei.api.ObjectHolder;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.util.Identifier;
 
@@ -14,10 +15,9 @@ import javax.annotation.Nullable;
 import java.util.Optional;
 
 @Deprecated
-public class EmptyEntryStack extends AbstractEntryStack {
+public class EmptyEntryStack implements EntryStack {
     
-    @Deprecated
-    public static final EntryStack EMPTY = new EmptyEntryStack();
+    @Deprecated public static final EntryStack EMPTY = new EmptyEntryStack();
     
     private EmptyEntryStack() {
     }
@@ -57,6 +57,11 @@ public class EmptyEntryStack extends AbstractEntryStack {
         return null;
     }
     
+    @Override
+    public boolean equals(EntryStack stack, boolean ignoreTags, boolean ignoreAmount) {
+        return stack.getType() == getType();
+    }
+    
     @Override
     public boolean equalsIgnoreTagsAndAmount(EntryStack stack) {
         return stack.getType() == getType();
@@ -77,6 +82,36 @@ public class EmptyEntryStack extends AbstractEntryStack {
         return stack.getType() == getType();
     }
     
+    @Override
+    public int getZ() {
+        return 0;
+    }
+    
+    @Override
+    public void setZ(int z) {
+    
+    }
+    
+    @Override
+    public <T> EntryStack setting(Settings<T> settings, T value) {
+        return this;
+    }
+    
+    @Override
+    public <T> EntryStack removeSetting(Settings<T> settings) {
+        return this;
+    }
+    
+    @Override
+    public EntryStack clearSettings() {
+        return this;
+    }
+    
+    @Override
+    public <T> ObjectHolder<T> getSetting(Settings<T> settings) {
+        return ObjectHolder.of(settings.getDefaultValue());
+    }
+    
     @Override
     @Nullable
     public QueuedTooltip getTooltip(int mouseX, int mouseY) {

+ 3 - 1
src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java

@@ -154,7 +154,9 @@ public class FluidEntryStack extends AbstractEntryStack {
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetEntryStackName(this));
         if (amount >= 0) {
             String amountTooltip = getSetting(Settings.Fluid.AMOUNT_TOOLTIP).value().apply(this);
-            if (amountTooltip != null) for (String s : amountTooltip.split("\n")) toolTip.add(s);
+            if (amountTooltip != null)
+                for (String s : amountTooltip.split("\n"))
+                    toolTip.add(s);
         }
         toolTip.addAll(getSetting(Settings.TOOLTIP_APPEND_EXTRA).value().apply(this));
         if (getSetting(Settings.TOOLTIP_APPEND_MOD).value().get() && ConfigObject.getInstance().shouldAppendModNames()) {

+ 6 - 11
src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java

@@ -6,7 +6,6 @@
 package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
-import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.ConfigObject;
@@ -119,7 +118,7 @@ public class ItemEntryStack extends AbstractEntryStack {
     @Nullable
     @Override
     public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-        if (!getSetting(Settings.TOOLTIP_ENABLED).value().get() || isEmpty())
+        if (isEmpty() || !getSetting(Settings.TOOLTIP_ENABLED).value().get())
             return null;
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true));
         toolTip.addAll(getSetting(Settings.TOOLTIP_APPEND_EXTRA).value().apply(this));
@@ -139,21 +138,17 @@ public class ItemEntryStack extends AbstractEntryStack {
     
     @Override
     public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
-        if (getSetting(Settings.RENDER).value().get()) {
-            ItemStack stack = getItemStack().copy();
-            ((ItemStackRenderOverlayHook) (Object) stack).rei_setRenderOverlay(getSetting(Settings.Item.RENDER_OVERLAY).value().get());
-            RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+        if (!isEmpty() && getSetting(Settings.RENDER).value().get()) {
+            ItemStack stack = getItemStack();
+            ((ItemStackRenderOverlayHook) (Object) stack).rei_setRenderEnchantmentGlint(getSetting(Settings.Item.RENDER_ENCHANTMENT_GLINT).value().get());
             ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
             itemRenderer.zOffset = getZ();
-            RenderSystem.colorMask(true, true, true, true);
-            RenderSystem.enableLighting();
-            RenderSystem.enableRescaleNormal();
-            RenderSystem.enableDepthTest();
             int i1 = bounds.getCenterX() - 8;
             int i2 = bounds.getCenterY() - 8;
-            itemRenderer.renderGuiItem(stack, i1, i2);
+            itemRenderer.renderGuiItemIcon(stack, i1, i2);
             itemRenderer.renderGuiItemOverlay(MinecraftClient.getInstance().textRenderer, stack, i1, i2, getSetting(Settings.RENDER_COUNTS).value().get() ? getSetting(Settings.COUNTS).value().apply(this) : "");
             itemRenderer.zOffset = 0.0F;
+            ((ItemStackRenderOverlayHook) (Object) stack).rei_setRenderEnchantmentGlint(true);
         }
     }
 }

+ 0 - 30
src/main/java/me/shedaniel/rei/impl/ObjectHolderImpl.java

@@ -15,36 +15,6 @@ public class ObjectHolderImpl<T> implements ObjectHolder<T> {
         this.o = o;
     }
     
-    @Override
-    public int intValue() {
-        return (int) o;
-    }
-    
-    @Override
-    public long longValue() {
-        return (long) o;
-    }
-    
-    @Override
-    public boolean booleanValue() {
-        return (boolean) o;
-    }
-    
-    @Override
-    public float floatValue() {
-        return (float) o;
-    }
-    
-    @Override
-    public double doubleValue() {
-        return (double) o;
-    }
-    
-    @Override
-    public String stringValue() {
-        return (String) o;
-    }
-    
     @Override
     public T value() {
         return (T) o;

+ 20 - 26
src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java

@@ -33,8 +33,7 @@ import java.util.stream.Collectors;
 public class RecipeHelperImpl implements RecipeHelper {
     
     private static final Comparator<DisplayVisibilityHandler> VISIBILITY_HANDLER_COMPARATOR;
-    @SuppressWarnings("rawtypes")
-    private static final Comparator<Recipe> RECIPE_COMPARATOR = (o1, o2) -> {
+    @SuppressWarnings("rawtypes") private static final Comparator<Recipe> RECIPE_COMPARATOR = (o1, o2) -> {
         int int_1 = o1.getId().getNamespace().compareTo(o2.getId().getNamespace());
         if (int_1 == 0)
             int_1 = o1.getId().getPath().compareTo(o2.getId().getPath());
@@ -251,46 +250,39 @@ public class RecipeHelperImpl implements RecipeHelper {
         Version reiVersion = FabricLoader.getInstance().getModContainer("roughlyenoughitems").get().getMetadata().getVersion();
         if (!(reiVersion instanceof SemanticVersion))
             RoughlyEnoughItemsCore.LOGGER.warn("[REI] Roughly Enough Items is not using semantic versioning, will be ignoring plugins' minimum versions!");
+        List<REIPluginV0> reiPluginV0s = new ArrayList<>();
         for (REIPluginEntry plugin : plugins) {
             try {
                 if (reiVersion instanceof SemanticVersion)
                     if (plugin.getMinimumVersion().compareTo((SemanticVersion) reiVersion) > 0) {
                         throw new IllegalStateException("Requires " + plugin.getMinimumVersion().getFriendlyString() + " version of REI!");
                     }
-                if (plugin instanceof REIPluginV0)
+                if (plugin instanceof REIPluginV0) {
                     ((REIPluginV0) plugin).preRegister();
+                    reiPluginV0s.add((REIPluginV0) plugin);
+                }
             } catch (Throwable e) {
                 RoughlyEnoughItemsCore.LOGGER.error("[REI] " + plugin.getPluginIdentifier().toString() + " plugin failed to pre register!", e);
             }
         }
-        for (REIPluginEntry plugin : plugins) {
+        for (REIPluginV0 plugin : reiPluginV0s) {
             Identifier identifier = plugin.getPluginIdentifier();
             try {
-                if (reiVersion instanceof SemanticVersion)
-                    if (plugin.getMinimumVersion().compareTo((SemanticVersion) reiVersion) > 0)
-                        return;
-                if (plugin instanceof REIPluginV0) {
-                    ((REIPluginV0) plugin).registerBounds(DisplayHelper.getInstance());
-                    ((REIPluginV0) plugin).registerEntries(EntryRegistry.getInstance());
-                    ((REIPluginV0) plugin).registerPluginCategories(this);
-                    ((REIPluginV0) plugin).registerRecipeDisplays(this);
-                    ((REIPluginV0) plugin).registerOthers(this);
-                } else {
-                    throw new IllegalStateException("Invaild Plugin Class!");
-                }
+                plugin.registerBounds(DisplayHelper.getInstance());
+                plugin.registerEntries(EntryRegistry.getInstance());
+                plugin.registerPluginCategories(this);
+                plugin.registerRecipeDisplays(this);
+                plugin.registerOthers(this);
             } catch (Throwable e) {
                 RoughlyEnoughItemsCore.LOGGER.error("[REI] " + identifier.toString() + " plugin failed to load!", e);
             }
         }
-        for (REIPluginEntry plugin : plugins) {
+        for (REIPluginV0 plugin : reiPluginV0s) {
+            Identifier identifier = plugin.getPluginIdentifier();
             try {
-                if (reiVersion instanceof SemanticVersion)
-                    if (plugin.getMinimumVersion().compareTo((SemanticVersion) reiVersion) > 0)
-                        return;
-                if (plugin instanceof REIPluginV0)
-                    ((REIPluginV0) plugin).postRegister();
+                plugin.postRegister();
             } catch (Throwable e) {
-                RoughlyEnoughItemsCore.LOGGER.error("[REI] " + plugin.getPluginIdentifier().toString() + " plugin failed to post register!", e);
+                RoughlyEnoughItemsCore.LOGGER.error("[REI] " + identifier.toString() + " plugin failed to post register!", e);
             }
         }
         if (!recipeFunctions.isEmpty()) {
@@ -323,7 +315,7 @@ public class RecipeHelperImpl implements RecipeHelper {
         ScreenHelper.getOptionalOverlay().ifPresent(overlay -> overlay.shouldReInit = true);
         
         long usedTime = System.currentTimeMillis() - startTime;
-        RoughlyEnoughItemsCore.LOGGER.info("[REI] Registered %d stack entries, %d recipes displays, %d bounds handler, %d visibility handlers and %d categories (%s) in %d ms.", EntryRegistry.getInstance().getStacksList().size(), recipeCount.get(), DisplayHelper.getInstance().getAllBoundsHandlers().size(), getDisplayVisibilityHandlers().size(), categories.size(), String.join(", ", categories.stream().map(RecipeCategory::getCategoryName).collect(Collectors.toList())), usedTime);
+        RoughlyEnoughItemsCore.LOGGER.info("[REI] Registered {} stack entries, {} recipes displays, {} exclusion zones suppliers, {} bounds handler, {} visibility handlers and {} categories ({}) in {} ms.", EntryRegistry.getInstance().getStacksList().size(), recipeCount.get(), DisplayHelper.getInstance().getBaseBoundsHandler().supplierSize(), DisplayHelper.getInstance().getAllBoundsHandlers().size(), getDisplayVisibilityHandlers().size(), categories.size(), String.join(", ", categories.stream().map(RecipeCategory::getCategoryName).collect(Collectors.toList())), usedTime);
         arePluginsLoading = false;
     }
     
@@ -416,12 +408,14 @@ public class RecipeHelperImpl implements RecipeHelper {
     }
     
     @Override
-    public <T extends Recipe<?>> void registerRecipes(Identifier category, @SuppressWarnings("rawtypes") Function<Recipe, Boolean> recipeFilter, Function<T, RecipeDisplay> mappingFunction) {
+    public <T extends Recipe<?>> void registerRecipes(Identifier category, @SuppressWarnings("rawtypes")
+            Function<Recipe, Boolean> recipeFilter, Function<T, RecipeDisplay> mappingFunction) {
         recipeFunctions.add(new RecipeFunction(category, recipeFilter::apply, mappingFunction));
     }
     
     @Override
-    public <T extends Recipe<?>> void registerRecipes(Identifier category, @SuppressWarnings("rawtypes") Predicate<Recipe> recipeFilter, Function<T, RecipeDisplay> mappingFunction) {
+    public <T extends Recipe<?>> void registerRecipes(Identifier category,
+            @SuppressWarnings("rawtypes") Predicate<Recipe> recipeFilter, Function<T, RecipeDisplay> mappingFunction) {
         recipeFunctions.add(new RecipeFunction(category, recipeFilter, mappingFunction));
     }
     

+ 1 - 2
src/main/java/me/shedaniel/rei/impl/ScreenHelper.java

@@ -33,8 +33,7 @@ public class ScreenHelper implements ClientModInitializer {
     /**
      * @deprecated Use getters instead
      */
-    @Deprecated
-    public static OverlaySearchField searchField;
+    @Deprecated public static OverlaySearchField searchField;
     public static List<ItemStack> inventoryStacks = Lists.newArrayList();
     private static ContainerScreenOverlay overlay;
     private static AbstractContainerScreen<?> lastContainerScreen = null;

+ 3 - 3
src/main/java/me/shedaniel/rei/impl/SearchArgument.java

@@ -31,8 +31,7 @@ import java.util.function.Function;
 public class SearchArgument {
     
     public static final SearchArgument ALWAYS = new SearchArgument(ArgumentType.ALWAYS, "", true);
-    @Deprecated
-    private static List<Item> searchBlacklisted = Lists.newArrayList();
+    @Deprecated private static List<Item> searchBlacklisted = Lists.newArrayList();
     private ArgumentType argumentType;
     private String text;
     public final Function<String, Boolean> INCLUDE = s -> s.contains(text);
@@ -61,7 +60,8 @@ public class SearchArgument {
     @Deprecated
     public static String tryGetEntryStackTooltip(EntryStack stack) {
         QueuedTooltip tooltip = stack.getTooltip(0, 0);
-        if (tooltip != null) return CollectionUtils.joinToString(tooltip.getText(), "\n");
+        if (tooltip != null)
+            return CollectionUtils.joinToString(tooltip.getText(), "\n");
         return "";
     }
     

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

@@ -28,12 +28,9 @@ import java.util.List;
 @Mixin(BrewingRecipeRegistry.class)
 public class MixinBrewingRecipeRegistry {
     
-    @Unique
-    private static final List<BrewingRecipe> SELF_ITEM_RECIPES = Lists.newArrayList();
-    @Unique
-    private static final List<Potion> REGISTERED_POTION_TYPES = Lists.newArrayList();
-    @Unique
-    private static final List<Ingredient> SELF_POTION_TYPES = Lists.newArrayList();
+    @Unique private static final List<BrewingRecipe> SELF_ITEM_RECIPES = Lists.newArrayList();
+    @Unique private static final List<Potion> REGISTERED_POTION_TYPES = Lists.newArrayList();
+    @Unique private static final List<Ingredient> SELF_POTION_TYPES = Lists.newArrayList();
     
     @Inject(method = "registerPotionType", at = @At("RETURN"))
     private static void method_8080(Item item_1, CallbackInfo ci) {

+ 1 - 1
src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java

@@ -17,7 +17,7 @@ public class MixinItemStack implements ItemStackRenderOverlayHook {
     private boolean rei_dontRenderOverlay = false;
     
     @Override
-    public void rei_setRenderOverlay(boolean b) {
+    public void rei_setRenderEnchantmentGlint(boolean b) {
         rei_dontRenderOverlay = !b;
     }
     

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

@@ -106,7 +106,8 @@ public class DefaultPlugin implements REIPluginV0 {
                 for (ItemStack stack : entryRegistry.getAllStacksFromItem(item)) {
                     entryRegistry.registerEntry(EntryStack.create(stack));
                 }
-            } else entryRegistry.registerEntry(EntryStack.create(item));
+            } else
+                entryRegistry.registerEntry(EntryStack.create(item));
         }
         EntryStack stack = EntryStack.create(Items.ENCHANTED_BOOK);
         for (Enchantment enchantment : Registry.ENCHANTMENT) {
@@ -225,9 +226,10 @@ public class DefaultPlugin implements REIPluginV0 {
         }
         displayHelper.getBaseBoundsHandler().registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
         displayHelper.getBaseBoundsHandler().registerExclusionZones(RecipeBookProvider.class, new DefaultRecipeBookExclusionZones());
-        displayHelper.getBaseBoundsHandler().registerExclusionZones(RecipeViewingScreen.class, isLeftSide -> {
+        displayHelper.getBaseBoundsHandler().registerExclusionZones(RecipeViewingScreen.class, () -> {
             CategoryBaseWidget widget = ((RecipeViewingScreen) MinecraftClient.getInstance().currentScreen).getWorkingStationsBaseWidget();
-            if (widget == null) return Collections.emptyList();
+            if (widget == null)
+                return Collections.emptyList();
             return Collections.singletonList(widget.getBounds().clone());
         });
         displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<AbstractContainerScreen<?>>() {

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

@@ -18,12 +18,12 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.function.Function;
+import java.util.function.Supplier;
 
-public class DefaultPotionEffectExclusionZones implements Function<Boolean, List<Rectangle>> {
+public class DefaultPotionEffectExclusionZones implements Supplier<List<Rectangle>> {
     @Override
-    public List<Rectangle> apply(Boolean isOnRightSide) {
-        if (isOnRightSide || !(ScreenHelper.getLastContainerScreen() instanceof AbstractInventoryScreen) || !((AbstractInventoryScreenHooks) ScreenHelper.getLastContainerScreen()).rei_doesOffsetGuiForEffects())
+    public List<Rectangle> get() {
+        if (!(ScreenHelper.getLastContainerScreen() instanceof AbstractInventoryScreen) || !((AbstractInventoryScreenHooks) ScreenHelper.getLastContainerScreen()).rei_doesOffsetGuiForEffects())
             return Collections.emptyList();
         Collection<StatusEffectInstance> activePotionEffects = MinecraftClient.getInstance().player.getStatusEffects();
         if (activePotionEffects.isEmpty())

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

@@ -16,13 +16,13 @@ import net.minecraft.container.CraftingContainer;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.function.Function;
+import java.util.function.Supplier;
 
-public class DefaultRecipeBookExclusionZones implements Function<Boolean, List<Rectangle>> {
+public class DefaultRecipeBookExclusionZones implements Supplier<List<Rectangle>> {
     
     @Override
-    public List<Rectangle> apply(Boolean isOnRightSide) {
-        if (isOnRightSide || !MinecraftClient.getInstance().player.getRecipeBook().isGuiOpen() || !(MinecraftClient.getInstance().currentScreen instanceof RecipeBookProvider) || !(ScreenHelper.getLastContainerScreen().getContainer() instanceof CraftingContainer))
+    public List<Rectangle> get() {
+        if (!MinecraftClient.getInstance().player.getRecipeBook().isGuiOpen() || !(MinecraftClient.getInstance().currentScreen instanceof RecipeBookProvider) || !(ScreenHelper.getLastContainerScreen().getContainer() instanceof CraftingContainer))
             return Collections.emptyList();
         ContainerScreenHooks screenHooks = ScreenHelper.getLastContainerScreenHooks();
         List<Rectangle> l = Lists.newArrayList(new Rectangle(screenHooks.rei_getContainerLeft() - 4 - 145, screenHooks.rei_getContainerTop(), 4 + 145 + 30, screenHooks.rei_getContainerHeight()));

+ 6 - 5
src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java

@@ -30,6 +30,10 @@ import java.util.List;
 
 public class DefaultCategoryHandler implements AutoTransferHandler {
     
+    public static boolean canUseMovePackets() {
+        return ClientSidePacketRegistry.INSTANCE.canServerReceive(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET);
+    }
+    
     @Override
     public Result handle(Context context) {
         if (!(context.getRecipe() instanceof TransferRecipeDisplay))
@@ -64,7 +68,8 @@ public class DefaultCategoryHandler implements AutoTransferHandler {
             for (EntryStack stack : stacks) {
                 if (stack.getItemStack() != null)
                     buf.writeItemStack(stack.getItemStack());
-                else buf.writeItemStack(ItemStack.EMPTY);
+                else
+                    buf.writeItemStack(ItemStack.EMPTY);
             }
         }
         ClientSidePacketRegistry.INSTANCE.sendToServer(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET, buf);
@@ -76,10 +81,6 @@ public class DefaultCategoryHandler implements AutoTransferHandler {
         return -10;
     }
     
-    public static boolean canUseMovePackets() {
-        return ClientSidePacketRegistry.INSTANCE.canServerReceive(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET);
-    }
-    
     public IntList hasItems(List<List<EntryStack>> inputs) {
         // Create a clone of player's inventory, and count
         DefaultedList<ItemStack> copyMain = DefaultedList.of();

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

@@ -15,13 +15,17 @@ import me.shedaniel.rei.api.TransferRecipeCategory;
 import me.shedaniel.rei.gui.widget.EntryWidget;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
 import me.shedaniel.rei.gui.widget.Widget;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.plugin.DefaultPlugin;
+import me.shedaniel.rei.server.ContainerInfo;
+import me.shedaniel.rei.server.ContainerInfoHandler;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.render.DiffuseLighting;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
 
 import java.util.Arrays;
 import java.util.LinkedList;
@@ -88,12 +92,16 @@ public class DefaultCraftingCategory implements TransferRecipeCategory<DefaultCr
     
     @Override
     public void renderRedSlots(List<Widget> widgets, Rectangle bounds, DefaultCraftingDisplay display, IntList redSlots) {
-        Point startPoint = new Point(bounds.getCenterX() - 58, bounds.getCenterY() - 27);
+        ContainerInfo info = ContainerInfoHandler.getContainerInfo(getIdentifier(), ScreenHelper.getLastContainerScreen().getContainer().getClass());
+        if (info == null)
+            return;
         RenderSystem.translatef(0, 0, 400);
+        Point startPoint = new Point(bounds.getCenterX() - 58, bounds.getCenterY() - 27);
+        int width = info.getCraftingWidth(ScreenHelper.getLastContainerScreen().getContainer());
         for (Integer slot : redSlots) {
             int i = slot;
-            int x = i % 3;
-            int y = (i - x) / 3;
+            int x = i % width;
+            int y = MathHelper.floor(i / (float) width);
             DrawableHelper.fill(startPoint.x + 1 + x * 18, startPoint.y + 1 + y * 18, startPoint.x + 1 + x * 18 + 16, startPoint.y + 1 + y * 18 + 16, 0x60ff0000);
         }
         RenderSystem.translatef(0, 0, -400);

+ 2 - 1
src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java

@@ -14,6 +14,7 @@ import net.minecraft.container.Container;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.util.Identifier;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
@@ -40,7 +41,7 @@ public interface DefaultCraftingDisplay extends TransferRecipeDisplay {
     default List<List<EntryStack>> getOrganisedInputEntries(ContainerInfo<Container> containerInfo, Container container) {
         List<List<EntryStack>> list = Lists.newArrayListWithCapacity(containerInfo.getCraftingWidth(container) * containerInfo.getCraftingHeight(container));
         for (int i = 0; i < containerInfo.getCraftingWidth(container) * containerInfo.getCraftingHeight(container); i++) {
-            list.add(Lists.newArrayList());
+            list.add(Collections.emptyList());
         }
         for (int i = 0; i < getInputEntries().size(); i++) {
             List<EntryStack> stacks = getInputEntries().get(i);

+ 6 - 3
src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java

@@ -25,11 +25,14 @@ public class ContainerInfoHandler {
     }
     
     public static ContainerInfo getContainerInfo(Identifier category, Class<?> containerClass) {
-        if (!isCategoryHandled(category)) return null;
+        if (!isCategoryHandled(category))
+            return null;
         Map<Class<? extends Container>, ContainerInfo> infoMap = containerInfoMap.get(category.toString());
-        if (infoMap.containsKey(containerClass)) return infoMap.get(containerClass);
+        if (infoMap.containsKey(containerClass))
+            return infoMap.get(containerClass);
         for (Map.Entry<Class<? extends Container>, ContainerInfo> entry : infoMap.entrySet())
-            if (entry.getKey().isAssignableFrom(containerClass)) return entry.getValue();
+            if (entry.getKey().isAssignableFrom(containerClass))
+                return entry.getValue();
         return null;
     }
 }

+ 1 - 2
src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java

@@ -238,7 +238,6 @@ public class InputSlotCrafter<C extends Inventory> implements RecipeGridAligner<
         return int_1;
     }
     
-    public static class NotEnoughMaterialsException extends RuntimeException {
-    }
+    public static class NotEnoughMaterialsException extends RuntimeException {}
     
 }

+ 2 - 1
src/main/java/me/shedaniel/rei/utils/CollectionUtils.java

@@ -140,7 +140,8 @@ public class CollectionUtils {
         List<R> l = null;
         for (T t : list) {
             if (predicate.test(t)) {
-                if (l == null) l = new LinkedList<>();
+                if (l == null)
+                    l = new LinkedList<>();
                 l.add(function.apply(t));
             }
         }

+ 2 - 1
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -94,13 +94,14 @@
   "config.roughlyenoughitems.appearance": "Appearance",
   "config.roughlyenoughitems.modules": "Modules",
   "config.roughlyenoughitems.technical": "Technical",
+  "config.roughlyenoughitems.performance": "Performance",
   "config.roughlyenoughitems.cheating": "Cheating:",
   "config.roughlyenoughitems.favoriteKeybind": "Favorite Entry:",
   "config.roughlyenoughitems.favoritesEnabled": "Favorites Enabled:",
   "config.roughlyenoughitems.clickableRecipeArrows": "Clickable Recipe Arrows:",
   "config.roughlyenoughitems.clickableRecipeArrows.boolean.true": "Enabled",
   "config.roughlyenoughitems.clickableRecipeArrows.boolean.false": "Disabled",
-  "config.roughlyenoughitems.renderEntryExtraOverlay": "Render Entry Extra Overlay:",
+  "config.roughlyenoughitems.renderEntryEnchantmentGlint": "Render Enchantment Glint:",
   "config.roughlyenoughitems.darkTheme": "Appearance Theme:",
   "config.roughlyenoughitems.darkTheme.boolean.true": "Dark Theme",
   "config.roughlyenoughitems.darkTheme.boolean.false": "Light Theme",