Selaa lähdekoodia

We are out of beta

- Fix #149
- Close #148
- SlotWidget API improvement
Danielshe 5 vuotta sitten
vanhempi
sitoutus
86bc462c24

+ 5 - 5
gradle.properties

@@ -1,9 +1,9 @@
-mod_version=3.1-pre
-minecraft_version=1.14.3
-yarn_version=1.14.3+build.1
-fabricloader_version=0.4.8+build.155
+mod_version=3.1
+minecraft_version=1.14.4
+yarn_version=1.14.4+build.1
+fabricloader_version=0.6.1+build.164
 jankson_version=1.1.0
 cloth_events_version=0.5.1
 cloth_config_version=1.1.1
 modmenu_version=1.7.9+build.118
-fabric_api=0.3.0+build.198
+fabric_api=0.3.2+build.218-1.14

+ 47 - 32
src/main/java/me/shedaniel/rei/api/Renderer.java

@@ -9,12 +9,16 @@ import me.shedaniel.rei.gui.renderers.EmptyRenderer;
 import me.shedaniel.rei.gui.renderers.FluidRenderer;
 import me.shedaniel.rei.gui.renderers.ItemStackRenderer;
 import me.shedaniel.rei.gui.renderers.SimpleRecipeRenderer;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.MathHelper;
 
