Unknown 5 ani în urmă
părinte
comite
f53bc4a43e
23 a modificat fișierele cu 387 adăugiri și 134 ștergeri
  1. 5 5
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  2. 32 0
      src/main/java/me/shedaniel/rei/api/Entry.java
  3. 7 4
      src/main/java/me/shedaniel/rei/api/EntryRegistry.java
  4. 10 0
      src/main/java/me/shedaniel/rei/api/Renderer.java
  5. 3 3
      src/main/java/me/shedaniel/rei/api/plugins/REIPluginV0.java
  6. 8 7
      src/main/java/me/shedaniel/rei/client/ConfigObjectImpl.java
  7. 19 12
      src/main/java/me/shedaniel/rei/client/EntryRegistryImpl.java
  8. 33 0
      src/main/java/me/shedaniel/rei/client/FluidEntry.java
  9. 33 0
      src/main/java/me/shedaniel/rei/client/ItemStackEntry.java
  10. 3 3
      src/main/java/me/shedaniel/rei/client/RecipeHelperImpl.java
  11. 22 21
      src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java
  12. 1 1
      src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java
  13. 1 1
      src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java
  14. 54 0
      src/main/java/me/shedaniel/rei/gui/renderers/FluidRenderer.java
  15. 15 12
      src/main/java/me/shedaniel/rei/gui/renderers/ItemStackRenderer.java
  16. 78 43
      src/main/java/me/shedaniel/rei/gui/widget/EntryListOverlay.java
  17. 40 3
      src/main/java/me/shedaniel/rei/gui/widget/SlotWidget.java
  18. 13 9
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  19. 1 1
      src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingCategory.java
  20. 5 5
      src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingCategory.java
  21. 2 2
      src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java
  22. 1 1
      src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingCategory.java
  23. 1 1
      src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingCategory.java

+ 5 - 5
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -13,7 +13,7 @@ import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
 import me.shedaniel.rei.client.*;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
-import me.shedaniel.rei.gui.widget.ItemListOverlay;
+import me.shedaniel.rei.gui.widget.EntryListOverlay;
 import me.shedaniel.rei.listeners.RecipeBookButtonWidgetHooks;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import net.fabricmc.api.ClientModInitializer;
@@ -57,7 +57,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
     
     public static final Logger LOGGER;
     private static final RecipeHelper RECIPE_HELPER = new RecipeHelperImpl();
-    private static final ItemRegistry ITEM_REGISTRY = new ItemRegistryImpl();
+    private static final EntryRegistry ENTRY_REGISTRY = new EntryRegistryImpl();
     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"));
@@ -75,8 +75,8 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         return configManager;
     }
     
