ForgePatch/src/main/java/net/minecraftforge/items/ItemStackHandler.java

227 lines
5.9 KiB
Java

/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.NonNullList;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.INBTSerializable;
import javax.annotation.Nonnull;
public class ItemStackHandler implements IItemHandler, IItemHandlerModifiable, INBTSerializable<NBTTagCompound>
{
protected NonNullList<ItemStack> stacks;
public ItemStackHandler()
{
this(1);
}
public ItemStackHandler(int size)
{
stacks = NonNullList.withSize(size, ItemStack.EMPTY);
}
public ItemStackHandler(NonNullList<ItemStack> stacks)
{
this.stacks = stacks;
}
public void setSize(int size)
{
stacks = NonNullList.withSize(size, ItemStack.EMPTY);
}
@Override
public void setStackInSlot(int slot, @Nonnull ItemStack stack)
{
validateSlotIndex(slot);
this.stacks.set(slot, stack);
onContentsChanged(slot);
}
@Override
public int getSlots()
{
return stacks.size();
}
@Override
@Nonnull
public ItemStack getStackInSlot(int slot)
{
validateSlotIndex(slot);
return this.stacks.get(slot);
}
@Override
@Nonnull
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate)
{
if (stack.isEmpty())
return ItemStack.EMPTY;
validateSlotIndex(slot);
ItemStack existing = this.stacks.get(slot);
int limit = getStackLimit(slot, stack);
if (!existing.isEmpty())
{
if (!ItemHandlerHelper.canItemStacksStack(stack, existing))
return stack;
limit -= existing.getCount();
}
if (limit <= 0)
return stack;
boolean reachedLimit = stack.getCount() > limit;
if (!simulate)
{
if (existing.isEmpty())
{
this.stacks.set(slot, reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack);
}
else
{
existing.grow(reachedLimit ? limit : stack.getCount());
}
onContentsChanged(slot);
}
return reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount()- limit) : ItemStack.EMPTY;
}
@Override
@Nonnull
public ItemStack extractItem(int slot, int amount, boolean simulate)
{
if (amount == 0)
return ItemStack.EMPTY;
validateSlotIndex(slot);
ItemStack existing = this.stacks.get(slot);
if (existing.isEmpty())
return ItemStack.EMPTY;
int toExtract = Math.min(amount, existing.getMaxStackSize());
if (existing.getCount() <= toExtract)
{
if (!simulate)
{
this.stacks.set(slot, ItemStack.EMPTY);
onContentsChanged(slot);
}
return existing;
}
else
{
if (!simulate)
{
this.stacks.set(slot, ItemHandlerHelper.copyStackWithSize(existing, existing.getCount() - toExtract));
onContentsChanged(slot);
}
return ItemHandlerHelper.copyStackWithSize(existing, toExtract);
}
}
@Override
public int getSlotLimit(int slot)
{
return 64;
}
protected int getStackLimit(int slot, @Nonnull ItemStack stack)
{
return Math.min(getSlotLimit(slot), stack.getMaxStackSize());
}
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{
return true;
}
@Override
public NBTTagCompound serializeNBT()
{
NBTTagList nbtTagList = new NBTTagList();
for (int i = 0; i < stacks.size(); i++)
{
if (!stacks.get(i).isEmpty())
{
NBTTagCompound itemTag = new NBTTagCompound();
itemTag.setInt("Slot", i);
stacks.get(i).write(itemTag);
nbtTagList.add(itemTag);
}
}
NBTTagCompound nbt = new NBTTagCompound();
nbt.setTag("Items", nbtTagList);
nbt.setInt("Size", stacks.size());
return nbt;
}
@Override
public void deserializeNBT(NBTTagCompound nbt)
{
setSize(nbt.contains("Size", Constants.NBT.TAG_INT) ? nbt.getInt("Size") : stacks.size());
NBTTagList tagList = nbt.getList("Items", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.size(); i++)
{
NBTTagCompound itemTags = tagList.getCompound(i);
int slot = itemTags.getInt("Slot");
if (slot >= 0 && slot < stacks.size())
{
stacks.set(slot, ItemStack.read(itemTags));
}
}
onLoad();
}
protected void validateSlotIndex(int slot)
{
if (slot < 0 || slot >= stacks.size())
throw new RuntimeException("Slot " + slot + " not in valid range - [0," + stacks.size() + ")");
}
protected void onLoad()
{
}
protected void onContentsChanged(int slot)
{
}
}