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.Item;
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;
@SideOnly(Side.CLIENT)
private short transactionID;
/** The current drag mode (0 : evenly split, 1 : one item by slot, 2 : not used ?) */
private int dragMode = -1;
/** The current drag event (0 : start, 1 : add slot : 2 : end) */
private int dragEvent;
/** The list of slots where the itemstack holds will be distributed */
private final Set dragSlots = 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();
private static final String __OBFID = "CL_00001730";
/**
* Adds an item slot to this container
*/
protected Slot addSlotToContainer(Slot p_75146_1_)
{
p_75146_1_.slotNumber = this.inventorySlots.size();
this.inventorySlots.add(p_75146_1_);
this.inventoryItemStacks.add((Object)null);
return p_75146_1_;
}
public void onCraftGuiOpened(ICrafting p_75132_1_)
{
if (this.crafters.contains(p_75132_1_))
{
throw new IllegalArgumentException("Listener already listening");
}
else
{
this.crafters.add(p_75132_1_);
p_75132_1_.updateCraftingInventory(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;
}
/**
* Remove this crafting listener from the listener list.
*/
@SideOnly(Side.CLIENT)
public void removeCraftingFromCrafters(ICrafting p_82847_1_)
{
this.crafters.remove(p_82847_1_);
}
/**
* 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 player, int id)
{
return false;
}
public Slot getSlotFromInventory(IInventory p_75147_1_, int p_75147_2_)
{
for (int j = 0; j < this.inventorySlots.size(); ++j)
{
Slot slot = (Slot)this.inventorySlots.get(j);
if (slot.isHere(p_75147_1_, p_75147_2_))
{
return slot;
}
}
return null;
}
public Slot getSlot(int p_75139_1_)
{
return (Slot)this.inventorySlots.get(p_75139_1_);
}
/**
* Take a stack from the specified inventory slot.
*/
public ItemStack transferStackInSlot(EntityPlayer player, int index)
{
Slot slot = (Slot)this.inventorySlots.get(index);
return slot != null ? slot.getStack() : null;
}
/**
* Handles slot click. Args : slotId, clickedButton, mode (0 = basic click, 1 = shift click, 2 = Hotbar, 3 =
* pickBlock, 4 = Drop, 5 = ?, 6 = Double click), player
*
* @param slotId Will be either the slot id in the current Container or -999 if dragging
* @param mode 0 for basic click, 1 for shift-click, 2 for hotbar, 3 for pickBlock, 4 for drop, 5 for item
* distribution drag, 6 for double click
*/
public ItemStack slotClick(int slotId, int clickedButton, int mode, EntityPlayer player)
{
ItemStack itemstack = null;
InventoryPlayer inventoryplayer = player.inventory;
int i1;
ItemStack itemstack3;
if (mode == 5)
{
int l = this.dragEvent;
this.dragEvent = getDragEvent(clickedButton);
if ((l != 1 || this.dragEvent != 2) && l != this.dragEvent)
{
this.resetDrag();
}
else if (inventoryplayer.getItemStack() == null)
{
this.resetDrag();
}
else if (this.dragEvent == 0)
{
this.dragMode = extractDragMode(clickedButton);
if (isValidDragMode(this.dragMode))
{
this.dragEvent = 1;
this.dragSlots.clear();
}
else
{
this.resetDrag();
}
}
else if (this.dragEvent == 1)
{
Slot slot = (Slot)this.inventorySlots.get(slotId);
if (slot != null && canAddItemToSlot(slot, inventoryplayer.getItemStack(), true) && slot.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize > this.dragSlots.size() && this.canDragIntoSlot(slot))
{
this.dragSlots.add(slot);
}
}
else if (this.dragEvent == 2)
{
if (!this.dragSlots.isEmpty())
{
itemstack3 = inventoryplayer.getItemStack().copy();
i1 = inventoryplayer.getItemStack().stackSize;
Iterator iterator = this.dragSlots.iterator();
while (iterator.hasNext())
{
Slot slot1 = (Slot)iterator.next();
if (slot1 != null && canAddItemToSlot(slot1, inventoryplayer.getItemStack(), true) && slot1.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize >= this.dragSlots.size() && this.canDragIntoSlot(slot1))
{
ItemStack itemstack1 = itemstack3.copy();
int j1 = slot1.getHasStack() ? slot1.getStack().stackSize : 0;
computeStackSize(this.dragSlots, this.dragMode, itemstack1, j1);
if (itemstack1.stackSize > itemstack1.getMaxStackSize())
{
itemstack1.stackSize = itemstack1.getMaxStackSize();
}
if (itemstack1.stackSize > slot1.getSlotStackLimit())
{
itemstack1.stackSize = slot1.getSlotStackLimit();
}
i1 -= itemstack1.stackSize - j1;
slot1.putStack(itemstack1);
}
}
itemstack3.stackSize = i1;
if (itemstack3.stackSize <= 0)
{
itemstack3 = null;
}
inventoryplayer.setItemStack(itemstack3);
}
this.resetDrag();
}
else
{
this.resetDrag();
}
}
else if (this.dragEvent != 0)
{
this.resetDrag();
}
else
{
Slot slot2;
int l1;
ItemStack itemstack5;
if ((mode == 0 || mode == 1) && (clickedButton == 0 || clickedButton == 1))
{
if (slotId == -999)
{
if (inventoryplayer.getItemStack() != null && slotId == -999)
{
if (clickedButton == 0)
{
player.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack(), true);
inventoryplayer.setItemStack((ItemStack)null);
}
if (clickedButton == 1)
{
player.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack().splitStack(1), true);
if (inventoryplayer.getItemStack().stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
}
}
}
else if (mode == 1)
{
if (slotId < 0)
{
return null;
}
slot2 = (Slot)this.inventorySlots.get(slotId);
if (slot2 != null && slot2.canTakeStack(player))
{
itemstack3 = this.transferStackInSlot(player, slotId);
if (itemstack3 != null)
{
Item item = itemstack3.getItem();
itemstack = itemstack3.copy();
if (slot2.getStack() != null && slot2.getStack().getItem() == item)
{
this.retrySlotClick(slotId, clickedButton, true, player);
}
}
}
}
else
{
if (slotId < 0)
{
return null;
}
slot2 = (Slot)this.inventorySlots.get(slotId);
if (slot2 != null)
{
itemstack3 = slot2.getStack();
ItemStack itemstack4 = inventoryplayer.getItemStack();
if (itemstack3 != null)
{
itemstack = itemstack3.copy();
}
if (itemstack3 == null)
{
if (itemstack4 != null && slot2.isItemValid(itemstack4))
{
l1 = clickedButton == 0 ? itemstack4.stackSize : 1;
if (l1 > slot2.getSlotStackLimit())
{
l1 = slot2.getSlotStackLimit();
}
if (itemstack4.stackSize >= l1)
{
slot2.putStack(itemstack4.splitStack(l1));
}
if (itemstack4.stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
}
}
else if (slot2.canTakeStack(player))
{
if (itemstack4 == null)
{
l1 = clickedButton == 0 ? itemstack3.stackSize : (itemstack3.stackSize + 1) / 2;
itemstack5 = slot2.decrStackSize(l1);
inventoryplayer.setItemStack(itemstack5);
if (itemstack3.stackSize == 0)
{
slot2.putStack((ItemStack)null);
}
slot2.onPickupFromSlot(player, inventoryplayer.getItemStack());
}
else if (slot2.isItemValid(itemstack4))
{
if (itemstack3.getItem() == itemstack4.getItem() && itemstack3.getMetadata() == itemstack4.getMetadata() && ItemStack.areItemStackTagsEqual(itemstack3, itemstack4))
{
l1 = clickedButton == 0 ? itemstack4.stackSize : 1;
if (l1 > slot2.getSlotStackLimit() - itemstack3.stackSize)
{
l1 = slot2.getSlotStackLimit() - itemstack3.stackSize;
}
if (l1 > itemstack4.getMaxStackSize() - itemstack3.stackSize)
{
l1 = itemstack4.getMaxStackSize() - itemstack3.stackSize;
}
itemstack4.splitStack(l1);
if (itemstack4.stackSize == 0)
{
inventoryplayer.setItemStack((ItemStack)null);
}
itemstack3.stackSize += l1;
}
else if (itemstack4.stackSize <= slot2.getSlotStackLimit())
{
slot2.putStack(itemstack4);
inventoryplayer.setItemStack(itemstack3);
}
}
else if (itemstack3.getItem() == itemstack4.getItem() && itemstack4.getMaxStackSize() > 1 && (!itemstack3.getHasSubtypes() || itemstack3.getMetadata() == itemstack4.getMetadata()) && ItemStack.areItemStackTagsEqual(itemstack3, itemstack4))
{
l1 = itemstack3.stackSize;
if (l1 > 0 && l1 + itemstack4.stackSize <= itemstack4.getMaxStackSize())
{
itemstack4.stackSize += l1;
itemstack3 = slot2.decrStackSize(l1);
if (itemstack3.stackSize == 0)
{
slot2.putStack((ItemStack)null);
}
slot2.onPickupFromSlot(player, inventoryplayer.getItemStack());
}
}
}
slot2.onSlotChanged();
}
}
}
else if (mode == 2 && clickedButton >= 0 && clickedButton < 9)
{
slot2 = (Slot)this.inventorySlots.get(slotId);
if (slot2.canTakeStack(player))
{
itemstack3 = inventoryplayer.getStackInSlot(clickedButton);
boolean flag = itemstack3 == null || slot2.inventory == inventoryplayer && slot2.isItemValid(itemstack3);
l1 = -1;
if (!flag)
{
l1 = inventoryplayer.getFirstEmptyStack();
flag |= l1 > -1;
}
if (slot2.getHasStack() && flag)
{
itemstack5 = slot2.getStack();
inventoryplayer.setInventorySlotContents(clickedButton, itemstack5.copy());
if ((slot2.inventory != inventoryplayer || !slot2.isItemValid(itemstack3)) && itemstack3 != null)
{
if (l1 > -1)
{
inventoryplayer.addItemStackToInventory(itemstack3);
slot2.decrStackSize(itemstack5.stackSize);
slot2.putStack((ItemStack)null);
slot2.onPickupFromSlot(player, itemstack5);
}
}
else
{
slot2.decrStackSize(itemstack5.stackSize);
slot2.putStack(itemstack3);
slot2.onPickupFromSlot(player, itemstack5);
}
}
else if (!slot2.getHasStack() && itemstack3 != null && slot2.isItemValid(itemstack3))
{
inventoryplayer.setInventorySlotContents(clickedButton, (ItemStack)null);
slot2.putStack(itemstack3);
}
}
}
else if (mode == 3 && player.capabilities.isCreativeMode && inventoryplayer.getItemStack() == null && slotId >= 0)
{
slot2 = (Slot)this.inventorySlots.get(slotId);
if (slot2 != null && slot2.getHasStack())
{
itemstack3 = slot2.getStack().copy();
itemstack3.stackSize = itemstack3.getMaxStackSize();
inventoryplayer.setItemStack(itemstack3);
}
}
else if (mode == 4 && inventoryplayer.getItemStack() == null && slotId >= 0)
{
slot2 = (Slot)this.inventorySlots.get(slotId);
if (slot2 != null && slot2.getHasStack() && slot2.canTakeStack(player))
{
itemstack3 = slot2.decrStackSize(clickedButton == 0 ? 1 : slot2.getStack().stackSize);
slot2.onPickupFromSlot(player, itemstack3);
player.dropPlayerItemWithRandomChoice(itemstack3, true);
}
}
else if (mode == 6 && slotId >= 0)
{
slot2 = (Slot)this.inventorySlots.get(slotId);
itemstack3 = inventoryplayer.getItemStack();
if (itemstack3 != null && (slot2 == null || !slot2.getHasStack() || !slot2.canTakeStack(player)))
{
i1 = clickedButton == 0 ? 0 : this.inventorySlots.size() - 1;
l1 = clickedButton == 0 ? 1 : -1;
for (int i2 = 0; i2 < 2; ++i2)
{
for (int j2 = i1; j2 >= 0 && j2 < this.inventorySlots.size() && itemstack3.stackSize < itemstack3.getMaxStackSize(); j2 += l1)
{
Slot slot3 = (Slot)this.inventorySlots.get(j2);
if (slot3.getHasStack() && canAddItemToSlot(slot3, itemstack3, true) && slot3.canTakeStack(player) && this.func_94530_a(itemstack3, slot3) && (i2 != 0 || slot3.getStack().stackSize != slot3.getStack().getMaxStackSize()))
{
int k1 = Math.min(itemstack3.getMaxStackSize() - itemstack3.stackSize, slot3.getStack().stackSize);
ItemStack itemstack2 = slot3.decrStackSize(k1);
itemstack3.stackSize += k1;
if (itemstack2.stackSize <= 0)
{
slot3.putStack((ItemStack)null);
}
slot3.onPickupFromSlot(player, itemstack2);
}
}
}
}
this.detectAndSendChanges();
}
}
return itemstack;
}
public boolean func_94530_a(ItemStack p_94530_1_, Slot p_94530_2_)
{
return true;
}
protected void retrySlotClick(int p_75133_1_, int p_75133_2_, boolean p_75133_3_, EntityPlayer p_75133_4_)
{
this.slotClick(p_75133_1_, p_75133_2_, 1, p_75133_4_);
}
/**
* Called when the container is closed.
*/
public void onContainerClosed(EntityPlayer p_75134_1_)
{
InventoryPlayer inventoryplayer = p_75134_1_.inventory;
if (inventoryplayer.getItemStack() != null)
{
p_75134_1_.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack(), false);
inventoryplayer.setItemStack((ItemStack)null);
}
}
/**
* Callback for when the crafting matrix is changed.
*/
public void onCraftMatrixChanged(IInventory p_75130_1_)
{
this.detectAndSendChanges();
}
/**
* args: slotID, itemStack to put in slot
*/
public void putStackInSlot(int p_75141_1_, ItemStack p_75141_2_)
{
this.getSlot(p_75141_1_).putStack(p_75141_2_);
}
/**
* places itemstacks in first x slots, x being aitemstack.lenght
*/
@SideOnly(Side.CLIENT)
public void putStacksInSlots(ItemStack[] p_75131_1_)
{
for (int i = 0; i < p_75131_1_.length; ++i)
{
this.getSlot(i).putStack(p_75131_1_[i]);
}
}
@SideOnly(Side.CLIENT)
public void updateProgressBar(int p_75137_1_, int p_75137_2_) {}
/**
* Gets a unique transaction ID. Parameter is unused.
*/
@SideOnly(Side.CLIENT)
public short getNextTransactionID(InventoryPlayer p_75136_1_)
{
++this.transactionID;
return this.transactionID;
}
/**
* gets whether or not the player can craft in this inventory or not
*/
public boolean getCanCraft(EntityPlayer p_75129_1_)
{
return !this.playerList.contains(p_75129_1_);
}
/**
* sets whether the player can craft in this inventory or not
*/
public void setCanCraft(EntityPlayer p_75128_1_, boolean p_75128_2_)
{
if (p_75128_2_)
{
this.playerList.remove(p_75128_1_);
}
else
{
this.playerList.add(p_75128_1_);
}
}
public abstract boolean canInteractWith(EntityPlayer player);
/**
* Merges provided ItemStack with the first avaliable one in the container/player inventor between minIndex
* (included) and maxIndex (excluded). Args : stack, minIndex, maxIndex, negativDirection. /!\ the Container
* implementation do not check if the item is valid for the slot
*/
protected boolean mergeItemStack(ItemStack p_75135_1_, int p_75135_2_, int p_75135_3_, boolean p_75135_4_)
{
boolean flag1 = false;
int k = p_75135_2_;
if (p_75135_4_)
{
k = p_75135_3_ - 1;
}
Slot slot;
ItemStack itemstack1;
if (p_75135_1_.isStackable())
{
while (p_75135_1_.stackSize > 0 && (!p_75135_4_ && k < p_75135_3_ || p_75135_4_ && k >= p_75135_2_))
{
slot = (Slot)this.inventorySlots.get(k);
itemstack1 = slot.getStack();
if (itemstack1 != null && itemstack1.getItem() == p_75135_1_.getItem() && (!p_75135_1_.getHasSubtypes() || p_75135_1_.getMetadata() == itemstack1.getMetadata()) && ItemStack.areItemStackTagsEqual(p_75135_1_, itemstack1))
{
int l = itemstack1.stackSize + p_75135_1_.stackSize;
if (l <= p_75135_1_.getMaxStackSize())
{
p_75135_1_.stackSize = 0;
itemstack1.stackSize = l;
slot.onSlotChanged();
flag1 = true;
}
else if (itemstack1.stackSize < p_75135_1_.getMaxStackSize())
{
p_75135_1_.stackSize -= p_75135_1_.getMaxStackSize() - itemstack1.stackSize;
itemstack1.stackSize = p_75135_1_.getMaxStackSize();
slot.onSlotChanged();
flag1 = true;
}
}
if (p_75135_4_)
{
--k;
}
else
{
++k;
}
}
}
if (p_75135_1_.stackSize > 0)
{
if (p_75135_4_)
{
k = p_75135_3_ - 1;
}
else
{
k = p_75135_2_;
}
while (!p_75135_4_ && k < p_75135_3_ || p_75135_4_ && k >= p_75135_2_)
{
slot = (Slot)this.inventorySlots.get(k);
itemstack1 = slot.getStack();
if (itemstack1 == null)
{
slot.putStack(p_75135_1_.copy());
slot.onSlotChanged();
p_75135_1_.stackSize = 0;
flag1 = true;
break;
}
if (p_75135_4_)
{
--k;
}
else
{
++k;
}
}
}
return flag1;
}
/**
* Extracts the drag mode. Args : eventButton. Return (0 : evenly split, 1 : one item by slot, 2 : not used ?)
*/
public static int extractDragMode(int p_94529_0_)
{
return p_94529_0_ >> 2 & 3;
}
/**
* Args : clickedButton, Returns (0 : start drag, 1 : add slot, 2 : end drag)
*/
public static int getDragEvent(int p_94532_0_)
{
return p_94532_0_ & 3;
}
@SideOnly(Side.CLIENT)
public static int func_94534_d(int p_94534_0_, int p_94534_1_)
{
return p_94534_0_ & 3 | (p_94534_1_ & 3) << 2;
}
/**
* Args : dragMode. Returns true if dragMode = 0 (evenly split) or = 1 (one item by slot)
*/
public static boolean isValidDragMode(int p_94528_0_)
{
return p_94528_0_ == 0 || p_94528_0_ == 1;
}
/**
* Reset the drag fields
*/
protected void resetDrag()
{
this.dragEvent = 0;
this.dragSlots.clear();
}
/**
* Checks if it's possible to add the given itemstack to the given slot.
*
* @param stackSizeMatters Will check if adding items to the slot will stack larger than the max stack size
*/
public static boolean canAddItemToSlot(Slot slotIn, ItemStack stack, boolean stackSizeMatters)
{
boolean flag1 = slotIn == null || !slotIn.getHasStack();
if (slotIn != null && slotIn.getHasStack() && stack != null && stack.isItemEqual(slotIn.getStack()) && ItemStack.areItemStackTagsEqual(slotIn.getStack(), stack))
{
int i = stackSizeMatters ? 0 : stack.stackSize;
flag1 |= slotIn.getStack().stackSize + i <= stack.getMaxStackSize();
}
return flag1;
}
/**
* Compute the new stack size, Returns the stack with the new size. Args : dragSlots, dragMode, dragStack,
* slotStackSize
*/
public static void computeStackSize(Set p_94525_0_, int p_94525_1_, ItemStack p_94525_2_, int p_94525_3_)
{
switch (p_94525_1_)
{
case 0:
p_94525_2_.stackSize = MathHelper.floor_float((float)p_94525_2_.stackSize / (float)p_94525_0_.size());
break;
case 1:
p_94525_2_.stackSize = 1;
}
p_94525_2_.stackSize += p_94525_3_;
}
/**
* Returns true if the player can "drag-spilt" items into this slot,. returns true by default. Called to check if
* the slot can be added to a list of Slots to split the held ItemStack across.
*/
public boolean canDragIntoSlot(Slot p_94531_1_)
{
return true;
}
public static int calcRedstoneFromInventory(IInventory p_94526_0_)
{
if (p_94526_0_ == null)
{
return 0;
}
else
{
int i = 0;
float f = 0.0F;
for (int j = 0; j < p_94526_0_.getSizeInventory(); ++j)
{
ItemStack itemstack = p_94526_0_.getStackInSlot(j);
if (itemstack != null)
{
f += (float)itemstack.stackSize / (float)Math.min(p_94526_0_.getInventoryStackLimit(), itemstack.getMaxStackSize());
++i;
}
}
f /= (float)p_94526_0_.getSizeInventory();
return MathHelper.floor_float(f * 14.0F) + (i > 0 ? 1 : 0);
}
}
}