Browse Source

API Change

Unknown 6 năm trước cách đây
mục cha
commit
943b3c0a7f

+ 1 - 1
build.gradle

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

+ 31 - 15
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -1,5 +1,7 @@
 package me.shedaniel.rei;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import me.shedaniel.rei.api.IRecipePlugin;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.ConfigHelper;
@@ -17,16 +19,19 @@ import net.minecraft.util.Identifier;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitializer {
     
     public static final Logger LOGGER = LogManager.getFormatterLogger("REI");
-    public static final Identifier DELETE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "deleteitem");
-    public static final Identifier CREATE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "createitem");
-    private static final List<IListener> listeners = new ArrayList<>();
+    public static final Identifier DELETE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "delete_item");
+    public static final Identifier CREATE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "create_item");
+    public static final Identifier DEFAULT_PLUGIN = new Identifier("roughlyenoughitems", "default_plugin");
+    private static final List<IListener> listeners = Lists.newArrayList();
+    private static final Map<Identifier, IRecipePlugin> plugins = Maps.newHashMap();
     private static ConfigHelper configHelper;
     
     public static <T> List<T> getListeners(Class<T> listenerClass) {
@@ -41,6 +46,27 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
         return configHelper;
     }
     
+    private static IListener registerListener(IListener listener) {
+        listeners.add(listener);
+        return listener;
+    }
+    
+    public static IRecipePlugin registerPlugin(Identifier identifier, IRecipePlugin plugin) {
+        plugins.put(identifier, plugin);
+        return plugin;
+    }
+    
+    public static List<IRecipePlugin> getPlugins() {
+        return new LinkedList<>(plugins.values());
+    }
+    
+    public static Identifier getPluginIdentifier(IRecipePlugin plugin) {
+        for(Identifier identifier : plugins.keySet())
+            if (plugins.get(identifier).equals(plugin))
+                return identifier;
+        return null;
+    }
+    
     @Override
     public void onInitializeClient() {
         registerREIListeners();
@@ -49,7 +75,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
     }
     
     private void registerDefaultPlugin() {
-        registerPlugin(new DefaultPlugin());
+        registerPlugin(RoughlyEnoughItemsCore.DEFAULT_PLUGIN, new DefaultPlugin());
     }
     
     private void registerREIListeners() {
@@ -57,16 +83,6 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
         registerListener(new RecipeHelper());
     }
     
