shedaniel 5 lat temu
rodzic
commit
c802f1008c

+ 1 - 0
build.gradle

@@ -120,6 +120,7 @@ curseforge {
             addGameVersion '1.15.2'
             addGameVersion '1.15-Snapshot'
             addGameVersion 'Java 8'
+            addGameVersion 'Fabric'
             relations {
                 requiredDependency 'fabric-api'
                 embeddedLibrary 'cloth'

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=3.3.15
+mod_version=3.3.16
 minecraft_version=1.15.2
 yarn_version=1.15.2+build.1
 fabricloader_version=0.7.2+build.174

+ 2 - 0
src/main/java/me/shedaniel/rei/api/ConfigObject.java

@@ -134,6 +134,8 @@ public interface ConfigObject {
     
     boolean isUsingCompactTabs();
     
+    boolean isLowerConfigButton();
+    
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
     @interface AddInFrontKeyCode {}

+ 51 - 41
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -81,10 +81,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         RenderSystem.enableDepthTest();
         RenderSystem.enableRescaleNormal();
     };
-    private Rectangle rectangle;
+    private Rectangle bounds;
     private Window window;
-    private CraftableToggleButtonWidget toggleButtonWidget;
-    private ButtonWidget buttonLeft, buttonRight;
+    @Nullable private LateRenderedButton craftableToggleButton;
+    private LateRenderedButton configButton;
+    private ButtonWidget leftButton, rightButton;
     
     public static EntryListWidget getEntryListWidget() {
         return ENTRY_LIST_WIDGET;
@@ -107,7 +108,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         this.window = MinecraftClient.getInstance().getWindow();
         @SuppressWarnings({"RawTypeCanBeGeneric", "rawtypes"})
         DisplayHelper.DisplayBoundsHandler boundsHandler = DisplayHelper.getInstance().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
-        this.rectangle = ConfigObject.getInstance().isLeftHandSidePanel() ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
+        this.bounds = ConfigObject.getInstance().isLeftHandSidePanel() ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
         widgets.add(ENTRY_LIST_WIDGET);
         if (ConfigObject.getInstance().doDisplayFavoritesOnTheLeft() && ConfigObject.getInstance().isFavoritesEnabled()) {
             if (favoritesListWidget == null)
@@ -118,11 +119,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         if (ScreenHelper.getSearchField() == null) {
             ScreenHelper.setSearchField(new OverlaySearchField(0, 0, 0, 0));
         }
-        ScreenHelper.getSearchField().getBounds().setBounds(getTextFieldArea());
+        ScreenHelper.getSearchField().getBounds().setBounds(getSearchFieldArea());
         this.widgets.add(ScreenHelper.getSearchField());
         ScreenHelper.getSearchField().setChangedListener(ENTRY_LIST_WIDGET::updateSearch);
         if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
-            widgets.add(buttonLeft = new ButtonWidget(new Rectangle(rectangle.x, rectangle.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), I18n.translate("text.rei.left_arrow")) {
+            widgets.add(leftButton = new ButtonWidget(new Rectangle(bounds.x, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), I18n.translate("text.rei.left_arrow")) {
                 @Override
                 public void onPressed() {
                     ENTRY_LIST_WIDGET.previousPage();
@@ -146,7 +147,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                     return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
                 }
             });
-            widgets.add(buttonRight = new ButtonWidget(new Rectangle(rectangle.x + rectangle.width - 18, rectangle.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), I18n.translate("text.rei.right_arrow")) {
+            widgets.add(rightButton = new ButtonWidget(new Rectangle(bounds.x + bounds.width - 18, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), I18n.translate("text.rei.right_arrow")) {
                 @Override
                 public void onPressed() {
                     ENTRY_LIST_WIDGET.nextPage();
@@ -172,7 +173,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             });
         }
         
-        widgets.add(new ButtonWidget(new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20), "") {
+        widgets.add(configButton = new LateRenderedButton(getConfigButtonArea(), "") {
             @Override
             public void onPressed() {
                 if (Screen.hasShiftDown()) {
@@ -184,6 +185,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             
             @Override
             public void render(int mouseX, int mouseY, float delta) {
+            }
+            
+            @Override
+            public void lateRender(int mouseX, int mouseY, float delta) {
+                setBlitOffset(600);
                 super.render(mouseX, mouseY, delta);
                 Rectangle bounds = getBounds();
                 if (ClientHelper.getInstance().isCheating() && RoughlyEnoughItemsCore.hasOperatorPermission()) {
@@ -195,6 +201,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                 MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
                 RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
                 blit(bounds.x + 3, bounds.y + 3, 0, 0, 14, 14);
+                setBlitOffset(0);
             }
             
             @Override
@@ -223,7 +230,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             }
         });
         if (ConfigObject.getInstance().doesShowUtilsButtons()) {
-            widgets.add(new ButtonWidget(new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 55 : 35, 10, 20, 20), "") {
+            widgets.add(new ButtonWidget(ConfigObject.getInstance().isLowerConfigButton() ? new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20) : new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 55 : 35, 10, 20, 20), "") {
                 @Override
                 public void onPressed() {
                     MinecraftClient.getInstance().player.sendChatMessage(ConfigObject.getInstance().getGamemodeCommand().replaceAll("\\{gamemode}", getNextGameMode(Screen.hasShiftDown()).getName()));
@@ -285,7 +292,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             }
         }
         if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
-            widgets.add(new ClickableLabelWidget(new Point(rectangle.x + (rectangle.width / 2), rectangle.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), "") {
+            widgets.add(new ClickableLabelWidget(new Point(bounds.x + (bounds.width / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), "") {
                 @Override
                 public void render(int mouseX, int mouseY, float delta) {
                     clickable(ENTRY_LIST_WIDGET.getTotalPages() > 1);
@@ -306,28 +313,22 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                 }
             }.tooltip(() -> I18n.translate("text.rei.go_back_first_page")));
         }
-        if (ConfigObject.getInstance().isCraftableFilterEnabled())
-            this.widgets.add(toggleButtonWidget = new CraftableToggleButtonWidget(getCraftableToggleArea()) {
+        if (ConfigObject.getInstance().isCraftableFilterEnabled()) {
+            this.widgets.add(craftableToggleButton = new CraftableToggleButtonWidget(getCraftableToggleArea()) {
                 @Override
                 public void onPressed() {
                     ConfigManager.getInstance().toggleCraftableOnly();
                     ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText());
                 }
                 
-                @Override
-                public void lateRender(int mouseX, int mouseY, float delta) {
-                    setBlitOffset(300);
-                    super.lateRender(mouseX, mouseY, delta);
-                    setBlitOffset(0);
-                }
-                
                 @Override
                 public boolean containsMouse(double mouseX, double mouseY) {
                     return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
                 }
             });
-        else
-            toggleButtonWidget = null;
+        } else {
+            craftableToggleButton = null;
+        }
     }
     
     private Weather getNextWeather() {
@@ -379,13 +380,13 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         return MinecraftClient.getInstance().getNetworkHandler().getPlayerListEntry(MinecraftClient.getInstance().player.getGameProfile().getId()).getGameMode();
     }
     
-    private Rectangle getTextFieldArea() {
-        int widthRemoved = ConfigObject.getInstance().isCraftableFilterEnabled() ? 22 : 2;
+    private Rectangle getSearchFieldArea() {
+        int widthRemoved = 1 + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 22 : 0) + (ConfigObject.getInstance().isLowerConfigButton() ? 22 : 0);
         SearchFieldLocation searchFieldLocation = ConfigObject.getInstance().getSearchFieldLocation();
         if (searchFieldLocation == SearchFieldLocation.BOTTOM_SIDE)
-            return new Rectangle(rectangle.x + 2, window.getScaledHeight() - 22, rectangle.width - 6 - widthRemoved, 18);
+            return new Rectangle(bounds.x + 2, window.getScaledHeight() - 22, bounds.width - 6 - widthRemoved, 18);
         if (searchFieldLocation == SearchFieldLocation.TOP_SIDE)
-            return new Rectangle(rectangle.x + 2, 4, rectangle.width - 6 - widthRemoved, 18);
+            return new Rectangle(bounds.x + 2, 4, bounds.width - 6 - widthRemoved, 18);
         if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
             RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
             return new Rectangle(widget.getBounds().x, window.getScaledHeight() - 22, widget.getBounds().width - widthRemoved, 18);
@@ -398,10 +399,20 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     }
     
     private Rectangle getCraftableToggleArea() {
-        Rectangle searchBoxArea = getTextFieldArea();
-        searchBoxArea.setLocation(searchBoxArea.x + searchBoxArea.width + 4, searchBoxArea.y - 1);
-        searchBoxArea.setSize(20, 20);
-        return searchBoxArea;
+        Rectangle area = getSearchFieldArea();
+        area.setLocation(area.x + area.width + 4, area.y - 1);
+        area.setSize(20, 20);
+        return area;
+    }
+    
+    private Rectangle getConfigButtonArea() {
+        if (ConfigObject.getInstance().isLowerConfigButton()) {
+            Rectangle area = getSearchFieldArea();
+            area.setLocation(area.x + area.width + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 26 : 4), area.y - 1);
+            area.setSize(20, 20);
+            return area;
+        }
+        return new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20);
     }
     
     private String getCheatModeText() {
@@ -410,7 +421,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     
     @Override
     public Rectangle getBounds() {
-        return rectangle;
+        return bounds;
     }
     
     @Override
@@ -420,7 +431,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             init();
         else {
             for (DisplayHelper.DisplayBoundsHandler<?> handler : DisplayHelper.getInstance().getSortedBoundsHandlers(minecraft.currentScreen.getClass())) {
-                if (handler != null && handler.shouldRecalculateArea(!ConfigObject.getInstance().isLeftHandSidePanel(), rectangle)) {
+                if (handler != null && handler.shouldRecalculateArea(!ConfigObject.getInstance().isLeftHandSidePanel(), bounds)) {
                     init();
                     break;
                 }
@@ -458,8 +469,9 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     public void lateRender(int mouseX, int mouseY, float delta) {
         if (ScreenHelper.isOverlayVisible()) {
             ScreenHelper.getSearchField().laterRender(mouseX, mouseY, delta);
-            if (toggleButtonWidget != null)
-                toggleButtonWidget.lateRender(mouseX, mouseY, delta);
+            if (craftableToggleButton != null)
+                craftableToggleButton.lateRender(mouseX, mouseY, delta);
+            configButton.lateRender(mouseX, mouseY, delta);
         }
         Screen currentScreen = MinecraftClient.getInstance().currentScreen;
         if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
@@ -470,7 +482,6 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         QUEUED_TOOLTIPS.clear();
     }
     
-    @SuppressWarnings("deprecation")
     public void renderTooltip(QueuedTooltip tooltip) {
         if (tooltip.getConsumer() == null)
             renderTooltip(tooltip.getText(), tooltip.getX(), tooltip.getY());
@@ -498,12 +509,11 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             QUEUED_TOOLTIPS.add(queuedTooltip);
     }
     
-    @SuppressWarnings("deprecation")
     public void renderWidgets(int int_1, int int_2, float float_1) {
         if (!ScreenHelper.isOverlayVisible())
             return;
         if (!ConfigObject.getInstance().isEntryListWidgetScrolled())
-            buttonLeft.enabled = buttonRight.enabled = ENTRY_LIST_WIDGET.getTotalPages() > 1;
+            leftButton.enabled = rightButton.enabled = ENTRY_LIST_WIDGET.getTotalPages() > 1;
         for (Widget widget : widgets) {
             widget.render(int_1, int_2, float_1);
         }
@@ -515,10 +525,10 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             return false;
         if (isInside(PointHelper.fromMouse())) {
             if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
-                if (amount > 0 && buttonLeft.enabled)
-                    buttonLeft.onPressed();
-                else if (amount < 0 && buttonRight.enabled)
-                    buttonRight.onPressed();
+                if (amount > 0 && leftButton.enabled)
+                    leftButton.onPressed();
+                else if (amount < 0 && rightButton.enabled)
+                    rightButton.onPressed();
                 else
                     return false;
                 return true;
@@ -621,7 +631,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     }
     
     public boolean isInside(double mouseX, double mouseY) {
-        return rectangle.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY);
+        return bounds.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY);
     }
     
     public boolean isNotInExclusionZones(double mouseX, double mouseY) {

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

@@ -5,11 +5,9 @@
 
 package me.shedaniel.rei.gui.widget;
 
-import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.ConfigManager;
 import net.minecraft.block.Blocks;
-import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.item.ItemRenderer;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
@@ -19,10 +17,11 @@ import org.jetbrains.annotations.ApiStatus;
 import java.util.Optional;
 
 @ApiStatus.Internal
-public abstract class CraftableToggleButtonWidget extends ButtonWidget {
+public abstract class CraftableToggleButtonWidget extends LateRenderedButton {
     
     public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private ItemRenderer itemRenderer;
+    private static final ItemStack ICON = new ItemStack(Blocks.CRAFTING_TABLE);
     
     public CraftableToggleButtonWidget(Rectangle rectangle) {
         super(rectangle, "");
@@ -33,17 +32,17 @@ public abstract class CraftableToggleButtonWidget extends ButtonWidget {
         this(new Rectangle(x, y, width, height));
     }
     
+    @Override
     public void lateRender(int mouseX, int mouseY, float delta) {
+        setBlitOffset(600);
         super.render(mouseX, mouseY, delta);
         
-        this.itemRenderer.zOffset = getBlitOffset();
+        this.itemRenderer.zOffset = getBlitOffset() - 98;
         Rectangle bounds = getBounds();
-        this.itemRenderer.renderGuiItem(new ItemStack(Blocks.CRAFTING_TABLE), bounds.x + 2, bounds.y + 2);
+        this.itemRenderer.renderGuiItemIcon(ICON, bounds.x + 2, bounds.y + 2);
         this.itemRenderer.zOffset = 0.0F;
-        MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
-        RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         int color = ConfigManager.getInstance().isCraftableOnlyEnabled() ? 939579655 : 956235776;
-        setBlitOffset(getBlitOffset() + 10);
+        setBlitOffset(getBlitOffset() + 1);
         this.fillGradient(bounds.x + 1, bounds.y + 1, bounds.getMaxX() - 1, bounds.getMaxY() - 1, color, color);
         setBlitOffset(0);
     }

+ 13 - 0
src/main/java/me/shedaniel/rei/gui/widget/LateRenderable.java

@@ -0,0 +1,13 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.gui.widget;
+
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+public interface LateRenderable {
+    void lateRender(int mouseX, int mouseY, float delta);
+}

+ 21 - 0
src/main/java/me/shedaniel/rei/gui/widget/LateRenderedButton.java

@@ -0,0 +1,21 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.gui.widget;
+
+import me.shedaniel.math.api.Rectangle;
+import net.minecraft.text.Text;
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+public abstract class LateRenderedButton extends ButtonWidget implements LateRenderable {
+    protected LateRenderedButton(Rectangle rectangle, Text text) {
+        super(rectangle, text);
+    }
+    
+    protected LateRenderedButton(Rectangle rectangle, String text) {
+        super(rectangle, text);
+    }
+}

+ 6 - 0
src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java

@@ -273,6 +273,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         return appearance.useCompactTabs;
     }
     
+    @Override
+    public boolean isLowerConfigButton() {
+        return appearance.lowerConfigButton;
+    }
+    
     public static class General {
         @ConfigEntry.Gui.Excluded public List<String> favorites = new ArrayList<>();
         @Comment("Declares whether cheating mode is on.") private boolean cheating = false;
@@ -310,6 +315,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         @Comment("Declares whether favorites will be searched.") private boolean searchFavorites = true;
         @UsePercentage(min = 0.5, max = 4.0) private double entrySize = 1.0;
         private boolean useCompactTabs = true;
+        private boolean lowerConfigButton = false;
     }
     
     public static class Technical {

+ 19 - 1
src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java

@@ -7,9 +7,13 @@ package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.math.api.Executor;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.impl.compat.ModelHasDepth1151Compat;
+import me.shedaniel.rei.impl.compat.ModelSideLit1152Compat;
+import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.OverlayTexture;
 import net.minecraft.client.render.VertexConsumerProvider;
@@ -26,14 +30,28 @@ import org.jetbrains.annotations.Nullable;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.function.Predicate;
 
 @ApiStatus.Internal
 public class ItemEntryStack extends AbstractEntryStack implements OptimalEntryStack {
     
+    private static final Predicate<BakedModel> IS_SIDE_LIT;
     private static final MatrixStack MATRICES = new MatrixStack();
     private ItemStack itemStack;
     private int hash = -1;
     
+    static {
+        boolean isOn1_15_2 = false;
+        String isSideLit = FabricLoader.getInstance().getMappingResolver().mapMethodName("intermediary", "net.minecraft.class_1087", "method_24304", "()Z");
+        try {
+            BakedModel.class.getDeclaredMethod(isSideLit);
+            isOn1_15_2 = true;
+        } catch (NoSuchMethodException ignored) {
+        }
+        //noinspection Convert2MethodRef
+        IS_SIDE_LIT = isOn1_15_2 ? Executor.call(() -> () -> new ModelSideLit1152Compat()) : Executor.call(() -> () -> new ModelHasDepth1151Compat());
+    }
+    
     public ItemEntryStack(ItemStack itemStack) {
         this.itemStack = itemStack;
     }
@@ -187,7 +205,7 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
             MATRICES.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight());
             VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
             BakedModel model = getModelFromStack(stack);
-            boolean bl = !model.isSideLit();
+            boolean bl = !IS_SIDE_LIT.test(model);
             if (bl)
                 GlStateManager.method_24221();
             MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, MATRICES, immediate, 15728880, OverlayTexture.DEFAULT_UV, model);

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

@@ -58,7 +58,7 @@ public class RecipeHelperImpl implements RecipeHelper {
     public List<EntryStack> findCraftableEntriesByItems(List<EntryStack> inventoryItems) {
         List<EntryStack> craftables = new ArrayList<>();
         for (List<RecipeDisplay> value : recipeCategoryListMap.values())
-            for (RecipeDisplay recipeDisplay : value) {
+            for (RecipeDisplay recipeDisplay : Lists.newArrayList(value)) {
                 int slotsCraftable = 0;
                 List<List<EntryStack>> requiredInput = recipeDisplay.getRequiredEntries();
                 for (List<EntryStack> slot : requiredInput) {
@@ -132,7 +132,7 @@ public class RecipeHelperImpl implements RecipeHelper {
             RecipeCategory<?> category = entry.getKey();
             Identifier categoryId = entry.getValue();
             Set<RecipeDisplay> set = Sets.newLinkedHashSet();
-            for (RecipeDisplay display : recipeCategoryListMap.get(categoryId)) {
+            for (RecipeDisplay display : Lists.newArrayList(recipeCategoryListMap.get(categoryId))) {
                 for (EntryStack outputStack : display.getOutputEntries())
                     if (stack.equals(outputStack) && isDisplayVisible(display)) {
                         set.add(display);
@@ -185,7 +185,7 @@ public class RecipeHelperImpl implements RecipeHelper {
             Set<RecipeDisplay> set = Sets.newLinkedHashSet();
             RecipeCategory<?> category = entry.getKey();
             Identifier categoryId = entry.getValue();
-            for (RecipeDisplay display : recipeCategoryListMap.get(categoryId)) {
+            for (RecipeDisplay display : Lists.newArrayList(recipeCategoryListMap.get(categoryId))) {
                 back:
                 for (List<EntryStack> input : display.getInputEntries()) {
                     for (EntryStack otherEntry : input) {
@@ -198,7 +198,7 @@ public class RecipeHelperImpl implements RecipeHelper {
                 }
             }
             if (isStackWorkStationOfCategory(categoryId, stack)) {
-                set.addAll(recipeCategoryListMap.get(categoryId));
+                set.addAll(Lists.newArrayList(recipeCategoryListMap.get(categoryId)));
             }
             if (!set.isEmpty())
                 CollectionUtils.getOrPutEmptyList(result, category).addAll(set);
@@ -378,11 +378,11 @@ public class RecipeHelperImpl implements RecipeHelper {
         for (Map.Entry<RecipeCategory<?>, Identifier> entry : categories.entrySet()) {
             RecipeCategory<?> category = entry.getKey();
             Identifier categoryId = entry.getValue();
-            List<RecipeDisplay> displays = recipeCategoryListMap.get(categoryId);
+            List<RecipeDisplay> displays = Lists.newArrayList(recipeCategoryListMap.get(categoryId));
             if (displays != null) {
                 displays.removeIf(this::isDisplayNotVisible);
                 if (!displays.isEmpty())
-                    result.put(category, Lists.newArrayList(displays));
+                    result.put(category, displays);
             }
         }
         return result;
@@ -390,7 +390,7 @@ public class RecipeHelperImpl implements RecipeHelper {
     
     @Override
     public List<RecipeDisplay> getAllRecipesFromCategory(RecipeCategory<?> category) {
-        return recipeCategoryListMap.get(category.getIdentifier());
+        return Lists.newArrayList(recipeCategoryListMap.get(category.getIdentifier()));
     }
     
     @Override

+ 17 - 0
src/main/java/me/shedaniel/rei/impl/compat/ModelHasDepth1151Compat.java

@@ -0,0 +1,17 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl.compat;
+
+import net.minecraft.client.render.model.BakedModel;
+
+import java.util.function.Predicate;
+
+public class ModelHasDepth1151Compat implements Predicate<BakedModel> {
+    @Override
+    public boolean test(BakedModel bakedModel) {
+        return bakedModel.hasDepth();
+    }
+}

+ 17 - 0
src/main/java/me/shedaniel/rei/impl/compat/ModelSideLit1152Compat.java

@@ -0,0 +1,17 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.impl.compat;
+
+import net.minecraft.client.render.model.BakedModel;
+
+import java.util.function.Predicate;
+
+public class ModelSideLit1152Compat implements Predicate<BakedModel> {
+    @Override
+    public boolean test(BakedModel bakedModel) {
+        return bakedModel.isSideLit();
+    }
+}

+ 3 - 0
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -110,6 +110,9 @@
   "config.roughlyenoughitems.clickableRecipeArrows.boolean.true": "Enabled",
   "config.roughlyenoughitems.clickableRecipeArrows.boolean.false": "Disabled",
   "config.roughlyenoughitems.renderEntryEnchantmentGlint": "Render Enchantment Glint:",
+  "config.roughlyenoughitems.lowerConfigButton": "Config Button Position:",
+  "config.roughlyenoughitems.lowerConfigButton.boolean.false": "Top",
+  "config.roughlyenoughitems.lowerConfigButton.boolean.true": "Next to Search",
   "config.roughlyenoughitems.entrySize": "Entry Size:",
   "config.roughlyenoughitems.useCompactTabs": "Compact Tabs:",
   "config.roughlyenoughitems.darkTheme": "Appearance Theme:",