Fix handling of resultant crafting container from craftItemResult (#12307)

The result object of overhanging items is based upon a derived view
of the provided crafting slots, meaning that we need to consider this
when handing back the resultant slots.
This commit is contained in:
Shane Freeder 2025-04-29 14:38:11 +01:00 committed by GitHub
parent 9e873f50d3
commit fc0c371761
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -87,6 +87,7 @@ import net.minecraft.world.inventory.ResultContainer;
import net.minecraft.world.inventory.TransientCraftingContainer; import net.minecraft.world.inventory.TransientCraftingContainer;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.MapItem; import net.minecraft.world.item.MapItem;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
@ -1717,25 +1718,31 @@ public final class CraftServer implements Server {
private CraftItemCraftResult createItemCraftResult(Optional<RecipeHolder<CraftingRecipe>> recipe, ItemStack itemStack, CraftingContainer inventoryCrafting) { private CraftItemCraftResult createItemCraftResult(Optional<RecipeHolder<CraftingRecipe>> recipe, ItemStack itemStack, CraftingContainer inventoryCrafting) {
CraftItemCraftResult craftItemResult = new CraftItemCraftResult(itemStack); CraftItemCraftResult craftItemResult = new CraftItemCraftResult(itemStack);
recipe.map((holder) -> holder.value().getRemainingItems(inventoryCrafting.asCraftInput())).ifPresent((remainingItems) -> { // tl;dr: this is an API adopted implementation of ResultSlot#onTake
final CraftingInput.Positioned positionedCraftInput = inventoryCrafting.asPositionedCraftInput();
final CraftingInput craftingInput = positionedCraftInput.input();
recipe.map((holder) -> holder.value().getRemainingItems(craftingInput)).ifPresent((remainingItems) -> {
// Set the resulting matrix items and overflow items // Set the resulting matrix items and overflow items
for (int i = 0; i < remainingItems.size(); ++i) { for (int height = 0; height < craftingInput.height(); height++) {
net.minecraft.world.item.ItemStack itemstack1 = inventoryCrafting.getItem(i); for (int width = 0; width < craftingInput.width(); width++) {
net.minecraft.world.item.ItemStack itemstack2 = remainingItems.get(i); final int inventorySlot = width + positionedCraftInput.left() + (height + positionedCraftInput.top()) * inventoryCrafting.getWidth();
net.minecraft.world.item.ItemStack itemInMenu = inventoryCrafting.getItem(inventorySlot);
net.minecraft.world.item.ItemStack remainingItem = remainingItems.get(width + height * craftingInput.width());
if (!itemstack1.isEmpty()) { if (!itemInMenu.isEmpty()) {
inventoryCrafting.removeItem(i, 1); inventoryCrafting.removeItem(inventorySlot, 1);
itemstack1 = inventoryCrafting.getItem(i); itemInMenu = inventoryCrafting.getItem(inventorySlot);
} }
if (!itemstack2.isEmpty()) { if (!remainingItem.isEmpty()) {
if (itemstack1.isEmpty()) { if (itemInMenu.isEmpty()) {
inventoryCrafting.setItem(i, itemstack2); inventoryCrafting.setItem(inventorySlot, remainingItem);
} else if (net.minecraft.world.item.ItemStack.isSameItemSameComponents(itemstack1, itemstack2)) { } else if (net.minecraft.world.item.ItemStack.isSameItemSameComponents(itemInMenu, remainingItem)) {
itemstack2.grow(itemstack1.getCount()); remainingItem.grow(itemInMenu.getCount());
inventoryCrafting.setItem(i, itemstack2); inventoryCrafting.setItem(inventorySlot, remainingItem);
} else { } else {
craftItemResult.getOverflowItems().add(CraftItemStack.asBukkitCopy(itemstack2)); craftItemResult.getOverflowItems().add(CraftItemStack.asBukkitCopy(remainingItem));
}
} }
} }
} }