-    private IListener registerListener(IListener listener) {
-        listeners.add(listener);
-        return listener;
-    }
-    
-    private IRecipePlugin registerPlugin(IRecipePlugin plugin) {
-        registerListener(plugin);
-        return plugin;
-    }
-    
     private boolean removeListener(IListener listener) {
         if (!listeners.contains(listener))
             return false;

+ 6 - 2
src/main/java/me/shedaniel/rei/api/IRecipePlugin.java

@@ -2,12 +2,16 @@ package me.shedaniel.rei.api;
 
 import me.shedaniel.rei.listeners.IListener;
 
-public interface IRecipePlugin extends IListener {
+public interface IRecipePlugin {
     
     public void registerPluginCategories();
     
     public void registerRecipes();
     
-    public void registerAutoCraftingGui();
+    public void registerSpeedCraft();
+    
+    default public int getPriority() {
+        return 0;
+    }
     
 }

+ 9 - 0
src/main/java/me/shedaniel/rei/api/SpeedCraftAreaSupplier.java

@@ -0,0 +1,9 @@
+package me.shedaniel.rei.api;
+
+import java.awt.*;
+
+public interface SpeedCraftAreaSupplier {
+    
+    public Rectangle get(Rectangle bounds);
+    
+}

+ 14 - 0
src/main/java/me/shedaniel/rei/api/SpeedCraftFunctional.java

@@ -0,0 +1,14 @@
+package me.shedaniel.rei.api;
+
+import me.shedaniel.rei.plugin.DefaultCraftingDisplay;
+import net.minecraft.client.gui.Gui;
+
+public interface SpeedCraftFunctional<T extends IRecipeDisplay> {
+    
+    public Class[] getFunctioningFor();
+    
+    public boolean performAutoCraft(Gui gui, T recipe);
+    
+    public boolean acceptRecipe(Gui gui, T recipe);
+    
+}

+ 39 - 20
src/main/java/me/shedaniel/rei/client/RecipeHelper.java

@@ -3,17 +3,15 @@ package me.shedaniel.rei.client;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
-import me.shedaniel.rei.api.IRecipeCategory;
-import me.shedaniel.rei.api.IRecipeCategoryCraftable;
-import me.shedaniel.rei.api.IRecipeDisplay;
-import me.shedaniel.rei.api.IRecipePlugin;
+import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.listeners.RecipeSync;
-import net.minecraft.client.gui.Gui;
 import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.util.Identifier;
 
+import java.awt.*;
 import java.util.*;
+import java.util.List;
 import java.util.stream.Collectors;
 
 public class RecipeHelper implements RecipeSync {
@@ -21,12 +19,14 @@ public class RecipeHelper implements RecipeSync {
     private static Map<Identifier, List<IRecipeDisplay>> recipeCategoryListMap;
     private static List<IRecipeCategory> categories;
     private static RecipeManager recipeManager;
-    private static Map<Class, IRecipeCategoryCraftable> craftables;
+    private static Map<Identifier, SpeedCraftAreaSupplier> speedCraftAreaSupplierMap;
+    private static Map<Identifier, List<SpeedCraftFunctional>> speedCraftFunctionalMap;
     
     public RecipeHelper() {
         this.recipeCategoryListMap = Maps.newHashMap();
         this.categories = Lists.newArrayList();
-        this.craftables = Maps.newHashMap();
+        this.speedCraftAreaSupplierMap = Maps.newHashMap();
+        this.speedCraftFunctionalMap = Maps.newHashMap();
     }
     
     public static List<ItemStack> findCraftableByItems(List<ItemStack> inventoryItems) {
@@ -59,7 +59,7 @@ public class RecipeHelper implements RecipeSync {
     }
     
     public static void registerCategory(IRecipeCategory category) {
-        categories.add(0, category);
+        categories.add(category);
         recipeCategoryListMap.put(category.getIdentifier(), Lists.newArrayList());
     }
     
@@ -121,18 +121,28 @@ public class RecipeHelper implements RecipeSync {
         return categories;
     }
     
-    public static void registerCategoryCraftable(Class<? extends IRecipeDisplay> guiClass, IRecipeCategoryCraftable categoryCraftable) {
-        craftables.put(guiClass, categoryCraftable);
+    public static SpeedCraftAreaSupplier getSpeedCraftButtonArea(IRecipeCategory category) {
+        if (!speedCraftAreaSupplierMap.containsKey(category.getIdentifier()))
+            return bounds -> {
+                return new Rectangle((int) bounds.getMaxX() - 16, (int) bounds.getMaxY() - 16, 10, 10);
+            };
+        return speedCraftAreaSupplierMap.get(category.getIdentifier());
     }
     
-    public static void registerCategoryCraftable(Class<? extends IRecipeDisplay>[] guiClasses, IRecipeCategoryCraftable categoryCraftable) {
-        for(Class<? extends IRecipeDisplay> guiClass : guiClasses) craftables.put(guiClass, categoryCraftable);
+    public static void registerSpeedCraftButtonArea(Identifier category, SpeedCraftAreaSupplier rectangle) {
+        speedCraftAreaSupplierMap.put(category, rectangle);
     }
     
-    public static IRecipeCategoryCraftable getCategoryCraftable(IRecipeDisplay gui) {
-        if (!craftables.containsKey(gui.getClass()))
-            return null;
-        return craftables.get(gui.getClass());
+    public static List<SpeedCraftFunctional> getSpeedCraftFunctional(IRecipeCategory category) {
+        if (speedCraftFunctionalMap.get(category.getIdentifier()) == null)
+            return Lists.newArrayList();
+        return speedCraftFunctionalMap.get(category.getIdentifier());
+    }
+    
+    public static void registerSpeedCraftFunctional(Identifier category, SpeedCraftFunctional functional) {
+        List<SpeedCraftFunctional> list = speedCraftFunctionalMap.containsKey(category) ? new LinkedList<>(speedCraftFunctionalMap.get(category)) : Lists.newLinkedList();
+        list.add(functional);
+        speedCraftFunctionalMap.put(category, list);
     }
     
     @Override
@@ -140,13 +150,22 @@ public class RecipeHelper implements RecipeSync {
         this.recipeManager = recipeManager;
         this.recipeCategoryListMap.clear();
         this.categories.clear();
-        this.craftables.clear();
-        RoughlyEnoughItemsCore.getListeners(IRecipePlugin.class).forEach(plugin -> {
+        this.speedCraftAreaSupplierMap.clear();
+        this.speedCraftFunctionalMap.clear();
+        List<IRecipePlugin> plugins = new LinkedList<>(RoughlyEnoughItemsCore.getPlugins());
+        plugins.sort((first, second) -> {
+            return second.getPriority() - first.getPriority();
+        });
+        RoughlyEnoughItemsCore.LOGGER.info("Loading %d REI plugins: %s", plugins.size(), String.join(", ", plugins.stream().map(plugin -> {
+            Identifier identifier = RoughlyEnoughItemsCore.getPluginIdentifier(plugin);
+            return identifier == null ? "NULL" : identifier.toString();
+        }).collect(Collectors.toList())));
+        Collections.reverse(plugins);
+        plugins.forEach(plugin -> {
             plugin.registerPluginCategories();
             plugin.registerRecipes();
-            plugin.registerAutoCraftingGui();
+            plugin.registerSpeedCraft();
         });
-        Collections.reverse(categories);
         RoughlyEnoughItemsCore.LOGGER.info("Registered REI Categories: " + String.join(", ", categories.stream().map(category -> {
             return category.getCategoryName();
         }).collect(Collectors.toList())));

+ 4 - 0
src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java

@@ -28,6 +28,10 @@ public abstract class ButtonWidget extends Drawable implements IWidget {
     private boolean pressed;
     private Rectangle bounds;
     
+    public ButtonWidget(Rectangle rectangle, String text) {
+        this(rectangle.x, rectangle.y, rectangle.width, rectangle.height, text);
+    }
+    
     public ButtonWidget(int x, int y, int width, int height, String text) {
         this.width = 200;
         this.height = 20;

+ 56 - 9
src/main/java/me/shedaniel/rei/gui/widget/RecipeViewingWidget.java

@@ -3,8 +3,9 @@ package me.shedaniel.rei.gui.widget;
 import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.api.IRecipeCategory;
-import me.shedaniel.rei.api.IRecipeCategoryCraftable;
 import me.shedaniel.rei.api.IRecipeDisplay;
+import me.shedaniel.rei.api.SpeedCraftAreaSupplier;
+import me.shedaniel.rei.api.SpeedCraftFunctional;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.GuiHelper;
 import me.shedaniel.rei.client.RecipeHelper;
@@ -14,6 +15,7 @@ import net.minecraft.client.audio.PositionedSoundInstance;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.GuiEventListener;
 import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.Window;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.util.Identifier;
@@ -21,6 +23,7 @@ import net.minecraft.util.math.MathHelper;
 
 import java.awt.*;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -175,20 +178,64 @@ public class RecipeViewingWidget extends Gui {
                 tab.setItem(categories.get(j).getCategoryIcon(), categories.get(j).getCategoryName(), tab.getId() + categoryPages * 6 == categories.indexOf(selectedCategory));
             }
         }
+        SpeedCraftAreaSupplier supplier = RecipeHelper.getSpeedCraftButtonArea(selectedCategory);
+        final SpeedCraftFunctional[] functional0 = {null};
+        RecipeHelper.getSpeedCraftFunctional(selectedCategory).forEach(functional1 -> {
+            for(Class aClass : functional1.getFunctioningFor())
+                if (parent.getContainerGui().getClass().isAssignableFrom(aClass)) {
+                    functional0[0] = functional1;
+                    break;
+                }
+        });
+        final SpeedCraftFunctional functional = functional0[0];
         if (page * getRecipesPerPage() < categoriesMap.get(selectedCategory).size()) {
             IRecipeDisplay topDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage());
             widgets.addAll(selectedCategory.setupDisplay(getParent(), topDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 118 : 66)));
-            IRecipeCategoryCraftable craftable = RecipeHelper.getCategoryCraftable(topDisplay);
-            if (craftable != null)
-                craftable.registerAutoCraftButton(widgets, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 118 : 66),
-                        getParent(), topDisplay);
+            if (supplier != null) {
+                ButtonWidget btn;
+                widgets.add(btn = new ButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 118 : 66)), "+") {
+                    @Override
+                    public void onPressed(int button, double mouseX, double mouseY) {
+                        MinecraftClient.getInstance().openGui(parent.getContainerGui());
+                        functional.performAutoCraft(parent.getContainerGui(), topDisplay);
+                    }
+                    
+                    @Override
+                    public void draw(int mouseX, int mouseY, float partialTicks) {
+                        super.draw(mouseX, mouseY, partialTicks);
+                        if (getBounds().contains(mouseX, mouseY))
+                            if (enabled)
+                                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.move_items"))));
+                            else
+                                GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.failed_move_items"))));
+                    }
+                });
+                btn.enabled = functional != null && functional.acceptRecipe(parent.getContainerGui(), topDisplay);
+            }
             if (!selectedCategory.usesFullPage() && page * getRecipesPerPage() + 1 < categoriesMap.get(selectedCategory).size()) {
                 IRecipeDisplay middleDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage() + 1);
                 widgets.addAll(selectedCategory.setupDisplay(getParent(), middleDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 108, 150, 66)));
-                craftable = RecipeHelper.getCategoryCraftable(middleDisplay);
-                if (craftable != null)
-                    craftable.registerAutoCraftButton(widgets, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 108, 150, 66),
-                            getParent(), middleDisplay);
+                if (supplier != null) {
+                    ButtonWidget btn;
+                    widgets.add(btn = new ButtonWidget(supplier.get(new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 108, 150, 66)), "+") {
+                        @Override
+                        public void onPressed(int button, double mouseX, double mouseY) {
+                            MinecraftClient.getInstance().openGui(parent.getContainerGui());
+                            functional.performAutoCraft(parent.getContainerGui(), middleDisplay);
+                        }
+                        
+                        @Override
+                        public void draw(int mouseX, int mouseY, float partialTicks) {
+                            super.draw(mouseX, mouseY, partialTicks);
+                            if (getBounds().contains(mouseX, mouseY))
+                                if (enabled)
+                                    GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.move_items"))));
+                                else
+                                    GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), Arrays.asList(I18n.translate("text.speed_craft.failed_move_items"))));
+                        }
+                    });
+                    btn.enabled = functional != null && functional.acceptRecipe(parent.getContainerGui(), middleDisplay);
+                }
             }
         }
         

