Browse Source

Stripping Recipes

Unknown 5 năm trước cách đây
mục cha
commit
a8afad705c

+ 69 - 67
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -44,7 +44,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 public class ContainerScreenOverlay extends AbstractParentElement implements Drawable {
-    
+
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
     public static String searchTerm = "";
@@ -56,15 +56,15 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
     private Window window;
     private CraftableToggleButtonWidget toggleButtonWidget;
     private ButtonWidget buttonLeft, buttonRight;
-    
+
     public static ItemListOverlay getItemListOverlay() {
         return itemListOverlay;
     }
-    
+
     public void init() {
         init(false);
     }
-    
+
     public void init(boolean setPage) {
         this.shouldReInit = false;
         //Update Variables
@@ -74,7 +74,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         this.rectangle = RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
         widgets.add(itemListOverlay = new ItemListOverlay(page));
         itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
-        
+
         widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.left_arrow")) {
             @Override
             public void onPressed() {
@@ -83,12 +83,12 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                     page = getTotalPage();
                 itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
-            
+
             @Override
             public Optional<String> getTooltips() {
                 return Optional.ofNullable(I18n.translate("text.rei.previous_page"));
             }
-            
+
             @Override
             public boolean changeFocus(boolean boolean_1) {
                 return false;
@@ -102,21 +102,21 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                     page = 0;
                 itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
-            
+
             @Override
             public Optional<String> getTooltips() {
                 return Optional.ofNullable(I18n.translate("text.rei.next_page"));
             }
-            
+
             @Override
             public boolean changeFocus(boolean boolean_1) {
                 return false;
             }
         });
-        
+
         if (setPage)
             page = MathHelper.clamp(page, 0, getTotalPage());
-        
+
         widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? window.getScaledWidth() - 30 : 10, 10, 20, 20, "") {
             @Override
             public void onPressed() {
@@ -126,7 +126,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                 }
                 RoughlyEnoughItemsCore.getConfigManager().openConfigScreen(ScreenHelper.getLastContainerScreen());
             }
-            
+
             @Override
             public void render(int mouseX, int mouseY, float delta) {
                 super.render(mouseX, mouseY, delta);
@@ -141,7 +141,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                 GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
                 blit(getBounds().x + 3, getBounds().y + 3, 0, 0, 14, 14);
             }
-            
+
             @Override
             public Optional<String> getTooltips() {
                 String tooltips = I18n.translate("text.rei.config_tooltip");
@@ -156,7 +156,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                     tooltips += "\n" + I18n.translate("text.rei.cheating_limited_enabled");
                 return Optional.ofNullable(tooltips);
             }
-            
+
             @Override
             public boolean changeFocus(boolean boolean_1) {
                 return false;
@@ -168,31 +168,31 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                 public void onPressed() {
                     MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().gamemodeCommand.replaceAll("\\{gamemode}", getNextGameMode(Screen.hasShiftDown()).getName()));
                 }
-                
+
                 @Override
                 public void render(int mouseX, int mouseY, float delta) {
                     text = getGameModeShortText(getCurrentGameMode());
                     super.render(mouseX, mouseY, delta);
                 }
-                
+
                 @Override
                 public Optional<String> getTooltips() {
                     return Optional.ofNullable(I18n.translate("text.rei.gamemode_button.tooltip", getGameModeText(getNextGameMode(Screen.hasShiftDown()))));
                 }
-                
+
                 @Override
                 public boolean changeFocus(boolean boolean_1) {
                     return false;
                 }
             });
             int xxx = RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? window.getScaledWidth() - 30 : 10;