-    public static ItemRegistry getItemRegisterer() {
-        return ITEM_REGISTRY;
+    public static EntryRegistry getEntryRegistry() {
+        return ENTRY_REGISTRY;
     }
     
     public static DisplayHelper getDisplayHelper() {
@@ -143,7 +143,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.CREATE_ITEMS_MESSAGE_PACKET, (packetContext, packetByteBuf) -> {
             ItemStack stack = packetByteBuf.readItemStack();
             String player = packetByteBuf.readString(32767);
-            packetContext.getPlayer().addChatMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", ItemListOverlay.tryGetItemStackName(stack.copy())).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false);
+            packetContext.getPlayer().addChatMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", EntryListOverlay.tryGetItemStackName(stack.copy())).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false);
         });
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.NOT_ENOUGH_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
             Screen currentScreen = MinecraftClient.getInstance().currentScreen;

+ 32 - 0
src/main/java/me/shedaniel/rei/api/Entry.java

@@ -0,0 +1,32 @@
+package me.shedaniel.rei.api;
+
+import me.shedaniel.rei.client.FluidEntry;
+import me.shedaniel.rei.client.ItemStackEntry;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.item.ItemStack;
+
+import javax.annotation.Nullable;
+
+public interface Entry {
+    @SuppressWarnings("deprecation")
+    static Entry create(ItemStack itemStack) {
+        return new ItemStackEntry(itemStack);
+    }
+    
+    @SuppressWarnings("deprecation")
+    static Entry create(Fluid fluid) {
+        return new FluidEntry(fluid);
+    }
+    
+    Type getEntryType();
+    
+    @Nullable
+    ItemStack getItemStack();
+    
+    @Nullable
+    Fluid getFluid();
+    
+    public static enum Type {
+        ITEM, FLUID
+    }
+}

+ 7 - 4
src/main/java/me/shedaniel/rei/api/ItemRegistry.java → src/main/java/me/shedaniel/rei/api/EntryRegistry.java

@@ -5,19 +5,20 @@
 
 package me.shedaniel.rei.api;
 
+import net.minecraft.fluid.Fluid;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 
 import java.util.List;
 
-public interface ItemRegistry {
+public interface EntryRegistry {
     
     /**
      * Gets the current unmodifiable item list
      *
      * @return an unmodifiable item list
      */
-    List<ItemStack> getItemList();
+    List<Entry> getEntryList();
     
     /**
      * Gets the current modifiable item list
@@ -25,7 +26,7 @@ public interface ItemRegistry {
      * @return an modifiable item list
      */
     @Deprecated
-    List<ItemStack> getModifiableItemList();
+    List<Entry> getModifiableEntryList();
     
     /**
      * Gets all possible stacks from an item
@@ -43,6 +44,8 @@ public interface ItemRegistry {
      */
     void registerItemStack(Item afterItem, ItemStack stack);
     
+    void registerFluid(Fluid fluid);
+    
     /**
      * Registers multiple stacks to the item list
      *
@@ -73,7 +76,7 @@ public interface ItemRegistry {
      * @return whether the stack has been registered
      */
     default boolean alreadyContain(ItemStack stack) {
-        return getItemList().stream().anyMatch(stack1 -> ItemStack.areEqualIgnoreDamage(stack, stack1));
+        return getEntryList().stream().filter(entry -> entry.getEntryType() == Entry.Type.ITEM).anyMatch(entry -> ItemStack.areEqualIgnoreDamage(stack, entry.getItemStack()));
     }
     
 }

+ 10 - 0
src/main/java/me/shedaniel/rei/api/Renderer.java

@@ -6,9 +6,11 @@
 package me.shedaniel.rei.api;
 
 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 net.minecraft.client.gui.DrawableHelper;
+import net.minecraft.fluid.Fluid;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.math.MathHelper;
 
@@ -60,6 +62,14 @@ public abstract class Renderer extends DrawableHelper {
     public static ItemStackRenderer fromItemStack(ItemStack stack) {
         return fromItemStackSupplier(() -> stack);
     }
+    public static FluidRenderer fromFluid(Fluid fluid) {
+        return new FluidRenderer() {
+            @Override
+            public Fluid getFluid() {
+                return fluid;
+            }
+        };
+    }
     
     /**
      * Gets an item stack renderer by an item stack

+ 3 - 3
src/main/java/me/shedaniel/rei/api/plugins/REIPluginV0.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.api.plugins;
 
 import me.shedaniel.rei.api.DisplayHelper;
-import me.shedaniel.rei.api.ItemRegistry;
+import me.shedaniel.rei.api.EntryRegistry;
 import me.shedaniel.rei.api.REIPluginEntry;
 import me.shedaniel.rei.api.RecipeHelper;
 import net.fabricmc.loader.api.SemanticVersion;
@@ -25,9 +25,9 @@ public interface REIPluginV0 extends REIPluginEntry {
     /**
      * Registers items on the item panel
      *
-     * @param itemRegistry the helper class
+     * @param entryRegistry the helper class
      */
-    default void registerItems(ItemRegistry itemRegistry) {
+    default void registerItems(EntryRegistry entryRegistry) {
     }
     
     /**

+ 8 - 7
src/main/java/me/shedaniel/rei/client/ConfigObjectImpl.java

@@ -165,11 +165,11 @@ public class ConfigObjectImpl implements ConfigObject {
             .withName("registerRecipesInAnotherThread")
             .build();
     
-    private ConfigValue<RelativePoint> choosePageDialogPoint = ConfigValue.builder(RelativePoint.class)
-            .withParent(technical)
-            .withDefaultValue(new RelativePoint(.5, .5))
-            .withName("choosePageDialogPoint")
-            .build();
+    //    private ConfigValue<RelativePoint> choosePageDialogPoint = ConfigValue.builder(RelativePoint.class)
+    //            .withParent(technical)
+    //            .withDefaultValue(new RelativePoint(.5, .5))
+    //            .withName("choosePageDialogPoint")
+    //            .build();
     
     public ConfigObjectImpl() throws FiberException {
     
@@ -297,11 +297,12 @@ public class ConfigObjectImpl implements ConfigObject {
     
     @Override
     public RelativePoint getChoosePageDialogPoint() {
-        return choosePageDialogPoint.getValue();
+        //        return choosePageDialogPoint.getValue();
+        return new RelativePoint(.5, .5);
     }
     
     @Override
     public void setChoosePageDialogPoint(RelativePoint choosePageDialogPoint) {
-        this.choosePageDialogPoint.setValue(choosePageDialogPoint);
+        //        this.choosePageDialogPoint.setValue(choosePageDialogPoint);
     }
 }

+ 19 - 12
src/main/java/me/shedaniel/rei/client/ItemRegistryImpl.java → src/main/java/me/shedaniel/rei/client/EntryRegistryImpl.java

@@ -6,7 +6,9 @@
 package me.shedaniel.rei.client;
 
 import com.google.common.collect.Lists;
-import me.shedaniel.rei.api.ItemRegistry;
+import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.EntryRegistry;
+import net.minecraft.fluid.Fluid;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
@@ -18,19 +20,19 @@ import java.util.TreeSet;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.stream.Collectors;
 
-public class ItemRegistryImpl implements ItemRegistry {
+public class EntryRegistryImpl implements EntryRegistry {
     
-    private final CopyOnWriteArrayList<ItemStack> itemList = Lists.newCopyOnWriteArrayList();
+    private final CopyOnWriteArrayList<Entry> entries = Lists.newCopyOnWriteArrayList();
     
     @Override
-    public List<ItemStack> getItemList() {
-        return Collections.unmodifiableList(itemList);
+    public List<Entry> getEntryList() {
+        return Collections.unmodifiableList(entries);
     }
     
     @SuppressWarnings("deprecation")
     @Override
-    public List<ItemStack> getModifiableItemList() {
-        return itemList;
+    public List<Entry> getModifiableEntryList() {
+        return entries;
     }
     
     @Override
@@ -46,14 +48,19 @@ public class ItemRegistryImpl implements ItemRegistry {
     public void registerItemStack(Item afterItem, ItemStack stack) {
         if (!stack.isEmpty() && !alreadyContain(stack))
             if (afterItem == null || afterItem.equals(Items.AIR))
-                itemList.add(stack);
+                entries.add(Entry.create(stack));
             else {
-                int last = itemList.size();
-                for (int i = 0; i < itemList.size(); i++)
-                    if (itemList.get(i).getItem().equals(afterItem))
+                int last = entries.size();
+                for (int i = 0; i < entries.size(); i++)
+                    if (entries.get(i).getEntryType() == Entry.Type.ITEM && entries.get(i).getItemStack().getItem().equals(afterItem))
                         last = i + 1;
-                itemList.add(last, stack);
+                entries.add(last, Entry.create(stack));
             }
     }
     
+    @Override
+    public void registerFluid(Fluid fluid) {
+        entries.add(Entry.create(fluid));
+    }
+    
 }

+ 33 - 0
src/main/java/me/shedaniel/rei/client/FluidEntry.java

@@ -0,0 +1,33 @@
+package me.shedaniel.rei.client;
+
+import me.shedaniel.rei.api.Entry;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.item.ItemStack;
+
+import javax.annotation.Nullable;
+
+public class FluidEntry implements Entry {
+    private Fluid fluid;
+    
+    @Deprecated
+    public FluidEntry(Fluid fluid) {
+        this.fluid = fluid;
+    }
+    
+    @Override
+    public Type getEntryType() {
+        return Type.FLUID;
+    }
+    
+    @Nullable
+    @Override
+    public ItemStack getItemStack() {
+        return null;
+    }
+    
+    @Nullable
+    @Override
+    public Fluid getFluid() {
+        return fluid;
+    }
+}

+ 33 - 0
src/main/java/me/shedaniel/rei/client/ItemStackEntry.java

@@ -0,0 +1,33 @@
+package me.shedaniel.rei.client;
+
+import me.shedaniel.rei.api.Entry;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.item.ItemStack;
+
+import javax.annotation.Nullable;
+
+public class ItemStackEntry implements Entry {
+    private ItemStack itemStack;
+    
+    @Deprecated
+    public ItemStackEntry(ItemStack itemStack) {
+        this.itemStack = itemStack;
+    }
+    
+    @Override
+    public Type getEntryType() {
+        return Type.ITEM;
+    }
+    
+    @Nullable
+    @Override
+    public ItemStack getItemStack() {
+        return itemStack;
+    }
+    
+    @Nullable
+    @Override
+    public Fluid getFluid() {
+        return null;
+    }
+}

+ 3 - 3
src/main/java/me/shedaniel/rei/client/RecipeHelperImpl.java

@@ -241,7 +241,7 @@ public class RecipeHelperImpl implements RecipeHelper {
         });
         RoughlyEnoughItemsCore.LOGGER.info("[REI] Loading %d plugins: %s", plugins.size(), plugins.stream().map(REIPluginEntry::getPluginIdentifier).map(Identifier::toString).collect(Collectors.joining(", ")));
         Collections.reverse(plugins);
-        RoughlyEnoughItemsCore.getItemRegisterer().getModifiableItemList().clear();
+        RoughlyEnoughItemsCore.getEntryRegistry().getModifiableEntryList().clear();
         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!");
@@ -257,7 +257,7 @@ public class RecipeHelperImpl implements RecipeHelper {
                     ((REIPluginV0) plugin).registerRecipeDisplays(this);
                     ((REIPluginV0) plugin).registerBounds(RoughlyEnoughItemsCore.getDisplayHelper());
                     ((REIPluginV0) plugin).registerOthers(this);
-                    ((REIPluginV0) plugin).registerItems(RoughlyEnoughItemsCore.getItemRegisterer());
+                    ((REIPluginV0) plugin).registerItems(RoughlyEnoughItemsCore.getEntryRegistry());
                 } else {
                     throw new IllegalStateException("Invaild Plugin Class!");
                 }
@@ -293,7 +293,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.", RoughlyEnoughItemsCore.getItemRegisterer().getItemList().size(), recipeCount.get(), RoughlyEnoughItemsCore.getDisplayHelper().getAllBoundsHandlers().size(), getDisplayVisibilityHandlers().size(), categories.size(), String.join(", ", categories.stream().map(RecipeCategory::getCategoryName).collect(Collectors.toList())), usedTime);
+        RoughlyEnoughItemsCore.LOGGER.info("[REI] Registered %d stack entries, %d recipes displays, %d bounds handler, %d visibility handlers and %d categories (%s) in %d ms.", RoughlyEnoughItemsCore.getEntryRegistry().getEntryList().size(), recipeCount.get(), RoughlyEnoughItemsCore.getDisplayHelper().getAllBoundsHandlers().size(), getDisplayVisibilityHandlers().size(), categories.size(), String.join(", ", categories.stream().map(RecipeCategory::getCategoryName).collect(Collectors.toList())), usedTime);
     }
     
     @Override

+ 22 - 21
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -11,6 +11,7 @@ import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.DisplayHelper;
+import me.shedaniel.rei.api.Entry;
 import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.client.RecipeHelperImpl;
 import me.shedaniel.rei.client.ScreenHelper;
@@ -19,8 +20,6 @@ import me.shedaniel.rei.gui.widget.*;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.font.TextRenderer;
-import net.minecraft.client.gui.AbstractParentElement;
-import net.minecraft.client.gui.Drawable;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
@@ -49,7 +48,7 @@ public class ContainerScreenOverlay extends Widget {
     private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
     public static String searchTerm = "";
     private static int page = 0;
-    private static ItemListOverlay itemListOverlay;
+    private static EntryListOverlay entryListOverlay;
     private final List<Widget> widgets = Lists.newLinkedList();
     public boolean shouldReInit = false;
     private Rectangle rectangle;
@@ -57,8 +56,8 @@ public class ContainerScreenOverlay extends Widget {
     private CraftableToggleButtonWidget toggleButtonWidget;
     private ButtonWidget buttonLeft, buttonRight;
     
-    public static ItemListOverlay getItemListOverlay() {
-        return itemListOverlay;
+    public static EntryListOverlay getEntryListOverlay() {
+        return entryListOverlay;
     }
     
     public void init() {
@@ -72,8 +71,8 @@ public class ContainerScreenOverlay extends Widget {
         this.window = MinecraftClient.getInstance().window;
         DisplayHelper.DisplayBoundsHandler boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
         this.rectangle = RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
-        widgets.add(itemListOverlay = new ItemListOverlay(page));
-        itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+        widgets.add(entryListOverlay = new EntryListOverlay(page));
+        entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
         
         widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.left_arrow")) {
             @Override
@@ -81,7 +80,7 @@ public class ContainerScreenOverlay extends Widget {
                 page--;
                 if (page < 0)
                     page = getTotalPage();
-                itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
             
             @Override
@@ -100,7 +99,7 @@ public class ContainerScreenOverlay extends Widget {
                 page++;
                 if (page > getTotalPage())
                     page = 0;
-                itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
             
             @Override
@@ -232,7 +231,7 @@ public class ContainerScreenOverlay extends Widget {
             public void onLabelClicked() {
                 MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
                 page = 0;
-                itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
             
             @Override
@@ -248,14 +247,14 @@ public class ContainerScreenOverlay extends Widget {
         ScreenHelper.searchField.setText(searchTerm);
         ScreenHelper.searchField.setChangedListener(s -> {
             searchTerm = s;
-            itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+            entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
         });
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isCraftableFilterEnabled())
             this.widgets.add(toggleButtonWidget = new CraftableToggleButtonWidget(getCraftableToggleArea()) {
                 @Override
                 public void onPressed() {
                     RoughlyEnoughItemsCore.getConfigManager().toggleCraftableOnly();
-                    itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+                    entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
                 }
                 
                 @Override
@@ -266,7 +265,7 @@ public class ContainerScreenOverlay extends Widget {
             });
         else
             toggleButtonWidget = null;
-        this.itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+        this.entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
     }
     
     private Weather getNextWeather() {
@@ -358,16 +357,18 @@ public class ContainerScreenOverlay extends Widget {
         else if (RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() && ((currentStacks.size() != ScreenHelper.inventoryStacks.size()) || !hasSameListContent(new LinkedList<>(ScreenHelper.inventoryStacks), currentStacks))) {
             ScreenHelper.inventoryStacks = currentStacks;
             DisplayHelper.DisplayBoundsHandler<?> boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
-            itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+            entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
         }
-        if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen && SearchFieldWidget.isSearching) {
+        if (SearchFieldWidget.isSearching) {
             GuiLighting.disable();
             blitOffset = 200;
-            ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
-            int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
-            for (Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
-                if (!slot.hasStack() || !itemListOverlay.filterItem(slot.getStack(), itemListOverlay.getLastSearchArgument()))
-                    fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
+            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)
+                    if (!slot.hasStack() || !entryListOverlay.filterEntry(Entry.create(slot.getStack()), entryListOverlay.getLastSearchArgument()))
+                        fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
+            }
             blitOffset = 0;
         }
         GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
@@ -461,7 +462,7 @@ public class ContainerScreenOverlay extends Widget {
     }
     
     private int getTotalPage() {
-        return itemListOverlay.getTotalPage();
+        return entryListOverlay.getTotalPage();
     }
     
     @Override

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

@@ -301,7 +301,7 @@ public class RecipeViewingScreen extends Screen {
             for (List<ItemStack> workingStation : workingStations) {
                 preWidgets.add(new SlotWidget(xx, yy, Renderer.fromItemStacks(workingStation), true, true, true) {
                     @Override
-                    protected List<String> getExtraToolTips(ItemStack stack) {
+                    protected List<String> getExtraItemToolTips(ItemStack stack) {
                         return list;
                     }
                 });

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

@@ -109,7 +109,7 @@ public class VillagerRecipeViewingScreen extends Screen {
             for (List<ItemStack> workingStation : workingStations) {
                 widgets.add(new SlotWidget(xx, yy, Renderer.fromItemStacks(workingStation), true, true, true) {
                     @Override
-                    protected List<String> getExtraToolTips(ItemStack stack) {
+                    protected List<String> getExtraItemToolTips(ItemStack stack) {
                         return list;
                     }
                 });

+ 54 - 0
src/main/java/me/shedaniel/rei/gui/renderers/FluidRenderer.java

@@ -0,0 +1,54 @@
+package me.shedaniel.rei.gui.renderers;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
+import me.shedaniel.rei.api.ClientHelper;
+import me.shedaniel.rei.api.Renderer;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.widget.EntryListOverlay;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.util.registry.Registry;
+
+import java.util.Collections;
+import java.util.List;
+
+public abstract class FluidRenderer extends Renderer {
+    public boolean drawTooltip = false;
+    
+    @Override
+    public void render(int x, int y, double mouseX, double mouseY, float delta) {
+        int l = x - 8, i1 = y - 6;
+        // TODO: Render Fluid
+        if (drawTooltip && mouseX >= x - 8 && mouseX <= x + 8 && mouseY >= y - 6 && mouseY <= y + 10)
+            queueTooltip(getFluid(), delta);
+        this.drawTooltip = false;
+    }
+    
+    protected void queueTooltip(Fluid fluid, float delta) {
+        ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(fluid)));
+    }
+    
+    private List<String> getTooltip(Fluid fluid) {
+        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetFluidName(fluid));
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
+            final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));
+            toolTip.addAll(getExtraToolTips(fluid));
+            boolean alreadyHasMod = false;
+            for (String s : toolTip)
+                if (s.equalsIgnoreCase(modString)) {
+                    alreadyHasMod = true;
+                    break;
+                }
+            if (!alreadyHasMod)
+                toolTip.add(modString);
+        }
+        return toolTip;
+    }
+    
+    protected List<String> getExtraToolTips(Fluid stack) {
+        return Collections.emptyList();
+    }
+    
+    public abstract Fluid getFluid();
+}

+ 15 - 12
src/main/java/me/shedaniel/rei/gui/renderers/ItemStackRenderer.java

@@ -7,10 +7,11 @@ package me.shedaniel.rei.gui.renderers;
 
 import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.Renderer;
 import me.shedaniel.rei.client.ScreenHelper;
-import me.shedaniel.rei.gui.widget.ItemListOverlay;
+import me.shedaniel.rei.gui.widget.EntryListOverlay;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -55,17 +56,19 @@ public abstract class ItemStackRenderer extends Renderer {
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {
-        final String modString = ClientHelper.getInstance().getFormattedModFromItem(itemStack.getItem());
-        List<String> toolTip = Lists.newArrayList(ItemListOverlay.tryGetItemStackToolTip(itemStack, true));
-        toolTip.addAll(getExtraToolTips(itemStack));
-        boolean alreadyHasMod = false;
-        for (String s : toolTip)
-            if (s.equalsIgnoreCase(modString)) {
-                alreadyHasMod = true;
-                break;
-            }
-        if (!alreadyHasMod)
-            toolTip.add(modString);
+        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetItemStackToolTip(itemStack, true));
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
+            final String modString = ClientHelper.getInstance().getFormattedModFromItem(itemStack.getItem());
+            toolTip.addAll(getExtraToolTips(itemStack));
+            boolean alreadyHasMod = false;
+            for (String s : toolTip)
+                if (s.equalsIgnoreCase(modString)) {
+                    alreadyHasMod = true;
+                    break;
+                }
+            if (!alreadyHasMod)
+                toolTip.add(modString);
+        }
         return toolTip;
     }
     

+ 78 - 43
src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java → src/main/java/me/shedaniel/rei/gui/widget/EntryListOverlay.java

@@ -8,10 +8,7 @@ package me.shedaniel.rei.gui.widget;
 import com.google.common.collect.Lists;
 import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
-import me.shedaniel.rei.api.ClientHelper;
-import me.shedaniel.rei.api.DisplayHelper;
-import me.shedaniel.rei.api.RecipeHelper;
-import me.shedaniel.rei.api.Renderer;
+import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.client.SearchArgument;
 import me.shedaniel.rei.gui.config.ItemCheatingMode;
@@ -21,6 +18,7 @@ import net.minecraft.client.item.TooltipContext;
 import net.minecraft.client.network.ClientPlayerEntity;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.fluid.Fluid;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemGroup;
 import net.minecraft.item.ItemStack;
@@ -35,32 +33,37 @@ import java.util.List;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
-public class ItemListOverlay extends Widget {
+public class EntryListOverlay extends Widget {
     
     private static final String SPACE = " ", EMPTY = "";
-    private static final Comparator<ItemStack> ASCENDING_COMPARATOR;
+    private static final Comparator<Entry> ASCENDING_COMPARATOR;
     private static List<Item> searchBlacklisted = Lists.newArrayList();
     
     static {
-        ASCENDING_COMPARATOR = (itemStack, t1) -> {
+        ASCENDING_COMPARATOR = (entry, entry1) -> {
             if (RoughlyEnoughItemsCore.getConfigManager().getConfig().getItemListOrdering().equals(ItemListOrdering.name))
-                return tryGetItemStackName(itemStack).compareToIgnoreCase(tryGetItemStackName(t1));
+                return tryGetEntryName(entry).compareToIgnoreCase(tryGetEntryName(entry1));
             if (RoughlyEnoughItemsCore.getConfigManager().getConfig().getItemListOrdering().equals(ItemListOrdering.item_groups)) {
-                List<ItemGroup> itemGroups = Arrays.asList(ItemGroup.GROUPS);
-                return itemGroups.indexOf(itemStack.getItem().getGroup()) - itemGroups.indexOf(t1.getItem().getGroup());
+                if (entry.getEntryType() == Entry.Type.ITEM && entry1.getEntryType() == Entry.Type.ITEM) {
+                    ItemStack stack0 = entry.getItemStack();
+                    ItemStack stack1 = entry1.getItemStack();
+                    List<ItemGroup> itemGroups = Arrays.asList(ItemGroup.GROUPS);
+                    return itemGroups.indexOf(stack0.getItem().getGroup()) - itemGroups.indexOf(stack1.getItem().getGroup());
+                }
             }
             return 0;
         };
     }
     
     private final List<SearchArgument[]> lastSearchArgument;
-    private List<ItemStack> currentDisplayed;
+    private List<Entry> currentDisplayed;
     private List<Widget> widgets;
     private int width, height, page;
     private Rectangle rectangle, listArea;
     
-    public ItemListOverlay(int page) {
+    public EntryListOverlay(int page) {
         this.currentDisplayed = Lists.newArrayList();
         this.width = 0;
         this.height = 0;
@@ -79,6 +82,18 @@ public class ItemListOverlay extends Widget {
         return Collections.singletonList(tryGetItemStackName(itemStack));
     }
     
+    public static String tryGetEntryName(Entry stack) {
+        if (stack.getEntryType() == Entry.Type.ITEM)
+            return tryGetItemStackName(stack.getItemStack());
+        else if (stack.getEntryType() == Entry.Type.FLUID)
+            return tryGetFluidName(stack.getFluid());
+        return "";
+    }
+    
+    public static String tryGetFluidName(Fluid fluid) {
+        return Stream.of(Registry.FLUID.getId(fluid).getPath().split("_")).map(StringUtils::capitalize).collect(Collectors.joining(" "));
+    }
+    
     public static String tryGetItemStackName(ItemStack stack) {
         if (!searchBlacklisted.contains(stack.getItem()))
             try {
@@ -95,27 +110,27 @@ public class ItemListOverlay extends Widget {
         return "ERROR";
     }
     
-    public static boolean filterItem(ItemStack itemStack, List<SearchArgument[]> arguments) {
+    public static boolean filterEntry(Entry entry, List<SearchArgument[]> arguments) {
         if (arguments.isEmpty())
             return true;
-        AtomicReference<String> mod = null, tooltips = null, name = null;
+        AtomicReference<String> mod = new AtomicReference<>(), tooltips = new AtomicReference<>(), name = new AtomicReference<>();
         for (SearchArgument[] arguments1 : arguments) {
             boolean b = true;
             for (SearchArgument argument : arguments1) {
-                if (argument.getArgumentType().equals(SearchArgument.ArgumentType.ALWAYS))
+                if (argument.getArgumentType() == (SearchArgument.ArgumentType.ALWAYS))
                     return true;
-                if (argument.getArgumentType().equals(SearchArgument.ArgumentType.MOD))
-                    if (argument.getFunction(!argument.isInclude()).apply(fillMod(itemStack, mod))) {
+                if (argument.getArgumentType() == SearchArgument.ArgumentType.MOD)
+                    if (argument.getFunction(!argument.isInclude()).apply(fillMod(entry, mod).get())) {
                         b = false;
                         break;
                     }
-                if (argument.getArgumentType().equals(SearchArgument.ArgumentType.TOOLTIP))
-                    if (argument.getFunction(!argument.isInclude()).apply(fillTooltip(itemStack, tooltips))) {
+                if (argument.getArgumentType() == SearchArgument.ArgumentType.TOOLTIP)
+                    if (argument.getFunction(!argument.isInclude()).apply(fillTooltip(entry, tooltips).get())) {
                         b = false;
                         break;
                     }
-                if (argument.getArgumentType().equals(SearchArgument.ArgumentType.TEXT))
-                    if (argument.getFunction(!argument.isInclude()).apply(fillName(itemStack, name))) {
+                if (argument.getArgumentType() == SearchArgument.ArgumentType.TEXT)
+                    if (argument.getFunction(!argument.isInclude()).apply(fillName(entry, name).get())) {
                         b = false;
                         break;
                     }
@@ -126,22 +141,31 @@ public class ItemListOverlay extends Widget {
         return false;
     }
     
-    private static String fillMod(ItemStack itemStack, AtomicReference<String> mod) {
-        if (mod == null)
-            mod = new AtomicReference<>(ClientHelper.getInstance().getModFromItem(itemStack.getItem()).toLowerCase(Locale.ROOT));
-        return mod.get();
+    private static AtomicReference<String> fillMod(Entry entry, AtomicReference<String> mod) {
+        if (mod.get() == null)
+            if (entry.getEntryType() == Entry.Type.ITEM)
+                mod.set(ClientHelper.getInstance().getModFromItem(entry.getItemStack().getItem()).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+            else if (entry.getEntryType() == Entry.Type.FLUID)
+                mod.set(ClientHelper.getInstance().getModFromIdentifier(Registry.FLUID.getId(entry.getFluid())).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+        return mod;
     }
     
-    private static String fillTooltip(ItemStack itemStack, AtomicReference<String> mod) {
-        if (mod == null)
-            mod = new AtomicReference<>(tryGetItemStackToolTip(itemStack, false).stream().collect(Collectors.joining("")).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
-        return mod.get();
+    private static AtomicReference<String> fillTooltip(Entry entry, AtomicReference<String> mod) {
+        if (mod.get() == null)
+            if (entry.getEntryType() == Entry.Type.ITEM)
+                mod.set(tryGetItemStackToolTip(entry.getItemStack(), false).stream().collect(Collectors.joining("")).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+            else
+                mod.set(tryGetFluidName(entry.getFluid()).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+        return mod;
     }
     
-    private static String fillName(ItemStack itemStack, AtomicReference<String> mod) {
-        if (mod == null)
-            mod = new AtomicReference<>(tryGetItemStackName(itemStack).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
-        return mod.get();
+    private static AtomicReference<String> fillName(Entry entry, AtomicReference<String> mod) {
+        if (mod.get() == null)
+            if (entry.getEntryType() == Entry.Type.ITEM)
+                mod.set(tryGetItemStackName(entry.getItemStack()).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+            else
+                mod.set(tryGetFluidName(entry.getFluid()).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT));
+        return mod;
     }
     
     public int getFullTotalSlotsPerPage() {
@@ -163,7 +187,7 @@ public class ItemListOverlay extends Widget {
         this.widgets = Lists.newLinkedList();
         calculateListSize(rectangle);
         if (currentDisplayed.isEmpty() || processSearchTerm)
-            currentDisplayed = processSearchTerm(searchTerm, RoughlyEnoughItemsCore.getItemRegisterer().getItemList(), new ArrayList<>(ScreenHelper.inventoryStacks));
+            currentDisplayed = processSearchTerm(searchTerm, RoughlyEnoughItemsCore.getEntryRegistry().getEntryList(), new ArrayList<>(ScreenHelper.inventoryStacks));
         int startX = (int) rectangle.getCenterX() - width * 9;
         int startY = (int) rectangle.getCenterY() - height * 9;
         this.listArea = new Rectangle((int) startX, (int) startY, width * 18, height * 18);
@@ -177,7 +201,8 @@ public class ItemListOverlay extends Widget {
                 j++;
                 if (j > currentDisplayed.size())
                     break;
-                widgets.add(new SlotWidget(x, y, Renderer.fromItemStackNoCounts(currentDisplayed.get(j - 1)), false, true, true) {
+                final Entry entry = currentDisplayed.get(j - 1);
+                widgets.add(new SlotWidget(x, y, entry.getEntryType() == Entry.Type.ITEM ? Renderer.fromItemStackNoCounts(entry.getItemStack()) : Renderer.fromFluid(entry.getFluid()), false, true, true) {
                     @Override
                     protected void queueTooltip(ItemStack itemStack, float delta) {
                         ClientPlayerEntity player = minecraft.player;
@@ -185,6 +210,13 @@ public class ItemListOverlay extends Widget {
                             super.queueTooltip(itemStack, delta);
                     }
                     
+                    @Override
+                    protected List<String> getExtraFluidToolTips(Fluid fluid) {
+                        if (MinecraftClient.getInstance().options.advancedItemTooltips)
+                            return Collections.singletonList("§8" + Registry.FLUID.getId(fluid).toString());
+                        return super.getExtraFluidToolTips(fluid);
+                    }
+                    
                     @Override
                     public boolean mouseClicked(double mouseX, double mouseY, int button) {
                         if (isCurrentRendererItem() && containsMouse(mouseX, mouseY)) {
@@ -250,13 +282,13 @@ public class ItemListOverlay extends Widget {
         return listArea;
     }
     
-    public List<ItemStack> getCurrentDisplayed() {
+    public List<Entry> getCurrentDisplayed() {
         return currentDisplayed;
     }
     
-    private List<ItemStack> processSearchTerm(String searchTerm, List<ItemStack> ol, List<ItemStack> inventoryItems) {
+    private List<Entry> processSearchTerm(String searchTerm, List<Entry> ol, List<ItemStack> inventoryItems) {
         lastSearchArgument.clear();
-        List<ItemStack> os = new LinkedList<>(ol);
+        List<Entry> os = new LinkedList<>(ol);
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().getItemListOrdering() != ItemListOrdering.registry)
             os = ol.stream().sorted(ASCENDING_COMPARATOR).collect(Collectors.toList());
         if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isItemListAscending())
@@ -285,18 +317,21 @@ public class ItemListOverlay extends Widget {
             else
                 lastSearchArgument.add(new SearchArgument[]{SearchArgument.ALWAYS});
         });
-        List<ItemStack> stacks = Collections.emptyList();
+        List<Entry> stacks = Collections.emptyList();
         if (lastSearchArgument.isEmpty())
             stacks = os;
         else
-            stacks = os.stream().filter(itemStack -> filterItem(itemStack, lastSearchArgument)).collect(Collectors.toList());
+            stacks = os.stream().filter(entry -> filterEntry(entry, lastSearchArgument)).collect(Collectors.toList());
         if (!RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() || stacks.isEmpty() || inventoryItems.isEmpty())
             return Collections.unmodifiableList(stacks);
         List<ItemStack> workingItems = RecipeHelper.getInstance().findCraftableByItems(inventoryItems);
-        List<ItemStack> newList = Lists.newArrayList();
+        List<Entry> newList = Lists.newArrayList();
         for (ItemStack workingItem : workingItems) {
-            if (stacks.stream().anyMatch(i -> i.isItemEqualIgnoreDamage(workingItem)))
-                newList.add(workingItem);
+            Optional<Entry> any = stacks.stream().filter(i -> i.getItemStack() != null && i.getItemStack().isItemEqualIgnoreDamage(workingItem)).findAny();
+            //            if (stacks.stream().anyMatch(i -> i.getItemStack() != null && i.getItemStack().isItemEqualIgnoreDamage(workingItem)))
+            //                newList.add(Entry.create(workingItem));
+            if (any.isPresent())
+                newList.add(any.get());
         }
         return newList;
     }

+ 40 - 3
src/main/java/me/shedaniel/rei/gui/widget/SlotWidget.java

@@ -12,11 +12,14 @@ import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.Renderer;
 import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.renderers.FluidRenderer;
 import me.shedaniel.rei.gui.renderers.ItemStackRenderer;
 import net.minecraft.client.gui.Element;
+import net.minecraft.fluid.Fluid;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.registry.Registry;
 
 import java.awt.*;
 import java.util.Collections;
@@ -133,6 +136,11 @@ public class SlotWidget extends WidgetWithBounds {
             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);
@@ -147,13 +155,34 @@ public class SlotWidget extends WidgetWithBounds {
         this.blitOffset = offset;
     }
     
+    protected void queueTooltip(Fluid fluid, float delta) {
+        ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(fluid)));
+    }
+    
+    private List<String> getTooltip(Fluid fluid) {
+        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetFluidName(fluid));
+        toolTip.addAll(getExtraFluidToolTips(fluid));
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
+            final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));
+            boolean alreadyHasMod = false;
+            for (String s : toolTip)
+                if (s.equalsIgnoreCase(modString)) {
+                    alreadyHasMod = true;
+                    break;
+                }
+            if (!alreadyHasMod)
+                toolTip.add(modString);
+        }
+        return toolTip;
+    }
+    
     protected void queueTooltip(ItemStack itemStack, float delta) {
         ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltip(itemStack)));
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {
-        List<String> toolTip = Lists.newArrayList(ItemListOverlay.tryGetItemStackToolTip(itemStack, true));
-        toolTip.addAll(getExtraToolTips(itemStack));
+        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetItemStackToolTip(itemStack, true));
+        toolTip.addAll(getExtraItemToolTips(itemStack));
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
             final String modString = ClientHelper.getInstance().getFormattedModFromItem(itemStack.getItem());
             String s1 = ClientHelper.getInstance().getModFromItem(itemStack.getItem()).toLowerCase(Locale.ROOT);
@@ -165,7 +194,11 @@ public class SlotWidget extends WidgetWithBounds {
         return toolTip;
     }
     
-    protected List<String> getExtraToolTips(ItemStack stack) {
+    protected List<String> getExtraItemToolTips(ItemStack stack) {
+        return Collections.emptyList();
+    }
+    
+    protected List<String> getExtraFluidToolTips(Fluid fluid) {
         return Collections.emptyList();
     }
     
@@ -210,6 +243,10 @@ public class SlotWidget extends WidgetWithBounds {
         return getCurrentRenderer() instanceof ItemStackRenderer;
     }
     
+    public boolean isCurrentRendererFluid() {
+        return getCurrentRenderer() instanceof FluidRenderer;
+    }
+    
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (!clickToMoreRecipes)

+ 13 - 9
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -9,7 +9,8 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.DisplayHelper;
-import me.shedaniel.rei.api.ItemRegistry;
+import me.shedaniel.rei.api.Entry;
+import me.shedaniel.rei.api.EntryRegistry;
 import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
 import me.shedaniel.rei.client.ScreenHelper;
@@ -92,14 +93,14 @@ public class DefaultPlugin implements REIPluginV0 {
     }
     
     @Override
-    public void registerItems(ItemRegistry itemRegistry) {
+    public void registerItems(EntryRegistry entryRegistry) {
         if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isLoadingDefaultPlugin()) {
             return;
         }
         Registry.ITEM.stream().forEach(item -> {
-            itemRegistry.registerItemStack(item.getStackForRender());
+            entryRegistry.registerItemStack(item.getStackForRender());
             try {
-                itemRegistry.registerItemStack(itemRegistry.getAllStacksFromItem(item));
+                entryRegistry.registerItemStack(entryRegistry.getAllStacksFromItem(item));
             } catch (Exception e) {
             }
         });
@@ -109,9 +110,12 @@ public class DefaultPlugin implements REIPluginV0 {
                 map.put(enchantment, i);
                 ItemStack itemStack = new ItemStack(Items.ENCHANTED_BOOK);
                 EnchantmentHelper.set(map, itemStack);
-                itemRegistry.registerItemStack(Items.ENCHANTED_BOOK, itemStack);
+                entryRegistry.registerItemStack(Items.ENCHANTED_BOOK, itemStack);
             }
         });
+        Registry.FLUID.forEach(fluid -> {
+            entryRegistry.registerFluid(fluid);
+        });
     }
     
     @Override
@@ -144,16 +148,16 @@ public class DefaultPlugin implements REIPluginV0 {
         recipeHelper.registerRecipes(STONE_CUTTING, StonecuttingRecipe.class, DefaultStoneCuttingDisplay::new);
         BREWING_DISPLAYS.stream().forEachOrdered(display -> recipeHelper.registerDisplay(BREWING, display));
         List<ItemStack> arrowStack = Collections.singletonList(Items.ARROW.getStackForRender());
-        RoughlyEnoughItemsCore.getItemRegisterer().getItemList().stream().filter(stack -> stack.getItem().equals(Items.LINGERING_POTION)).forEach(stack -> {
+        RoughlyEnoughItemsCore.getEntryRegistry().getEntryList().stream().filter(stack -> stack.getEntryType() == Entry.Type.ITEM && stack.getItemStack().getItem().equals(Items.LINGERING_POTION)).forEach(entry -> {
             List<List<ItemStack>> input = new ArrayList<>();
             for (int i = 0; i < 4; i++)
                 input.add(arrowStack);
-            input.add(Collections.singletonList(stack));
+            input.add(Collections.singletonList(entry.getItemStack()));
             for (int i = 0; i < 4; i++)
                 input.add(arrowStack);
             ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8);
-            PotionUtil.setPotion(outputStack, PotionUtil.getPotion(stack));
-            PotionUtil.setCustomPotionEffects(outputStack, PotionUtil.getCustomPotionEffects(stack));
+            PotionUtil.setPotion(outputStack, PotionUtil.getPotion(entry.getItemStack()));
+            PotionUtil.setCustomPotionEffects(outputStack, PotionUtil.getCustomPotionEffects(entry.getItemStack()));
             List<ItemStack> output = Collections.singletonList(outputStack);
             recipeHelper.registerDisplay(CRAFTING, new DefaultCustomDisplay(input, output));
         });

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

@@ -73,7 +73,7 @@ public class DefaultBlastingCategory implements RecipeCategory<DefaultBlastingDi
         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> getExtraToolTips(ItemStack stack) {
+            protected List<String> getExtraItemToolTips(ItemStack stack) {
                 return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
             }
         });

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

@@ -65,31 +65,31 @@ 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 + 63, startPoint.y + 1, Renderer.fromItemStacks(recipeDisplay.getInput().get(0)), false, true, true) {
             @Override
-            protected List<String> getExtraToolTips(ItemStack stack) {
+            protected List<String> getExtraItemToolTips(ItemStack stack) {
                 return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.input"));
             }
         });
         widgets.add(new SlotWidget(startPoint.x + 40, startPoint.y + 1, Renderer.fromItemStacks(recipeDisplay.getInput().get(1)), false, true, true) {
             @Override
-            protected List<String> getExtraToolTips(ItemStack stack) {
+            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> getExtraToolTips(ItemStack stack) {
+            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> getExtraToolTips(ItemStack stack) {
+            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> getExtraToolTips(ItemStack stack) {
+            protected List<String> getExtraItemToolTips(ItemStack stack) {
                 return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result"));
             }
         });

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

@@ -80,7 +80,7 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
             for (int x = 0; x < 8; x++) {
                 widgets.add(new SlotWidget((int) 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> getExtraToolTips(ItemStack stack) {
+                    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()))
@@ -88,7 +88,7 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
                         });
                         if (thing[0] != null)
                             return thing[0];
-                        return super.getExtraToolTips(stack);
+                        return super.getExtraItemToolTips(stack);
                     }
                 });
                 i++;

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

@@ -72,7 +72,7 @@ public class DefaultSmeltingCategory implements RecipeCategory<DefaultSmeltingDi
         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> getExtraToolTips(ItemStack stack) {
+            protected List<String> getExtraItemToolTips(ItemStack stack) {
                 return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
             }
         });

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

@@ -72,7 +72,7 @@ public class DefaultSmokingCategory implements RecipeCategory<DefaultSmokingDisp
         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> getExtraToolTips(ItemStack stack) {
+            protected List<String> getExtraItemToolTips(ItemStack stack) {
                 return Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel"));
             }
         });