+import javax.annotation.Nullable;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.Function;
 import java.util.function.Supplier;
 
 public abstract class Renderer extends DrawableHelper {
@@ -25,12 +29,7 @@ public abstract class Renderer extends DrawableHelper {
      * @return the item stack renderer
      */
     public static ItemStackRenderer fromItemStackSupplier(Supplier<ItemStack> supplier) {
-        return new ItemStackRenderer() {
-            @Override
-            public ItemStack getItemStack() {
-                return supplier.get();
-            }
-        };
+        return fromItemStacks(() -> Collections.singletonList(supplier.get()), true, null);
     }
     
     /**
@@ -40,17 +39,7 @@ public abstract class Renderer extends DrawableHelper {
      * @return the item stack renderer
      */
     public static ItemStackRenderer fromItemStackSupplierNoCounts(Supplier<ItemStack> supplier) {
-        return new ItemStackRenderer() {
-            @Override
-            public ItemStack getItemStack() {
-                return supplier.get();
-            }
-            
-            @Override
-            protected boolean renderCounts() {
-                return false;
-            }
-        };
+        return fromItemStacks(() -> Collections.singletonList(supplier.get()), false, null);
     }
     
     /**
@@ -60,14 +49,28 @@ public abstract class Renderer extends DrawableHelper {
      * @return the item stack renderer
      */
     public static ItemStackRenderer fromItemStack(ItemStack stack) {
-        return fromItemStackSupplier(() -> stack);
+        return fromItemStacks(() -> Collections.singletonList(stack), true, null);
     }
     
     public static FluidRenderer fromFluid(Fluid fluid) {
+        return fromFluid(() -> fluid, null);
+    }
+    
+    public static FluidRenderer fromFluid(Supplier<Fluid> fluidSupplier, @Nullable Function<Fluid, List<String>> extraTooltipSupplier) {
         return new FluidRenderer() {
             @Override
             public Fluid getFluid() {
-                return fluid;
+                return fluidSupplier.get();
+            }
+            
+            @Override
+            protected List<String> getExtraToolTips(Fluid fluid) {
+                if (extraTooltipSupplier == null)
+                    return super.getExtraToolTips(fluid);
+                List<String> apply = extraTooltipSupplier.apply(fluid);
+                if (apply == null)
+                    return super.getExtraToolTips(fluid);
+                return apply;
             }
         };
     }
@@ -79,7 +82,7 @@ public abstract class Renderer extends DrawableHelper {
      * @return the item stack renderer
      */
     public static ItemStackRenderer fromItemStackNoCounts(ItemStack stack) {
-        return fromItemStackSupplierNoCounts(() -> stack);
+        return fromItemStacks(() -> Collections.singletonList(stack), false, null);
     }
     
     /**
@@ -103,32 +106,39 @@ public abstract class Renderer extends DrawableHelper {
     }
     
     public static ItemStackRenderer fromItemStacks(List<ItemStack> stacks) {
-        return new ItemStackRenderer() {
-            @Override
-            public ItemStack getItemStack() {
-                if (stacks.isEmpty())
-                    return ItemStack.EMPTY;
-                return stacks.get(MathHelper.floor((System.currentTimeMillis() / 500 % (double) stacks.size()) / 1f));
-            }
-        };
+        return fromItemStacks(() -> stacks, true, null);
     }
     
-    public static ItemStackRenderer fromItemStacksNoCounts(List<ItemStack> stacks) {
+    public static ItemStackRenderer fromItemStacks(Supplier<List<ItemStack>> stacksSupplier, boolean renderCounts, @Nullable Function<ItemStack, List<String>> extraTooltipSupplier) {
         return new ItemStackRenderer() {
             @Override
             public ItemStack getItemStack() {
-                if (stacks.isEmpty())
+                if (stacksSupplier.get().isEmpty())
                     return ItemStack.EMPTY;
-                return stacks.get(MathHelper.floor((System.currentTimeMillis() / 500 % (double) stacks.size()) / 1f));
+                return stacksSupplier.get().get(MathHelper.floor((System.currentTimeMillis() / 500 % (double) stacksSupplier.get().size()) / 1f));
             }
             
             @Override
             protected boolean renderCounts() {
-                return false;
+                return renderCounts;
+            }
+            
+            @Override
+            protected List<String> getExtraToolTips(ItemStack stack) {
+                if (extraTooltipSupplier == null)
+                    return super.getExtraToolTips(stack);
+                List<String> apply = extraTooltipSupplier.apply(stack);
+                if (apply == null)
+                    return super.getExtraToolTips(stack);
+                return apply;
             }
         };
     }
     
+    public static ItemStackRenderer fromItemStacksNoCounts(List<ItemStack> stacks) {
+        return fromItemStacks(() -> stacks, false, null);
+    }
+    
     /**
      * Gets the current blit offset
      *
@@ -158,4 +168,9 @@ public abstract class Renderer extends DrawableHelper {
      */
     public abstract void render(int x, int y, double mouseX, double mouseY, float delta);
     
+    @Nullable
+    public QueuedTooltip getQueuedTooltip(float delta) {
+        return null;
+    }
+    
 }

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

@@ -358,6 +358,7 @@ public class VillagerRecipeViewingScreen extends Screen {
                 GuiLighting.disable();
                 recipeRenderers.get(i).setBlitOffset(1);
                 recipeRenderers.get(i).render(buttonWidgets.get(i).getBounds().x, buttonWidgets.get(i).getBounds().y, mouseX, mouseY, delta);
+                ScreenHelper.getLastOverlay().addTooltip(recipeRenderers.get(i).getQueuedTooltip(delta));
             }
         }
         double height = buttonWidgets.stream().map(ButtonWidget::getBounds).collect(Collectors.summingDouble(Rectangle::getHeight));

+ 21 - 5
src/main/java/me/shedaniel/rei/gui/renderers/FluidRenderer.java

@@ -27,10 +27,15 @@ import net.minecraft.util.Pair;
 import net.minecraft.util.math.BlockPos;
 import net.minecraft.util.registry.Registry;
 
+import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.List;
 
 public abstract class FluidRenderer extends Renderer {
+    /**
+     * @deprecated This boolean is no longer used
+     */
+    @Deprecated
     public boolean drawTooltip = false;
     public Lazy<Pair<Sprite, Integer>> sprite = new Lazy<>(() -> {
         try {
@@ -72,16 +77,27 @@ public abstract class FluidRenderer extends Renderer {
             tess.draw();
         }
         this.blitOffset = 0;
-        if (drawTooltip && mouseX >= x - 8 && mouseX <= x + 8 && mouseY >= y - 6 && mouseY <= y + 10)
-            queueTooltip(getFluid(), delta);
-        this.drawTooltip = false;
     }
     
+    @Nullable
+    @Override
+    public QueuedTooltip getQueuedTooltip(float delta) {
+        return QueuedTooltip.create(getTooltip(getFluid()));
+    }
+    
+    /**
+     * Queue a tooltip to the REI overlay
+     *
+     * @param fluid the fluid to queue
+     * @param delta the delta
+     * @deprecated Use {@link Renderer#getQueuedTooltip(float)} instead and queue manually
+     */
+    @Deprecated
     protected void queueTooltip(Fluid fluid, float delta) {
-        ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(fluid)));
+        ScreenHelper.getLastOverlay().addTooltip(getQueuedTooltip(delta));
     }
     
-    private List<String> getTooltip(Fluid fluid) {
+    protected List<String> getTooltip(Fluid fluid) {
         List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetFluidName(fluid));
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
             final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));

+ 19 - 3
src/main/java/me/shedaniel/rei/gui/renderers/ItemStackRenderer.java

@@ -19,12 +19,17 @@ import net.minecraft.client.render.item.ItemRenderer;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.Identifier;
 
+import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.List;
 
 public abstract class ItemStackRenderer extends Renderer {
     
     public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
+    /**
+     * @deprecated This boolean is no longer used
+     */
+    @Deprecated
     public boolean drawTooltip = false;
     
     @Override
@@ -42,15 +47,26 @@ public abstract class ItemStackRenderer extends Renderer {
         itemRenderer.renderGuiItemOverlay(MinecraftClient.getInstance().textRenderer, getItemStack(), l, i1, renderCounts() ? null : "");
         itemRenderer.zOffset = 0.0F;
         this.blitOffset = 0;
-        if (drawTooltip && mouseX >= x - 8 && mouseX <= x + 8 && mouseY >= y - 6 && mouseY <= y + 10)
-            queueTooltip(getItemStack(), delta);
-        this.drawTooltip = false;
     }
     
+    /**
+     * Queue a tooltip to the REI overlay
+     *
+     * @param itemStack the stack to queue
+     * @param delta     the delta
+     * @deprecated Use {@link Renderer#getQueuedTooltip(float)} instead and queue manually
+     */
+    @Deprecated
     protected void queueTooltip(ItemStack itemStack, float delta) {
         ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(itemStack)));
     }
     
