package net.minecraft.inventory;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
public abstract class Container
{
/** the list of all items(stacks) for the corresponding slot */
public List inventoryItemStacks = new ArrayList();
/** the list of all slots in the inventory */
public List inventorySlots = new ArrayList();
public int windowId = 0;
private short transactionID = 0;
private int field_94535_f = -1;
private int field_94536_g = 0;
private final Set field_94537_h = new HashSet();
/**
* list of all people that need to be notified when this craftinventory changes
*/
protected List crafters = new ArrayList();
private Set playerList = new HashSet();
/**
* the slot is assumed empty
*/
protected Slot addSlotToContainer(Slot par1Slot)
{
par1Slot.slotNumber = this.inventorySlots.size();
this.inventorySlots.add(par1Slot);
this.inventoryItemStacks.add((Object)null);
return par1Slot;
}
public void addCraftingToCrafters(ICrafting par1ICrafting)
{
if (this.crafters.contains(par1ICrafting))
{
throw new IllegalArgumentException("Listener already listening");
}
else
{
this.crafters.add(par1ICrafting);
par1ICrafting.sendContainerAndContentsToPlayer(this, this.getInventory());
this.detectAndSendChanges();
}
}
/**
* returns a list if itemStacks, for each slot.
*/
public List getInventory()
{
ArrayList arraylist = new ArrayList();
for (int i = 0; i < this.inventorySlots.size(); ++i)
{
arraylist.add(((Slot)this.inventorySlots.get(i)).getStack());
}
return arraylist;
}
@SideOnly(Side.CLIENT)
/**
* Remove this crafting listener from the listener list.
*/
public void removeCraftingFromCrafters(ICrafting par1ICrafting)
{
this.crafters.remove(par1ICrafting);
}
/**
* Looks for changes made in the container, sends them to every listener.
*/
public void detectAndSendChanges()
{
for (int i = 0; i < this.inventorySlots.size(); ++i)
{
ItemStack itemstack = ((Slot)this.inventorySlots.get(i)).getStack();
ItemStack itemstack1 = (ItemStack)this.inventoryItemStacks.get(i);
if (!ItemStack.areItemStacksEqual(itemstack1, itemstack))
{
itemstack1 = itemstack == null ? null : itemstack.copy();
this.inventoryItemStacks.set(i, itemstack1);
for (int j = 0; j < this.crafters.size(); ++j)
{
((ICrafting)this.crafters.get(j)).sendSlotContents(this, i, itemstack1);
}
}
}
}
/**
* enchants the item on the table using the specified slot; also deducts XP from player
*/
public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2)
{
return false;
}
public Slot getSlotFromInventory(IInventory par1IInventory, int par2)
{
for (int j = 0; j < this.inventorySlots.size(); ++j)
{
Slot slot = (Slot)this.inventorySlots.get(j);
if (slot.isSlotInInventory(par1IInventory, par2))
{
return slot;
}
}
return null;
}
public Slot getSlot(int par1)
{
return (Slot)this.inventorySlots.get(par1);
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
*/
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
Slot slot = (Slot)this.inventorySlots.get(par2);
return slot != null ? slot.getStack() : null;
}
public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer)
{
ItemStack itemstack = null;
InventoryPlayer inventoryplayer = par4EntityPlayer.inventory;
int l;
ItemStack itemstack1;
if (par3 == 5)
{
int i1 = this.field_94536_g;
this.field_94536_g = func_94532_c(par2);
if ((i1 != 1 || this.field_94536_g != 2) && i1 != this.field_94536_g)
{
this.func_94533_d();
}
else if (inventoryplayer.getItemStack() == null)
{
this.func_94533_d();
}
else if (this.field_94536_g == 0)
{
this.field_94535_f = func_94529_b(par2);
if (func_94528_d(this.field_94535_f))
{
this.field_94536_g = 1;
this.field_94537_h.clear();
}
else
{
this.func_94533_d();
}
}
else if (this.field_94536_g == 1)
{
Slot slot = (Slot)this.inventorySlots.get(par1);
if (slot != null && func_94527_a(slot, inventoryplayer.getItemStack(), true) && slot.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize > this.field_94537_h.size() && this.func_94531_b(slot))
{
this.field_94537_h.add(slot);
}
}
else if (this.field_94536_g == 2)
{
if (!this.field_94537_h.isEmpty())
{
itemstack1 = inventoryplayer.getItemStack().copy();
l = inventoryplayer.getItemStack().stackSize;
Iterator iterator = this.field_94537_h.iterator();
while (iterator.hasNext())
{
Slot slot1 = (Slot)iterator.next();
if (slot1 != null && func_94527_a(slot1, inventoryplayer.getItemStack(), true) && slot1.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize >= this.field_94537_h.size() && this.func_94531_b(slot1))
{
ItemStack itemstack2 = itemstack1.copy();
int j1 = slot1.getHasStack() ? slot1.getStack().stackSize : 0;
func_94525_a(this.field_94537_h, this.field_94535_f, itemstack2, j1);
if (itemstack2.stackSize > itemstack2.getMaxStackSize())
{
itemstack2.stackSize = itemstack2.getMaxStackSize();
}
if (itemstack2.stackSize > slot1.getSlotStackLimit())
{
itemstack2.stackSize = slot1.getSlotStackLimit();
}
l -= itemstack2.stackSize - j1;
slot1.putStack(itemstack2);
}
}
itemstack1.stackSize = l;
if (itemstack1.stackSize <= 0)
{
itemstack1 = null;
}
inventoryplayer.setItemStack(itemstack1);
}
this.func_94533_d();
}
else
{
this.func_94533_d();
}
}
else if (this.field_94536_g != 0)
{
this.func_94533_d();
}
else
{
Slot slot2;
int k1;
ItemStack itemstack3;
if ((par3 == 0 || par3 == 1) && (par2 == 0 || par2 == 1))
{
if (par1 == -999)
{
if (inventoryplayer.getItemStack() != null && par1 == -999)
{
if (par2 == 0)
{
par4EntityPlayer.dropPlayerItem(inventoryplayer.getItemStack());
inventoryplayer.setItemStack((ItemStack)null);
}
if (par2 == 1)
{
par4EntityPlayer.dropPlayerItem(inventoryplayer.getItemStack().splitStack(1));
if (inventoryplayer.getItemStack().stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
}
}
}
else if (par3 == 1)
{
if (par1 < 0)
{
return null;
}
slot2 = (Slot)this.inventorySlots.get(par1);
if (slot2 != null && slot2.canTakeStack(par4EntityPlayer))
{
itemstack1 = this.transferStackInSlot(par4EntityPlayer, par1);
if (itemstack1 != null)
{
l = itemstack1.itemID;
itemstack = itemstack1.copy();
if (slot2 != null && slot2.getStack() != null && slot2.getStack().itemID == l)
{
this.retrySlotClick(par1, par2, true, par4EntityPlayer);
}
}
}
}
else
{
if (par1 < 0)
{
return null;
}
slot2 = (Slot)this.inventorySlots.get(par1);
if (slot2 != null)
{
itemstack1 = slot2.getStack();
ItemStack itemstack4 = inventoryplayer.getItemStack();
if (itemstack1 != null)
{
itemstack = itemstack1.copy();
}
if (itemstack1 == null)
{
if (itemstack4 != null && slot2.isItemValid(itemstack4))
{
k1 = par2 == 0 ? itemstack4.stackSize : 1;
if (k1 > slot2.getSlotStackLimit())
{
k1 = slot2.getSlotStackLimit();
}
slot2.putStack(itemstack4.splitStack(k1));
if (itemstack4.stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
}
}
else if (slot2.canTakeStack(par4EntityPlayer))
{
if (itemstack4 == null)
{
k1 = par2 == 0 ? itemstack1.stackSize : (itemstack1.stackSize + 1) / 2;
itemstack3 = slot2.decrStackSize(k1);
inventoryplayer.setItemStack(itemstack3);
if (itemstack1.stackSize == 0)
{
slot2.putStack((ItemStack)null);
}
slot2.onPickupFromSlot(par4EntityPlayer, inventoryplayer.getItemStack());
}
else if (slot2.isItemValid(itemstack4))
{
if (itemstack1.itemID == itemstack4.itemID && itemstack1.getItemDamage() == itemstack4.getItemDamage() && ItemStack.areItemStackTagsEqual(itemstack1, itemstack4))
{
k1 = par2 == 0 ? itemstack4.stackSize : 1;
if (k1 > slot2.getSlotStackLimit() - itemstack1.stackSize)
{
k1 = slot2.getSlotStackLimit() - itemstack1.stackSize;
}
if (k1 > itemstack4.getMaxStackSize() - itemstack1.stackSize)
{
k1 = itemstack4.getMaxStackSize() - itemstack1.stackSize;
}
itemstack4.splitStack(k1);
if (itemstack4.stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
itemstack1.stackSize += k1;
}
else if (itemstack4.stackSize <= slot2.getSlotStackLimit())
{
slot2.putStack(itemstack4);
inventoryplayer.setItemStack(itemstack1);
}
}
else if (itemstack1.itemID == itemstack4.itemID && itemstack4.getMaxStackSize() > 1 && (!itemstack1.getHasSubtypes() || itemstack1.getItemDamage() == itemstack4.getItemDamage()) && ItemStack.areItemStackTagsEqual(itemstack1, itemstack4))
{
k1 = itemstack1.stackSize;
if (k1 > 0 && k1 + itemstack4.stackSize <= itemstack4.getMaxStackSize())
{
itemstack4.stackSize += k1;
itemstack1 = slot2.decrStackSize(k1);
if (itemstack1.stackSize == 0)
{
slot2.putStack((ItemStack)null);
}
slot2.onPickupFromSlot(par4EntityPlayer, inventoryplayer.getItemStack());
}
}
}
slot2.onSlotChanged();
}
}
}
else if (par3 == 2 && par2 >= 0 && par2 < 9)
{
slot2 = (Slot)this.inventorySlots.get(par1);
if (slot2.canTakeStack(par4EntityPlayer))
{
itemstack1 = inventoryplayer.getStackInSlot(par2);
boolean flag = itemstack1 == null || slot2.inventory == inventoryplayer && slot2.isItemValid(itemstack1);
k1 = -1;
if (!flag)
{
k1 = inventoryplayer.getFirstEmptyStack();
flag |= k1 > -1;
}
if (slot2.getHasStack() && flag)
{
itemstack3 = slot2.getStack();
inventoryplayer.setInventorySlotContents(par2, itemstack3.copy());
if ((slot2.inventory != inventoryplayer || !slot2.isItemValid(itemstack1)) && itemstack1 != null)
{
if (k1 > -1)
{
inventoryplayer.addItemStackToInventory(itemstack1);
slot2.decrStackSize(itemstack3.stackSize);
slot2.putStack((ItemStack)null);
slot2.onPickupFromSlot(par4EntityPlayer, itemstack3);
}
}
else
{
slot2.decrStackSize(itemstack3.stackSize);
slot2.putStack(itemstack1);
slot2.onPickupFromSlot(par4EntityPlayer, itemstack3);
}
}
else if (!slot2.getHasStack() && itemstack1 != null && slot2.isItemValid(itemstack1))
{
inventoryplayer.setInventorySlotContents(par2, (ItemStack)null);
slot2.putStack(itemstack1);
}
}
}
else if (par3 == 3 && par4EntityPlayer.capabilities.isCreativeMode && inventoryplayer.getItemStack() == null && par1 >= 0)
{
slot2 = (Slot)this.inventorySlots.get(par1);
if (slot2 != null && slot2.getHasStack())
{
itemstack1 = slot2.getStack().copy();
itemstack1.stackSize = itemstack1.getMaxStackSize();
inventoryplayer.setItemStack(itemstack1);
}
}
else if (par3 == 4 && inventoryplayer.getItemStack() == null && par1 >= 0)
{
slot2 = (Slot)this.inventorySlots.get(par1);
if (slot2 != null && slot2.getHasStack() && slot2.canTakeStack(par4EntityPlayer))
{
itemstack1 = slot2.decrStackSize(par2 == 0 ? 1 : slot2.getStack().stackSize);
slot2.onPickupFromSlot(par4EntityPlayer, itemstack1);
par4EntityPlayer.dropPlayerItem(itemstack1);
}
}
else if (par3 == 6 && par1 >= 0)
{
slot2 = (Slot)this.inventorySlots.get(par1);
itemstack1 = inventoryplayer.getItemStack();
if (itemstack1 != null && (slot2 == null || !slot2.getHasStack() || !slot2.canTakeStack(par4EntityPlayer)))
{
l = par2 == 0 ? 0 : this.inventorySlots.size() - 1;
k1 = par2 == 0 ? 1 : -1;
for (int l1 = 0; l1 < 2; ++l1)
{
for (int i2 = l; i2 >= 0 && i2 < this.inventorySlots.size() && itemstack1.stackSize < itemstack1.getMaxStackSize(); i2 += k1)
{
Slot slot3 = (Slot)this.inventorySlots.get(i2);
if (slot3.getHasStack() && func_94527_a(slot3, itemstack1, true) && slot3.canTakeStack(par4EntityPlayer) && this.func_94530_a(itemstack1, slot3) && (l1 != 0 || slot3.getStack().stackSize != slot3.getStack().getMaxStackSize()))
{
int j2 = Math.min(itemstack1.getMaxStackSize() - itemstack1.stackSize, slot3.getStack().stackSize);
ItemStack itemstack5 = slot3.decrStackSize(j2);
itemstack1.stackSize += j2;
if (itemstack5.stackSize <= 0)
{
slot3.putStack((ItemStack)null);
}
slot3.onPickupFromSlot(par4EntityPlayer, itemstack5);
}
}
}
}
this.detectAndSendChanges();
}
}
return itemstack;
}
public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot)
{
return true;
}
protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer)
{
this.slotClick(par1, par2, 1, par4EntityPlayer);
}
/**
* Callback for when the crafting gui is closed.
*/
public void onCraftGuiClosed(EntityPlayer par1EntityPlayer)
{
InventoryPlayer inventoryplayer = par1EntityPlayer.inventory;
if (inventoryplayer.getItemStack() != null)
{
par1EntityPlayer.dropPlayerItem(inventoryplayer.getItemStack());
inventoryplayer.setItemStack((ItemStack)null);
}
}
/**
* Callback for when the crafting matrix is changed.
*/
public void onCraftMatrixChanged(IInventory par1IInventory)
{
this.detectAndSendChanges();
}
/**
* args: slotID, itemStack to put in slot
*/
public void putStackInSlot(int par1, ItemStack par2ItemStack)
{
this.getSlot(par1).putStack(par2ItemStack);
}
@SideOnly(Side.CLIENT)
/**
* places itemstacks in first x slots, x being aitemstack.lenght
*/
public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack)
{
for (int i = 0; i < par1ArrayOfItemStack.length; ++i)
{
this.getSlot(i).putStack(par1ArrayOfItemStack[i]);
}
}
@SideOnly(Side.CLIENT)
public void updateProgressBar(int par1, int par2) {}
@SideOnly(Side.CLIENT)
/**
* Gets a unique transaction ID. Parameter is unused.
*/
public short getNextTransactionID(InventoryPlayer par1InventoryPlayer)
{
++this.transactionID;
return this.transactionID;
}
/**
* NotUsing because adding a player twice is an error
*/
public boolean isPlayerNotUsingContainer(EntityPlayer par1EntityPlayer)
{
return !this.playerList.contains(par1EntityPlayer);
}
/**
* adds or removes the player from the container based on par2
*/
public void setPlayerIsPresent(EntityPlayer par1EntityPlayer, boolean par2)
{
if (par2)
{
this.playerList.remove(par1EntityPlayer);
}
else
{
this.playerList.add(par1EntityPlayer);
}
}
public abstract boolean canInteractWith(EntityPlayer entityplayer);
/**
* merges provided ItemStack with the first avaliable one in the container/player inventory
*/
protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4)
{
boolean flag1 = false;
int k = par2;
if (par4)
{
k = par3 - 1;
}
Slot slot;
ItemStack itemstack1;
if (par1ItemStack.isStackable())
{
while (par1ItemStack.stackSize > 0 && (!par4 && k < par3 || par4 && k >= par2))
{
slot = (Slot)this.inventorySlots.get(k);
itemstack1 = slot.getStack();
if (itemstack1 != null && itemstack1.itemID == par1ItemStack.itemID && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == itemstack1.getItemDamage()) && ItemStack.areItemStackTagsEqual(par1ItemStack, itemstack1))
{
int l = itemstack1.stackSize + par1ItemStack.stackSize;
if (l <= par1ItemStack.getMaxStackSize())
{
par1ItemStack.stackSize = 0;
itemstack1.stackSize = l;
slot.onSlotChanged();
flag1 = true;
}
else if (itemstack1.stackSize < par1ItemStack.getMaxStackSize())
{
par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - itemstack1.stackSize;
itemstack1.stackSize = par1ItemStack.getMaxStackSize();
slot.onSlotChanged();
flag1 = true;
}
}
if (par4)
{
--k;
}
else
{
++k;
}
}
}
if (par1ItemStack.stackSize > 0)
{
if (par4)
{
k = par3 - 1;
}
else
{
k = par2;
}
while (!par4 && k < par3 || par4 && k >= par2)
{
slot = (Slot)this.inventorySlots.get(k);
itemstack1 = slot.getStack();
if (itemstack1 == null)
{
slot.putStack(par1ItemStack.copy());
slot.onSlotChanged();
par1ItemStack.stackSize = 0;
flag1 = true;
break;
}
if (par4)
{
--k;
}
else
{
++k;
}
}
}
return flag1;
}
public static int func_94529_b(int par0)
{
return par0 >> 2 & 3;
}
public static int func_94532_c(int par0)
{
return par0 & 3;
}
@SideOnly(Side.CLIENT)
public static int func_94534_d(int par0, int par1)
{
return par0 & 3 | (par1 & 3) << 2;
}
public static boolean func_94528_d(int par0)
{
return par0 == 0 || par0 == 1;
}
protected void func_94533_d()
{
this.field_94536_g = 0;
this.field_94537_h.clear();
}
public static boolean func_94527_a(Slot par0Slot, ItemStack par1ItemStack, boolean par2)
{
boolean flag1 = par0Slot == null || !par0Slot.getHasStack();
if (par0Slot != null && par0Slot.getHasStack() && par1ItemStack != null && par1ItemStack.isItemEqual(par0Slot.getStack()) && ItemStack.areItemStackTagsEqual(par0Slot.getStack(), par1ItemStack))
{
int i = par2 ? 0 : par1ItemStack.stackSize;
flag1 |= par0Slot.getStack().stackSize + i <= par1ItemStack.getMaxStackSize();
}
return flag1;
}
public static void func_94525_a(Set par0Set, int par1, ItemStack par2ItemStack, int par3)
{
switch (par1)
{
case 0:
par2ItemStack.stackSize = MathHelper.floor_float((float)par2ItemStack.stackSize / (float)par0Set.size());
break;
case 1:
par2ItemStack.stackSize = 1;
}
par2ItemStack.stackSize += par3;
}
public boolean func_94531_b(Slot par1Slot)
{
return true;
}
public static int calcRedstoneFromInventory(IInventory par0IInventory)
{
if (par0IInventory == null)
{
return 0;
}
else
{
int i = 0;
float f = 0.0F;
for (int j = 0; j < par0IInventory.getSizeInventory(); ++j)
{
ItemStack itemstack = par0IInventory.getStackInSlot(j);
if (itemstack != null)
{
f += (float)itemstack.stackSize / (float)Math.min(par0IInventory.getInventoryStackLimit(), itemstack.getMaxStackSize());
++i;
}
}
f /= (float)par0IInventory.getSizeInventory();
return MathHelper.floor_float(f * 14.0F) + (i > 0 ? 1 : 0);
}
}
}