Unknown 6 лет назад
Родитель
Сommit
60bb2d5d0e

+ 1 - 1
build.gradle

@@ -6,7 +6,7 @@ sourceCompatibility = 1.8
 targetCompatibility = 1.8
 
 archivesBaseName = "RoughlyEnoughItems"
-version = "2.0.0.28"
+version = "2.0.0.29"
 
 minecraft {
 }

+ 2 - 4
src/main/java/me/shedaniel/rei/client/ClientHelper.java

@@ -24,11 +24,9 @@ import net.minecraft.util.PacketByteBuf;
 import net.minecraft.util.registry.Registry;
 
 import java.awt.*;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 public class ClientHelper implements ClientLoaded, ClientModInitializer {
     
@@ -99,14 +97,14 @@ public class ClientHelper implements ClientLoaded, ClientModInitializer {
     public static boolean executeRecipeKeyBind(ContainerGuiOverlay overlay, ItemStack stack, IMixinContainerGui parent) {
         Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getRecipesFor(stack);
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(overlay, MinecraftClient.getInstance().window, parent, map));
+            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, parent, map));
         return map.keySet().size() > 0;
     }
     
     public static boolean executeUsageKeyBind(ContainerGuiOverlay overlay, ItemStack stack, IMixinContainerGui parent) {
         Map<IRecipeCategory, List<IRecipeDisplay>> map = RecipeHelper.getUsagesFor(stack);
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(overlay, MinecraftClient.getInstance().window, parent, map));
+            MinecraftClient.getInstance().openGui(new RecipeViewingWidget(MinecraftClient.getInstance().window, parent, map));
         return map.keySet().size() > 0;
     }
     

+ 5 - 0
src/main/java/me/shedaniel/rei/client/RecipeHelper.java

@@ -122,6 +122,11 @@ public class RecipeHelper implements RecipeSync {
             plugin.registerPluginCategories();
             plugin.registerRecipes();
         });
+        Collections.reverse(categories);
+        RoughlyEnoughItemsCore.LOGGER.info("Registered REI Categories: " + String.join(", ", categories.stream().map(category -> {return category.getCategoryName();}).collect(Collectors.toList())));
     }
     
+    public static List<IRecipeCategory> getCategories() {
+        return categories;
+    }
 }

+ 12 - 7
src/main/java/me/shedaniel/rei/gui/ContainerGuiOverlay.java

@@ -1,6 +1,7 @@
 package me.shedaniel.rei.gui;
 
 import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.gui.widget.*;
 import me.shedaniel.rei.listeners.IMixinContainerGui;
@@ -29,6 +30,7 @@ public class ContainerGuiOverlay extends Gui {
     private ItemListOverlay itemListOverlay;
     private ButtonWidget buttonLeft, buttonRight;
     private TextFieldWidget searchField;
+    public static String searchTerm= "";
     
     public ContainerGuiOverlay(ContainerGui containerGui) {
         this.queuedTooltips = new ArrayList<>();
@@ -37,14 +39,13 @@ public class ContainerGuiOverlay extends Gui {
     }
     
     public void onInitialized() {
-        String searchTerm = searchField != null ? searchField.getText() : "";
         //Update Variables
         this.widgets.clear();
         this.window = MinecraftClient.getInstance().window;
         if (MinecraftClient.getInstance().currentGui instanceof ContainerGui)
             this.containerGui = (IMixinContainerGui) MinecraftClient.getInstance().currentGui;
         this.rectangle = calculateBoundary();
-        widgets.add(this.itemListOverlay = new ItemListOverlay(this, containerGui, page));
+        widgets.add(this.itemListOverlay = new ItemListOverlay(containerGui, page));
         
         this.itemListOverlay.updateList(getItemListArea(), page, searchTerm);
         widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, "<") {
@@ -53,7 +54,7 @@ public class ContainerGuiOverlay extends Gui {
                 page--;
                 if (page < 0)
                     page = getTotalPage();
-                itemListOverlay.updateList(getItemListArea(), page, searchField.getText());
+                itemListOverlay.updateList(getItemListArea(), page, searchTerm);
             }
         });
         widgets.add(buttonRight = new ButtonWidget(rectangle.x + rectangle.width - 18, rectangle.y + 5, 16, 16, ">") {
@@ -62,7 +63,7 @@ public class ContainerGuiOverlay extends Gui {
                 page++;
                 if (page > getTotalPage())
                     page = 0;
-                itemListOverlay.updateList(getItemListArea(), page, searchField.getText());
+                itemListOverlay.updateList(getItemListArea(), page, searchTerm);
             }
         });
         page = MathHelper.clamp(page, 0, getTotalPage());
@@ -88,9 +89,13 @@ public class ContainerGuiOverlay extends Gui {
         });
         Rectangle textFieldArea = getTextFieldArea();
         this.listeners.add(searchField = new TextFieldWidget(-1, MinecraftClient.getInstance().fontRenderer,
-                (int) textFieldArea.getX(), (int) textFieldArea.getY(), (int) textFieldArea.getWidth(), (int) textFieldArea.getHeight()));
-        searchField.setChangedListener((id, text) -> {
-            itemListOverlay.updateList(page, text);
+                (int) textFieldArea.getX(), (int) textFieldArea.getY(), (int) textFieldArea.getWidth(), (int) textFieldArea.getHeight()) {
+            @Override
+            public void addText(String string_1) {
+                super.addText(string_1);
+                searchTerm = this.getText();
+                itemListOverlay.updateList(page, searchTerm);
+            }
         });
         searchField.setText(searchTerm);
         

