package net.minecraft.world.inventory; import net.minecraft.core.NonNullList; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.CraftingInput.Positioned; import net.minecraft.world.level.Level; public class ResultSlot extends Slot { private final CraftingContainer craftSlots; private final Player player; private int removeCount; public ResultSlot(Player player, CraftingContainer craftSlots, Container container, int slot, int xPosition, int yPosition) { super(container, slot, xPosition, yPosition); this.player = player; this.craftSlots = craftSlots; } @Override public boolean mayPlace(ItemStack stack) { return false; } @Override public ItemStack remove(int amount) { if (this.hasItem()) { this.removeCount = this.removeCount + Math.min(amount, this.getItem().getCount()); } return super.remove(amount); } @Override protected void onQuickCraft(ItemStack stack, int amount) { this.removeCount += amount; this.checkTakeAchievements(stack); } @Override protected void onSwapCraft(int numItemsCrafted) { this.removeCount += numItemsCrafted; } @Override protected void checkTakeAchievements(ItemStack stack) { if (this.removeCount > 0) { stack.onCraftedBy(this.player, this.removeCount); } if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) { recipeCraftingHolder.awardUsedRecipes(this.player, this.craftSlots.getItems()); } this.removeCount = 0; } private static NonNullList copyAllInputItems(CraftingInput input) { NonNullList nonNullList = NonNullList.withSize(input.size(), ItemStack.EMPTY); for (int i = 0; i < nonNullList.size(); i++) { nonNullList.set(i, input.getItem(i)); } return nonNullList; } private NonNullList getRemainingItems(CraftingInput input, Level level) { return level instanceof ServerLevel serverLevel ? (NonNullList)serverLevel.recipeAccess() .getRecipeFor(RecipeType.CRAFTING, input, serverLevel) .map(recipeHolder -> ((CraftingRecipe)recipeHolder.value()).getRemainingItems(input)) .orElseGet(() -> copyAllInputItems(input)) : CraftingRecipe.defaultCraftingReminder(input); } @Override public void onTake(Player player, ItemStack stack) { this.checkTakeAchievements(stack); Positioned positioned = this.craftSlots.asPositionedCraftInput(); CraftingInput craftingInput = positioned.input(); int i = positioned.left(); int j = positioned.top(); NonNullList nonNullList = this.getRemainingItems(craftingInput, player.level()); for (int k = 0; k < craftingInput.height(); k++) { for (int l = 0; l < craftingInput.width(); l++) { int m = l + i + (k + j) * this.craftSlots.getWidth(); ItemStack itemStack = this.craftSlots.getItem(m); ItemStack itemStack2 = nonNullList.get(l + k * craftingInput.width()); if (!itemStack.isEmpty()) { this.craftSlots.removeItem(m, 1); itemStack = this.craftSlots.getItem(m); } if (!itemStack2.isEmpty()) { if (itemStack.isEmpty()) { this.craftSlots.setItem(m, itemStack2); } else if (ItemStack.isSameItemSameComponents(itemStack, itemStack2)) { itemStack2.grow(itemStack.getCount()); this.craftSlots.setItem(m, itemStack2); } else if (!this.player.getInventory().add(itemStack2)) { this.player.drop(itemStack2, false); } } } } } @Override public boolean isFake() { return true; } }