+    @Nullable
+    @Override
+    public QueuedTooltip getQueuedTooltip(float delta) {
+        return QueuedTooltip.create(getTooltip(getItemStack()));
+    }
+    
     protected boolean renderCounts() {
         return true;
     }

+ 16 - 2
src/main/java/me/shedaniel/rei/gui/renderers/SimpleRecipeRenderer.java

@@ -8,6 +8,7 @@ package me.shedaniel.rei.gui.renderers;
 import com.google.common.collect.Lists;
 import me.shedaniel.rei.api.Renderer;
 import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.item.ItemStack;
@@ -15,6 +16,7 @@ import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 import net.minecraft.util.math.MathHelper;
 
+import javax.annotation.Nullable;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
@@ -40,6 +42,7 @@ public class SimpleRecipeRenderer extends RecipeRenderer {
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private List<ItemStackRenderer> inputRenderer;
     private ItemStackRenderer outputRenderer;
+    private QueuedTooltip lastTooltip;
     
     public SimpleRecipeRenderer(Supplier<List<List<ItemStack>>> input, Supplier<List<ItemStack>> output) {
         List<Pair<List<ItemStack>, AtomicInteger>> newList = Lists.newArrayList();
@@ -77,12 +80,15 @@ public class SimpleRecipeRenderer extends RecipeRenderer {
     
     @Override
     public void render(int x, int y, double mouseX, double mouseY, float delta) {
+        lastTooltip = null;
         int xx = x + 4, yy = y + 2;
         int j = 0;
         int itemsPerLine = getItemsPerLine();
         for (ItemStackRenderer itemStackRenderer : inputRenderer) {
             itemStackRenderer.setBlitOffset(getBlitOffset() + 50);
-            itemStackRenderer.drawTooltip = MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen;
+            if (lastTooltip == null && MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen && mouseX >= xx && mouseX <= xx + 16 && mouseY >= yy && mouseY <= yy + 16) {
+                lastTooltip = itemStackRenderer.getQueuedTooltip(delta);
+            }
             itemStackRenderer.render(xx + 8, yy + 6, mouseX, mouseY, delta);
             xx += 18;
             j++;
@@ -99,8 +105,16 @@ public class SimpleRecipeRenderer extends RecipeRenderer {
         blit(xx, yy, 0, 28, 18, 18);
         xx += 18;
         outputRenderer.setBlitOffset(getBlitOffset() + 50);
-        outputRenderer.drawTooltip = MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen;
         outputRenderer.render(xx + 8, yy + 6, mouseX, mouseY, delta);
+        if (lastTooltip == null && MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen && mouseX >= xx && mouseX <= xx + 16 && mouseY >= yy && mouseY <= yy + 16) {
+            lastTooltip = outputRenderer.getQueuedTooltip(delta);
+        }
+    }
+    
+    @Nullable
+    @Override
+    public QueuedTooltip getQueuedTooltip(float delta) {
+        return lastTooltip;
     }
     
     @Override

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

@@ -29,6 +29,7 @@ import net.minecraft.item.ItemStack;
 import net.minecraft.text.Text;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.Formatting;
+import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
 import org.apache.commons.lang3.StringUtils;
@@ -128,7 +129,10 @@ public class EntryListWidget extends Widget {
     }
     
     public static String tryGetFluidName(Fluid fluid) {
-        return Stream.of(Registry.FLUID.getId(fluid).getPath().split("_")).map(StringUtils::capitalize).collect(Collectors.joining(" "));
+        Identifier id = Registry.FLUID.getId(fluid);
+        if (I18n.hasTranslation("block." + id.toString().replaceFirst(":", ".")))
+            return I18n.translate("block." + id.toString().replaceFirst(":", "."));
+        return Stream.of(id.getPath().split("_")).map(StringUtils::capitalize).collect(Collectors.joining(" "));
     }
     
     public static String tryGetItemStackName(ItemStack stack) {
@@ -325,9 +329,9 @@ public class EntryListWidget extends Widget {
                                         cheatedStack.setCount(1);
                                     return ClientHelper.getInstance().tryCheatingStack(cheatedStack);
                                 }
-                            } else if (button == 0)
+                            } else if (button == 0) {
                                 return ClientHelper.getInstance().executeRecipeKeyBind(getCurrentItemStack().copy());
-                            else if (button == 1)
+                            } else if (button == 1)
                                 return ClientHelper.getInstance().executeUsageKeyBind(getCurrentItemStack().copy());
                         }
                         return false;

+ 39 - 14
src/main/java/me/shedaniel/rei/gui/widget/SlotWidget.java

@@ -122,19 +122,13 @@ public class SlotWidget extends WidgetWithBounds {
             blit(this.x - 1, this.y - 1, 0, 222, 18, 18);
         }
         boolean highlighted = containsMouse(mouseX, mouseY);
-        if (isCurrentRendererItem() && !getCurrentItemStack().isEmpty()) {
-            renderer.setBlitOffset(200);
-            renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
-            if (!getCurrentItemStack().isEmpty() && highlighted && showToolTips)
-                queueTooltip(getCurrentItemStack(), delta);
-        } else if (isCurrentRendererFluid()) {
-            renderer.setBlitOffset(200);
-            renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
-            if (((FluidRenderer) renderer).getFluid() != null && highlighted && showToolTips)
-                queueTooltip(((FluidRenderer) renderer).getFluid(), delta);
-        } else {
-            renderer.setBlitOffset(200);
-            renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
+        renderer.setBlitOffset(200);
+        renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
+        if (highlighted && showToolTips) {
+            QueuedTooltip queuedTooltip = renderer.getQueuedTooltip(delta);
+            if (queuedTooltip != null) {
+                ScreenHelper.getLastOverlay().addTooltip(queuedTooltip);
+            }
         }
         if (drawHighlightedBackground && highlighted) {
             RenderHelper.disableLighting();
@@ -150,18 +144,28 @@ public class SlotWidget extends WidgetWithBounds {
         }
     }
     
+    @Deprecated
     public int getBlitOffset() {
         return this.blitOffset;
     }
     
+    @Deprecated
     public void setBlitOffset(int offset) {
         this.blitOffset = offset;
     }
     
+    /**
+     * @deprecated Not used anymore, see {@link Renderer#getQueuedTooltip(float)}
+     */
+    @Deprecated
     protected void queueTooltip(Fluid fluid, float delta) {
         ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(fluid)));
     }
     
+    /**
+     * @deprecated Not used anymore, see {@link Renderer#getQueuedTooltip(float)}
+     */
+    @Deprecated
     private List<String> getTooltip(Fluid fluid) {
         List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetFluidName(fluid));
         toolTip.addAll(getExtraFluidToolTips(fluid));
@@ -179,10 +183,18 @@ public class SlotWidget extends WidgetWithBounds {
         return toolTip;
     }
     
+    /**
+     * @deprecated Not used anymore, see {@link Renderer#getQueuedTooltip(float)}
+     */
+    @Deprecated
     protected void queueTooltip(ItemStack itemStack, float delta) {
         ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(itemStack)));
     }
     
