瀏覽代碼

auto crafting... still using vanilla recipe book, can't figure how

Unknown 6 年之前
父節點
當前提交
96dafd2a0b
共有 22 個文件被更改,包括 284 次插入64 次删除
  1. 1 1
      gradle.properties
  2. 6 1
      src/main/java/me/shedaniel/rei/api/AutoCraftingHandler.java
  3. 3 0
      src/main/java/me/shedaniel/rei/api/ClientHelper.java
  4. 2 0
      src/main/java/me/shedaniel/rei/api/RecipeHelper.java
  5. 13 0
      src/main/java/me/shedaniel/rei/client/ClientHelperImpl.java
  6. 5 18
      src/main/java/me/shedaniel/rei/client/RecipeHelperImpl.java
  7. 11 3
      src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java
  8. 5 4
      src/main/java/me/shedaniel/rei/mixin/MixinBrewingRecipeRegistry.java
  9. 6 2
      src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java
  10. 39 0
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoBlastingBookHandler.java
  11. 39 0
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableBookHandler.java
  12. 0 31
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableHandler.java
  13. 39 0
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoFurnaceBookHandler.java
  14. 39 0
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoInventoryBookHandler.java
  15. 39 0
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoSmokerBookHandler.java
  16. 4 0
      src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingDisplay.java
  17. 6 1
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java
  18. 7 2
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java
  19. 7 1
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultShapedDisplay.java
  20. 6 0
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultShapelessDisplay.java
  21. 3 0
      src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingDisplay.java
  22. 4 0
      src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingDisplay.java

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=2.9.4
+mod_version=2.10
 minecraft_version=1.14.2
 yarn_version=1.14.2+build.3
 fabricloader_version=0.4.7+build.147

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

@@ -9,6 +9,9 @@ import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.util.ActionResult;
+
+import java.util.function.Supplier;
 
 public interface AutoCraftingHandler {
     
@@ -16,6 +19,8 @@ public interface AutoCraftingHandler {
         return 0d;
     }
     
-    boolean handle(MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay);
+    boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay);
+    
+    boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay);
     
 }

+ 3 - 0
src/main/java/me/shedaniel/rei/api/ClientHelper.java

@@ -146,4 +146,7 @@ public interface ClientHelper {
      * @return whether there are any recipes to show
      */
     boolean executeViewAllRecipesKeyBind();
+    
+    boolean executeViewAllRecipesFromCategory(Identifier category);
+    
 }

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