+ 38 - 138
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -1,25 +1,18 @@
 package me.shedaniel.rei.plugin;
 
 import com.google.common.collect.Lists;
-import me.shedaniel.rei.api.IRecipeCategoryCraftable;
+import me.shedaniel.rei.api.IRecipeDisplay;
 import me.shedaniel.rei.api.IRecipePlugin;
-import me.shedaniel.rei.client.ClientHelper;
-import me.shedaniel.rei.client.GuiHelper;
+import me.shedaniel.rei.api.SpeedCraftFunctional;
 import me.shedaniel.rei.client.RecipeHelper;
-import me.shedaniel.rei.gui.widget.ButtonWidget;
-import me.shedaniel.rei.gui.widget.IWidget;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
-import me.shedaniel.rei.listeners.IMixinContainerGui;
 import me.shedaniel.rei.listeners.IMixinRecipeBookGui;
 import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.ContainerGui;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.container.BlastFurnaceGui;
 import net.minecraft.client.gui.container.CraftingTableGui;
 import net.minecraft.client.gui.container.FurnaceGui;
 import net.minecraft.client.gui.container.SmokerGui;
 import net.minecraft.client.gui.ingame.PlayerInventoryGui;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.crafting.ShapedRecipe;
 import net.minecraft.recipe.crafting.ShapelessRecipe;