+    /**
+     * @deprecated Not used anymore, see {@link Renderer#getQueuedTooltip(float)}
+     */
+    @Deprecated
     protected List<String> getTooltip(ItemStack itemStack) {
         List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetItemStackToolTip(itemStack, true));
         toolTip.addAll(getExtraItemToolTips(itemStack));
@@ -197,10 +209,18 @@ public class SlotWidget extends WidgetWithBounds {
         return toolTip;
     }
     
+    /**
+     * @deprecated See {@link ItemStackRenderer#getExtraToolTips(ItemStack)}
+     */
+    @Deprecated
     protected List<String> getExtraItemToolTips(ItemStack stack) {
         return Collections.emptyList();
     }
     
+    /**
+     * @deprecated See {@link FluidRenderer#getExtraToolTips(Fluid)}
+     */
+    @Deprecated
     protected List<String> getExtraFluidToolTips(Fluid fluid) {
         return Collections.emptyList();
     }
@@ -212,11 +232,16 @@ public class SlotWidget extends WidgetWithBounds {
     }
     
     public Renderer getCurrentRenderer() {
-        if (renderers.size() == 0)
+        if (renderers.isEmpty())
             return Renderer.empty();
         return renderers.get(MathHelper.floor((System.currentTimeMillis() / 500 % (double) renderers.size()) / 1f));
     }
     