@@ -152,6 +152,8 @@ public interface RecipeHelper {
      */
     Map<RecipeCategory, List<RecipeDisplay>> getAllRecipes();
     
+    List<RecipeDisplay> getAllRecipesFromCategory(RecipeCategory category);
+    
     /**
      * Registers a recipe visibility handler
      *

+ 13 - 0
src/main/java/me/shedaniel/rei/client/ClientHelperImpl.java

@@ -205,6 +205,19 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
         return map.keySet().size() > 0;
     }
     
+    @Override
+    public boolean executeViewAllRecipesFromCategory(Identifier category) {
+        Map<RecipeCategory, List<RecipeDisplay>> map = Maps.newLinkedHashMap();
+        Optional<RecipeCategory> any = RecipeHelper.getInstance().getAllCategories().stream().filter(c -> c.getIdentifier().equals(category)).findAny();
+        if (!any.isPresent())
+            return false;
+        RecipeCategory<?> recipeCategory = any.get();
+        map.put(recipeCategory, RecipeHelper.getInstance().getAllRecipesFromCategory(recipeCategory));
+        if (map.keySet().size() > 0)
+            openRecipeViewingScreen(map);
+        return map.keySet().size() > 0;
+    }
+    
     @Override
     public void openRecipeViewingScreen(Map<RecipeCategory, List<RecipeDisplay>> map) {
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().screenType == RecipeScreenType.VILLAGER)

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

@@ -9,11 +9,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
-import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.config.DisplayVisibility;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
 import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.RecipeManager;
@@ -280,20 +276,6 @@ public class RecipeHelperImpl implements RecipeHelper {
                     return -1f;
                 }
             });
-        registerAutoCraftingHandler(new AutoCraftingHandler() {
-            @Override
-            public double getPriority() {
-                return -Double.MAX_VALUE;
-            }
-            
-            @Override
-            public boolean handle(MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
-                minecraft.openScreen(parentScreen);
-                ScreenHelper.getLastOverlay().init();
-                return true;
-            }
-        });
-        
         // Clear Cache
         ((DisplayHelperImpl) RoughlyEnoughItemsCore.getDisplayHelper()).resetCache();
         this.categoryDisplaySettingsMap.clear();
@@ -338,6 +320,11 @@ public class RecipeHelperImpl implements RecipeHelper {
         return map;
     }
     
+    @Override
+    public List<RecipeDisplay> getAllRecipesFromCategory(RecipeCategory category) {
+        return recipeCategoryListMap.get(category.getIdentifier());
+    }
+    
     @Override
     public void registerRecipeVisibilityHandler(DisplayVisibilityHandler visibilityHandler) {
         displayVisibilityHandlers.add(visibilityHandler);

+ 11 - 3
src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java

@@ -35,13 +35,21 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
     @Override
     public void onPressed() {
         for(AutoCraftingHandler autoCraftingHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler())
-            if (autoCraftingHandler.handle(minecraft,minecraft.currentScreen, containerScreen, ScreenHelper.getLastOverlay()))
-                break;
+            if (autoCraftingHandler.canHandle(displaySupplier, minecraft, minecraft.currentScreen, containerScreen, ScreenHelper.getLastOverlay()))
+                if (autoCraftingHandler.handle(displaySupplier, minecraft, minecraft.currentScreen, containerScreen, ScreenHelper.getLastOverlay()))
+                    return;
+        minecraft.openScreen(containerScreen);
+        ScreenHelper.getLastOverlay().init();
     }
     
     @Override
     public void render(int mouseX, int mouseY, float delta) {
-        this.enabled = true;
+        this.enabled = false;
+        for(AutoCraftingHandler autoCraftingHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler())
+            if (autoCraftingHandler.canHandle(displaySupplier, minecraft, minecraft.currentScreen, containerScreen, ScreenHelper.getLastOverlay())) {
+                enabled = true;
+                break;
+            }
         super.render(mouseX, mouseY, delta);
     }
     

+ 5 - 4
src/main/java/me/shedaniel/rei/mixin/MixinBrewingRecipeRegistry.java

@@ -6,9 +6,9 @@
 package me.shedaniel.rei.mixin;
 
 import com.google.common.collect.Lists;
+import me.shedaniel.rei.plugin.DefaultPlugin;
 import me.shedaniel.rei.plugin.brewing.BrewingRecipe;
 import me.shedaniel.rei.plugin.brewing.DefaultBrewingDisplay;
-import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.item.PotionItem;
@@ -17,6 +17,7 @@ import net.minecraft.potion.PotionUtil;
 import net.minecraft.recipe.BrewingRecipeRegistry;
 import net.minecraft.recipe.Ingredient;
 import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
 import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -27,9 +28,9 @@ import java.util.List;
 @Mixin(BrewingRecipeRegistry.class)
 public class MixinBrewingRecipeRegistry {
     
-    private static final List<BrewingRecipe> SELF_ITEM_RECIPES = Lists.newArrayList();
-    private static final List<Potion> REGISTERED_POTION_TYPES = Lists.newArrayList();
-    private static final List<Ingredient> SELF_POTION_TYPES = Lists.newArrayList();
+    @Unique private static final List<BrewingRecipe> SELF_ITEM_RECIPES = Lists.newArrayList();
+    @Unique private static final List<Potion> REGISTERED_POTION_TYPES = Lists.newArrayList();
+    @Unique private static final List<Ingredient> SELF_POTION_TYPES = Lists.newArrayList();
     
     @Inject(method = "registerPotionType", at = @At("RETURN"))
     private static void method_8080(Item item_1, CallbackInfo ci) {

+ 6 - 2
src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java

@@ -10,7 +10,7 @@ import me.shedaniel.rei.api.PluginDisabler;
 import me.shedaniel.rei.api.PluginFunction;
 import me.shedaniel.rei.api.REIPluginEntry;
 import me.shedaniel.rei.api.RecipeHelper;
-import me.shedaniel.rei.plugin.autocrafting.AutoCraftingTableHandler;
+import me.shedaniel.rei.plugin.autocrafting.*;
 import net.minecraft.util.Identifier;
 
 public class DefaultAutoCraftingPlugin implements REIPluginEntry {
@@ -34,7 +34,11 @@ public class DefaultAutoCraftingPlugin implements REIPluginEntry {
     
     @Override
     public void registerOthers(RecipeHelper recipeHelper) {
-        recipeHelper.registerAutoCraftingHandler(new AutoCraftingTableHandler());
+        recipeHelper.registerAutoCraftingHandler(new AutoCraftingTableBookHandler());
+        recipeHelper.registerAutoCraftingHandler(new AutoInventoryBookHandler());
+        recipeHelper.registerAutoCraftingHandler(new AutoFurnaceBookHandler());
+        recipeHelper.registerAutoCraftingHandler(new AutoSmokerBookHandler());
+        recipeHelper.registerAutoCraftingHandler(new AutoBlastingBookHandler());
     }
     
 }

+ 39 - 0
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoBlastingBookHandler.java

@@ -0,0 +1,39 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.autocrafting;
+
+import me.shedaniel.rei.api.AutoCraftingHandler;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
+import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.client.gui.screen.ingame.BlastFurnaceScreen;
+import net.minecraft.container.BlastFurnaceContainer;
+
+import java.util.function.Supplier;
+
+public class AutoBlastingBookHandler implements AutoCraftingHandler {
+    @Override
+    public boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        DefaultBlastingDisplay display = (DefaultBlastingDisplay) displaySupplier.get();
+        BlastFurnaceScreen furnaceScreen = (BlastFurnaceScreen) parentScreen;
+        minecraft.openScreen(furnaceScreen);
+        ((RecipeBookGuiHooks) furnaceScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
+        BlastFurnaceContainer container = furnaceScreen.getContainer();
+        minecraft.interactionManager.clickRecipe(container.syncId, display.getOptionalRecipe().get(), Screen.hasShiftDown());
+        ScreenHelper.getLastOverlay().init();
+        return true;
+    }
+    
+    @Override
+    public boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        return parentScreen instanceof BlastFurnaceScreen && displaySupplier.get() instanceof DefaultBlastingDisplay && ((DefaultBlastingDisplay) displaySupplier.get()).getOptionalRecipe().isPresent() && minecraft.player.getRecipeBook().contains(((DefaultBlastingDisplay) displaySupplier.get()).getOptionalRecipe().get());
+    }
+}

+ 39 - 0
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableBookHandler.java

@@ -0,0 +1,39 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.autocrafting;
+
+import me.shedaniel.rei.api.AutoCraftingHandler;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
+import me.shedaniel.rei.plugin.crafting.DefaultCraftingDisplay;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.client.gui.screen.ingame.CraftingTableScreen;
+import net.minecraft.container.CraftingTableContainer;
+
+import java.util.function.Supplier;
+
+public class AutoCraftingTableBookHandler implements AutoCraftingHandler {
+    @Override
+    public boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        DefaultCraftingDisplay display = (DefaultCraftingDisplay) displaySupplier.get();
+        CraftingTableScreen craftingTableScreen = (CraftingTableScreen) parentScreen;
+        minecraft.openScreen(craftingTableScreen);
+        ((RecipeBookGuiHooks) craftingTableScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
+        CraftingTableContainer container = craftingTableScreen.getContainer();
+        minecraft.interactionManager.clickRecipe(container.syncId, display.getOptionalRecipe().get(), Screen.hasShiftDown());
+        ScreenHelper.getLastOverlay().init();
+        return true;
+    }
+    
+    @Override
+    public boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        return parentScreen instanceof CraftingTableScreen && displaySupplier.get() instanceof DefaultCraftingDisplay && ((DefaultCraftingDisplay) displaySupplier.get()).getOptionalRecipe().isPresent() && minecraft.player.getRecipeBook().contains(((DefaultCraftingDisplay) displaySupplier.get()).getOptionalRecipe().get());
+    }
+}

+ 0 - 31
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableHandler.java

@@ -1,31 +0,0 @@
-/*
- * Roughly Enough Items by Danielshe.
- * Licensed under the MIT License.
- */
-
-package me.shedaniel.rei.plugin.autocrafting;
-
-import me.shedaniel.rei.api.AutoCraftingHandler;
-import me.shedaniel.rei.client.ScreenHelper;
-import me.shedaniel.rei.gui.ContainerScreenOverlay;
-import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
-import net.minecraft.client.gui.screen.ingame.CraftingTableScreen;
-import net.minecraft.container.CraftingTableContainer;
-
-public class AutoCraftingTableHandler implements AutoCraftingHandler {
-    @Override
-    public boolean handle(MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
-        if (parentScreen instanceof CraftingTableScreen) {
-            CraftingTableScreen craftingTableScreen = (CraftingTableScreen) parentScreen;
-            minecraft.openScreen(craftingTableScreen);
-            ((RecipeBookGuiHooks) craftingTableScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
-            CraftingTableContainer container = craftingTableScreen.getContainer();
-            ScreenHelper.getLastOverlay().init();
-            return true;
-        }
-        return false;
-    }
-}

+ 39 - 0
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoFurnaceBookHandler.java

@@ -0,0 +1,39 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.autocrafting;
+
+import me.shedaniel.rei.api.AutoCraftingHandler;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
+import me.shedaniel.rei.plugin.smelting.DefaultSmeltingDisplay;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.client.gui.screen.ingame.FurnaceScreen;
+import net.minecraft.container.FurnaceContainer;
+
+import java.util.function.Supplier;
+
+public class AutoFurnaceBookHandler implements AutoCraftingHandler {
+    @Override
+    public boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        DefaultSmeltingDisplay display = (DefaultSmeltingDisplay) displaySupplier.get();
+        FurnaceScreen furnaceScreen = (FurnaceScreen) parentScreen;
+        minecraft.openScreen(furnaceScreen);
+        ((RecipeBookGuiHooks) furnaceScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
+        FurnaceContainer container = furnaceScreen.getContainer();
+        minecraft.interactionManager.clickRecipe(container.syncId, display.getOptionalRecipe().get(), Screen.hasShiftDown());
+        ScreenHelper.getLastOverlay().init();
+        return true;
+    }
+    
+    @Override
+    public boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        return parentScreen instanceof FurnaceScreen && displaySupplier.get() instanceof DefaultSmeltingDisplay && ((DefaultSmeltingDisplay) displaySupplier.get()).getOptionalRecipe().isPresent() && minecraft.player.getRecipeBook().contains(((DefaultSmeltingDisplay) displaySupplier.get()).getOptionalRecipe().get());
+    }
+}

+ 39 - 0
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoInventoryBookHandler.java

@@ -0,0 +1,39 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.autocrafting;
+
+import me.shedaniel.rei.api.AutoCraftingHandler;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
+import me.shedaniel.rei.plugin.crafting.DefaultCraftingDisplay;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.client.gui.screen.ingame.InventoryScreen;
+import net.minecraft.container.PlayerContainer;
+
+import java.util.function.Supplier;
+
+public class AutoInventoryBookHandler implements AutoCraftingHandler {
+    @Override
+    public boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        DefaultCraftingDisplay display = (DefaultCraftingDisplay) displaySupplier.get();
+        InventoryScreen inventoryScreen = (InventoryScreen) parentScreen;
+        minecraft.openScreen(inventoryScreen);
+        ((RecipeBookGuiHooks) inventoryScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
+        PlayerContainer container = inventoryScreen.getContainer();
+        minecraft.interactionManager.clickRecipe(container.syncId, display.getOptionalRecipe().get(), Screen.hasShiftDown());
+        ScreenHelper.getLastOverlay().init();
+        return true;
+    }
+    
+    @Override
+    public boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        return parentScreen instanceof InventoryScreen && displaySupplier.get() instanceof DefaultCraftingDisplay && ((DefaultCraftingDisplay) displaySupplier.get()).getOptionalRecipe().isPresent() && minecraft.player.getRecipeBook().contains(((DefaultCraftingDisplay) displaySupplier.get()).getOptionalRecipe().get()) && ((DefaultCraftingDisplay) displaySupplier.get()).getWidth() <= 2 && ((DefaultCraftingDisplay) displaySupplier.get()).getHeight() <= 2;
+    }
+}

