From 004cbc70ff6af305052e4e582f9765acf161139b Mon Sep 17 00:00:00 2001 From: Ddggdd135 <1306334428@qq.com> Date: Sat, 27 Apr 2024 15:30:51 +0800 Subject: [PATCH] fix AContainer can't find recipes with similar items --- .../slimefun4/utils/ItemUtils.java | 35 +++++++++++++++ .../abstractItems/AContainer.java | 43 +++++++++++-------- 2 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/ItemUtils.java diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ItemUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ItemUtils.java new file mode 100644 index 0000000000..683908719f --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ItemUtils.java @@ -0,0 +1,35 @@ +package io.github.thebusybiscuit.slimefun4.utils; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Set; + +public class ItemUtils { + public static int getAllItemAmount(@Nonnull ItemStack... itemStacks) { + int amount = 0; + for (ItemStack itemStack : itemStacks) { + if (itemStack == null || itemStack.getType().isAir()) continue; + amount += itemStack.getAmount(); + } + + return amount; + } + + public static int getAllItemTypeAmount(@Nonnull ItemStack... itemStacks) { + Set sfitems = new HashSet<>(); + Set materials = new HashSet<>(); + + for (ItemStack itemStack : itemStacks) { + if (itemStack == null || itemStack.getType().isAir()) continue; + SlimefunItem sfitem = SlimefunItem.getByItem(itemStack); + if (sfitem != null) sfitems.add(sfitem); + else materials.add(itemStack.getType()); + } + + return sfitems.size() + materials.size(); + } +} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java index be71fbe598..385b38ea8d 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java @@ -1,13 +1,13 @@ package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import io.github.bakedlibs.dough.collections.Pair; +import io.github.thebusybiscuit.slimefun4.utils.ItemUtils; import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.Material; @@ -416,9 +416,11 @@ protected MachineRecipe findNextRecipe(BlockMenu inv) { } } - Map found = new HashMap<>(); + Map> matched = new HashMap<>(); for (MachineRecipe recipe : recipes) { + Map found = new HashMap<>(); + for (ItemStack input : recipe.getInput()) { for (int slot : getInputSlots()) { if (SlimefunUtils.isItemSimilar(inventory.get(slot), input, true)) { @@ -426,23 +428,26 @@ protected MachineRecipe findNextRecipe(BlockMenu inv) { break; } } - } - - if (found.size() == recipe.getInput().length) { - if (!InvUtils.fitAll(inv.toInventory(), recipe.getOutput(), getOutputSlots())) { - return null; - } - - for (Map.Entry entry : found.entrySet()) { - inv.consumeItem(entry.getKey(), entry.getValue()); + if (found.size() == recipe.getInput().length) { + matched.put(recipe, found); } - - return recipe; - } else { - found.clear(); } } + if (matched.isEmpty()) return null; + Map.Entry> recipe = matched.entrySet().stream().max((x, y) -> { + int sizex = ItemUtils.getAllItemTypeAmount(x.getKey().getInput()) * 1000 + ItemUtils.getAllItemAmount(x.getKey().getInput()); + int sizey = ItemUtils.getAllItemTypeAmount(y.getKey().getInput()) * 1000 + ItemUtils.getAllItemAmount(y.getKey().getInput()); + return Integer.compare(sizex, sizey); + }).get(); + + if (!InvUtils.fitAll(inv.toInventory(), recipe.getKey().getOutput(), getOutputSlots())) { + return null; + } + + for (Map.Entry entry : recipe.getValue().entrySet()) { + inv.consumeItem(entry.getKey(), entry.getValue()); + } - return null; + return recipe.getKey(); } }