@@ -29,7 +22,6 @@ import net.minecraft.recipe.smelting.SmokingRecipe;
 import net.minecraft.util.Identifier;
 
 import java.awt.*;
-import java.util.Arrays;
 import java.util.List;
 
 public class DefaultPlugin implements IRecipePlugin {
@@ -72,11 +64,12 @@ public class DefaultPlugin implements IRecipePlugin {
     }
     
     @Override
-    public void registerAutoCraftingGui() {
-        RecipeHelper.registerCategoryCraftable(new Class[]{DefaultShapelessDisplay.class, DefaultShapedDisplay.class}, new IRecipeCategoryCraftable<DefaultCraftingDisplay>() {
+    public void registerSpeedCraft() {
+        RecipeHelper.registerSpeedCraftButtonArea(DefaultPlugin.BREWING, null);
+        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.CRAFTING, new SpeedCraftFunctional<DefaultCraftingDisplay>() {
             @Override
-            public boolean canAutoCraftHere(Class<? extends Gui> guiClass, DefaultCraftingDisplay recipe) {
-                return guiClass.isAssignableFrom(CraftingTableGui.class) || (guiClass.isAssignableFrom(PlayerInventoryGui.class) && recipe.getHeight() < 3 && recipe.getWidth() < 3);
+            public Class[] getFunctioningFor() {
+                return new Class[]{PlayerInventoryGui.class, CraftingTableGui.class};
             }
             
             @Override
@@ -91,168 +84,75 @@ public class DefaultPlugin implements IRecipePlugin {
             }
             
             @Override
-            public void registerAutoCraftButton(List<IWidget> widgets, Rectangle rectangle, IMixinContainerGui parentGui, DefaultCraftingDisplay recipe) {
-                Point startPoint = new Point((int) rectangle.getCenterX() - 58, (int) rectangle.getCenterY() - 27);
-                ButtonWidget widget;
-                widgets.add(widget = new ButtonWidget(rectangle.x + 134, startPoint.y + 45, 10, 10, "+") {
-                    @Override
-                    public void onPressed(int button, double mouseX, double mouseY) {
-                        MinecraftClient.getInstance().openGui(parentGui.getContainerGui());
-                        if (canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe))
-                            performAutoCraft(parentGui.getContainerGui(), recipe);
-                    }
-                    
-                    @Override
-                    public void draw(int mouseX, int mouseY, float partialTicks) {
-                        super.draw(mouseX, mouseY, partialTicks);
-                        List<String> tooltips = getToolTip(parentGui.getContainerGui(), recipe);
-                        if (tooltips.size() > 0 && getBounds().contains(mouseX, mouseY))
-                            GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), tooltips));
-                    }
-                });
-                widget.enabled = canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe);
-            }
-            
-            private List<String> getToolTip(ContainerGui parentGui, DefaultCraftingDisplay recipe) {
-                if (!(parentGui instanceof CraftingTableGui || parentGui instanceof PlayerInventoryGui))
-                    return Arrays.asList(I18n.translate("text.auto_craft.wrong_gui"));
-                if (parentGui instanceof PlayerInventoryGui && !(recipe.getHeight() < 3 && recipe.getWidth() < 3))
-                    return Arrays.asList(I18n.translate("text.auto_craft.crafting.too_small"));
-                return Lists.newArrayList();
+            public boolean acceptRecipe(Gui gui, DefaultCraftingDisplay recipe) {
+                return gui instanceof CraftingTableGui || (gui instanceof PlayerInventoryGui && recipe.getHeight() < 3 && recipe.getWidth() < 3);
             }
         });
-        RecipeHelper.registerCategoryCraftable(DefaultSmeltingDisplay.class, new IRecipeCategoryCraftable<DefaultSmeltingDisplay>() {
+        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.SMELTING, new SpeedCraftFunctional<DefaultSmeltingDisplay>() {
             @Override
-            public boolean canAutoCraftHere(Class<? extends Gui> guiClass, DefaultSmeltingDisplay recipe) {
-                return guiClass.isAssignableFrom(FurnaceGui.class);
+            public Class[] getFunctioningFor() {
+                return new Class[]{FurnaceGui.class};
             }
-            
+    
             @Override
             public boolean performAutoCraft(Gui gui, DefaultSmeltingDisplay recipe) {
-                if (gui.getClass().isAssignableFrom(FurnaceGui.class))
+                if (gui instanceof FurnaceGui)
                     ((IMixinRecipeBookGui) (((FurnaceGui) gui).getRecipeBookGui())).getGhostSlots().reset();
                 else return false;
                 MinecraftClient.getInstance().interactionManager.clickRecipe(MinecraftClient.getInstance().player.container.syncId, recipe.getRecipe(), Gui.isShiftPressed());
                 return true;
             }
-            
+    
             @Override
-            public void registerAutoCraftButton(List<IWidget> widgets, Rectangle rectangle, IMixinContainerGui parentGui, DefaultSmeltingDisplay recipe) {
-                Point startPoint = new Point((int) rectangle.getCenterX() - 58, (int) rectangle.getCenterY() - 27);
-                ButtonWidget widget;
-                widgets.add(widget = new ButtonWidget(rectangle.x + 134, startPoint.y + 45, 10, 10, "+") {
-                    @Override
-                    public void onPressed(int button, double mouseX, double mouseY) {
-                        MinecraftClient.getInstance().openGui(parentGui.getContainerGui());
-                        if (canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe))
-                            performAutoCraft(parentGui.getContainerGui(), recipe);
-                    }
-                    
-                    @Override
-                    public void draw(int mouseX, int mouseY, float partialTicks) {
-                        super.draw(mouseX, mouseY, partialTicks);
-                        List<String> tooltips = getToolTip(parentGui.getContainerGui(), recipe);
-                        if (tooltips.size() > 0 && getBounds().contains(mouseX, mouseY))
-                            GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), tooltips));
-                    }
-                });
-                widget.enabled = canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe);
-            }
-            
-            private List<String> getToolTip(ContainerGui parentGui, DefaultSmeltingDisplay recipe) {
-                if (!(parentGui instanceof FurnaceGui))
-                    return Arrays.asList(I18n.translate("text.auto_craft.wrong_gui"));
-                return Lists.newArrayList();
+            public boolean acceptRecipe(Gui gui, DefaultSmeltingDisplay recipe) {
+                return gui instanceof FurnaceGui;
             }
         });