-            for(Weather weather : Weather.values()) {
+            for (Weather weather : Weather.values()) {
                 widgets.add(new ButtonWidget(xxx, 35, 20, 20, "") {
                     @Override
                     public void onPressed() {
                         MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().weatherCommand.replaceAll("\\{weather}", weather.name().toLowerCase(Locale.ROOT)));
                     }
-                    
+
                     @Override
                     public void render(int mouseX, int mouseY, float delta) {
                         super.render(mouseX, mouseY, delta);
@@ -201,12 +201,12 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                         GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
                         blit(getBounds().x + 3, getBounds().y + 3, weather.getId() * 14, 14, 14, 14);
                     }
-                    
+
                     @Override
                     public Optional<String> getTooltips() {
                         return Optional.ofNullable(I18n.translate("text.rei.weather_button.tooltip", I18n.translate(weather.getTranslateKey())));
                     }
-                    
+
                     @Override
                     public boolean changeFocus(boolean boolean_1) {
                         return false;
@@ -222,19 +222,19 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                 this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
                 super.render(mouseX, mouseY, delta);
             }
-            
+
             @Override
             public Optional<String> getTooltips() {
                 return Optional.ofNullable(I18n.translate("text.rei.go_back_first_page"));
             }
-            
+
             @Override
             public void onLabelClicked() {
                 MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
                 page = 0;
                 itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
             }
-            
+
             @Override
             public boolean changeFocus(boolean boolean_1) {
                 return false;
@@ -257,7 +257,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                     RoughlyEnoughItemsCore.getConfigManager().toggleCraftableOnly();
                     itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
                 }
-                
+
                 @Override
                 public void lateRender(int mouseX, int mouseY, float delta) {
                     blitOffset = 300;
@@ -268,7 +268,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             toggleButtonWidget = null;
         this.itemListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
     }
-    
+
     private Weather getNextWeather() {
         try {
             Weather current = getCurrentWeather();
@@ -280,7 +280,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             return Weather.CLEAR;
         }
     }
-    
+
     private Weather getCurrentWeather() {
         ClientWorld world = MinecraftClient.getInstance().world;
         if (world.isThundering())
@@ -289,15 +289,15 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             return Weather.RAIN;
         return Weather.CLEAR;
     }
-    
+
     private String getGameModeShortText(GameMode gameMode) {
         return I18n.translate("text.rei.short_gamemode." + gameMode.getName());
     }
-    
+
     private String getGameModeText(GameMode gameMode) {
         return I18n.translate("selectWorld.gameMode." + gameMode.getName());
     }
-    
+
     private GameMode getNextGameMode(boolean reverse) {
         try {
             GameMode current = getCurrentGameMode();
@@ -313,11 +313,11 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             return GameMode.NOT_SET;
         }
     }
-    
+
     private GameMode getCurrentGameMode() {
         return MinecraftClient.getInstance().getNetworkHandler().getPlayerListEntry(MinecraftClient.getInstance().player.getGameProfile().getId()).getGameMode();
     }
-    
+
     private Rectangle getTextFieldArea() {
         int widthRemoved = RoughlyEnoughItemsCore.getConfigManager().getConfig().enableCraftableOnlyButton ? 22 : 2;
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField)
@@ -332,22 +332,22 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         }
         return new Rectangle(ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft(), window.getScaledHeight() - 22, ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth() - widthRemoved, 18);
     }
-    
+
     private Rectangle getCraftableToggleArea() {
         Rectangle searchBoxArea = getTextFieldArea();
         searchBoxArea.setLocation(searchBoxArea.x + searchBoxArea.width + 4, searchBoxArea.y - 1);
         searchBoxArea.setSize(20, 20);
         return searchBoxArea;
     }
-    
+
     private String getCheatModeText() {
         return I18n.translate(String.format("%s%s", "text.rei.", ClientHelper.getInstance().isCheating() ? "cheat" : "nocheat"));
     }
-    
+
     public Rectangle getRectangle() {
         return rectangle;
     }
-    
+
     @Override
     public void render(int mouseX, int mouseY, float delta) {
         List<ItemStack> currentStacks = ClientHelper.getInstance().getInventoryItemsTypes();
@@ -365,7 +365,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             blitOffset = 200;
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
             int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
-            for(Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
+            for (Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
                 if (!slot.hasStack() || !itemListOverlay.filterItem(slot.getStack(), itemListOverlay.getLastSearchArgument()))
                     fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
             blitOffset = 0;
@@ -375,7 +375,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         this.renderWidgets(mouseX, mouseY, delta);
         if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
-            for(RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
+            for (RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(mouseX - hooks.rei_getContainerLeft(), mouseY - hooks.rei_getContainerTop())) {
                         String collect = Arrays.asList(area.getCategories()).stream().map(identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName()).collect(Collectors.joining(", "));
@@ -384,17 +384,19 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                     }
         }
     }
-    
+
     public void lateRender(int mouseX, int mouseY, float delta) {
-        ScreenHelper.searchField.laterRender(mouseX, mouseY, delta);
-        if (toggleButtonWidget != null)
-            toggleButtonWidget.lateRender(mouseX, mouseY, delta);
-        Screen currentScreen = MinecraftClient.getInstance().currentScreen;
-        if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
-            QUEUED_TOOLTIPS.stream().filter(Objects::nonNull).forEach(this::renderTooltip);
+        if (ScreenHelper.isOverlayVisible()) {
+            ScreenHelper.searchField.laterRender(mouseX, mouseY, delta);
+            if (toggleButtonWidget != null)
+                toggleButtonWidget.lateRender(mouseX, mouseY, delta);
+            Screen currentScreen = MinecraftClient.getInstance().currentScreen;
+            if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
+                QUEUED_TOOLTIPS.stream().filter(Objects::nonNull).forEach(this::renderTooltip);
+        }
         QUEUED_TOOLTIPS.clear();
     }
-    
+
     @SuppressWarnings("deprecation")
     public void renderTooltip(QueuedTooltip tooltip) {
         if (tooltip.getConsumer() == null)
@@ -402,7 +404,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         else
             tooltip.getConsumer().accept(tooltip);
     }
-    
+
     public void renderTooltip(List<String> lines, int mouseX, int mouseY) {
         if (lines.isEmpty())
             return;
@@ -424,7 +426,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             this.fillGradient(x - 3, y - 3, x + width + 3, y - 3 + 1, 1347420415, 1347420415);
             this.fillGradient(x - 3, y + height + 2, x + width + 3, y + height + 3, 1344798847, 1344798847);
             int currentY = y;
-            for(int lineIndex = 0; lineIndex < lines.size(); lineIndex++) {
+            for (int lineIndex = 0; lineIndex < lines.size(); lineIndex++) {
                 GlStateManager.disableDepthTest();
                 font.drawWithShadow(lines.get(lineIndex), x, currentY, -1);
                 GlStateManager.enableDepthTest();
@@ -436,18 +438,18 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             GlStateManager.enableRescaleNormal();
         }, width, height, 0);
     }
-    
+
     private boolean hasSameListContent(List<ItemStack> list1, List<ItemStack> list2) {
         list1.sort((itemStack, t1) -> ItemListOverlay.tryGetItemStackName(itemStack).compareToIgnoreCase(ItemListOverlay.tryGetItemStackName(t1)));
         list2.sort((itemStack, t1) -> ItemListOverlay.tryGetItemStackName(itemStack).compareToIgnoreCase(ItemListOverlay.tryGetItemStackName(t1)));
-        
+
         return list1.stream().map(ItemListOverlay::tryGetItemStackName).collect(Collectors.joining("")).equals(list2.stream().map(ItemListOverlay::tryGetItemStackName).collect(Collectors.joining("")));
     }
-    
+
     public void addTooltip(QueuedTooltip queuedTooltip) {
         QUEUED_TOOLTIPS.add(queuedTooltip);
     }
-    
+
     public void renderWidgets(int int_1, int int_2, float float_1) {
         if (!ScreenHelper.isOverlayVisible())
             return;
@@ -458,11 +460,11 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         });
         GuiLighting.disable();
     }
-    
+
     private int getTotalPage() {
         return itemListOverlay.getTotalPage();
     }
-    
+
     @Override
     public boolean mouseScrolled(double i, double j, double amount) {
         if (!ScreenHelper.isOverlayVisible())
@@ -476,16 +478,16 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                 return false;
             return true;
         }
-        for(Widget widget : widgets)
+        for (Widget widget : widgets)
             if (widget.mouseScrolled(i, j, amount))
                 return true;
         return false;
     }
