package de.take_weiland.mods.commons.inv; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Iterator; import java.util.List; /** * <p>Basic implementation of {@link net.minecraft.inventory.IInventory}.</p> */ public abstract class AbstractInventory extends FluentIterable<ItemStack> implements IInventory, ListenableInventory { private static final String NBT_KEY = "_sc$inventory"; /** * <p>Backing storage.</p> */ protected final ItemStack[] storage; private List<Listener> listeners; /** * <p>This constructor calls {@link #getSizeInventory()} to determine the size of the inventory. It needs to be overridden and work properly when called from this constructor.</p> */ protected AbstractInventory() { storage = new ItemStack[getSizeInventory()]; } /** * <p>Alternate constructor that doesn't need {@link #getSizeInventory()} to be overridden.</p> * * @param size the size of this inventory */ protected AbstractInventory(int size) { storage = new ItemStack[size]; } @Override public int getSizeInventory() { return storage.length; } @Override public ItemStack getStackInSlot(int slot) { return storage[slot]; } /** * {@inheritDoc} * <p>This implementation uses {@link Inventories#decreaseStackSize(net.minecraft.inventory.IInventory, int, int)}</p> */ @Override public ItemStack decrStackSize(int slot, int count) { return Inventories.decreaseStackSize(this, slot, count); } /** * {@inheritDoc} * <p>This implementation uses {@link Inventories#getAndRemove(net.minecraft.inventory.IInventory, int)}</p> */ @Override public ItemStack getStackInSlotOnClosing(int slot) { return Inventories.getAndRemove(this, slot); } @Override public void setInventorySlotContents(int slot, @Nullable ItemStack stack) { if (listeners != null) { ItemStack old = storage[slot]; storage[slot] = stack; for (Listener listener : listeners) { listener.slotChange(this, slot, old, stack); } } else { storage[slot] = stack; } onInventoryChanged(); } @Override public int getInventoryStackLimit() { return 64; } @Override public void openChest() { } @Override public void closeChest() { } @Override public boolean isItemValidForSlot(int slot, ItemStack item) { return true; } @Override public void onInventoryChanged() { if (listeners != null) { for (Listener listener : listeners) { listener.onChange(this); } } } @Nonnull @Override public final Iterator<ItemStack> iterator() { return Iterators.forArray(storage); } /** * <p>Writes this inventory to the {@link net.minecraft.nbt.NBTTagCompound}.</p> * <p>This method stores the inventory into the key {@code _sc$inventory} using * {@link de.take_weiland.mods.commons.inv.Inventories#writeInventory(net.minecraft.item.ItemStack[], net.minecraft.nbt.NBTTagCompound, String)}.</p> * * @param nbt the NBTTagCompound to write to */ public void writeToNbt(NBTTagCompound nbt) { Inventories.writeInventory(storage, nbt, NBT_KEY); } /** * <p>Reads this inventory from an {@link net.minecraft.nbt.NBTTagCompound}.</p> * <p>This method reads the inventory from the key {@code _sc$inventory} using * {@link de.take_weiland.mods.commons.inv.Inventories#readInventory(net.minecraft.item.ItemStack[], net.minecraft.nbt.NBTTagCompound, String)}.</p> * * @param nbt the NBTTagCompound to read from */ public void readFromNbt(NBTTagCompound nbt) { Inventories.readInventory(storage, nbt.getTagList(NBT_KEY)); } @Override public void removeListener(Listener listener) { if (listeners != null) { listeners.remove(listener); } } @Override public void addListener(Listener listener) { (listeners == null ? (listeners = Lists.newArrayListWithExpectedSize(1)) : listeners).add(listener); } }