+ 39 - 0
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoSmokerBookHandler.java

@@ -0,0 +1,39 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.autocrafting;
+
+import me.shedaniel.rei.api.AutoCraftingHandler;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
+import me.shedaniel.rei.plugin.smoking.DefaultSmokingDisplay;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
+import net.minecraft.client.gui.screen.ingame.SmokerScreen;
+import net.minecraft.container.SmokerContainer;
+
+import java.util.function.Supplier;
+
+public class AutoSmokerBookHandler implements AutoCraftingHandler {
+    @Override
+    public boolean handle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        DefaultSmokingDisplay display = (DefaultSmokingDisplay) displaySupplier.get();
+        SmokerScreen smokerScreen = (SmokerScreen) parentScreen;
+        minecraft.openScreen(smokerScreen);
+        ((RecipeBookGuiHooks) smokerScreen.getRecipeBookGui()).rei_getGhostSlots().reset();
+        SmokerContainer container = smokerScreen.getContainer();
+        minecraft.interactionManager.clickRecipe(container.syncId, display.getOptionalRecipe().get(), Screen.hasShiftDown());
+        ScreenHelper.getLastOverlay().init();
+        return true;
+    }
+    
+    @Override
+    public boolean canHandle(Supplier<RecipeDisplay> displaySupplier, MinecraftClient minecraft, Screen recipeViewingScreen, AbstractContainerScreen<?> parentScreen, ContainerScreenOverlay overlay) {
+        return parentScreen instanceof SmokerScreen && displaySupplier.get() instanceof DefaultSmokingDisplay && ((DefaultSmokingDisplay) displaySupplier.get()).getOptionalRecipe().isPresent() && minecraft.player.getRecipeBook().contains(((DefaultSmokingDisplay) displaySupplier.get()).getOptionalRecipe().get());
+    }
+}

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