-    
+
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (ScreenHelper.isOverlayVisible())
-            for(Element listener : widgets)
+            for (Element listener : widgets)
                 if (listener.keyPressed(int_1, int_2, int_3))
                     return true;
         if (ClientHelper.getInstance().getHideKeyBinding().matchesKey(int_1, int_2)) {
@@ -511,29 +513,29 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
         }
         return false;
     }
-    
+
     @Override
     public boolean charTyped(char char_1, int int_1) {
         if (!ScreenHelper.isOverlayVisible())
             return false;
-        for(Element listener : widgets)
+        for (Element listener : widgets)
             if (listener.charTyped(char_1, int_1))
                 return true;
         return false;
     }
-    
+
     @Override
     public List<? extends Element> children() {
         return widgets;
     }
-    
+
     @Override
     public boolean mouseClicked(double double_1, double double_2, int int_1) {
         if (!ScreenHelper.isOverlayVisible())
             return false;
         if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
-            for(RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
+            for (RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(double_1 - hooks.rei_getContainerLeft(), double_2 - hooks.rei_getContainerTop())) {
                         ClientHelper.getInstance().executeViewAllRecipesFromCategories(Arrays.asList(area.getCategories()));
@@ -541,7 +543,7 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
                         return true;
                     }
         }
-        for(Element element : widgets)
+        for (Element element : widgets)
             if (element.mouseClicked(double_1, double_2, int_1)) {
                 this.setFocused(element);
                 if (int_1 == 0)
@@ -550,20 +552,20 @@ public class ContainerScreenOverlay extends AbstractParentElement implements Dra
             }
         return false;
     }
