package mffs.base; import java.util.HashSet; import java.util.Set; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import universalelectricity.core.vector.Vector3; import universalelectricity.prefab.multiblock.TileEntityMulti; public abstract class TileEntityInventory extends TileEntityBase implements IInventory { protected ItemStack[] inventory; public TileEntityInventory() { this.inventory = new ItemStack[this.getSizeInventory()]; } // TODO: WTF // @Override // public List getPacketUpdate() { // final List objects = new ArrayList(); // objects.addAll(super.getPacketUpdate()); // final NBTTagCompound nbt = new NBTTagCompound(); // this.writeToNBT(nbt); // objects.add(nbt); // return objects; // } @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); this.writeToNBT(nbt); return new S35PacketUpdateTileEntity( this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt ); } @Override public void onDataPacket(NetworkManager arg0, S35PacketUpdateTileEntity arg1) { NBTTagCompound nbt = arg1.func_148857_g(); this.readFromNBT(nbt); } // TODO: WTF // @Override // public void sendInventoryToClients() { // final NBTTagCompound nbt = new NBTTagCompound(); // this.writeToNBT(nbt); // PacketManager.sendPacketToClients(PacketManager.getPacket("MFFS", this, // TilePacketType.INVENTORY.ordinal(), nbt)); // } @Override public ItemStack getStackInSlot(final int i) { return this.inventory[i]; } @Override public String getInventoryName() { return this.getBlockType().getLocalizedName(); } @Override public boolean hasCustomInventoryName() { return true; } @Override public void setInventorySlotContents(final int i, final ItemStack itemstack) { this.inventory[i] = itemstack; if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) { itemstack.stackSize = this.getInventoryStackLimit(); } } @Override public ItemStack decrStackSize(final int i, final int j) { if (this.inventory[i] == null) { return null; } if (this.inventory[i].stackSize <= j) { final ItemStack itemstack = this.inventory[i]; this.inventory[i] = null; return itemstack; } final ItemStack itemstack2 = this.inventory[i].splitStack(j); if (this.inventory[i].stackSize == 0) { this.inventory[i] = null; } return itemstack2; } @Override public void openInventory() {} @Override public void closeInventory() {} @Override public boolean isUseableByPlayer(final EntityPlayer entityplayer) { return this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) == this; } @Override public ItemStack getStackInSlotOnClosing(final int slotID) { if (this.inventory[slotID] != null) { final ItemStack itemstack = this.inventory[slotID]; this.inventory[slotID] = null; return itemstack; } return null; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isItemValidForSlot(final int slotID, final ItemStack itemStack) { return true; } public boolean canIncreaseStack(final int slotID, final ItemStack itemStack) { return this.getStackInSlot(slotID) == null || (this.getStackInSlot(slotID).stackSize + 1 <= 64 && this.getStackInSlot(slotID).isItemEqual(itemStack)); } public void incrStackSize(final int slot, final ItemStack itemStack) { if (this.getStackInSlot(slot) == null) { this.setInventorySlotContents(slot, itemStack.copy()); } else if (this.getStackInSlot(slot).isItemEqual(itemStack)) { final ItemStack stackInSlot = this.getStackInSlot(slot); ++stackInSlot.stackSize; } } public Set getCards() { final Set cards = new HashSet<>(); cards.add(this.getStackInSlot(0)); return cards; } public ItemStack tryPlaceInPosition( ItemStack itemStack, final Vector3 position, final ForgeDirection dir ) { final TileEntity tileEntity = position.getTileEntity((IBlockAccess) this.worldObj); final ForgeDirection direction = dir.getOpposite(); if (tileEntity != null && itemStack != null) { if (tileEntity instanceof TileEntityMulti) { final Vector3 mainBlockPosition = ((TileEntityMulti) tileEntity).mainBlockPosition; if (mainBlockPosition != null && !( mainBlockPosition.getTileEntity((IBlockAccess) this.worldObj) instanceof TileEntityMulti )) { return this.tryPlaceInPosition( itemStack, mainBlockPosition, direction ); } } else if (tileEntity instanceof TileEntityChest) { final TileEntityChest[] chests = { (TileEntityChest) tileEntity, null }; for (int i = 2; i < 6; ++i) { final ForgeDirection searchDirection = ForgeDirection.getOrientation(i); final Vector3 searchPosition = position.clone(); searchPosition.modifyPositionFromSide(searchDirection); if (searchPosition.getTileEntity((IBlockAccess) this.worldObj) != null && searchPosition.getTileEntity((IBlockAccess) this.worldObj) .getClass() == chests[0].getClass()) { chests[1] = (TileEntityChest ) searchPosition.getTileEntity((IBlockAccess) this.worldObj); break; } } for (final TileEntityChest chest : chests) { if (chest != null) { for (int j = 0; j < chest.getSizeInventory(); ++j) { itemStack = this.addStackToInventory( j, (IInventory) chest, itemStack ); if (itemStack == null) { return null; } } } } } else if (tileEntity instanceof ISidedInventory) { final ISidedInventory inventory = (ISidedInventory) tileEntity; final int[] slots = inventory.getAccessibleSlotsFromSide(direction.ordinal()); for (int k = 0; k < slots.length; ++k) { if (inventory.canInsertItem( slots[k], itemStack, direction.ordinal() )) { itemStack = this.addStackToInventory( slots[k], (IInventory) inventory, itemStack ); } if (itemStack == null) { return null; } } } else if (tileEntity instanceof IInventory) { final IInventory inventory2 = (IInventory) tileEntity; for (int i = 0; i < inventory2.getSizeInventory(); ++i) { itemStack = this.addStackToInventory(i, inventory2, itemStack); if (itemStack == null) { return null; } } } } if (itemStack.stackSize <= 0) { return null; } return itemStack; } public ItemStack addStackToInventory( final int slotIndex, final IInventory inventory, final ItemStack itemStack ) { if (inventory.getSizeInventory() > slotIndex) { ItemStack stackInInventory = inventory.getStackInSlot(slotIndex); if (stackInInventory == null) { inventory.setInventorySlotContents(slotIndex, itemStack); if (inventory.getStackInSlot(slotIndex) == null) { return itemStack; } return null; } else if (stackInInventory.isItemEqual(itemStack) && stackInInventory.isStackable()) { stackInInventory = stackInInventory.copy(); final int stackLim = Math.min( inventory.getInventoryStackLimit(), itemStack.getMaxStackSize() ); final int rejectedAmount = Math.max( stackInInventory.stackSize + itemStack.stackSize - stackLim, 0 ); stackInInventory.stackSize = Math.min( Math.max( stackInInventory.stackSize + itemStack.stackSize - rejectedAmount, 0 ), inventory.getInventoryStackLimit() ); itemStack.stackSize = rejectedAmount; inventory.setInventorySlotContents(slotIndex, stackInInventory); } } if (itemStack.stackSize <= 0) { return null; } return itemStack; } public boolean mergeIntoInventory(ItemStack itemStack) { if (!this.worldObj.isRemote) { for (final ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) { if (itemStack != null) { itemStack = this.tryPlaceInPosition( itemStack, new Vector3(this).modifyPositionFromSide(direction), direction ); } } if (itemStack != null) { this.worldObj.spawnEntityInWorld((Entity) new EntityItem( this.worldObj, this.xCoord + 0.5, (double) (this.yCoord + 1), this.zCoord + 0.5, itemStack )); } } return false; } @Override public void readFromNBT(final NBTTagCompound nbttagcompound) { super.readFromNBT(nbttagcompound); final NBTTagList nbtTagList = nbttagcompound.getTagList("Items", 10); this.inventory = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < nbtTagList.tagCount(); ++i) { final NBTTagCompound nbttagcompound2 = (NBTTagCompound) nbtTagList.getCompoundTagAt(i); final byte byte0 = nbttagcompound2.getByte("Slot"); if (byte0 >= 0 && byte0 < this.inventory.length) { this.inventory[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound2); } } } @Override public void writeToNBT(final NBTTagCompound nbttagcompound) { super.writeToNBT(nbttagcompound); final NBTTagList nbtTagList = new NBTTagList(); for (int i = 0; i < this.inventory.length; ++i) { if (this.inventory[i] != null) { final NBTTagCompound nbttagcompound2 = new NBTTagCompound(); nbttagcompound2.setByte("Slot", (byte) i); this.inventory[i].writeToNBT(nbttagcompound2); nbtTagList.appendTag((NBTBase) nbttagcompound2); } } nbttagcompound.setTag("Items", (NBTBase) nbtTagList); } @Override public String getType() { return this.getInventoryName(); } @Override public String[] getMethodNames() { return new String[] { "isActivate", "setActivate" }; } @Override public Object[] callMethod( IComputerAccess computer, ILuaContext context, int method, Object[] arguments ) throws LuaException, InterruptedException { switch (method) { case 0: { return new Object[] { this.isActive() }; } case 1: { this.setActive((boolean) arguments[0]); return null; } default: { throw new LuaException("Invalid method."); } } } @Override public void attach(final IComputerAccess computer) {} @Override public void detach(final IComputerAccess computer) {} }