+ 29 - 20
src/main/java/me/shedaniel/rei/gui/widget/ItemListOverlay.java

@@ -6,7 +6,6 @@ import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.REIItemListOrdering;
 import me.shedaniel.rei.client.RecipeHelper;
 import me.shedaniel.rei.client.SearchArgument;
-import me.shedaniel.rei.gui.ContainerGuiOverlay;
 import me.shedaniel.rei.listeners.ClientLoaded;
 import me.shedaniel.rei.listeners.IMixinContainerGui;
 import net.minecraft.client.MinecraftClient;
@@ -27,16 +26,14 @@ import java.util.stream.Stream;
 
 public class ItemListOverlay extends Drawable implements IWidget {
     
-    private ContainerGuiOverlay containerGuiOverlay;
     private IMixinContainerGui containerGui;
     private List<IWidget> widgets = new ArrayList<>();
     private int width, height, page;
     private Rectangle rectangle;
     private List<ItemStack> currentDisplayed;
     
-    public ItemListOverlay(ContainerGuiOverlay containerGuiOverlay, IMixinContainerGui containerGui, int page) {
+    public ItemListOverlay(IMixinContainerGui containerGui, int page) {
         this.currentDisplayed = Lists.newArrayList();
-        this.containerGuiOverlay = containerGuiOverlay;
         this.containerGui = containerGui;
         this.width = 0;
         this.height = 0;
@@ -50,6 +47,9 @@ public class ItemListOverlay extends Drawable implements IWidget {
     @Override
     public void draw(int int_1, int int_2, float float_1) {
         widgets.forEach(widget -> widget.draw(int_1, int_2, float_1));
+        ClientPlayerEntity player = MinecraftClient.getInstance().player;
+        if (rectangle.contains(ClientHelper.getMouseLocation()) && ClientHelper.isCheating() && !player.inventory.getCursorStack().isEmpty())
+            containerGui.getOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.rei.delete_items"))));
     }
     
     public void updateList(int page, String searchTerm) {
@@ -73,24 +73,15 @@ public class ItemListOverlay extends Drawable implements IWidget {
             widgets.add(new ItemSlotWidget((int) (startX + (i % width) * 18), (int) (startY + MathHelper.floor(i / width) * 18),
                     currentDisplayed.get(j), false, true, containerGui) {
                 @Override
-                protected List<String> getTooltip(ItemStack itemStack) {
-                    if (!ClientHelper.isCheating() || MinecraftClient.getInstance().player.inventory.getCursorStack().isEmpty())
-                        return super.getTooltip(itemStack);
-                    List<String> list = Lists.newArrayList();
-                    list.add(I18n.translate("text.rei.delete_items"));
-                    return list;
+                protected void drawToolTip(ItemStack itemStack) {
+                    ClientPlayerEntity player = MinecraftClient.getInstance().player;
+                    if (!ClientHelper.isCheating() || player.inventory.getCursorStack().isEmpty())
+                        super.drawToolTip(itemStack);
                 }
                 
                 @Override
                 public boolean onMouseClick(int button, double mouseX, double mouseY) {
-                    ClientPlayerEntity player = MinecraftClient.getInstance().player;
                     if (getBounds().contains(mouseX, mouseY)) {
-                        if (ClientHelper.isCheating() && !player.inventory.getCursorStack().isEmpty()) {
-                            ClientHelper.sendDeletePacket();
-                            return true;
-                        }
-                        if (!player.inventory.getCursorStack().isEmpty())
-                            return false;
                         if (ClientHelper.isCheating()) {
                             if (getCurrentStack() != null && !getCurrentStack().isEmpty()) {
                                 ItemStack cheatedStack = getCurrentStack().copy();
@@ -99,9 +90,9 @@ public class ItemListOverlay extends Drawable implements IWidget {
                             }
                         } else {
                             if (button == 0)
-                                return ClientHelper.executeRecipeKeyBind(containerGuiOverlay, getCurrentStack().copy(), containerGui);
+                                return ClientHelper.executeRecipeKeyBind(containerGui.getOverlay(), getCurrentStack().copy(), containerGui);
                             else if (button == 1)
-                                return ClientHelper.executeUsageKeyBind(containerGuiOverlay, getCurrentStack().copy(), containerGui);
+                                return ClientHelper.executeUsageKeyBind(containerGui.getOverlay(), getCurrentStack().copy(), containerGui);
                         }
                     }
                     return false;
@@ -198,7 +189,7 @@ public class ItemListOverlay extends Drawable implements IWidget {
         MinecraftClient client = MinecraftClient.getInstance();
         return itemStack.getTooltipText(client.player, client.options.advancedItemTooltips ?
                 TooltipOptions.Instance.ADVANCED : TooltipOptions.Instance.NORMAL).stream().map(
-                        TextComponent::getFormattedText).collect(Collectors.toList());
+                TextComponent::getFormattedText).collect(Collectors.toList());
     }
     
     private void calculateListSize(Rectangle rect) {
@@ -219,6 +210,24 @@ public class ItemListOverlay extends Drawable implements IWidget {
         }
     }
     
+    @Override
+    public boolean mouseClicked(double double_1, double double_2, int int_1) {
+        ClientPlayerEntity player = MinecraftClient.getInstance().player;
+        if (rectangle.contains(double_1, double_2))
+            if (ClientHelper.isCheating() && !player.inventory.getCursorStack().isEmpty()) {
+                ClientHelper.sendDeletePacket();
+                return true;
+            }
+        if (!player.inventory.getCursorStack().isEmpty())
+            return false;
+        if (onMouseClick(int_1, double_1, double_2))
+            return true;
+        for(IWidget widget : getListeners())
+            if (widget.mouseClicked(double_1, double_2, int_1))
+                return true;
+        return false;
+    }
+    
     @Override
     public List<IWidget> getListeners() {
         return widgets;

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

@@ -75,10 +75,13 @@ public class ItemSlotWidget extends Drawable implements HighlightableWidget {
         else
             itemRenderer.renderItemOverlaysInGUIWithText(MinecraftClient.getInstance().fontRenderer, itemStack, x, y - 8, getItemCountOverlay(itemStack));
         itemRenderer.zOffset = 0.0F;
-        if (isHighlighted(mouseX, mouseY) && showToolTips) {
-            List<String> toolTip = getTooltip(itemStack);
-            containerGui.getOverlay().addTooltip(new QueuedTooltip(new Point(mouseX, mouseY), toolTip));
-        }
+        if (isHighlighted(mouseX, mouseY) && showToolTips)
+            drawToolTip(itemStack);
+    }
+    
+    protected void drawToolTip(ItemStack itemStack) {
+        List<String> toolTip = getTooltip(itemStack);
+        containerGui.getOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), toolTip));
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {

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

@@ -40,7 +40,7 @@ public class RecipeViewingWidget extends Gui {
     private int page, categoryPages;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     
-    public RecipeViewingWidget(ContainerGuiOverlay overlay, Window window, IMixinContainerGui parent, Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap) {
+    public RecipeViewingWidget(Window window, IMixinContainerGui parent, Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap) {
         this.categoryPages = 0;
         this.parent = parent;
         this.window = window;
@@ -50,7 +50,7 @@ public class RecipeViewingWidget extends Gui {
         this.categories = new LinkedList<>(categoriesMap.keySet());
         Collections.reverse(categories);
         this.selectedCategory = categories.get(0);
-        this.overlay = overlay;
+        this.overlay = parent.getOverlay();
         this.tabs = new ArrayList<>();
     }
     
@@ -74,6 +74,11 @@ public class RecipeViewingWidget extends Gui {
         return super.keyPressed(int_1, int_2, int_3);
     }
     
+    @Override
+    public void onClosed() {
+        parent.setOverlay(overlay);
+    }
+    
     @Override
     protected void onInitialized() {
         super.onInitialized();

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

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

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

@@ -22,4 +22,6 @@ public interface IMixinContainerGui {
     
     public ContainerGui getContainerGui();
     
+    public void setOverlay(ContainerGuiOverlay overlay);
+    
 }

+ 5 - 0
src/main/java/me/shedaniel/rei/mixin/MixinContainerGui.java

@@ -110,4 +110,9 @@ public class MixinContainerGui extends Gui implements IMixinContainerGui {
             }
     }
     
+    @Override
+    public void setOverlay(ContainerGuiOverlay overlay) {
+        this.overlay = overlay;
+        overlay.onInitialized();
+    }
 }

+ 65 - 0
src/main/java/me/shedaniel/rei/plugin/DefaultBlastingCategory.java

@@ -0,0 +1,65 @@
+package me.shedaniel.rei.plugin;
+
+import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.IRecipeCategory;
+import me.shedaniel.rei.gui.widget.IWidget;
+import me.shedaniel.rei.gui.widget.ItemSlotWidget;
+import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
+import me.shedaniel.rei.listeners.IMixinContainerGui;
+import net.minecraft.block.Blocks;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DefaultBlastingCategory implements IRecipeCategory<DefaultBlastingDisplay> {
+    
+    private static final Identifier DISPLAY_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/display.png");
+    
+    @Override
+    public Identifier getIdentifier() {
+        return DefaultPlugin.BLASTING;
+    }
+    
+    @Override
+    public ItemStack getCategoryIcon() {
+        return new ItemStack(Blocks.BLAST_FURNACE.getItem());
+    }
+    
+    @Override
+    public String getCategoryName() {
+        return I18n.translate("category.rei.blasting");
+    }
+    
+    @Override
+    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultBlastingDisplay recipeDisplay, Rectangle bounds) {
+        Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
+        List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
+            @Override
+            public void draw(int mouseX, int mouseY, float partialTicks) {
+                super.draw(mouseX, mouseY, partialTicks);
+                GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+                GuiLighting.disable();
+                MinecraftClient.getInstance().getTextureManager().bindTexture(DISPLAY_TEXTURE);
+                drawTexturedRect(startPoint.x, startPoint.y, 0, 54, 82, 54);
+                int height = MathHelper.ceil((System.currentTimeMillis() / 250 % 14d) / 1f);
+                drawTexturedRect(startPoint.x + 2, startPoint.y + 21 + (14 - height), 82, 77 + (14 - height), 14, height);
+                int width = MathHelper.ceil((System.currentTimeMillis() / 250 % 24d) / 1f);
+                drawTexturedRect(startPoint.x + 24, startPoint.y + 19, 82, 92, width, 17);
+            }
+        }));
+        List<List<ItemStack>> input = recipeDisplay.getInput();
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        return widgets;
+    }
+    
+}

+ 63 - 0
src/main/java/me/shedaniel/rei/plugin/DefaultBlastingDisplay.java

@@ -0,0 +1,63 @@
+package me.shedaniel.rei.plugin;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.rei.api.IRecipeDisplay;
+import net.minecraft.block.entity.FurnaceBlockEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.recipe.smelting.BlastingRecipe;
+import net.minecraft.recipe.smelting.SmokingRecipe;
+import net.minecraft.util.Identifier;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DefaultBlastingDisplay implements IRecipeDisplay<BlastingRecipe> {
+    
+    private BlastingRecipe display;
+    private List<List<ItemStack>> input;
+    private List<ItemStack> output;
+    
+    public DefaultBlastingDisplay(BlastingRecipe recipe) {
+        this.display = recipe;
+        List<ItemStack> fuel = Lists.newArrayList();
+        this.input = Lists.newArrayList();
+        fuel.addAll(FurnaceBlockEntity.createBurnableMap().keySet().stream().map(Item::getDefaultStack).collect(Collectors.toList()));
+        recipe.getPreviewInputs().forEach(ingredient -> {
+            input.add(Arrays.asList(ingredient.getStackArray()));
+        });
+        input.add(fuel);
+        this.output = Arrays.asList(recipe.getOutput());
+    }
+    
+    @Override
+    public BlastingRecipe getRecipe() {
+        return display;
+    }
+    
+    @Override
+    public List<List<ItemStack>> getInput() {
+        return input;
+    }
+    
+    public List<ItemStack> getFuel() {
+        return input.get(1);
+    }
+    
+    @Override
+    public List<ItemStack> getOutput() {
+        return output;
+    }
+    
+    @Override
+    public Identifier getRecipeCategory() {
+        return DefaultPlugin.BLASTING;
+    }
+    
+    @Override
+    public List<List<ItemStack>> getRequiredItems() {
+        return input;
+    }
+    
+}

+ 10 - 0
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -5,18 +5,24 @@ import me.shedaniel.rei.client.RecipeHelper;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.crafting.ShapedRecipe;
 import net.minecraft.recipe.crafting.ShapelessRecipe;
+import net.minecraft.recipe.smelting.BlastingRecipe;
 import net.minecraft.recipe.smelting.SmeltingRecipe;
+import net.minecraft.recipe.smelting.SmokingRecipe;
 import net.minecraft.util.Identifier;
 
 public class DefaultPlugin implements IRecipePlugin {
     
     static final Identifier CRAFTING = new Identifier("roughlyenoughitems", "plugins/crafting");
     static final Identifier SMELTING = new Identifier("roughlyenoughitems", "plugins/smelting");
+    static final Identifier SMOKING = new Identifier("roughlyenoughitems", "plugins/smoking");
+    static final Identifier BLASTING = new Identifier("roughlyenoughitems", "plugins/blasting");
     
     @Override
     public void registerPluginCategories() {
         RecipeHelper.registerCategory(new DefaultCraftingCategory());
         RecipeHelper.registerCategory(new DefaultSmeltingCategory());
+        RecipeHelper.registerCategory(new DefaultSmokingCategory());
+        RecipeHelper.registerCategory(new DefaultBlastingCategory());
     }
     
     @Override
@@ -28,6 +34,10 @@ public class DefaultPlugin implements IRecipePlugin {
                 RecipeHelper.registerRecipe(CRAFTING, new DefaultShapedDisplay((ShapedRecipe) value));
             else if (value instanceof SmeltingRecipe)
                 RecipeHelper.registerRecipe(SMELTING, new DefaultSmeltingDisplay((SmeltingRecipe) value));
+            else if (value instanceof SmokingRecipe)
+                RecipeHelper.registerRecipe(SMOKING, new DefaultSmokingDisplay((SmokingRecipe) value));
+            else if (value instanceof BlastingRecipe)
+                RecipeHelper.registerRecipe(BLASTING, new DefaultBlastingDisplay((BlastingRecipe) value));
     }
     
 }

+ 0 - 2
src/main/java/me/shedaniel/rei/plugin/DefaultSmeltingDisplay.java

@@ -5,8 +5,6 @@ import me.shedaniel.rei.api.IRecipeDisplay;
 import net.minecraft.block.entity.FurnaceBlockEntity;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
-import net.minecraft.recipe.Recipe;
-import net.minecraft.recipe.crafting.ShapelessRecipe;
 import net.minecraft.recipe.smelting.SmeltingRecipe;
 import net.minecraft.util.Identifier;
 

+ 65 - 0
src/main/java/me/shedaniel/rei/plugin/DefaultSmokingCategory.java

@@ -0,0 +1,65 @@
+package me.shedaniel.rei.plugin;
+
+import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.IRecipeCategory;
+import me.shedaniel.rei.gui.widget.IWidget;
+import me.shedaniel.rei.gui.widget.ItemSlotWidget;
+import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
+import me.shedaniel.rei.listeners.IMixinContainerGui;
+import net.minecraft.block.Blocks;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DefaultSmokingCategory implements IRecipeCategory<DefaultSmokingDisplay> {
+    
+    private static final Identifier DISPLAY_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/display.png");
+    
+    @Override
+    public Identifier getIdentifier() {
+        return DefaultPlugin.SMOKING;
+    }
+    
+    @Override
+    public ItemStack getCategoryIcon() {
+        return new ItemStack(Blocks.SMOKER.getItem());
+    }
+    
+    @Override
+    public String getCategoryName() {
+        return I18n.translate("category.rei.smoking");
+    }
+    
+    @Override
+    public List<IWidget> setupDisplay(IMixinContainerGui containerGui, DefaultSmokingDisplay recipeDisplay, Rectangle bounds) {
+        Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 27);
+        List<IWidget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
+            @Override
+            public void draw(int mouseX, int mouseY, float partialTicks) {
+                super.draw(mouseX, mouseY, partialTicks);
+                GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+                GuiLighting.disable();
+                MinecraftClient.getInstance().getTextureManager().bindTexture(DISPLAY_TEXTURE);
+                drawTexturedRect(startPoint.x, startPoint.y, 0, 54, 82, 54);
+                int height = MathHelper.ceil((System.currentTimeMillis() / 250 % 14d) / 1f);
+                drawTexturedRect(startPoint.x + 2, startPoint.y + 21 + (14 - height), 82, 77 + (14 - height), 14, height);
+                int width = MathHelper.ceil((System.currentTimeMillis() / 250 % 24d) / 1f);
+                drawTexturedRect(startPoint.x + 24, startPoint.y + 19, 82, 92, width, 17);
+            }
+        }));
+        List<List<ItemStack>> input = recipeDisplay.getInput();
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 1, input.get(0), true, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 1, startPoint.y + 37, recipeDisplay.getFuel(), true, true, containerGui, true));
+        widgets.add(new ItemSlotWidget(startPoint.x + 61, startPoint.y + 19, recipeDisplay.getOutput(), false, true, containerGui, true));
+        return widgets;
+    }
+    
+}

+ 63 - 0
src/main/java/me/shedaniel/rei/plugin/DefaultSmokingDisplay.java

@@ -0,0 +1,63 @@
+package me.shedaniel.rei.plugin;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.rei.api.IRecipeDisplay;
+import net.minecraft.block.entity.FurnaceBlockEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.recipe.smelting.SmeltingRecipe;
+import net.minecraft.recipe.smelting.SmokingRecipe;
+import net.minecraft.util.Identifier;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DefaultSmokingDisplay implements IRecipeDisplay<SmokingRecipe> {
+    
+    private SmokingRecipe display;
+    private List<List<ItemStack>> input;
+    private List<ItemStack> output;
+    
+    public DefaultSmokingDisplay(SmokingRecipe recipe) {
+        this.display = recipe;
+        List<ItemStack> fuel = Lists.newArrayList();
+        this.input = Lists.newArrayList();
+        fuel.addAll(FurnaceBlockEntity.createBurnableMap().keySet().stream().map(Item::getDefaultStack).collect(Collectors.toList()));
+        recipe.getPreviewInputs().forEach(ingredient -> {
+            input.add(Arrays.asList(ingredient.getStackArray()));
+        });
+        input.add(fuel);
+        this.output = Arrays.asList(recipe.getOutput());
+    }
+    
+    @Override
+    public SmokingRecipe getRecipe() {
+        return display;
+    }
+    
+    @Override
+    public List<List<ItemStack>> getInput() {
+        return input;
+    }
+    
+    public List<ItemStack> getFuel() {
+        return input.get(1);
+    }
+    
+    @Override
+    public List<ItemStack> getOutput() {
+        return output;
+    }
+    
+    @Override
+    public Identifier getRecipeCategory() {
+        return DefaultPlugin.SMOKING;
+    }
+    
+    @Override
+    public List<List<ItemStack>> getRequiredItems() {
+        return input;
+    }
+    
+}

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

@@ -2,7 +2,7 @@
   "id": "roughlyenoughitems",
   "name": "RoughlyEnoughItems",
   "description": "To allow players to view items and recipes.",
-  "version": "2.0.0.28",
+  "version": "2.0.0.29",
   "side": "client",
   "authors": [
     "Danielshe"