-    
+
     public boolean isInside(double mouseX, double mouseY) {
         if (!rectangle.contains(mouseX, mouseY))
             return false;
-        for(DisplayHelper.DisplayBoundsHandler handler : RoughlyEnoughItemsCore.getDisplayHelper().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
+        for (DisplayHelper.DisplayBoundsHandler handler : RoughlyEnoughItemsCore.getDisplayHelper().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
             ActionResult in = handler.isInZone(!RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel, mouseX, mouseY);
             if (in != ActionResult.PASS)
                 return in == ActionResult.SUCCESS;
         }
         return true;
     }
-    
+
     public boolean isInside(Point point) {
         return isInside(point.getX(), point.getY());
     }
-    
+
 }

+ 0 - 2
src/main/java/me/shedaniel/rei/gui/widget/RecipeBaseWidget.java

@@ -25,8 +25,6 @@ public class RecipeBaseWidget extends WidgetWithBounds {
     
     public RecipeBaseWidget(Rectangle bounds) {
         this.bounds = bounds;
-        if (bounds.width < 8 || bounds.height < 8)
-            throw new IllegalArgumentException("Base too small, at least 8x8!");
     }
     
     public int getBlitOffset() {

+ 42 - 33
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -31,8 +31,10 @@ import me.shedaniel.rei.plugin.smoking.DefaultSmokingCategory;
 import me.shedaniel.rei.plugin.smoking.DefaultSmokingDisplay;
 import me.shedaniel.rei.plugin.stonecutting.DefaultStoneCuttingCategory;
 import me.shedaniel.rei.plugin.stonecutting.DefaultStoneCuttingDisplay;
+import me.shedaniel.rei.plugin.stripping.DefaultStrippingCategory;
+import me.shedaniel.rei.plugin.stripping.DefaultStrippingDisplay;
+import me.shedaniel.rei.plugin.stripping.DummyAxeItem;
 import net.fabricmc.loader.api.SemanticVersion;
-import net.fabricmc.loader.util.version.SemanticVersionImpl;
 import net.fabricmc.loader.util.version.VersionParsingException;
 import net.minecraft.block.ComposterBlock;
 import net.minecraft.client.MinecraftClient;
@@ -40,6 +42,7 @@ import net.minecraft.client.gui.screen.ingame.*;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.enchantment.Enchantment;
 import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.item.EnchantedBookItem;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
@@ -54,38 +57,39 @@ import java.util.List;
 import java.util.*;
 
 public class DefaultPlugin implements REIPluginV0 {
-    
+
     public static final Identifier CRAFTING = new Identifier("minecraft", "plugins/crafting");
     public static final Identifier SMELTING = new Identifier("minecraft", "plugins/smelting");
     public static final Identifier SMOKING = new Identifier("minecraft", "plugins/smoking");
     public static final Identifier BLASTING = new Identifier("minecraft", "plugins/blasting");
     public static final Identifier CAMPFIRE = new Identifier("minecraft", "plugins/campfire");
     public static final Identifier STONE_CUTTING = new Identifier("minecraft", "plugins/stone_cutting");
+    public static final Identifier STRIPPING = new Identifier("minecraft", "plugins/stripping");
     public static final Identifier BREWING = new Identifier("minecraft", "plugins/brewing");
     public static final Identifier PLUGIN = new Identifier("roughlyenoughitems", "default_plugin");
     public static final Identifier COMPOSTING = new Identifier("minecraft", "plugins/composting");
     private static final Identifier DISPLAY_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/display.png");
     private static final Identifier DISPLAY_TEXTURE_DARK = new Identifier("roughlyenoughitems", "textures/gui/display_dark.png");
     private static final List<DefaultBrewingDisplay> BREWING_DISPLAYS = Lists.newArrayList();
-    
+
     public static Identifier getDisplayTexture() {
         return ScreenHelper.isDarkModeEnabled() ? DISPLAY_TEXTURE_DARK : DISPLAY_TEXTURE;
     }
-    
+
     public static void registerBrewingDisplay(DefaultBrewingDisplay display) {
         BREWING_DISPLAYS.add(display);
     }
-    
+
     @Override
     public Identifier getPluginIdentifier() {
         return PLUGIN;
     }
-    
+
     @Override
     public SemanticVersion getMinimumVersion() throws VersionParsingException {
         return SemanticVersion.parse("2.10");
     }
-    
+
     @Override
     public void onFirstLoad(PluginDisabler pluginDisabler) {
         if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().loadDefaultPlugin) {
@@ -95,7 +99,7 @@ public class DefaultPlugin implements REIPluginV0 {
             pluginDisabler.disablePluginFunction(PLUGIN, PluginFunction.REGISTER_OTHERS);
         }
     }
-    
+
     @Override
     public void registerItems(ItemRegistry itemRegistry) {
         Registry.ITEM.stream().forEach(item -> {
@@ -103,11 +107,12 @@ public class DefaultPlugin implements REIPluginV0 {
             try {
                 itemRegistry.registerItemStack(itemRegistry.getAllStacksFromItem(item));
             } catch (Exception e) {
-                e.printStackTrace();
+                if (!(item instanceof EnchantedBookItem))
+                    e.printStackTrace();
             }
         });
         Registry.ENCHANTMENT.forEach(enchantment -> {
-            for(int i = enchantment.getMinimumLevel(); i <= enchantment.getMaximumLevel(); i++) {
+            for (int i = enchantment.getMinimumLevel(); i <= enchantment.getMaximumLevel(); i++) {
                 Map<Enchantment, Integer> map = new HashMap<>();
                 map.put(enchantment, i);
                 ItemStack itemStack = new ItemStack(Items.ENCHANTED_BOOK);
@@ -116,7 +121,7 @@ public class DefaultPlugin implements REIPluginV0 {
             }
         });
     }
-    
+
     @Override
     public void registerPluginCategories(RecipeHelper recipeHelper) {
         recipeHelper.registerCategory(new DefaultCraftingCategory());
@@ -127,8 +132,9 @@ public class DefaultPlugin implements REIPluginV0 {
         recipeHelper.registerCategory(new DefaultStoneCuttingCategory());
         recipeHelper.registerCategory(new DefaultBrewingCategory());
         recipeHelper.registerCategory(new DefaultCompostingCategory());
+        recipeHelper.registerCategory(new DefaultStrippingCategory());
     }
-    
+
     @Override
     public void registerRecipeDisplays(RecipeHelper recipeHelper) {
         recipeHelper.registerRecipes(CRAFTING, ShapelessRecipe.class, DefaultShapelessDisplay::new);
@@ -142,10 +148,10 @@ public class DefaultPlugin implements REIPluginV0 {
         List<ItemStack> arrowStack = Collections.singletonList(Items.ARROW.getStackForRender());
         RoughlyEnoughItemsCore.getItemRegisterer().getItemList().stream().filter(stack -> stack.getItem().equals(Items.LINGERING_POTION)).forEach(stack -> {
             List<List<ItemStack>> input = new ArrayList<>();
-            for(int i = 0; i < 4; i++)
+            for (int i = 0; i < 4; i++)
                 input.add(arrowStack);
             input.add(Collections.singletonList(stack));
-            for(int i = 0; i < 4; i++)
+            for (int i = 0; i < 4; i++)
                 input.add(arrowStack);
             ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8);
             PotionUtil.setPotion(outputStack, PotionUtil.getPotion(stack));
@@ -165,15 +171,18 @@ public class DefaultPlugin implements REIPluginV0 {
         stacks.sort((first, second) -> {
             return (int) ((map.get(first) - map.get(second)) * 100);
         });
-        for(int i = 0; i < stacks.size(); i += MathHelper.clamp(48, 1, stacks.size() - i)) {
+        for (int i = 0; i < stacks.size(); i += MathHelper.clamp(48, 1, stacks.size() - i)) {
             List<ItemConvertible> thisStacks = Lists.newArrayList();
-            for(int j = i; j < i + 48; j++)
+            for (int j = i; j < i + 48; j++)
                 if (j < stacks.size())
                     thisStacks.add(stacks.get(j));
             recipeHelper.registerDisplay(COMPOSTING, new DefaultCompostingDisplay(MathHelper.floor(i / 48f), thisStacks, map, Lists.newArrayList(map.keySet()), new ItemStack[]{new ItemStack(Items.BONE_MEAL)}));
         }
+        DummyAxeItem.getStrippedBlocksMap().entrySet().stream().sorted(Comparator.comparing(b -> Registry.BLOCK.getId(b.getKey()))).forEach(set -> {
+            recipeHelper.registerDisplay(STRIPPING, new DefaultStrippingDisplay(new ItemStack(set.getKey()), new ItemStack(set.getValue())));
+        });
     }
-    
+
     @Override
     public void registerBounds(DisplayHelper displayHelper) {
         displayHelper.getBaseBoundsHandler().registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
@@ -183,18 +192,18 @@ public class DefaultPlugin implements REIPluginV0 {
             public Class<?> getBaseSupportedClass() {
                 return AbstractContainerScreen.class;
             }
-            
+
             @Override
             public Rectangle getLeftBounds(AbstractContainerScreen<?> screen) {
                 return new Rectangle(2, 0, ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() - 4, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public Rectangle getRightBounds(AbstractContainerScreen<?> screen) {
                 int startX = ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() + ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth() + 2;
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public float getPriority() {
                 return -1.0f;
@@ -205,18 +214,18 @@ public class DefaultPlugin implements REIPluginV0 {
             public Class<?> getBaseSupportedClass() {
                 return RecipeViewingScreen.class;
             }
-            
+
             @Override
             public Rectangle getLeftBounds(RecipeViewingScreen screen) {
                 return new Rectangle(2, 0, ((RecipeViewingScreen) screen).getBounds().x - 4, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public Rectangle getRightBounds(RecipeViewingScreen screen) {
                 int startX = ((RecipeViewingScreen) screen).getBounds().x + ((RecipeViewingScreen) screen).getBounds().width + 2;
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public float getPriority() {
                 return -1.0f;
@@ -227,18 +236,18 @@ public class DefaultPlugin implements REIPluginV0 {
             public Class<?> getBaseSupportedClass() {
                 return VillagerRecipeViewingScreen.class;
             }
-            
+
             @Override
             public Rectangle getLeftBounds(VillagerRecipeViewingScreen screen) {
                 return new Rectangle(2, 0, ((VillagerRecipeViewingScreen) screen).bounds.x - 4, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public Rectangle getRightBounds(VillagerRecipeViewingScreen screen) {
                 int startX = ((VillagerRecipeViewingScreen) screen).bounds.x + ((VillagerRecipeViewingScreen) screen).bounds.width + 2;
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public float getPriority() {
                 return -1.0f;
@@ -249,30 +258,30 @@ public class DefaultPlugin implements REIPluginV0 {
             public Class<?> getBaseSupportedClass() {
                 return CreativeInventoryScreen.class;
             }
-            
+
             @Override
             public Rectangle getLeftBounds(CreativeInventoryScreen screen) {
                 return new Rectangle(2, 0, ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() - 2, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public Rectangle getRightBounds(CreativeInventoryScreen screen) {
                 int startX = ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() + ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth();
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
             }
-            
+
             @Override
             public Rectangle getItemListArea(Rectangle rectangle) {
                 return new Rectangle(rectangle.x + 1, rectangle.y + 24, rectangle.width - 2, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField ? 27 + 22 : 27));
             }
-            
+
             @Override
             public float getPriority() {
                 return -0.9f;
             }
         });
     }
-    
+
     @Override
     public void registerOthers(RecipeHelper recipeHelper) {
         recipeHelper.registerWorkingStations(CRAFTING, new ItemStack(Items.CRAFTING_TABLE));
@@ -292,10 +301,10 @@ public class DefaultPlugin implements REIPluginV0 {
         recipeHelper.registerScreenClickArea(new Rectangle(78, 32, 28, 23), SmokerScreen.class, SMOKING);
         recipeHelper.registerScreenClickArea(new Rectangle(78, 32, 28, 23), BlastFurnaceScreen.class, BLASTING);
     }
-    
+
     @Override
     public int getPriority() {
         return -1;
     }
-    
+
 }

+ 69 - 0
src/main/java/me/shedaniel/rei/plugin/stripping/DefaultStrippingCategory.java

@@ -0,0 +1,69 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.stripping;
+
+import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.RecipeCategory;
+import me.shedaniel.rei.api.Renderer;
+import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
+import me.shedaniel.rei.gui.widget.SlotWidget;
+import me.shedaniel.rei.gui.widget.Widget;
+import me.shedaniel.rei.plugin.DefaultPlugin;
+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.item.Items;
+import net.minecraft.util.Identifier;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Supplier;
+
+public class DefaultStrippingCategory implements RecipeCategory<DefaultStrippingDisplay> {
+    
+    @Override
+    public Identifier getIdentifier() {
+        return DefaultPlugin.STRIPPING;
+    }
+    
+    @Override
+    public Renderer getIcon() {
+        return Renderer.fromItemStack(new ItemStack(Items.IRON_AXE));
+    }
+    
+    @Override
+    public String getCategoryName() {
+        return I18n.translate("category.rei.stripping");
+    }
+    
+    @Override
+    public List<Widget> setupDisplay(Supplier<DefaultStrippingDisplay> recipeDisplaySupplier, Rectangle bounds) {
+        Point startPoint = new Point((int) bounds.getCenterX() - 41, (int) bounds.getCenterY() - 13);
+        List<Widget> widgets = new LinkedList<>(Arrays.asList(new RecipeBaseWidget(bounds) {
+            @Override
+            public void render(int mouseX, int mouseY, float delta) {
+                super.render(mouseX, mouseY, delta);
+                GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+                GuiLighting.disable();
+                MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
+                blit(startPoint.x, startPoint.y, 0, 221, 82, 26);
+            }
+        }));
+        widgets.add(new SlotWidget(startPoint.x + 4, startPoint.y + 5, recipeDisplaySupplier.get().getInput().get(0), true, true, true));
+        widgets.add(new SlotWidget(startPoint.x + 61, startPoint.y + 5, recipeDisplaySupplier.get().getOutput(), false, true, true));
+        return widgets;
+    }
+    
+    @Override
+    public int getDisplayHeight() {
+        return 36;
+    }
+    
+}

+ 53 - 0
src/main/java/me/shedaniel/rei/plugin/stripping/DefaultStrippingDisplay.java

@@ -0,0 +1,53 @@
+/*
+ * Roughly Enough Items by Danielshe.
+ * Licensed under the MIT License.
+ */
+
+package me.shedaniel.rei.plugin.stripping;
+
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.plugin.DefaultPlugin;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+
+import java.util.Collections;
+import java.util.List;
+
+public class DefaultStrippingDisplay implements RecipeDisplay {
+
+    private ItemStack in, out;
+
+    public DefaultStrippingDisplay(ItemStack in, ItemStack out) {
+        this.in = in;
+        this.out = out;
+    }
+
+    public final ItemStack getIn() {
+        return in;
+    }
+
+    public final ItemStack getOut() {
+        return out;
+    }
+
+    @Override
+    public List<List<ItemStack>> getInput() {
+        return Collections.singletonList(Collections.singletonList(in));
+    }
+
+    @Override
+    public List<ItemStack> getOutput() {
+        return Collections.singletonList(out);
+    }
+
+    @Override
+    public Identifier getRecipeCategory() {
+        return DefaultPlugin.STRIPPING;
+    }
+
+    @Override
+    public List<List<ItemStack>> getRequiredItems() {
+        return getInput();
+    }
+
+}

+ 17 - 0
src/main/java/me/shedaniel/rei/plugin/stripping/DummyAxeItem.java

@@ -0,0 +1,17 @@
+package me.shedaniel.rei.plugin.stripping;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.AxeItem;
+import net.minecraft.item.ToolMaterial;
+
+import java.util.Map;
+
+public class DummyAxeItem extends AxeItem {
+    protected DummyAxeItem(ToolMaterial toolMaterial_1, float float_1, float float_2, Settings item$Settings_1) {
+        super(toolMaterial_1, float_1, float_2, item$Settings_1);
+    }
+
+    public static Map<Block, Block> getStrippedBlocksMap() {
+        return STRIPPED_BLOCKS;
+    }
+}

+ 1 - 0
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -28,6 +28,7 @@
   "category.rei.brewing.reactant": "Ingredient",
   "category.rei.brewing.result": "Resulted Potion",
   "category.rei.composting": "Composting",
+  "category.rei.stripping": "Stripping",
   "text.rei.composting.chance": "§e%d%% Chance",
   "text.rei.composting.page": "Page %d",
   "text.rei.config": "Config",