-        RecipeHelper.registerCategoryCraftable(DefaultSmokingDisplay.class, new IRecipeCategoryCraftable<DefaultSmokingDisplay>() {
+        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.SMOKING, new SpeedCraftFunctional<DefaultSmokingDisplay>() {
             @Override
-            public boolean canAutoCraftHere(Class<? extends Gui> guiClass, DefaultSmokingDisplay recipe) {
-                return guiClass.isAssignableFrom(SmokerGui.class);
+            public Class[] getFunctioningFor() {
+                return new Class[]{SmokerGui.class};
             }
-            
+        
             @Override
             public boolean performAutoCraft(Gui gui, DefaultSmokingDisplay recipe) {
-                if (gui.getClass().isAssignableFrom(SmokerGui.class))
+                if (gui instanceof SmokerGui)
                     ((IMixinRecipeBookGui) (((SmokerGui) gui).getRecipeBookGui())).getGhostSlots().reset();
                 else return false;
                 MinecraftClient.getInstance().interactionManager.clickRecipe(MinecraftClient.getInstance().player.container.syncId, recipe.getRecipe(), Gui.isShiftPressed());
                 return true;
             }
-            
+        
             @Override
-            public void registerAutoCraftButton(List<IWidget> widgets, Rectangle rectangle, IMixinContainerGui parentGui, DefaultSmokingDisplay recipe) {
-                Point startPoint = new Point((int) rectangle.getCenterX() - 58, (int) rectangle.getCenterY() - 27);
-                ButtonWidget widget;
-                widgets.add(widget = new ButtonWidget(rectangle.x + 134, startPoint.y + 45, 10, 10, "+") {
-                    @Override
-                    public void onPressed(int button, double mouseX, double mouseY) {
-                        MinecraftClient.getInstance().openGui(parentGui.getContainerGui());
-                        if (canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe))
-                            performAutoCraft(parentGui.getContainerGui(), recipe);
-                    }
-                    
-                    @Override
-                    public void draw(int mouseX, int mouseY, float partialTicks) {
-                        super.draw(mouseX, mouseY, partialTicks);
-                        List<String> tooltips = getToolTip(parentGui.getContainerGui(), recipe);
-                        if (tooltips.size() > 0 && getBounds().contains(mouseX, mouseY))
-                            GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), tooltips));
-                    }
-                });
-                widget.enabled = canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe);
-            }
-            
-            private List<String> getToolTip(ContainerGui parentGui, DefaultSmokingDisplay recipe) {
-                if (!(parentGui instanceof SmokerGui))
-                    return Arrays.asList(I18n.translate("text.auto_craft.wrong_gui"));
-                return Lists.newArrayList();
+            public boolean acceptRecipe(Gui gui, DefaultSmokingDisplay recipe) {
+                return gui instanceof SmokerGui;
             }
         });
