package net.minecraft.world.inventory; import java.util.Optional; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; public class Slot { private final int slot; public final Container container; public int index; public final int x; public final int y; public Slot(Container container, int slot, int x, int y) { this.container = container; this.slot = slot; this.x = x; this.y = y; } /** * if par2 has more items than par1, onCrafting(item,countIncrease) is called */ public void onQuickCraft(ItemStack oldStack, ItemStack newStack) { int i = newStack.getCount() - oldStack.getCount(); if (i > 0) { this.onQuickCraft(newStack, i); } } /** * Typically increases an internal count, then calls {@code onCrafting(item)}. * * @param stack the output - ie, iron ingots, and pickaxes, not ore and wood. */ protected void onQuickCraft(ItemStack stack, int amount) { } protected void onSwapCraft(int numItemsCrafted) { } /** * @param stack the output - ie, iron ingots, and pickaxes, not ore and wood. */ protected void checkTakeAchievements(ItemStack stack) { } public void onTake(Player player, ItemStack stack) { this.setChanged(); } /** * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel. */ public boolean mayPlace(ItemStack stack) { return true; } /** * Helper function to get the stack in the slot. */ public ItemStack getItem() { return this.container.getItem(this.slot); } /** * Returns if this slot contains a stack. */ public boolean hasItem() { return !this.getItem().isEmpty(); } public void setByPlayer(ItemStack stack) { this.setByPlayer(stack, this.getItem()); } public void setByPlayer(ItemStack newStack, ItemStack oldStack) { this.set(newStack); } /** * Helper method to put a stack in the slot. */ public void set(ItemStack stack) { this.container.setItem(this.slot, stack); this.setChanged(); } /** * Called when the stack in a Slot changes */ public void setChanged() { this.container.setChanged(); } /** * Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the case of armor slots) */ public int getMaxStackSize() { return this.container.getMaxStackSize(); } public int getMaxStackSize(ItemStack stack) { return Math.min(this.getMaxStackSize(), stack.getMaxStackSize()); } @Nullable public ResourceLocation getNoItemIcon() { return null; } /** * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new stack. */ public ItemStack remove(int amount) { return this.container.removeItem(this.slot, amount); } /** * Return whether this slot's stack can be taken from this slot. */ public boolean mayPickup(Player player) { return true; } /** * Actually only call when we want to render the white square effect over the slots. Return always True, except for the armor slot of the Donkey/Mule (we can't interact with the Undead and Skeleton horses) */ public boolean isActive() { return true; } public Optional tryRemove(int count, int decrement, Player player) { if (!this.mayPickup(player)) { return Optional.empty(); } else if (!this.allowModification(player) && decrement < this.getItem().getCount()) { return Optional.empty(); } else { count = Math.min(count, decrement); ItemStack itemStack = this.remove(count); if (itemStack.isEmpty()) { return Optional.empty(); } else { if (this.getItem().isEmpty()) { this.setByPlayer(ItemStack.EMPTY, itemStack); } return Optional.of(itemStack); } } } public ItemStack safeTake(int count, int decrement, Player player) { Optional optional = this.tryRemove(count, decrement, player); optional.ifPresent(itemStack -> this.onTake(player, itemStack)); return (ItemStack)optional.orElse(ItemStack.EMPTY); } public ItemStack safeInsert(ItemStack stack) { return this.safeInsert(stack, stack.getCount()); } public ItemStack safeInsert(ItemStack stack, int increment) { if (!stack.isEmpty() && this.mayPlace(stack)) { ItemStack itemStack = this.getItem(); int i = Math.min(Math.min(increment, stack.getCount()), this.getMaxStackSize(stack) - itemStack.getCount()); if (i <= 0) { return stack; } else { if (itemStack.isEmpty()) { this.setByPlayer(stack.split(i)); } else if (ItemStack.isSameItemSameComponents(itemStack, stack)) { stack.shrink(i); itemStack.grow(i); this.setByPlayer(itemStack); } return stack; } } else { return stack; } } public boolean allowModification(Player player) { return this.mayPickup(player) && this.mayPlace(this.getItem()); } public int getContainerSlot() { return this.slot; } public boolean isHighlightable() { return true; } public boolean isFake() { return false; } }