package net.minecraft.tileentity;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockHopper;
import net.minecraft.command.IEntitySelector;
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.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Facing;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class TileEntityHopper extends TileEntity implements IHopper
{
private ItemStack[] field_145900_a = new ItemStack[5];
private String field_145902_i;
private int transferCooldown = -1;
private static final String __OBFID = "CL_00000359";
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
NBTTagList nbttaglist = compound.getTagList("Items", 10);
this.field_145900_a = new ItemStack[this.getSizeInventory()];
if (compound.hasKey("CustomName", 8))
{
this.field_145902_i = compound.getString("CustomName");
}
this.transferCooldown = compound.getInteger("TransferCooldown");
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
byte b0 = nbttagcompound1.getByte("Slot");
if (b0 >= 0 && b0 < this.field_145900_a.length)
{
this.field_145900_a[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
}
public void writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < this.field_145900_a.length; ++i)
{
if (this.field_145900_a[i] != null)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
this.field_145900_a[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
compound.setTag("Items", nbttaglist);
compound.setInteger("TransferCooldown", this.transferCooldown);
if (this.isCustomInventoryName())
{
compound.setString("CustomName", this.field_145902_i);
}
}
/**
* For tile entities, ensures the chunk containing the tile entity is saved to disk later - the game won't think it
* hasn't changed and skip it.
*/
public void markDirty()
{
super.markDirty();
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.field_145900_a.length;
}
/**
* Returns the stack in slot i
*/
public ItemStack getStackInSlot(int slotIn)
{
return this.field_145900_a[slotIn];
}
/**
* Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
* new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
if (this.field_145900_a[index] != null)
{
ItemStack itemstack;
if (this.field_145900_a[index].stackSize <= count)
{
itemstack = this.field_145900_a[index];
this.field_145900_a[index] = null;
return itemstack;
}
else
{
itemstack = this.field_145900_a[index].splitStack(count);
if (this.field_145900_a[index].stackSize == 0)
{
this.field_145900_a[index] = null;
}
return itemstack;
}
}
else
{
return null;
}
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
public ItemStack getStackInSlotOnClosing(int index)
{
if (this.field_145900_a[index] != null)
{
ItemStack itemstack = this.field_145900_a[index];
this.field_145900_a[index] = null;
return itemstack;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, ItemStack stack)
{
this.field_145900_a[index] = stack;
if (stack != null && stack.stackSize > this.getInventoryStackLimit())
{
stack.stackSize = this.getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory
*/
public String getInventoryName()
{
return this.isCustomInventoryName() ? this.field_145902_i : "container.hopper";
}
/**
* Returns if the inventory is named
*/
public boolean isCustomInventoryName()
{
return this.field_145902_i != null && this.field_145902_i.length() > 0;
}
public void func_145886_a(String p_145886_1_)
{
this.field_145902_i = p_145886_1_;
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
public int getInventoryStackLimit()
{
return 64;
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
public boolean isUseableByPlayer(EntityPlayer player)
{
return this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : player.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
}
public void openChest() {}
public void closeChest() {}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.
*/
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return true;
}
public void updateEntity()
{
if (this.worldObj != null && !this.worldObj.isRemote)
{
--this.transferCooldown;
if (!this.isOnTransferCooldown())
{
this.setTransferCooldown(0);
this.func_145887_i();
}
}
}
public boolean func_145887_i()
{
if (this.worldObj != null && !this.worldObj.isRemote)
{
if (!this.isOnTransferCooldown() && BlockHopper.getActiveStateFromMetadata(this.getBlockMetadata()))
{
boolean flag = false;
if (!this.func_152104_k())
{
flag = this.func_145883_k();
}
if (!this.func_152105_l())
{
flag = func_145891_a(this) || flag;
}
if (flag)
{
this.setTransferCooldown(8);
this.markDirty();
return true;
}
}
return false;
}
else
{
return false;
}
}
private boolean func_152104_k()
{
ItemStack[] aitemstack = this.field_145900_a;
int i = aitemstack.length;
for (int j = 0; j < i; ++j)
{
ItemStack itemstack = aitemstack[j];
if (itemstack != null)
{
return false;
}
}
return true;
}
private boolean func_152105_l()
{
ItemStack[] aitemstack = this.field_145900_a;
int i = aitemstack.length;
for (int j = 0; j < i; ++j)
{
ItemStack itemstack = aitemstack[j];
if (itemstack == null || itemstack.stackSize != itemstack.getMaxStackSize())
{
return false;
}
}
return true;
}
private boolean func_145883_k()
{
IInventory iinventory = this.func_145895_l();
if (iinventory == null)
{
return false;
}
else
{
int i = Facing.oppositeSide[BlockHopper.getDirectionFromMetadata(this.getBlockMetadata())];
if (this.func_152102_a(iinventory, i))
{
return false;
}
else
{
for (int j = 0; j < this.getSizeInventory(); ++j)
{
if (this.getStackInSlot(j) != null)
{
ItemStack itemstack = this.getStackInSlot(j).copy();
ItemStack itemstack1 = func_145889_a(iinventory, this.decrStackSize(j, 1), i);
if (itemstack1 == null || itemstack1.stackSize == 0)
{
iinventory.markDirty();
return true;
}
this.setInventorySlotContents(j, itemstack);
}
}
return false;
}
}
}
private boolean func_152102_a(IInventory p_152102_1_, int p_152102_2_)
{
if (p_152102_1_ instanceof ISidedInventory && p_152102_2_ > -1)
{
ISidedInventory isidedinventory = (ISidedInventory)p_152102_1_;
int[] aint = isidedinventory.getSlotsForFace(p_152102_2_);
for (int l = 0; l < aint.length; ++l)
{
ItemStack itemstack1 = isidedinventory.getStackInSlot(aint[l]);
if (itemstack1 == null || itemstack1.stackSize != itemstack1.getMaxStackSize())
{
return false;
}
}
}
else
{
int j = p_152102_1_.getSizeInventory();
for (int k = 0; k < j; ++k)
{
ItemStack itemstack = p_152102_1_.getStackInSlot(k);
if (itemstack == null || itemstack.stackSize != itemstack.getMaxStackSize())
{
return false;
}
}
}
return true;
}
private static boolean func_152103_b(IInventory p_152103_0_, int p_152103_1_)
{
if (p_152103_0_ instanceof ISidedInventory && p_152103_1_ > -1)
{
ISidedInventory isidedinventory = (ISidedInventory)p_152103_0_;
int[] aint = isidedinventory.getSlotsForFace(p_152103_1_);
for (int l = 0; l < aint.length; ++l)
{
if (isidedinventory.getStackInSlot(aint[l]) != null)
{
return false;
}
}
}
else
{
int j = p_152103_0_.getSizeInventory();
for (int k = 0; k < j; ++k)
{
if (p_152103_0_.getStackInSlot(k) != null)
{
return false;
}
}
}
return true;
}
public static boolean func_145891_a(IHopper p_145891_0_)
{
IInventory iinventory = func_145884_b(p_145891_0_);
if (iinventory != null)
{
byte b0 = 0;
if (func_152103_b(iinventory, b0))
{
return false;
}
if (iinventory instanceof ISidedInventory && b0 > -1)
{
ISidedInventory isidedinventory = (ISidedInventory)iinventory;
int[] aint = isidedinventory.getSlotsForFace(b0);
for (int k = 0; k < aint.length; ++k)
{
if (func_145892_a(p_145891_0_, iinventory, aint[k], b0))
{
return true;
}
}
}
else
{
int i = iinventory.getSizeInventory();
for (int j = 0; j < i; ++j)
{
if (func_145892_a(p_145891_0_, iinventory, j, b0))
{
return true;
}
}
}
}
else
{
EntityItem entityitem = func_145897_a(p_145891_0_.getWorld(), p_145891_0_.getXPos(), p_145891_0_.getYPos() + 1.0D, p_145891_0_.getZPos());
if (entityitem != null)
{
return func_145898_a(p_145891_0_, entityitem);
}
}
return false;
}
private static boolean func_145892_a(IHopper p_145892_0_, IInventory p_145892_1_, int p_145892_2_, int p_145892_3_)
{
ItemStack itemstack = p_145892_1_.getStackInSlot(p_145892_2_);
if (itemstack != null && func_145890_b(p_145892_1_, itemstack, p_145892_2_, p_145892_3_))
{
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = func_145889_a(p_145892_0_, p_145892_1_.decrStackSize(p_145892_2_, 1), -1);
if (itemstack2 == null || itemstack2.stackSize == 0)
{
p_145892_1_.markDirty();
return true;
}
p_145892_1_.setInventorySlotContents(p_145892_2_, itemstack1);
}
return false;
}
public static boolean func_145898_a(IInventory p_145898_0_, EntityItem p_145898_1_)
{
boolean flag = false;
if (p_145898_1_ == null)
{
return false;
}
else
{
ItemStack itemstack = p_145898_1_.getEntityItem().copy();
ItemStack itemstack1 = func_145889_a(p_145898_0_, itemstack, -1);
if (itemstack1 != null && itemstack1.stackSize != 0)
{
p_145898_1_.setEntityItemStack(itemstack1);
}
else
{
flag = true;
p_145898_1_.setDead();
}
return flag;
}
}
public static ItemStack func_145889_a(IInventory p_145889_0_, ItemStack p_145889_1_, int p_145889_2_)
{
if (p_145889_0_ instanceof ISidedInventory && p_145889_2_ > -1)
{
ISidedInventory isidedinventory = (ISidedInventory)p_145889_0_;
int[] aint = isidedinventory.getSlotsForFace(p_145889_2_);
for (int l = 0; l < aint.length && p_145889_1_ != null && p_145889_1_.stackSize > 0; ++l)
{
p_145889_1_ = func_145899_c(p_145889_0_, p_145889_1_, aint[l], p_145889_2_);
}
}
else
{
int j = p_145889_0_.getSizeInventory();
for (int k = 0; k < j && p_145889_1_ != null && p_145889_1_.stackSize > 0; ++k)
{
p_145889_1_ = func_145899_c(p_145889_0_, p_145889_1_, k, p_145889_2_);
}
}
if (p_145889_1_ != null && p_145889_1_.stackSize == 0)
{
p_145889_1_ = null;
}
return p_145889_1_;
}
private static boolean func_145885_a(IInventory p_145885_0_, ItemStack p_145885_1_, int p_145885_2_, int p_145885_3_)
{
return !p_145885_0_.isItemValidForSlot(p_145885_2_, p_145885_1_) ? false : !(p_145885_0_ instanceof ISidedInventory) || ((ISidedInventory)p_145885_0_).canInsertItem(p_145885_2_, p_145885_1_, p_145885_3_);
}
private static boolean func_145890_b(IInventory p_145890_0_, ItemStack p_145890_1_, int p_145890_2_, int p_145890_3_)
{
return !(p_145890_0_ instanceof ISidedInventory) || ((ISidedInventory)p_145890_0_).canExtractItem(p_145890_2_, p_145890_1_, p_145890_3_);
}
private static ItemStack func_145899_c(IInventory p_145899_0_, ItemStack p_145899_1_, int p_145899_2_, int p_145899_3_)
{
ItemStack itemstack1 = p_145899_0_.getStackInSlot(p_145899_2_);
if (func_145885_a(p_145899_0_, p_145899_1_, p_145899_2_, p_145899_3_))
{
boolean flag = false;
if (itemstack1 == null)
{
//Forge: BUGFIX: Again, make things respect max stack sizes.
int max = Math.min(p_145899_1_.getMaxStackSize(), p_145899_0_.getInventoryStackLimit());
if (max >= p_145899_1_.stackSize)
{
p_145899_0_.setInventorySlotContents(p_145899_2_, p_145899_1_);
p_145899_1_ = null;
}
else
{
p_145899_0_.setInventorySlotContents(p_145899_2_, p_145899_1_.splitStack(max));
}
flag = true;
}
else if (func_145894_a(itemstack1, p_145899_1_))
{
//Forge: BUGFIX: Again, make things respect max stack sizes.
int max = Math.min(p_145899_1_.getMaxStackSize(), p_145899_0_.getInventoryStackLimit());
if (max > itemstack1.stackSize)
{
int l = Math.min(p_145899_1_.stackSize, max - itemstack1.stackSize);
p_145899_1_.stackSize -= l;
itemstack1.stackSize += l;
flag = l > 0;
}
}
if (flag)
{
if (p_145899_0_ instanceof TileEntityHopper)
{
((TileEntityHopper)p_145899_0_).setTransferCooldown(8);
p_145899_0_.markDirty();
}
p_145899_0_.markDirty();
}
}
return p_145899_1_;
}
private IInventory func_145895_l()
{
int i = BlockHopper.getDirectionFromMetadata(this.getBlockMetadata());
return func_145893_b(this.getWorld(), (double)(this.xCoord + Facing.offsetsXForSide[i]), (double)(this.yCoord + Facing.offsetsYForSide[i]), (double)(this.zCoord + Facing.offsetsZForSide[i]));
}
public static IInventory func_145884_b(IHopper p_145884_0_)
{
return func_145893_b(p_145884_0_.getWorld(), p_145884_0_.getXPos(), p_145884_0_.getYPos() + 1.0D, p_145884_0_.getZPos());
}
public static EntityItem func_145897_a(World p_145897_0_, double p_145897_1_, double p_145897_3_, double p_145897_5_)
{
List list = p_145897_0_.selectEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(p_145897_1_, p_145897_3_, p_145897_5_, p_145897_1_ + 1.0D, p_145897_3_ + 1.0D, p_145897_5_ + 1.0D), IEntitySelector.selectAnything);
return list.size() > 0 ? (EntityItem)list.get(0) : null;
}
public static IInventory func_145893_b(World p_145893_0_, double p_145893_1_, double p_145893_3_, double p_145893_5_)
{
IInventory iinventory = null;
int i = MathHelper.floor_double(p_145893_1_);
int j = MathHelper.floor_double(p_145893_3_);
int k = MathHelper.floor_double(p_145893_5_);
TileEntity tileentity = p_145893_0_.getTileEntity(i, j, k);
if (tileentity != null && tileentity instanceof IInventory)
{
iinventory = (IInventory)tileentity;
if (iinventory instanceof TileEntityChest)
{
Block block = p_145893_0_.getBlock(i, j, k);
if (block instanceof BlockChest)
{
iinventory = ((BlockChest)block).getInventory(p_145893_0_, i, j, k);
}
}
}
if (iinventory == null)
{
List list = p_145893_0_.getEntitiesWithinAABBExcludingEntity((Entity)null, AxisAlignedBB.getBoundingBox(p_145893_1_, p_145893_3_, p_145893_5_, p_145893_1_ + 1.0D, p_145893_3_ + 1.0D, p_145893_5_ + 1.0D), IEntitySelector.selectInventories);
if (list != null && list.size() > 0)
{
iinventory = (IInventory)list.get(p_145893_0_.rand.nextInt(list.size()));
}
}
return iinventory;
}
private static boolean func_145894_a(ItemStack p_145894_0_, ItemStack p_145894_1_)
{
return p_145894_0_.getItem() != p_145894_1_.getItem() ? false : (p_145894_0_.getMetadata() != p_145894_1_.getMetadata() ? false : (p_145894_0_.stackSize > p_145894_0_.getMaxStackSize() ? false : ItemStack.areItemStackTagsEqual(p_145894_0_, p_145894_1_)));
}
/**
* Gets the world X position for this hopper entity.
*/
public double getXPos()
{
return (double)this.xCoord;
}
/**
* Gets the world Y position for this hopper entity.
*/
public double getYPos()
{
return (double)this.yCoord;
}
/**
* Gets the world Z position for this hopper entity.
*/
public double getZPos()
{
return (double)this.zCoord;
}
public void setTransferCooldown(int p_145896_1_)
{
this.transferCooldown = p_145896_1_;
}
public boolean isOnTransferCooldown()
{
return this.transferCooldown > 0;
}
}