@@ -62,4 +62,8 @@ public class DefaultBlastingDisplay implements RecipeDisplay {
         return input;
     }
     
+    public Optional<BlastingRecipe> getOptionalRecipe() {
+        return Optional.ofNullable(display);
+    }
+    
 }

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

@@ -7,9 +7,12 @@ package me.shedaniel.rei.plugin.crafting;
 
 import me.shedaniel.rei.api.RecipeDisplay;
 import me.shedaniel.rei.plugin.DefaultPlugin;
+import net.minecraft.recipe.Recipe;
 import net.minecraft.util.Identifier;
 
-public interface DefaultCraftingDisplay<T> extends RecipeDisplay {
+import java.util.Optional;
+
+public interface DefaultCraftingDisplay extends RecipeDisplay {
     
     @Override
     default Identifier getRecipeCategory() {
@@ -24,4 +27,6 @@ public interface DefaultCraftingDisplay<T> extends RecipeDisplay {
         return 2;
     }
     
+    Optional<Recipe<?>> getOptionalRecipe();
+    
 }

+ 7 - 2
src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java

@@ -17,10 +17,10 @@ public class DefaultCustomDisplay implements DefaultCraftingDisplay {
     
     private List<List<ItemStack>> input;
     private List<ItemStack> output;
-    private Recipe possibleRecipe;
+    private Recipe<?> possibleRecipe;
     private int width, height;
     
-    public DefaultCustomDisplay(List<List<ItemStack>> input, List<ItemStack> output, Recipe possibleRecipe) {
+    public DefaultCustomDisplay(List<List<ItemStack>> input, List<ItemStack> output, Recipe<?> possibleRecipe) {
         this.input = input;
         this.output = output;
         this.possibleRecipe = possibleRecipe;
@@ -76,4 +76,9 @@ public class DefaultCustomDisplay implements DefaultCraftingDisplay {
         return height;
     }
     
+    @Override
+    public Optional<Recipe<?>> getOptionalRecipe() {
+        return Optional.ofNullable(possibleRecipe);
+    }
+    
 }

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

@@ -6,6 +6,7 @@
 package me.shedaniel.rei.plugin.crafting;
 
 import net.minecraft.item.ItemStack;
+import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.ShapedRecipe;
 import net.minecraft.util.Identifier;
 
@@ -15,7 +16,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
-public class DefaultShapedDisplay implements DefaultCraftingDisplay<ShapedRecipe> {
+public class DefaultShapedDisplay implements DefaultCraftingDisplay {
     
     private ShapedRecipe display;
     private List<List<ItemStack>> input;
@@ -52,6 +53,11 @@ public class DefaultShapedDisplay implements DefaultCraftingDisplay<ShapedRecipe
         return display.getHeight();
     }
     
+    @Override
+    public Optional<Recipe<?>> getOptionalRecipe() {
+        return Optional.ofNullable(display);
+    }
+    
     @Override
     public int getWidth() {
         return display.getWidth();

+ 6 - 0
src/main/java/me/shedaniel/rei/plugin/crafting/DefaultShapelessDisplay.java

@@ -6,6 +6,7 @@
 package me.shedaniel.rei.plugin.crafting;
 
 import net.minecraft.item.ItemStack;
+import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.ShapelessRecipe;
 import net.minecraft.util.Identifier;
 
@@ -27,6 +28,11 @@ public class DefaultShapelessDisplay implements DefaultCraftingDisplay {
         this.output = Collections.singletonList(recipe.getOutput());
     }
     
+    @Override
+    public Optional<Recipe<?>> getOptionalRecipe() {
+        return Optional.ofNullable(display);
+    }
+    
     @Override
     public Optional<Identifier> getRecipeLocation() {
         return Optional.ofNullable(display).map(ShapelessRecipe::getId);

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

@@ -62,4 +62,7 @@ public class DefaultSmeltingDisplay implements RecipeDisplay {
         return input;
     }
     
+    public Optional<SmeltingRecipe> getOptionalRecipe() {
+        return Optional.ofNullable(display);
+    }
 }

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

@@ -62,4 +62,8 @@ public class DefaultSmokingDisplay implements RecipeDisplay {
         return input;
     }
     
+    public Optional<SmokingRecipe> getOptionalRecipe() {
+        return Optional.ofNullable(display);
+    }
+    
 }