Files
CodeChickenCore/codechicken/lib/inventory/InventoryUtils.java
T

353 lines
11 KiB
Java
Raw Normal View History

2013-12-18 12:25:28 +10:00
package codechicken.lib.inventory;
import com.google.common.base.Objects;
import codechicken.lib.vec.Vector3;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryLargeChest;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
public class InventoryUtils
{
/**
* Static default implementation for IInventory method
*/
2013-12-18 12:25:28 +10:00
public static ItemStack decrStackSize(IInventory inv, int slot, int size)
{
ItemStack item = inv.getStackInSlot(slot);
if(item != null)
{
if(item.stackSize <= size)
{
ItemStack itemstack = item;
inv.setInventorySlotContents(slot, null);
inv.onInventoryChanged();
return itemstack;
}
ItemStack itemstack1 = item.splitStack(size);
if(item.stackSize == 0)
{
inv.setInventorySlotContents(slot, null);
}
inv.onInventoryChanged();
return itemstack1;
}
return null;
}
/**
* Static default implementation for IInventory method
*/
2013-12-18 12:25:28 +10:00
public static ItemStack getStackInSlotOnClosing(IInventory inv, int slot)
{
ItemStack stack = inv.getStackInSlot(slot);
inv.setInventorySlotContents(slot, null);
return stack;
}
/**
* @return The quantity of items from addition that can be added to base
*/
public static int incrStackSize(ItemStack base, ItemStack addition)
{
if (canStack(base, addition))
return incrStackSize(base, addition.stackSize);
return 0;
}
/**
* @return The quantity of items from addition that can be added to base
*/
public static int incrStackSize(ItemStack base, int addition)
{
int totalSize = base.stackSize + addition;
if (totalSize <= base.getMaxStackSize())
return addition;
else if (base.stackSize < base.getMaxStackSize())
return base.getMaxStackSize() - base.stackSize;
return 0;
}
/**
* NBT item saving function
*/
2013-12-18 12:25:28 +10:00
public static NBTTagList writeItemStacksToTag(ItemStack[] items)
{
return writeItemStacksToTag(items, 64);
}
/**
* NBT item saving function with support for stack sizes > 32K
*/
2013-12-18 12:25:28 +10:00
public static NBTTagList writeItemStacksToTag(ItemStack[] items, int maxQuantity)
{
NBTTagList tagList = new NBTTagList();
for(int i = 0; i < items.length; i++)
{
if (items[i] != null)
{
NBTTagCompound tag = new NBTTagCompound();
tag.setShort("Slot", (short) i);
items[i].writeToNBT(tag);
if(maxQuantity > Short.MAX_VALUE)
tag.setInteger("Quantity", items[i].stackSize);
else if(maxQuantity > Byte.MAX_VALUE)
tag.setShort("Quantity", (short) items[i].stackSize);
tagList.appendTag(tag);
}
}
return tagList;
}
/**
* NBT item loading function with support for stack sizes > 32K
*/
2013-12-18 12:25:28 +10:00
public static void readItemStacksFromTag(ItemStack[] items, NBTTagList tagList)
{
for(int i = 0; i < tagList.tagCount(); i++)
{
NBTTagCompound tag = (NBTTagCompound) tagList.tagAt(i);
int b = tag.getShort("Slot");
items[b] = ItemStack.loadItemStackFromNBT(tag);
if(tag.hasKey("Quantity"))
{
NBTBase qtag = tag.getTag("Quantity");
if(qtag instanceof NBTTagInt)
items[b].stackSize = ((NBTTagInt)qtag).data;
else if(qtag instanceof NBTTagShort)
items[b].stackSize = ((NBTTagShort)qtag).data;
}
}
}
/**
* Spawns an itemstack in the world at a location
*/
2013-12-18 12:25:28 +10:00
public static void dropItem(ItemStack stack, World world, Vector3 dropLocation)
{
EntityItem item = new EntityItem(world, dropLocation.x, dropLocation.y, dropLocation.z, stack);
item.motionX = world.rand.nextGaussian() * 0.05;
item.motionY = world.rand.nextGaussian() * 0.05 + 0.2F;
item.motionZ = world.rand.nextGaussian() * 0.05;
world.spawnEntityInWorld(item);
}
/**
* Copies an itemstack with a new quantity
*/
2013-12-18 12:25:28 +10:00
public static ItemStack copyStack(ItemStack stack, int quantity)
{
if(stack == null)
return null;
stack = stack.copy();
stack.stackSize = quantity;
return stack;
}
/**
* Gets the maximum quantity of an item that can be inserted into inv
*/
public static int getInsertibleQuantity(InventoryRange inv, ItemStack stack)
2013-12-18 12:25:28 +10:00
{
int quantity = 0;
stack = copyStack(stack, Integer.MAX_VALUE);
for(int slot : inv.slots)
quantity+=fitStackInSlot(inv, slot, stack);
return quantity;
}
public static int getInsertibleQuantity(IInventory inv, ItemStack stack)
{
return getInsertibleQuantity(new InventoryRange(inv), stack);
}
2013-12-18 12:25:28 +10:00
public static int fitStackInSlot(InventoryRange inv, int slot, ItemStack stack)
{
ItemStack base = inv.inv.getStackInSlot(slot);
if(!canStack(base, stack) || !inv.canInsertItem(slot, stack))
return 0;
int fit = base != null ? incrStackSize(base, inv.inv.getInventoryStackLimit()-base.stackSize) : inv.inv.getInventoryStackLimit();
return Math.min(fit, stack.stackSize);
}
public static int fitStackInSlot(IInventory inv, int slot, ItemStack stack)
2013-12-18 12:25:28 +10:00
{
return fitStackInSlot(new InventoryRange(inv), slot, stack);
}
2013-12-18 12:25:28 +10:00
/**
* @param simulate. If set to true, no items will actually be inserted
* @return The number of items unable to be inserted
*/
public static int insertItem(InventoryRange inv, ItemStack stack, boolean simulate)
{
2013-12-18 12:25:28 +10:00
stack = stack.copy();
for(int pass = 0; pass < 2; pass++)
{
for(int slot : inv.slots)
{
ItemStack base = inv.inv.getStackInSlot(slot);
int fit = fitStackInSlot(inv, slot, stack);
if(fit == 0)
continue;
if(base != null)
{
stack.stackSize-=fit;
if(!simulate)
2013-12-18 12:25:28 +10:00
{
base.stackSize+=fit;
inv.inv.setInventorySlotContents(slot, base);
}
}
else if(pass == 1)
{
if(!simulate)
2013-12-18 12:25:28 +10:00
inv.inv.setInventorySlotContents(slot, copyStack(stack, fit));
stack.stackSize-=fit;
}
if(stack.stackSize == 0)
return 0;
2013-12-18 12:25:28 +10:00
}
}
return stack.stackSize;
}
public static int insertItem(IInventory inv, ItemStack stack, boolean simulate)
{
return insertItem(new InventoryRange(inv), stack, simulate);
}
/**
* Gets the stack in slot if it can be extracted
*/
public static ItemStack getExtractableStack(InventoryRange inv, int slot)
{
ItemStack stack = inv.inv.getStackInSlot(slot);
if(stack == null || !inv.canExtractItem(slot, stack))
return null;
return stack;
}
public static ItemStack getExtractableStack(IInventory inv, int slot)
{
return getExtractableStack(new InventoryRange(inv), slot);
2013-12-18 12:25:28 +10:00
}
public static boolean areStacksIdentical(ItemStack stack1, ItemStack stack2)
{
if(stack1 == null || stack2 == null)
return stack1 == stack2;
2013-12-18 12:25:28 +10:00
return stack1.itemID == stack2.itemID
&& stack1.getItemDamage() == stack2.getItemDamage()
&& stack1.stackSize == stack2.stackSize
&& Objects.equal(stack1.getTagCompound(), stack2.getTagCompound());
}
/**
* Gets an IInventory from a coordinate with support for double chests
*/
2013-12-18 12:25:28 +10:00
public static IInventory getInventory(World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if(!(tile instanceof IInventory))
return null;
if(tile instanceof TileEntityChest)
return getChest((TileEntityChest) tile);
return (IInventory)tile;
}
public static final ForgeDirection[] chestSides = new ForgeDirection[]{ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
public static IInventory getChest(TileEntityChest chest)
{
for(ForgeDirection fside : chestSides)
{
if(chest.worldObj.getBlockId(chest.xCoord+fside.offsetX, chest.yCoord+fside.offsetY, chest.zCoord+fside.offsetZ) == chest.getBlockType().blockID)
return new InventoryLargeChest("container.chestDouble",
(TileEntityChest)chest.worldObj.getBlockTileEntity(chest.xCoord+fside.offsetX, chest.yCoord+fside.offsetY, chest.zCoord+fside.offsetZ), chest);
}
return chest;
}
public static boolean canStack(ItemStack stack1, ItemStack stack2)
{
return stack1 == null || stack2 == null ||
(stack1.itemID == stack2.itemID &&
(!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) &&
ItemStack.areItemStackTagsEqual(stack2, stack1)) &&
stack1.isStackable();
}
/**
* Consumes one item from slot in inv with support for containers.
*/
2013-12-18 12:25:28 +10:00
public static void consumeItem(IInventory inv, int slot)
{
ItemStack stack = inv.getStackInSlot(slot);
Item item = stack.getItem();
if(item.hasContainerItem())
{
ItemStack container = item.getContainerItemStack(stack);
inv.setInventorySlotContents(slot, container);
}
else
{
inv.decrStackSize(slot, 1);
}
}
/**
* Gets the size of the stack in a slot. Returns 0 on null stacks
*/
2013-12-18 12:25:28 +10:00
public static int stackSize(IInventory inv, int slot)
{
ItemStack stack = inv.getStackInSlot(slot);
return stack == null ? 0 : stack.stackSize;
}
/**
* Drops all items from inv using getStackInSlotOnClosing
*/
2013-12-18 12:25:28 +10:00
public static void dropOnClose(EntityPlayer player, IInventory inv)
{
for (int i = 0; i < inv.getSizeInventory(); i++)
{
ItemStack stack = inv.getStackInSlotOnClosing(i);
if (stack != null)
player.dropPlayerItem(stack);
}
}
/**
* Gets the actual damage of an item without asking the Item
*/
2013-12-18 12:25:28 +10:00
public static int actualDamage(ItemStack stack)
{
return Item.diamond.getDamage(stack);
}
}