package net.minecraft.world; import com.google.common.collect.Lists; import java.util.List; import java.util.stream.Collectors; import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; import net.minecraft.nbt.ListTag; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.StackedItemContents; import net.minecraft.world.inventory.StackedContentsCompatible; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; public class SimpleContainer implements Container, StackedContentsCompatible { private final int size; private final NonNullList items; @Nullable private List listeners; public SimpleContainer(int size) { this.size = size; this.items = NonNullList.withSize(size, ItemStack.EMPTY); } public SimpleContainer(ItemStack... items) { this.size = items.length; this.items = NonNullList.of(ItemStack.EMPTY, items); } /** * Add a listener that will be notified when any item in this inventory is modified. */ public void addListener(ContainerListener listener) { if (this.listeners == null) { this.listeners = Lists.newArrayList(); } this.listeners.add(listener); } /** * Removes the specified {@link net.minecraft.world.ContainerListener} from receiving further change notices. */ public void removeListener(ContainerListener listener) { if (this.listeners != null) { this.listeners.remove(listener); } } @Override public ItemStack getItem(int slot) { return slot >= 0 && slot < this.items.size() ? this.items.get(slot) : ItemStack.EMPTY; } public List removeAllItems() { List list = (List)this.items.stream().filter(itemStack -> !itemStack.isEmpty()).collect(Collectors.toList()); this.clearContent(); return list; } @Override public ItemStack removeItem(int slot, int amount) { ItemStack itemStack = ContainerHelper.removeItem(this.items, slot, amount); if (!itemStack.isEmpty()) { this.setChanged(); } return itemStack; } public ItemStack removeItemType(Item item, int amount) { ItemStack itemStack = new ItemStack(item, 0); for (int i = this.size - 1; i >= 0; i--) { ItemStack itemStack2 = this.getItem(i); if (itemStack2.getItem().equals(item)) { int j = amount - itemStack.getCount(); ItemStack itemStack3 = itemStack2.split(j); itemStack.grow(itemStack3.getCount()); if (itemStack.getCount() == amount) { break; } } } if (!itemStack.isEmpty()) { this.setChanged(); } return itemStack; } public ItemStack addItem(ItemStack stack) { if (stack.isEmpty()) { return ItemStack.EMPTY; } else { ItemStack itemStack = stack.copy(); this.moveItemToOccupiedSlotsWithSameType(itemStack); if (itemStack.isEmpty()) { return ItemStack.EMPTY; } else { this.moveItemToEmptySlots(itemStack); return itemStack.isEmpty() ? ItemStack.EMPTY : itemStack; } } } public boolean canAddItem(ItemStack stack) { boolean bl = false; for (ItemStack itemStack : this.items) { if (itemStack.isEmpty() || ItemStack.isSameItemSameComponents(itemStack, stack) && itemStack.getCount() < itemStack.getMaxStackSize()) { bl = true; break; } } return bl; } @Override public ItemStack removeItemNoUpdate(int slot) { ItemStack itemStack = this.items.get(slot); if (itemStack.isEmpty()) { return ItemStack.EMPTY; } else { this.items.set(slot, ItemStack.EMPTY); return itemStack; } } @Override public void setItem(int slot, ItemStack stack) { this.items.set(slot, stack); stack.limitSize(this.getMaxStackSize(stack)); this.setChanged(); } @Override public int getContainerSize() { return this.size; } @Override public boolean isEmpty() { for (ItemStack itemStack : this.items) { if (!itemStack.isEmpty()) { return false; } } return true; } @Override public void setChanged() { if (this.listeners != null) { for (ContainerListener containerListener : this.listeners) { containerListener.containerChanged(this); } } } @Override public boolean stillValid(Player player) { return true; } @Override public void clearContent() { this.items.clear(); this.setChanged(); } @Override public void fillStackedContents(StackedItemContents stackedItemContents) { for (ItemStack itemStack : this.items) { stackedItemContents.accountStack(itemStack); } } public String toString() { return ((List)this.items.stream().filter(itemStack -> !itemStack.isEmpty()).collect(Collectors.toList())).toString(); } private void moveItemToEmptySlots(ItemStack stack) { for (int i = 0; i < this.size; i++) { ItemStack itemStack = this.getItem(i); if (itemStack.isEmpty()) { this.setItem(i, stack.copyAndClear()); return; } } } private void moveItemToOccupiedSlotsWithSameType(ItemStack stack) { for (int i = 0; i < this.size; i++) { ItemStack itemStack = this.getItem(i); if (ItemStack.isSameItemSameComponents(itemStack, stack)) { this.moveItemsBetweenStacks(stack, itemStack); if (stack.isEmpty()) { return; } } } } private void moveItemsBetweenStacks(ItemStack stack, ItemStack other) { int i = this.getMaxStackSize(other); int j = Math.min(stack.getCount(), i - other.getCount()); if (j > 0) { other.grow(j); stack.shrink(j); this.setChanged(); } } public void fromTag(ListTag tag, HolderLookup.Provider levelRegistry) { this.clearContent(); tag.compoundStream().flatMap(compoundTag -> ItemStack.parse(levelRegistry, compoundTag).stream()).forEach(this::addItem); } public ListTag createTag(HolderLookup.Provider levelRegistry) { ListTag listTag = new ListTag(); for (int i = 0; i < this.getContainerSize(); i++) { ItemStack itemStack = this.getItem(i); if (!itemStack.isEmpty()) { listTag.add(itemStack.save(levelRegistry)); } } return listTag; } public NonNullList getItems() { return this.items; } }