+    /**
+     * @param itemList the list of items
+     * @deprecated Use {@link SlotWidget#setRenderers(List)}
+     */
+    @Deprecated
     public void setItemList(List<ItemStack> itemList) {
         this.setRenderers(itemList.stream().map(Renderer::fromItemStack).collect(Collectors.toList()));
     }

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

@@ -37,7 +37,7 @@ public class EntryRegistryImpl implements EntryRegistry {
     
     @Override
     public ItemStack[] getAllStacksFromItem(Item item) {
-        DefaultedList<ItemStack> list = DefaultedList.create();
+        DefaultedList<ItemStack> list = DefaultedList.of();
         list.add(item.getStackForRender());
         item.appendStacks(item.getGroup(), list);
         TreeSet<ItemStack> stackSet = list.stream().collect(Collectors.toCollection(() -> new TreeSet<ItemStack>((p1, p2) -> ItemStack.areEqualIgnoreDamage(p1, p2) ? 0 : 1)));

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

@@ -81,7 +81,7 @@ public class DefaultCategoryHandler implements AutoTransferHandler {
     
     public IntList hasItems(List<List<ItemStack>> inputs) {
         // Create a clone of player's inventory, and count
-        DefaultedList<ItemStack> copyMain = DefaultedList.create();
+        DefaultedList<ItemStack> copyMain = DefaultedList.of();
         for (ItemStack stack : MinecraftClient.getInstance().player.inventory.main) {
             copyMain.add(stack.copy());
         }

+ 1 - 6
src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingCategory.java

@@ -74,12 +74,7 @@ public class DefaultBlastingCategory implements TransferRecipeCategory<DefaultBl
         widgets.add(new RecipeArrowWidget(startPoint.x + 24, startPoint.y + 18, true));
         List<List<ItemStack>> input = recipeDisplay.getInput();
         widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 1, Renderer.fromItemStacks(input.get(0)), true, true, true));
-        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(recipeDisplay.getFuel()), true, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
-            }
-        });
+        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(() -> recipeDisplay.getFuel(), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"))), true, true, true));
         widgets.add(new SlotWidget(startPoint.x + 61, startPoint.y + 19, Renderer.fromItemStacks(recipeDisplay.getOutput()), false, true, true));
         return widgets;
     }

