package com.arkcraft.module.weapon.common.container;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import com.arkcraft.lib.LogHelper;
import com.arkcraft.module.weapon.common.container.inventory.InventoryAttachment;
public class ContainerInventoryAttachment extends Container
{
/** The Item Inventory for this Container */
private final InventoryAttachment tileInventoryAttachment;
private final int ATTACHMENT_SLOT_COUNT = 1;
public static final int ATTACHMENT_SLOT_YPOS = 30;
public static final int ATTACHMENT_SLOT_XPOS = 79;
public ContainerInventoryAttachment(EntityPlayer player, InventoryPlayer invPlayer, InventoryAttachment tileInventoryAttachment)
{
LogHelper.info("ContainerInventoryCompostBin: constructor called.");
this.tileInventoryAttachment = tileInventoryAttachment;
if (ATTACHMENT_SLOT_COUNT != tileInventoryAttachment.getSizeInventory())
{
LogHelper
.error("Mismatched slot count in container(" + ATTACHMENT_SLOT_COUNT + ") and CompostBinInventory (" + tileInventoryAttachment
.getSizeInventory() + ")");
}
for (int col = 0; col < ATTACHMENT_SLOT_COUNT; col++)
{
int slotIndex = col;
addSlotToContainer(new SlotAttachment(tileInventoryAttachment,
slotIndex, ATTACHMENT_SLOT_XPOS + col * 18,
ATTACHMENT_SLOT_YPOS));
}
/* Player inventory */
final int PLAYER_INVENTORY_YPOS = 84;
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 9; col++)
{
int slotIndex = col + row * 9 + 9;
addSlotToContainer(new Slot(invPlayer, slotIndex, 8 + col * 18,
PLAYER_INVENTORY_YPOS + row * 18));
}
}
/* Hotbar inventory */
final int HOTBAR_YPOS = 142;
for (int col = 0; col < 9; col++)
{
addSlotToContainer(new Slot(invPlayer, col, 8 + col * 18,
HOTBAR_YPOS));
}
}
@Override
public boolean canInteractWith(EntityPlayer player)
{
return tileInventoryAttachment.isUseableByPlayer(player);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index)
{
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(index);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// If item is in our custom Inventory or an ARMOR slot
if (index < ATTACHMENT_SLOT_COUNT)
{
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, ATTACHMENT_SLOT_COUNT, 37,
true)) { return null; }
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place in custom inventory
// or armor slots
else
{
// item is in inventory or action bar
if (index >= ATTACHMENT_SLOT_COUNT)
{
// place in custom inventory
if (!this.mergeItemStack(itemstack1, 0,
ATTACHMENT_SLOT_COUNT, false)) { return null; }
}
}
if (itemstack1.stackSize == 0)
{
slot.putStack((ItemStack) null);
}
else
{
slot.onSlotChanged();
}
if (itemstack1.stackSize == itemstack.stackSize) { return null; }
slot.onPickupFromSlot(player, itemstack1);
}
return itemstack;
}
@Override
public ItemStack slotClick(int slot, int button, int flag, EntityPlayer player)
{
// this will prevent the player from interacting with the item that
// opened the inventory:
if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack() == player
.getHeldItem()) { return null; }
return super.slotClick(slot, button, flag, player);
}
// IMPORTANT to override the mergeItemStack method if your inventory stack
// size limit is 1
/**
* Vanilla method fails to account for stack size limits of one, resulting
* in only one item getting placed in the slot and the rest disappearing
* into thin air; vanilla method also fails to check whether stack is valid
* for slot
*/
@Override
protected boolean mergeItemStack(ItemStack stack, int start, int end, boolean backwards)
{
boolean flag1 = false;
int k = (backwards ? end - 1 : start);
Slot slot;
ItemStack itemstack1;
if (stack.isStackable())
{
while (stack.stackSize > 0 && (!backwards && k < end || backwards && k >= start))
{
slot = (Slot) inventorySlots.get(k);
itemstack1 = slot.getStack();
if (!slot.isItemValid(stack))
{
k += (backwards ? -1 : 1);
continue;
}
if (itemstack1 != null && itemstack1.getItem() == stack
.getItem() && (!stack.getHasSubtypes() || stack
.getItemDamage() == itemstack1.getItemDamage()) && ItemStack
.areItemStackTagsEqual(stack, itemstack1))
{
int l = itemstack1.stackSize + stack.stackSize;
if (l <= stack.getMaxStackSize() && l <= slot
.getSlotStackLimit())
{
stack.stackSize = 0;
itemstack1.stackSize = l;
tileInventoryAttachment.markDirty();
flag1 = true;
}
else if (itemstack1.stackSize < stack.getMaxStackSize() && l < slot
.getSlotStackLimit())
{
stack.stackSize -= stack.getMaxStackSize() - itemstack1.stackSize;
itemstack1.stackSize = stack.getMaxStackSize();
tileInventoryAttachment.markDirty();
flag1 = true;
}
}
k += (backwards ? -1 : 1);
}
}
if (stack.stackSize > 0)
{
k = (backwards ? end - 1 : start);
while (!backwards && k < end || backwards && k >= start)
{
slot = (Slot) inventorySlots.get(k);
itemstack1 = slot.getStack();
if (!slot.isItemValid(stack))
{
k += (backwards ? -1 : 1);
continue;
}
if (itemstack1 == null)
{
int l = stack.stackSize;
if (l <= slot.getSlotStackLimit())
{
slot.putStack(stack.copy());
stack.stackSize = 0;
tileInventoryAttachment.markDirty();
flag1 = true;
break;
}
else
{
putStackInSlot(
k,
new ItemStack(stack.getItem(), slot
.getSlotStackLimit(), stack
.getItemDamage()));
stack.stackSize -= slot.getSlotStackLimit();
tileInventoryAttachment.markDirty();
flag1 = true;
}
}
k += (backwards ? -1 : 1);
}
}
return flag1;
}
private class SlotAttachment extends Slot
{
public SlotAttachment(IInventory inventoryIn, int index, int xPosition, int yPosition)
{
super(inventoryIn, index, xPosition, yPosition);
}
@Override
public boolean isItemValid(ItemStack stack)
{
return tileInventoryAttachment.isItemValidForSlot(this.slotNumber,
stack);
}
}
}