From 5c91a6654e697fdadde79508f3ef994936e4b952 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 17 Aug 2019 17:05:59 +0800 Subject: Finishing the auto crafting API --- .../shedaniel/rei/RoughlyEnoughItemsNetwork.java | 75 ++++++------- .../me/shedaniel/rei/api/AutoTransferHandler.java | 25 ++++- .../shedaniel/rei/api/TransferRecipeDisplay.java | 17 +++ .../shedaniel/rei/gui/ContainerScreenOverlay.java | 10 +- .../me/shedaniel/rei/gui/RecipeViewingScreen.java | 5 +- .../rei/gui/VillagerRecipeViewingScreen.java | 7 +- .../rei/gui/widget/AutoCraftingButtonWidget.java | 77 ++++++++++++-- .../shedaniel/rei/gui/widget/EntryListWidget.java | 4 +- .../rei/plugin/DefaultAutoCraftingPlugin.java | 14 +-- .../rei/plugin/DefaultServerContainerPlugin.java | 17 +++ .../plugin/autocrafting/AutoCraftingHandler.java | 116 --------------------- .../autocrafting/DefaultCategoryHandler.java | 116 +++++++++++++++++++++ .../plugin/blasting/DefaultBlastingDisplay.java | 19 +++- .../containers/CraftingContainerInfoWrapper.java | 50 +++++++++ .../plugin/crafting/DefaultCraftingDisplay.java | 27 ++++- .../plugin/smelting/DefaultSmeltingDisplay.java | 21 +++- .../rei/plugin/smoking/DefaultSmokingDisplay.java | 20 +++- .../me/shedaniel/rei/server/ContainerInfo.java | 17 +++ .../shedaniel/rei/server/ContainerInfoHandler.java | 25 +++++ .../me/shedaniel/rei/server/InputSlotCrafter.java | 45 ++++---- 20 files changed, 491 insertions(+), 216 deletions(-) create mode 100644 src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java create mode 100644 src/main/java/me/shedaniel/rei/plugin/DefaultServerContainerPlugin.java delete mode 100644 src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingHandler.java create mode 100644 src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java create mode 100644 src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java create mode 100644 src/main/java/me/shedaniel/rei/server/ContainerInfo.java create mode 100644 src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java (limited to 'src/main/java') diff --git a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java index c25a82439..8fd0f5030 100644 --- a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java +++ b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java @@ -11,6 +11,8 @@ import io.netty.buffer.Unpooled; import me.shedaniel.rei.server.InputSlotCrafter; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.container.Container; import net.minecraft.container.CraftingContainer; import net.minecraft.container.PlayerContainer; import net.minecraft.item.ItemStack; @@ -23,7 +25,6 @@ import net.minecraft.util.PacketByteBuf; import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.UUID; public class RoughlyEnoughItemsNetwork implements ModInitializer { @@ -32,7 +33,7 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer { public static final Identifier CREATE_ITEMS_MESSAGE_PACKET = new Identifier("roughlyenoughitems", "ci_msg"); public static final Identifier MOVE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "move_items"); public static final Identifier NOT_ENOUGH_ITEMS_PACKET = new Identifier("roughlyenoughitems", "og_not_enough"); - public static final UUID CRAFTING_TABLE_MOVE = UUID.fromString("190c2b2d-d1f6-4149-a4a8-62860189403e"); + // public static final UUID CRAFTING_TABLE_MOVE = UUID.fromString("190c2b2d-d1f6-4149-a4a8-62860189403e"); @Override public void onInitialize() { @@ -58,49 +59,53 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer { player.addChatMessage(new TranslatableText("text.rei.failed_cheat_items"), false); }); ServerSidePacketRegistry.INSTANCE.register(MOVE_ITEMS_PACKET, (packetContext, packetByteBuf) -> { - UUID type = packetByteBuf.readUuid(); + // UUID type = packetByteBuf.readUuid(); + Identifier category = packetByteBuf.readIdentifier(); ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer(); - CraftingContainer container = (CraftingContainer) player.container; + Container container = player.container; PlayerContainer playerContainer = player.playerContainer; - if (type.equals(CRAFTING_TABLE_MOVE)) { - try { - boolean shift = packetByteBuf.readBoolean(); - Map> input = Maps.newHashMap(); - int mapSize = packetByteBuf.readInt(); - for (int i = 0; i < mapSize; i++) { - List list = Lists.newArrayList(); - int count = packetByteBuf.readInt(); - for (int j = 0; j < count; j++) { - list.add(packetByteBuf.readItemStack()); - } - input.put(i, list); + // if (type.equals(CRAFTING_TABLE_MOVE)) { + try { + boolean shift = packetByteBuf.readBoolean(); + Map> input = Maps.newHashMap(); + int mapSize = packetByteBuf.readInt(); + for (int i = 0; i < mapSize; i++) { + List list = Lists.newArrayList(); + int count = packetByteBuf.readInt(); + for (int j = 0; j < count; j++) { + list.add(packetByteBuf.readItemStack()); } - try { - InputSlotCrafter.start(container, player, input, shift); - } catch (NullPointerException e) { - PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); - buf.writeInt(input.size()); - input.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> { - List stacks = entry.getValue(); - buf.writeInt(stacks.size()); - for (ItemStack stack : stacks) { - buf.writeItemStack(stack); - } - }); - if (ServerSidePacketRegistry.INSTANCE.canPlayerReceive(player, NOT_ENOUGH_ITEMS_PACKET)) { - ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, NOT_ENOUGH_ITEMS_PACKET, buf); + input.put(i, list); + } + try { + InputSlotCrafter.start(category, container, player, input, shift); + } catch (NullPointerException e) { + if (!(container instanceof CraftingContainer)) + return; + PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); + buf.writeInt(input.size()); + input.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> { + List stacks = entry.getValue(); + buf.writeInt(stacks.size()); + for (ItemStack stack : stacks) { + buf.writeItemStack(stack); } - } catch (IllegalStateException e) { - player.sendMessage(new TranslatableText(e.getMessage()).formatted(Formatting.RED)); - } catch (Exception e) { - player.sendMessage(new TranslatableText("error.rei.internal.error",e.getMessage()).formatted(Formatting.RED)); - e.printStackTrace(); + }); + if (ServerSidePacketRegistry.INSTANCE.canPlayerReceive(player, NOT_ENOUGH_ITEMS_PACKET)) { + ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, NOT_ENOUGH_ITEMS_PACKET, buf); } + } catch (IllegalStateException e) { + player.sendMessage(new TranslatableText(e.getMessage()).formatted(Formatting.RED)); } catch (Exception e) { + player.sendMessage(new TranslatableText("error.rei.internal.error", e.getMessage()).formatted(Formatting.RED)); e.printStackTrace(); } + } catch (Exception e) { + e.printStackTrace(); } + // } }); + FabricLoader.getInstance().getEntrypoints("rei_containers", Runnable.class).forEach(Runnable::run); } } diff --git a/src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java b/src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java index c0eaa26e6..44bc4f8d2 100644 --- a/src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java +++ b/src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java @@ -7,8 +7,8 @@ package me.shedaniel.rei.api; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import me.shedaniel.rei.impl.ScreenHelper; import me.shedaniel.rei.gui.ContainerScreenOverlay; +import me.shedaniel.rei.impl.ScreenHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; import net.minecraft.container.Container; @@ -33,13 +33,23 @@ public interface AutoTransferHandler { } static Result createFailed(String errorKey) { - return new ResultImpl(errorKey, new IntArrayList()); + return new ResultImpl(errorKey, new IntArrayList(), 1744764928); + } + + static Result createFailedCustomButtonColor(String errorKey, int color) { + return new ResultImpl(errorKey, new IntArrayList(), color); } static Result createFailed(String errorKey, IntList redSlots) { - return new ResultImpl(errorKey, redSlots); + return new ResultImpl(errorKey, redSlots, 1744764928); + } + + static Result createFailedCustomButtonColor(String errorKey, IntList redSlots, int color) { + return new ResultImpl(errorKey, redSlots, color); } + int getColor(); + boolean isSuccessful(); boolean isApplicable(); @@ -75,6 +85,7 @@ public interface AutoTransferHandler { private boolean successful, applicable; private String errorKey; private IntList integers = new IntArrayList(); + private int color; private ResultImpl() { this.successful = true; @@ -86,12 +97,18 @@ public interface AutoTransferHandler { this.applicable = applicable; } - public ResultImpl(String errorKey, IntList integers) { + public ResultImpl(String errorKey, IntList integers, int color) { this.successful = false; this.applicable = true; this.errorKey = errorKey; if (integers != null) this.integers = integers; + this.color = color; + } + + @Override + public int getColor() { + return color; } @Override diff --git a/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java b/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java new file mode 100644 index 000000000..becd280f8 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java @@ -0,0 +1,17 @@ +package me.shedaniel.rei.api; + +import me.shedaniel.rei.server.ContainerInfo; +import net.minecraft.container.Container; +import net.minecraft.item.ItemStack; + +import java.util.List; + +public interface TransferRecipeDisplay extends RecipeDisplay { + + int getWidth(); + + int getHeight(); + + List> getOrganisedInput(ContainerInfo containerInfo, Container container); + +} diff --git a/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java b/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java index cf302aa9e..2401083dd 100644 --- a/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java +++ b/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java @@ -8,7 +8,6 @@ package me.shedaniel.rei.gui; import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.GlStateManager; import me.shedaniel.cloth.api.ClientUtils; -import me.shedaniel.clothconfig2.api.MouseUtils; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.ClientHelper; import me.shedaniel.rei.api.DisplayHelper; @@ -500,7 +499,7 @@ public class ContainerScreenOverlay extends Widget { @Override public boolean keyPressed(int int_1, int int_2, int int_3) { - if (ScreenHelper.isOverlayVisible() && isInside(MouseUtils.getMouseLocation())) + if (ScreenHelper.isOverlayVisible()) for (Element listener : widgets) if (listener.keyPressed(int_1, int_2, int_3)) return true; @@ -532,10 +531,9 @@ public class ContainerScreenOverlay extends Widget { public boolean charTyped(char char_1, int int_1) { if (!ScreenHelper.isOverlayVisible()) return false; - if (isInside(MouseUtils.getMouseLocation())) - for (Element listener : widgets) - if (listener.charTyped(char_1, int_1)) - return true; + for (Element listener : widgets) + if (listener.charTyped(char_1, int_1)) + return true; return false; } diff --git a/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java b/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java index 0282ca50e..7d980c9d4 100644 --- a/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java @@ -278,9 +278,10 @@ public class RecipeViewingScreen extends Screen { final Supplier displaySupplier = () -> currentDisplayed.get(finalI); int displayWidth = selectedCategory.getDisplayWidth(displaySupplier.get()); final Rectangle displayBounds = new Rectangle((int) getBounds().getCenterX() - displayWidth / 2, getBounds().y + 40 + recipeHeight * i + 7 * i, displayWidth, recipeHeight); - widgets.addAll(selectedCategory.setupDisplay(displaySupplier, displayBounds)); + List setupDisplay = selectedCategory.setupDisplay(displaySupplier, displayBounds); + this.widgets.addAll(setupDisplay); if (supplier.isPresent() && supplier.get().get(displayBounds) != null) - widgets.add(new AutoCraftingButtonWidget(supplier.get().get(displayBounds), supplier.get().getButtonText(), displaySupplier)); + this.widgets.add(new AutoCraftingButtonWidget(supplier.get().get(displayBounds), supplier.get().getButtonText(), displaySupplier, setupDisplay)); } if (choosePageActivated) recipeChoosePageWidget = new RecipeChoosePageWidget(this, page, getTotalPages(selectedCategory)); diff --git a/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java b/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java index 6a4cfe2e9..3485e56d8 100644 --- a/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java @@ -12,9 +12,9 @@ import com.zeitheron.hammercore.client.utils.Scissors; import me.shedaniel.cloth.api.ClientUtils; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.*; -import me.shedaniel.rei.impl.ScreenHelper; import me.shedaniel.rei.gui.renderers.RecipeRenderer; import me.shedaniel.rei.gui.widget.*; +import me.shedaniel.rei.impl.ScreenHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.Screen; @@ -128,10 +128,11 @@ public class VillagerRecipeViewingScreen extends Screen { this.widgets.add(new SlotBaseWidget(scrollListBounds)); Rectangle recipeBounds = new Rectangle(bounds.x + 100 + (guiWidth - 100) / 2 - category.getDisplayWidth(display) / 2, bounds.y + bounds.height / 2 - category.getDisplayHeight() / 2, category.getDisplayWidth(display), category.getDisplayHeight()); - this.widgets.addAll(category.setupDisplay(() -> display, recipeBounds)); + List setupDisplay = category.setupDisplay(() -> display, recipeBounds); + this.widgets.addAll(setupDisplay); Optional supplier = RecipeHelper.getInstance().getSpeedCraftButtonArea(category); if (supplier.isPresent() && supplier.get().get(recipeBounds) != null) - this.widgets.add(new AutoCraftingButtonWidget(supplier.get().get(recipeBounds), supplier.get().getButtonText(), () -> display)); + this.widgets.add(new AutoCraftingButtonWidget(supplier.get().get(recipeBounds), supplier.get().getButtonText(), () -> display, setupDisplay)); int index = 0; for (RecipeDisplay recipeDisplay : categoryMap.get(category)) { diff --git a/src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java index 5006dedda..adcaacd8b 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java @@ -5,6 +5,7 @@ package me.shedaniel.rei.gui.widget; +import com.mojang.blaze3d.platform.GlStateManager; import me.shedaniel.rei.api.AutoTransferHandler; import me.shedaniel.rei.api.RecipeDisplay; import me.shedaniel.rei.api.RecipeHelper; @@ -13,8 +14,10 @@ import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen; import net.minecraft.client.resource.language.I18n; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; import java.awt.*; +import java.util.List; import java.util.Optional; import java.util.function.Supplier; @@ -23,14 +26,17 @@ public class AutoCraftingButtonWidget extends ButtonWidget { private final Supplier displaySupplier; private String extraTooltip; private String errorTooltip; + private List setupDisplay; private AbstractContainerScreen containerScreen; + private boolean visible = false; - public AutoCraftingButtonWidget(Rectangle rectangle, String text, Supplier displaySupplier) { + public AutoCraftingButtonWidget(Rectangle rectangle, String text, Supplier displaySupplier, List setupDisplay) { super(rectangle, text); this.displaySupplier = () -> displaySupplier.get(); Optional recipe = displaySupplier.get().getRecipeLocation(); extraTooltip = recipe.isPresent() ? I18n.translate("text.rei.recipe_id", Formatting.GRAY.toString(), recipe.get().toString()) : ""; this.containerScreen = ScreenHelper.getLastContainerScreen(); + this.setupDisplay = setupDisplay; } @Override @@ -52,19 +58,72 @@ public class AutoCraftingButtonWidget extends ButtonWidget { public void render(int mouseX, int mouseY, float delta) { this.enabled = false; String error = null; + int color = 0; + visible = false; AutoTransferHandler.Context context = AutoTransferHandler.Context.create(false, containerScreen, displaySupplier.get()); for (AutoTransferHandler autoTransferHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler()) { - AutoTransferHandler.Result result = autoTransferHandler.handle(context); - if (result.isSuccessful()) { - enabled = true; - error = null; - break; - } else if (error == null) { - error = result.getErrorKey(); + try { + AutoTransferHandler.Result result = autoTransferHandler.handle(context); + if (result.isApplicable()) + visible = true; + if (result.isSuccessful()) { + enabled = true; + error = null; + break; + } else if (error == null) { + error = result.getErrorKey(); + color = result.getColor(); + } + } catch (Exception e) { + e.printStackTrace(); } } + if (!visible) + enabled = false; errorTooltip = error; - super.render(mouseX, mouseY, delta); + int x = getBounds().x, y = getBounds().y, width = getBounds().width, height = getBounds().height; + minecraft.getTextureManager().bindTexture(ScreenHelper.isDarkModeEnabled() ? BUTTON_LOCATION_DARK : BUTTON_LOCATION); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + int textureOffset = this.getTextureId(isHovered(mouseX, mouseY)); + GlStateManager.enableBlend(); + GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + //Four Corners + blit(x, y, 0, textureOffset * 80, 4, 4); + blit(x + width - 4, y, 252, textureOffset * 80, 4, 4); + blit(x, y + height - 4, 0, textureOffset * 80 + 76, 4, 4); + blit(x + width - 4, y + height - 4, 252, textureOffset * 80 + 76, 4, 4); + + //Sides + blit(x + 4, y, 4, textureOffset * 80, MathHelper.ceil((width - 8) / 2f), 4); + blit(x + 4, y + height - 4, 4, textureOffset * 80 + 76, MathHelper.ceil((width - 8) / 2f), 4); + blit(x + 4 + MathHelper.ceil((width - 8) / 2f), y + height - 4, 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80 + 76, MathHelper.floor((width - 8) / 2f), 4); + blit(x + 4 + MathHelper.ceil((width - 8) / 2f), y, 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80, MathHelper.floor((width - 8) / 2f), 4); + for (int i = y + 4; i < y + height - 4; i += 76) { + blit(x, i, 0, 4 + textureOffset * 80, MathHelper.ceil(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76)); + blit(x + MathHelper.ceil(width / 2f), i, 256 - MathHelper.floor(width / 2f), 4 + textureOffset * 80, MathHelper.floor(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76)); + } + + int colour = 14737632; + if (!this.visible) { + colour = 10526880; + } else if (enabled && isHovered(mouseX, mouseY)) { + colour = 16777120; + } + + fillGradient(x, y, x + width, y + height, color, color); + this.drawCenteredString(font, text, x + width / 2, y + (height - 8) / 2, colour); + + if (getTooltips().isPresent()) + if (!focused && containsMouse(mouseX, mouseY)) + ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(getTooltips().get().split("\n"))); + else if (focused) + ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n"))); + } + + @Override + protected int getTextureId(boolean boolean_1) { + return !visible ? 0 :boolean_1 && enabled ? 2 : 1; } @Override diff --git a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java index c9925eef9..71760efd1 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java @@ -421,13 +421,13 @@ public class EntryListWidget extends Widget { if (!RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() || stacks.isEmpty() || inventoryItems.isEmpty()) return Collections.unmodifiableList(stacks); List workingItems = RecipeHelper.getInstance().findCraftableByItems(inventoryItems); - List newList = Lists.newArrayList(); + List newList = Lists.newLinkedList(); for (ItemStack workingItem : workingItems) { Optional any = stacks.stream().filter(i -> i.getItemStack() != null && i.getItemStack().isItemEqualIgnoreDamage(workingItem)).findAny(); if (any.isPresent()) newList.add(any.get()); } - return newList; + return Collections.unmodifiableList(newList); } public List getLastSearchArgument() { diff --git a/src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java b/src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java index 8bcbe5083..ff59c1148 100644 --- a/src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java +++ b/src/main/java/me/shedaniel/rei/plugin/DefaultAutoCraftingPlugin.java @@ -8,10 +8,7 @@ package me.shedaniel.rei.plugin; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.RecipeHelper; import me.shedaniel.rei.api.plugins.REIPluginV0; -import me.shedaniel.rei.plugin.autocrafting.AutoBlastingBookHandler; -import me.shedaniel.rei.plugin.autocrafting.AutoCraftingHandler; -import me.shedaniel.rei.plugin.autocrafting.AutoFurnaceBookHandler; -import me.shedaniel.rei.plugin.autocrafting.AutoSmokerBookHandler; +import me.shedaniel.rei.plugin.autocrafting.DefaultCategoryHandler; import net.fabricmc.loader.api.SemanticVersion; import net.fabricmc.loader.util.version.VersionParsingException; import net.minecraft.util.Identifier; @@ -37,10 +34,9 @@ public class DefaultAutoCraftingPlugin implements REIPluginV0 { } // recipeHelper.registerAutoCraftingHandler(new AutoCraftingTableBookHandler()); // recipeHelper.registerAutoCraftingHandler(new AutoInventoryBookHandler()); - recipeHelper.registerAutoCraftingHandler(new AutoFurnaceBookHandler()); - recipeHelper.registerAutoCraftingHandler(new AutoSmokerBookHandler()); - recipeHelper.registerAutoCraftingHandler(new AutoBlastingBookHandler()); - recipeHelper.registerAutoCraftingHandler(new AutoCraftingHandler()); + // recipeHelper.registerAutoCraftingHandler(new AutoFurnaceBookHandler()); + // recipeHelper.registerAutoCraftingHandler(new AutoSmokerBookHandler()); + // recipeHelper.registerAutoCraftingHandler(new AutoBlastingBookHandler()); + recipeHelper.registerAutoCraftingHandler(new DefaultCategoryHandler()); } - } diff --git a/src/main/java/me/shedaniel/rei/plugin/DefaultServerContainerPlugin.java b/src/main/java/me/shedaniel/rei/plugin/DefaultServerContainerPlugin.java new file mode 100644 index 000000000..d192cf39e --- /dev/null +++ b/src/main/java/me/shedaniel/rei/plugin/DefaultServerContainerPlugin.java @@ -0,0 +1,17 @@ +package me.shedaniel.rei.plugin; + +import me.shedaniel.rei.plugin.containers.CraftingContainerInfoWrapper; +import me.shedaniel.rei.server.ContainerInfoHandler; +import net.minecraft.container.*; +import net.minecraft.util.Identifier; + +public class DefaultServerContainerPlugin implements Runnable { + @Override + public void run() { + ContainerInfoHandler.registerContainerInfo(new Identifier("minecraft", "plugins/crafting"), new CraftingContainerInfoWrapper(CraftingTableContainer.class)); + ContainerInfoHandler.registerContainerInfo(new Identifier("minecraft", "plugins/crafting"), new CraftingContainerInfoWrapper(PlayerContainer.class)); + ContainerInfoHandler.registerContainerInfo(new Identifier("minecraft", "plugins/smelting"), new CraftingContainerInfoWrapper(FurnaceContainer.class)); + ContainerInfoHandler.registerContainerInfo(new Identifier("minecraft", "plugins/smoking"), new CraftingContainerInfoWrapper(SmokerContainer.class)); + ContainerInfoHandler.registerContainerInfo(new Identifier("minecraft", "plugins/blasting"), new CraftingContainerInfoWrapper(BlastFurnaceContainer.class)); + } +} diff --git a/src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingHandler.java b/src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingHandler.java deleted file mode 100644 index f99a8734b..000000000 --- a/src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingHandler.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Roughly Enough Items by Danielshe. - * Licensed under the MIT License. - */ - -package me.shedaniel.rei.plugin.autocrafting; - -import com.google.common.collect.Lists; -import io.netty.buffer.Unpooled; -import me.shedaniel.rei.RoughlyEnoughItemsNetwork; -import me.shedaniel.rei.api.AutoTransferHandler; -import me.shedaniel.rei.listeners.RecipeBookGuiHooks; -import me.shedaniel.rei.plugin.crafting.DefaultCraftingCategory; -import me.shedaniel.rei.plugin.crafting.DefaultCraftingDisplay; -import me.shedaniel.rei.plugin.crafting.DefaultShapedDisplay; -import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.CraftingTableScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; -import net.minecraft.container.CraftingContainer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.DefaultedList; -import net.minecraft.util.PacketByteBuf; - -import java.util.List; - -public class AutoCraftingHandler implements AutoTransferHandler { - @Override - public Result handle(Context context) { - if (!(context.getRecipe() instanceof DefaultCraftingDisplay)) - return Result.createNotApplicable(); - if (!(context.getContainerScreen() instanceof CraftingTableScreen) && !(context.getContainerScreen() instanceof InventoryScreen)) - return Result.createNotApplicable(); - if (context.getContainerScreen() instanceof InventoryScreen && (((DefaultCraftingDisplay) context.getRecipe()).getWidth() > 2 || ((DefaultCraftingDisplay) context.getRecipe()).getHeight() > 2)) - return Result.createFailed("error.rei.transfer.too_small"); - if (!canUseMovePackets()) - return Result.createFailed("error.rei.not.on.server"); - if (!hasItems(context.getRecipe().getInput())) - return Result.createFailed("error.rei.not.enough.materials"); - if (!context.isActuallyCrafting()) - return Result.createSuccessful(); - - context.getMinecraft().openScreen(context.getContainerScreen()); - ((RecipeBookGuiHooks) ((RecipeBookProvider) context.getContainerScreen()).getRecipeBookGui()).rei_getGhostSlots().reset(); - DefaultCraftingDisplay display = (DefaultCraftingDisplay) context.getRecipe(); - PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); - buf.writeUuid(RoughlyEnoughItemsNetwork.CRAFTING_TABLE_MOVE); - buf.writeBoolean(Screen.hasShiftDown()); - CraftingContainer craftingContainer = (CraftingContainer) context.getContainer(); - - List> ogInput = display.getInput(); - List> input = Lists.newArrayListWithCapacity(craftingContainer.getCraftingWidth() * craftingContainer.getCraftingHeight()); - for (int i = 0; i < craftingContainer.getCraftingWidth() * craftingContainer.getCraftingHeight(); i++) { - input.add(Lists.newArrayList()); - } - for (int i = 0; i < ogInput.size(); i++) { - List ogStacks = ogInput.get(i); - if (display instanceof DefaultShapedDisplay) { - if (!ogInput.get(i).isEmpty()) - input.set(DefaultCraftingCategory.getSlotWithSize(display, i), ogInput.get(i)); - } else if (!ogInput.get(i).isEmpty()) - input.set(i, ogInput.get(i)); - } - - buf.writeInt(input.size()); - for (List stacks : input) { - buf.writeInt(stacks.size()); - for (ItemStack stack : stacks) { - buf.writeItemStack(stack); - } - } - ClientSidePacketRegistry.INSTANCE.sendToServer(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET, buf); - return Result.createSuccessful(); - } - - @Override - public double getPriority() { - return -10; - } - - public boolean canUseMovePackets() { - return ClientSidePacketRegistry.INSTANCE.canServerReceive(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET); - } - - public boolean hasItems(List> inputs) { - // Create a clone of player's inventory, and count - DefaultedList copyMain = DefaultedList.create(); - for (ItemStack stack : MinecraftClient.getInstance().player.inventory.main) { - copyMain.add(stack.copy()); - } - for (List possibleStacks : inputs) { - boolean done = possibleStacks.isEmpty(); - for (ItemStack possibleStack : possibleStacks) { - if (!done) { - int invRequiredCount = possibleStack.getCount(); - for (ItemStack stack : copyMain) { - if (ItemStack.areItemsEqualIgnoreDamage(possibleStack, stack)) { - while (invRequiredCount > 0 && !stack.isEmpty()) { - invRequiredCount--; - stack.decrement(1); - } - } - } - if (invRequiredCount <= 0) { - done = true; - } - } - } - if (!done) - return false; - } - return true; - } -} diff --git a/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java b/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java new file mode 100644 index 000000000..c12d7e809 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java @@ -0,0 +1,116 @@ +/* + * Roughly Enough Items by Danielshe. + * Licensed under the MIT License. + */ + +package me.shedaniel.rei.plugin.autocrafting; + +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import me.shedaniel.rei.RoughlyEnoughItemsNetwork; +import me.shedaniel.rei.api.AutoTransferHandler; +import me.shedaniel.rei.api.TransferRecipeDisplay; +import me.shedaniel.rei.listeners.RecipeBookGuiHooks; +import me.shedaniel.rei.server.ContainerInfo; +import me.shedaniel.rei.server.ContainerInfoHandler; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +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.recipebook.RecipeBookProvider; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.container.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DefaultedList; +import net.minecraft.util.PacketByteBuf; + +import java.util.List; + +public class DefaultCategoryHandler implements AutoTransferHandler { + + @Override + public Result handle(Context context) { + if (!(context.getRecipe() instanceof TransferRecipeDisplay)) + return Result.createNotApplicable(); + TransferRecipeDisplay recipe = (TransferRecipeDisplay) context.getRecipe(); + if (!ContainerInfoHandler.isCategoryHandled(recipe.getRecipeCategory())) + return Result.createNotApplicable(); + AbstractContainerScreen containerScreen = context.getContainerScreen(); + Container container = containerScreen.getContainer(); + ContainerInfo containerInfo = ContainerInfoHandler.getContainerInfo(recipe.getRecipeCategory(), container.getClass()); + if (containerInfo == null) + return Result.createNotApplicable(); + if (recipe.getHeight() > containerInfo.getCraftingHeight(container) || recipe.getWidth() > containerInfo.getCraftingWidth(container)) + return Result.createFailed(I18n.translate("error.rei.transfer.too_small", containerInfo.getCraftingWidth(container), containerInfo.getCraftingHeight(container))); + if (!canUseMovePackets()) + return Result.createFailed("error.rei.not.on.server"); + List> input = recipe.getOrganisedInput(containerInfo, container); + IntList intList = hasItems(input); + if (!intList.isEmpty()) + return Result.createFailed("error.rei.not.enough.materials", intList); + if (!context.isActuallyCrafting()) + return Result.createSuccessful(); + + context.getMinecraft().openScreen(containerScreen); + if (containerScreen instanceof RecipeBookProvider) + ((RecipeBookGuiHooks) ((RecipeBookProvider) containerScreen).getRecipeBookGui()).rei_getGhostSlots().reset(); + PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); + // buf.writeUuid(RoughlyEnoughItemsNetwork.CRAFTING_TABLE_MOVE); + buf.writeIdentifier(recipe.getRecipeCategory()); + buf.writeBoolean(Screen.hasShiftDown()); + + buf.writeInt(input.size()); + for (List stacks : input) { + buf.writeInt(stacks.size()); + for (ItemStack stack : stacks) { + buf.writeItemStack(stack); + } + } + ClientSidePacketRegistry.INSTANCE.sendToServer(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET, buf); + return Result.createSuccessful(); + } + + @Override + public double getPriority() { + return -10; + } + + public boolean canUseMovePackets() { + return ClientSidePacketRegistry.INSTANCE.canServerReceive(RoughlyEnoughItemsNetwork.MOVE_ITEMS_PACKET); + } + + public IntList hasItems(List> inputs) { + // Create a clone of player's inventory, and count + DefaultedList copyMain = DefaultedList.create(); + for (ItemStack stack : MinecraftClient.getInstance().player.inventory.main) { + copyMain.add(stack.copy()); + } + IntList intList = new IntArrayList(); + for (int i = 0; i < inputs.size(); i++) { + List possibleStacks = inputs.get(i); + boolean done = possibleStacks.isEmpty(); + for (ItemStack possibleStack : possibleStacks) { + if (!done) { + int invRequiredCount = possibleStack.getCount(); + for (ItemStack stack : copyMain) { + if (ItemStack.areItemsEqualIgnoreDamage(possibleStack, stack)) { + while (invRequiredCount > 0 && !stack.isEmpty()) { + invRequiredCount--; + stack.decrement(1); + } + } + } + if (invRequiredCount <= 0) { + done = true; + break; + } + } + } + if (!done) { + intList.add(i); + } + } + return intList; + } +} diff --git a/src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingDisplay.java b/src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingDisplay.java index cda9d3c6f..d8437887e 100644 --- a/src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingDisplay.java +++ b/src/main/java/me/shedaniel/rei/plugin/blasting/DefaultBlastingDisplay.java @@ -6,8 +6,11 @@ package me.shedaniel.rei.plugin.blasting; import me.shedaniel.rei.api.RecipeDisplay; +import me.shedaniel.rei.api.TransferRecipeDisplay; import me.shedaniel.rei.plugin.DefaultPlugin; +import me.shedaniel.rei.server.ContainerInfo; import net.minecraft.block.entity.FurnaceBlockEntity; +import net.minecraft.container.Container; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.AbstractCookingRecipe; @@ -20,7 +23,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -public class DefaultBlastingDisplay implements RecipeDisplay { +public class DefaultBlastingDisplay implements TransferRecipeDisplay { private BlastingRecipe display; private List> input; @@ -66,4 +69,18 @@ public class DefaultBlastingDisplay implements RecipeDisplay { return Optional.ofNullable(display); } + @Override + public int getWidth() { + return 1; + } + + @Override + public int getHeight() { + return 1; + } + + @Override + public List> getOrganisedInput(ContainerInfo containerInfo, Container container) { + return display.getPreviewInputs().stream().map(i -> Arrays.asList(i.getStackArray())).collect(Collectors.toList()); + } } diff --git a/src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java b/src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java new file mode 100644 index 000000000..19bd70b38 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java @@ -0,0 +1,50 @@ +package me.shedaniel.rei.plugin.containers; + +import me.shedaniel.rei.server.ContainerInfo; +import me.shedaniel.rei.server.RecipeFinder; +import net.minecraft.container.Container; +import net.minecraft.container.CraftingContainer; +import net.minecraft.item.ItemStack; + +public class CraftingContainerInfoWrapper> implements ContainerInfo { + private Class> containerClass; + + public > CraftingContainerInfoWrapper(Class containerClass) { + this.containerClass = containerClass; + } + + @Override + public Class getContainerClass() { + return containerClass; + } + + @Override + public int getCraftingResultSlotIndex(T container) { + return container.getCraftingResultSlotIndex(); + } + + @Override + public int getCraftingWidth(T container) { + return container.getCraftingWidth(); + } + + @Override + public int getCraftingHeight(T container) { + return container.getCraftingHeight(); + } + + @Override + public void clearCraftingSlots(T container) { + container.clearCraftingSlots(); + } + + @Override + public void populateRecipeFinder(T container, RecipeFinder var1) { + container.populateRecipeFinder(new net.minecraft.recipe.RecipeFinder() { + @Override + public void addNormalItem(ItemStack itemStack_1) { + var1.addNormalItem(itemStack_1); + } + }); + } +} diff --git a/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java b/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java index e0ea0235c..740a7f545 100644 --- a/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java +++ b/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingDisplay.java @@ -5,28 +5,51 @@ package me.shedaniel.rei.plugin.crafting; -import me.shedaniel.rei.api.RecipeDisplay; +import com.google.common.collect.Lists; +import me.shedaniel.rei.api.TransferRecipeDisplay; import me.shedaniel.rei.plugin.DefaultPlugin; +import me.shedaniel.rei.server.ContainerInfo; +import net.minecraft.container.Container; +import net.minecraft.item.ItemStack; import net.minecraft.recipe.Recipe; import net.minecraft.util.Identifier; +import java.util.List; import java.util.Optional; -public interface DefaultCraftingDisplay extends RecipeDisplay { +public interface DefaultCraftingDisplay extends TransferRecipeDisplay { @Override default Identifier getRecipeCategory() { return DefaultPlugin.CRAFTING; } + @Override default public int getWidth() { return 2; } + @Override default public int getHeight() { return 2; } Optional> getOptionalRecipe(); + @Override + default List> getOrganisedInput(ContainerInfo containerInfo, Container container) { + List> list = Lists.newArrayListWithCapacity(containerInfo.getCraftingWidth(container) * containerInfo.getCraftingHeight(container)); + for (int i = 0; i < containerInfo.getCraftingWidth(container) * containerInfo.getCraftingHeight(container); i++) { + list.add(Lists.newArrayList()); + } + for (int i = 0; i < getInput().size(); i++) { + List stacks = getInput().get(i); + if (this instanceof DefaultShapedDisplay) { + if (!stacks.isEmpty()) + list.set(DefaultCraftingCategory.getSlotWithSize(this, i), stacks); + } else if (!stacks.isEmpty()) + list.set(i, stacks); + } + return list; + } } diff --git a/src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingDisplay.java b/src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingDisplay.java index cfe5515d4..81823eedc 100644 --- a/src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingDisplay.java +++ b/src/main/java/me/shedaniel/rei/plugin/smelting/DefaultSmeltingDisplay.java @@ -5,9 +5,11 @@ package me.shedaniel.rei.plugin.smelting; -import me.shedaniel.rei.api.RecipeDisplay; +import me.shedaniel.rei.api.TransferRecipeDisplay; import me.shedaniel.rei.plugin.DefaultPlugin; +import me.shedaniel.rei.server.ContainerInfo; import net.minecraft.block.entity.FurnaceBlockEntity; +import net.minecraft.container.Container; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.AbstractCookingRecipe; @@ -20,7 +22,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -public class DefaultSmeltingDisplay implements RecipeDisplay { +public class DefaultSmeltingDisplay implements TransferRecipeDisplay { private SmeltingRecipe display; private List> input; @@ -65,4 +67,19 @@ public class DefaultSmeltingDisplay implements RecipeDisplay { public Optional getOptionalRecipe() { return Optional.ofNullable(display); } + + @Override + public int getWidth() { + return 1; + } + + @Override + public int getHeight() { + return 1; + } + + @Override + public List> getOrganisedInput(ContainerInfo containerInfo, Container container) { + return display.getPreviewInputs().stream().map(i -> Arrays.asList(i.getStackArray())).collect(Collectors.toList()); + } } diff --git a/src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingDisplay.java b/src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingDisplay.java index 7c992751f..0c58b5baa 100644 --- a/src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingDisplay.java +++ b/src/main/java/me/shedaniel/rei/plugin/smoking/DefaultSmokingDisplay.java @@ -6,8 +6,11 @@ package me.shedaniel.rei.plugin.smoking; import me.shedaniel.rei.api.RecipeDisplay; +import me.shedaniel.rei.api.TransferRecipeDisplay; import me.shedaniel.rei.plugin.DefaultPlugin; +import me.shedaniel.rei.server.ContainerInfo; import net.minecraft.block.entity.FurnaceBlockEntity; +import net.minecraft.container.Container; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.recipe.AbstractCookingRecipe; @@ -20,7 +23,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -public class DefaultSmokingDisplay implements RecipeDisplay { +public class DefaultSmokingDisplay implements TransferRecipeDisplay { private SmokingRecipe display; private List> input; @@ -66,4 +69,19 @@ public class DefaultSmokingDisplay implements RecipeDisplay { return Optional.ofNullable(display); } + @Override + public int getWidth() { + return 1; + } + + @Override + public int getHeight() { + return 1; + } + + @Override + public List> getOrganisedInput(ContainerInfo containerInfo, Container container) { + return display.getPreviewInputs().stream().map(i -> Arrays.asList(i.getStackArray())).collect(Collectors.toList()); + } + } diff --git a/src/main/java/me/shedaniel/rei/server/ContainerInfo.java b/src/main/java/me/shedaniel/rei/server/ContainerInfo.java new file mode 100644 index 000000000..69408fb05 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/ContainerInfo.java @@ -0,0 +1,17 @@ +package me.shedaniel.rei.server; + +import net.minecraft.container.Container; + +public interface ContainerInfo { + Class getContainerClass(); + + int getCraftingResultSlotIndex(T container); + + int getCraftingWidth(T container); + + int getCraftingHeight(T container); + + void clearCraftingSlots(T container); + + void populateRecipeFinder(T container, RecipeFinder var1); +} diff --git a/src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java b/src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java new file mode 100644 index 000000000..ca009695b --- /dev/null +++ b/src/main/java/me/shedaniel/rei/server/ContainerInfoHandler.java @@ -0,0 +1,25 @@ +package me.shedaniel.rei.server; + +import com.google.common.collect.Maps; +import net.minecraft.container.Container; +import net.minecraft.util.Identifier; + +import java.util.Map; + +public class ContainerInfoHandler { + private static final Map, ContainerInfo>> containerInfoMap = Maps.newHashMap(); + + public static void registerContainerInfo(Identifier category, ContainerInfo containerInfo) { + if (!containerInfoMap.containsKey(category)) + containerInfoMap.put(category, Maps.newHashMap()); + containerInfoMap.get(category).put(containerInfo.getContainerClass(), containerInfo); + } + + public static boolean isCategoryHandled(Identifier category) { + return containerInfoMap.containsKey(category) && !containerInfoMap.get(category).isEmpty(); + } + + public static ContainerInfo getContainerInfo(Identifier category, Class containerClass) { + return containerInfoMap.get(category).get(containerClass); + } +} diff --git a/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java b/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java index fcab45737..8f894aadb 100644 --- a/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java +++ b/src/main/java/me/shedaniel/rei/server/InputSlotCrafter.java @@ -9,9 +9,7 @@ import com.google.common.collect.Lists; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntListIterator; -import net.minecraft.container.CraftingContainer; -import net.minecraft.container.CraftingTableContainer; -import net.minecraft.container.PlayerContainer; +import net.minecraft.container.Container; import net.minecraft.container.Slot; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; @@ -19,6 +17,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.DefaultedList; +import net.minecraft.util.Identifier; import java.util.Comparator; import java.util.Iterator; @@ -27,15 +26,18 @@ import java.util.Map; public class InputSlotCrafter implements RecipeGridAligner { - protected CraftingContainer craftingContainer; + protected Container craftingContainer; + protected ContainerInfo containerInfo; protected PlayerInventory inventory; - private InputSlotCrafter(CraftingContainer craftingContainer_1) { - this.craftingContainer = craftingContainer_1; + private InputSlotCrafter(Container craftingContainer, ContainerInfo containerInfo) { + this.craftingContainer = craftingContainer; + this.containerInfo = containerInfo; } - public static void start(CraftingContainer craftingContainer_1, ServerPlayerEntity player, Map> map, boolean hasShift) { - new InputSlotCrafter(craftingContainer_1).fillInputSlots(player, map, hasShift); + public static void start(Identifier category, Container craftingContainer_1, ServerPlayerEntity player, Map> map, boolean hasShift) { + ContainerInfo containerInfo = ContainerInfoHandler.getContainerInfo(category, craftingContainer_1.getClass()); + new InputSlotCrafter(craftingContainer_1, containerInfo).fillInputSlots(player, map, hasShift); } private void fillInputSlots(ServerPlayerEntity player, Map> map, boolean hasShift) { @@ -49,12 +51,7 @@ public class InputSlotCrafter implements RecipeGridAligner< for (ItemStack stack : player.inventory.main) { recipeFinder.addNormalItem(stack); } - this.craftingContainer.populateRecipeFinder(new net.minecraft.recipe.RecipeFinder() { - @Override - public void addNormalItem(ItemStack itemStack_1) { - recipeFinder.addNormalItem(itemStack_1); - } - }); + this.containerInfo.populateRecipeFinder(craftingContainer, recipeFinder); DefaultedList ingredients = DefaultedList.create(); map.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).forEach(entry -> { ingredients.add(Ingredient.ofStacks(entry.getValue().toArray(new ItemStack[0]))); @@ -112,8 +109,8 @@ public class InputSlotCrafter implements RecipeGridAligner< int int_1 = recipeFinder.countRecipeCrafts(ingredients, (IntList) null); int int_2; if (boolean_2) { - for (int_2 = 0; int_2 < this.craftingContainer.getCraftingHeight() * this.craftingContainer.getCraftingWidth() + 1; ++int_2) { - if (int_2 != this.craftingContainer.getCraftingResultSlotIndex()) { + for (int_2 = 0; int_2 < this.containerInfo.getCraftingHeight(craftingContainer) * this.containerInfo.getCraftingWidth(craftingContainer) + 1; ++int_2) { + if (int_2 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) { ItemStack itemStack_1 = this.craftingContainer.getSlot(int_2).getStack(); if (!itemStack_1.isEmpty() && Math.min(int_1, itemStack_1.getMaxCount()) < itemStack_1.getCount() + 1) { return; @@ -138,7 +135,7 @@ public class InputSlotCrafter implements RecipeGridAligner< if (recipeFinder.findRecipe(ingredients, intList_1, int_4)) { this.returnInputs(); - this.alignRecipeToGrid(this.craftingContainer.getCraftingWidth(), this.craftingContainer.getCraftingHeight(), this.craftingContainer.getCraftingResultSlotIndex(), ingredients, intList_1.iterator(), int_4); + this.alignRecipeToGrid(this.containerInfo.getCraftingWidth(craftingContainer), this.containerInfo.getCraftingHeight(craftingContainer), this.containerInfo.getCraftingResultSlotIndex(craftingContainer), ingredients, intList_1.iterator(), int_4); } } @@ -150,8 +147,8 @@ public class InputSlotCrafter implements RecipeGridAligner< int_2 = int_1; } else if (boolean_2) { int_2 = 64; - for (int int_3 = 0; int_3 < this.craftingContainer.getCraftingWidth() * this.craftingContainer.getCraftingHeight() + 1; ++int_3) { - if (int_3 != this.craftingContainer.getCraftingResultSlotIndex()) { + for (int int_3 = 0; int_3 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_3) { + if (int_3 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) { ItemStack itemStack_1 = this.craftingContainer.getSlot(int_3).getStack(); if (!itemStack_1.isEmpty() && int_2 > itemStack_1.getCount()) { int_2 = itemStack_1.getCount(); @@ -166,13 +163,13 @@ public class InputSlotCrafter implements RecipeGridAligner< } protected void returnInputs() { - for (int int_1 = 0; int_1 < this.craftingContainer.getCraftingWidth() * this.craftingContainer.getCraftingHeight() + 1; ++int_1) { - if (int_1 != this.craftingContainer.getCraftingResultSlotIndex() || !(this.craftingContainer instanceof CraftingTableContainer) && !(this.craftingContainer instanceof PlayerContainer)) { + for (int int_1 = 0; int_1 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_1) { + if (int_1 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) { this.returnSlot(int_1); } } - this.craftingContainer.clearCraftingSlots(); + this.containerInfo.clearCraftingSlots(craftingContainer); } protected void returnSlot(int int_1) { @@ -197,8 +194,8 @@ public class InputSlotCrafter implements RecipeGridAligner< List list_1 = Lists.newArrayList(); int int_1 = this.getFreeInventorySlots(); - for (int int_2 = 0; int_2 < this.craftingContainer.getCraftingWidth() * this.craftingContainer.getCraftingHeight() + 1; ++int_2) { - if (int_2 != this.craftingContainer.getCraftingResultSlotIndex()) { + for (int int_2 = 0; int_2 < this.containerInfo.getCraftingWidth(craftingContainer) * this.containerInfo.getCraftingHeight(craftingContainer) + 1; ++int_2) { + if (int_2 != this.containerInfo.getCraftingResultSlotIndex(craftingContainer)) { ItemStack itemStack_1 = this.craftingContainer.getSlot(int_2).getStack().copy(); if (!itemStack_1.isEmpty()) { int int_3 = this.inventory.getOccupiedSlotWithRoomForStack(itemStack_1); -- cgit