+ 5 - 30
src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingCategory.java

@@ -64,36 +64,11 @@ public class DefaultBrewingCategory implements RecipeCategory<DefaultBrewingDisp
             }
         }));
         widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 1, Renderer.fromItemStack(new ItemStack(Items.BLAZE_POWDER)), false, true, true));
-        widgets.add(new SlotWidget(startPoint.x + 40, startPoint.y + 1, Renderer.fromItemStacks(recipeDisplay.getInput().get(0)), false, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.input"));
-            }
-        });
-        widgets.add(new SlotWidget(startPoint.x + 63, startPoint.y + 1, Renderer.fromItemStacks(recipeDisplay.getInput().get(1)), false, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.reactant"));
-            }
-        });
-        widgets.add(new SlotWidget(startPoint.x + 40, startPoint.y + 35, Renderer.fromItemStacks(recipeDisplay.getOutput(0)), false, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"));
-            }
-        });
-        widgets.add(new SlotWidget(startPoint.x + 63, startPoint.y + 42, Renderer.fromItemStacks(recipeDisplay.getOutput(1)), false, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"));
-            }
-        });
-        widgets.add(new SlotWidget(startPoint.x + 86, startPoint.y + 35, Renderer.fromItemStacks(recipeDisplay.getOutput(2)), false, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"));
-            }
-        });
+        widgets.add(new SlotWidget(startPoint.x + 40, startPoint.y + 1, Renderer.fromItemStacks(() -> recipeDisplay.getInput().get(0), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.input"))), false, true, true));
+        widgets.add(new SlotWidget(startPoint.x + 63, startPoint.y + 1, Renderer.fromItemStacks(() -> recipeDisplay.getInput().get(1), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.reactant"))), false, true, true));
+        widgets.add(new SlotWidget(startPoint.x + 40, startPoint.y + 35, Renderer.fromItemStacks(() -> recipeDisplay.getOutput(0), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"))), false, true, true));
+        widgets.add(new SlotWidget(startPoint.x + 63, startPoint.y + 42, Renderer.fromItemStacks(() -> recipeDisplay.getOutput(1), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"))), false, true, true));
+        widgets.add(new SlotWidget(startPoint.x + 86, startPoint.y + 35, Renderer.fromItemStacks(() -> recipeDisplay.getOutput(2), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"))), false, true, true));
         return widgets;
     }
     

+ 12 - 13
src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java

@@ -26,6 +26,7 @@ import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.function.Supplier;
@@ -79,19 +80,17 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
         int i = 0;
         for (int y = 0; y < 6; y++)
             for (int x = 0; x < 8; x++) {
-                widgets.add(new SlotWidget(bounds.getCenterX() - 72 + x * 18, bounds.y + y * 18, stacks.size() > i ? Renderer.fromItemStack(stacks.get(i).asItem().getStackForRender()) : Renderer.empty(), true, true, true) {
-                    @Override
-                    protected List<String> getExtraItemToolTips(ItemStack stack) {
-                        final List<String>[] thing = new List[]{null};
-                        recipeDisplaySupplier.get().getInputMap().forEach((itemProvider, aFloat) -> {
-                            if (itemProvider.asItem().equals(stack.getItem()))
-                                thing[0] = Arrays.asList(I18n.translate("text.rei.composting.chance", MathHelper.fastFloor(aFloat * 100)));
-                        });
-                        if (thing[0] != null)
-                            return thing[0];
-                        return super.getExtraItemToolTips(stack);
-                    }
-                });
+                int finalI = i;
+                widgets.add(new SlotWidget(bounds.getCenterX() - 72 + x * 18, bounds.y + y * 18, stacks.size() > i ? Renderer.fromItemStacks(() -> Collections.singletonList(new ItemStack(stacks.get(finalI))), true, stack -> {
+                    final List<String>[] thing = new List[]{null};
+                    recipeDisplaySupplier.get().getInputMap().forEach((itemProvider, aFloat) -> {
+                        if (itemProvider.asItem().equals(stack.getItem()))
+                            thing[0] = Arrays.asList(I18n.translate("text.rei.composting.chance", MathHelper.fastFloor(aFloat * 100)));
+                    });
+                    if (thing[0] != null)
+                        return thing[0];
+                    return null;
+                }) : Renderer.empty(), true, true, true));
                 i++;
             }
         widgets.add(new SlotWidget(startingPoint.x + 34, startingPoint.y + 5, Renderer.fromItemStacks(recipeDisplaySupplier.get().getOutput()), false, true, true));

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

@@ -44,7 +44,7 @@ public interface DefaultCraftingDisplay extends TransferRecipeDisplay {
         }
         for (int i = 0; i < getInput().size(); i++) {
             List<ItemStack> stacks = getInput().get(i);
-            list.set(i, stacks);
+            list.set(DefaultCraftingCategory.getSlotWithSize(this, i), stacks);
         }
         return list;
     }

+ 1 - 6
src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingCategory.java

@@ -73,12 +73,7 @@ public class DefaultSmeltingCategory implements TransferRecipeCategory<DefaultSm
         widgets.add(new RecipeArrowWidget(startPoint.x + 24, startPoint.y + 18, true));
         List<List<ItemStack>> input = recipeDisplaySupplier.get().getInput();
         widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 1, Renderer.fromItemStacks(input.get(0)), true, true, true));
-        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(recipeDisplaySupplier.get().getFuel()), true, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
-            }
-        });
+        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(() -> recipeDisplaySupplier.get().getFuel(), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"))), true, true, true));
         widgets.add(new SlotWidget(startPoint.x + 61, startPoint.y + 19, Renderer.fromItemStacks(recipeDisplaySupplier.get().getOutput()), false, true, true));
         return widgets;
     }

+ 1 - 6
src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingCategory.java

@@ -73,12 +73,7 @@ public class DefaultSmokingCategory implements TransferRecipeCategory<DefaultSmo
         widgets.add(new RecipeArrowWidget(startPoint.x + 24, startPoint.y + 18, true));
         List<List<ItemStack>> input = recipeDisplaySupplier.get().getInput();
         widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 1, Renderer.fromItemStacks(input.get(0)), true, true, true));
-        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(recipeDisplaySupplier.get().getFuel()), true, true, true) {
-            @Override
-            protected List<String> getExtraItemToolTips(ItemStack stack) {
-                return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
-            }
-        });
+        widgets.add(new SlotWidget(startPoint.x + 1, startPoint.y + 37, Renderer.fromItemStacks(() -> recipeDisplaySupplier.get().getFuel(), true, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"))), true, true, true));
         widgets.add(new SlotWidget(startPoint.x + 61, startPoint.y + 19, Renderer.fromItemStacks(recipeDisplaySupplier.get().getOutput()), false, true, true));
         return widgets;
     }

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

@@ -52,7 +52,7 @@ public class InputSlotCrafter<C extends Inventory> implements RecipeGridAligner<
                 recipeFinder.addNormalItem(stack);
             }
             this.containerInfo.populateRecipeFinder(craftingContainer, recipeFinder);
-            DefaultedList<Ingredient> ingredients = DefaultedList.create();
+            DefaultedList<Ingredient> ingredients = DefaultedList.of();
             map.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> {
                 ingredients.add(Ingredient.ofStacks(entry.getValue().toArray(new ItemStack[0])));
             });