-        RecipeHelper.registerCategoryCraftable(DefaultBlastingDisplay.class, new IRecipeCategoryCraftable<DefaultBlastingDisplay>() {
+        RecipeHelper.registerSpeedCraftFunctional(DefaultPlugin.BLASTING, new SpeedCraftFunctional<DefaultBlastingDisplay>() {
             @Override
-            public boolean canAutoCraftHere(Class<? extends Gui> guiClass, DefaultBlastingDisplay recipe) {
-                return guiClass.isAssignableFrom(BlastFurnaceGui.class);
+            public Class[] getFunctioningFor() {
+                return new Class[]{BlastFurnaceGui.class};
             }
-            
+        
             @Override
             public boolean performAutoCraft(Gui gui, DefaultBlastingDisplay recipe) {
-                if (gui.getClass().isAssignableFrom(BlastFurnaceGui.class))
+                if (gui instanceof BlastFurnaceGui)
                     ((IMixinRecipeBookGui) (((BlastFurnaceGui) gui).getRecipeBookGui())).getGhostSlots().reset();
                 else return false;
                 MinecraftClient.getInstance().interactionManager.clickRecipe(MinecraftClient.getInstance().player.container.syncId, recipe.getRecipe(), Gui.isShiftPressed());
                 return true;
             }
-            
+        
             @Override
-            public void registerAutoCraftButton(List<IWidget> widgets, Rectangle rectangle, IMixinContainerGui parentGui, DefaultBlastingDisplay recipe) {
-                Point startPoint = new Point((int) rectangle.getCenterX() - 58, (int) rectangle.getCenterY() - 27);
-                ButtonWidget widget;
-                widgets.add(widget = new ButtonWidget(rectangle.x + 134, startPoint.y + 45, 10, 10, "+") {
-                    @Override
-                    public void onPressed(int button, double mouseX, double mouseY) {
-                        MinecraftClient.getInstance().openGui(parentGui.getContainerGui());
-                        if (canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe))
-                            performAutoCraft(parentGui.getContainerGui(), recipe);
-                    }
-                    
-                    @Override
-                    public void draw(int mouseX, int mouseY, float partialTicks) {
-                        super.draw(mouseX, mouseY, partialTicks);
-                        List<String> tooltips = getToolTip(parentGui.getContainerGui(), recipe);
-                        if (tooltips.size() > 0 && getBounds().contains(mouseX, mouseY))
-                            GuiHelper.getLastOverlay().addTooltip(new QueuedTooltip(ClientHelper.getMouseLocation(), tooltips));
-                    }
-                });
-                widget.enabled = canAutoCraftHere(parentGui.getContainerGui().getClass(), recipe);
-            }
-            
-            private List<String> getToolTip(ContainerGui parentGui, DefaultBlastingDisplay recipe) {
-                if (!(parentGui instanceof BlastFurnaceGui))
-                    return Arrays.asList(I18n.translate("text.auto_craft.wrong_gui"));
-                return Lists.newArrayList();
+            public boolean acceptRecipe(Gui gui, DefaultBlastingDisplay recipe) {
+                return gui instanceof BlastFurnaceGui;
             }
         });
     }
     
+    @Override
+    public int getPriority() {
+        return -1;
+    }
+    
 }

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

@@ -5,7 +5,6 @@
   "key.roughlyenoughitems.usage_keybind": "Show Uses",
   "text.rei.cheat": "Cheat",
   "text.rei.nocheat": "§4§mCheat",
-  "text.rei.mod": "§9§o%s",
   "category.rei.crafting": "Crafting",
   "category.rei.smelting": "Smelting",
   "category.rei.smelting.fuel": "§eFuel",
@@ -26,8 +25,8 @@
   "ordering.rei.registry": "Registry",
   "ordering.rei.name": "Name",
   "ordering.rei.item_groups": "Item Groups",
-  "text.auto_craft.wrong_gui": "§cCan't auto craft in this inventory!",
-  "text.auto_craft.crafting.too_small": "§cThis inventory is too small!",
+  "text.speed_craft.failed_move_items": "§cCan't move items!",
+  "text.speed_craft.move_items": "Move Items",
   "text.rei.enable_craftable_only": "Enable Craftable Only: ",
   "text.rei.showing_craftable": "Showing Craftable",
   "text.rei.showing_all": "Showing All",

+ 9 - 9
src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json

@@ -1,11 +1,10 @@
 {
   "key.rei.category": "Roughly Enough Items",
-  "key.rei.recipe": "显示配方",
-  "key.rei.hide": "隐藏/显示REI",
-  "key.rei.use": "显示用途",
+  "key.roughlyenoughitems.recipe_keybind": "显示配方",
+  "key.roughlyenoughitems.hide_keybind": "隐藏/显示 REI",
+  "key.roughlyenoughitems.usage_keybind": "显示用途",
   "text.rei.cheat": "作弊",
   "text.rei.nocheat": "§4§m作弊",
-  "text.rei.mod": "§9§o%s",
   "category.rei.crafting": "合成",
   "category.rei.smelting": "冶炼",
   "category.rei.smelting.fuel": "§e燃料",
@@ -16,9 +15,7 @@
   "category.rei.brewing.reactant": "§e材料",
   "category.rei.brewing.result": "§e输出药水",
   "text.rei.config": "设置",
-  "text.rei.listeningkey": "正聆听按键",
-  "text.rei.centre_searchbox": "置中搜索栏: %s%b",
-  "text.rei.centre_searchbox.tooltip": "更改此设置后请重启游戏以完成更改",
+  "text.rei.centre_searchbox": "右置搜索栏: ",
   "text.rei.list_ordering": "物品清单排序",
   "text.rei.list_ordering_button": "%s [%s]",
   "ordering.rei.ascending": "顺序",
@@ -26,6 +23,9 @@
   "ordering.rei.registry": "注册",
   "ordering.rei.name": "名字",
   "ordering.rei.item_groups": "物品分类",
-  "text.auto_craft.wrong_gui": "§c不能在此菜单中自动合成!",
-  "text.auto_craft.crafting.too_small": "§c合成格太小!"
+  "text.speed_craft.failed_move_items": "§c不能移动物品!",
+  "text.speed_craft.move_items": "移动物品",
+  "text.rei.showing_craftable": "显示可合成的物品",
+  "text.rei.showing_all": "显示所有物品",
+  "text.rei.delete_items": "§c删除物品"
 }

+ 9 - 9
src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json

@@ -1,11 +1,10 @@
 {
   "key.rei.category": "Roughly Enough Items",
-  "key.rei.recipe": "顯示配方",
-  "key.rei.hide": "隱藏/顯示REI",
-  "key.rei.use": "顯示用途",
+  "key.roughlyenoughitems.recipe_keybind": "顯示配方",
+  "key.roughlyenoughitems.hide_keybind": "隱藏/顯示 REI",
+  "key.roughlyenoughitems.usage_keybind": "顯示用途",
   "text.rei.cheat": "作弊",
   "text.rei.nocheat": "§4§m作弊",
-  "text.rei.mod": "§9§o%s",
   "category.rei.crafting": "合成",
   "category.rei.smelting": "冶煉",
   "category.rei.smelting.fuel": "§e燃料",
@@ -16,9 +15,7 @@
   "category.rei.brewing.reactant": "§e材料",
   "category.rei.brewing.result": "§e輸出藥水",
   "text.rei.config": "設置",
-  "text.rei.listeningkey": "正聆聽按鍵",
-  "text.rei.centre_searchbox": "置中搜索欄: %s%b",
-  "text.rei.centre_searchbox.tooltip": "更改此設置後請重啟遊戲以完成更改",
+  "text.rei.centre_searchbox": "右置搜索欄: ",
   "text.rei.list_ordering": "物品清單排序",
   "text.rei.list_ordering_button": "%s [%s]",
   "ordering.rei.ascending": "順序",
@@ -26,6 +23,9 @@
   "ordering.rei.registry": "註冊",
   "ordering.rei.name": "名字",
   "ordering.rei.item_groups": "物品分類",
-  "text.auto_craft.wrong_gui": "§c不能在此菜單中自動合成!",
-  "text.auto_craft.crafting.too_small": "§c合成格太小!"
+  "text.speed_craft.failed_move_items": "§c不能移動物品!",
+  "text.speed_craft.move_items": "移動物品",
+  "text.rei.showing_craftable": "顯示可合成的物品",
+  "text.rei.showing_all": "顯示所有物品",
+  "text.rei.delete_items": "§c刪除物品"
 }

+ 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.37",
+  "version": "2.0.0.38",
   "side": "client",
   "authors": [
     "Danielshe"