package redstonedistortion.factory.containers;
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 redstonedistortion.utils.helpers.SlotPhantom;
/**
* Copyright (c) 2014, AEnterprise
* http://buildcraftadditions.wordpress.com/
* Eureka is distributed under the terms of GNU GPL v3.0
* Please check the contents of the license located in
* http://buildcraftadditions.wordpress.com/wiki/licensing-stuff/
*/
public class ContainerBase<T> extends Container {
protected final InventoryPlayer inventoryPlayer;
protected final T inventory;
private boolean canShift = true;
public ContainerBase(InventoryPlayer inventoryPlayer, T inventory) {
this.inventoryPlayer = inventoryPlayer;
this.inventory = inventory;
}
public ContainerBase setCanShift(boolean canShift) {
this.canShift = canShift;
return this;
}
protected void addPlayerInventory(int x, int y) {
if (inventoryPlayer != null) {
for (int inventoryRowIndex = 0; inventoryRowIndex < 3; ++inventoryRowIndex)
for (int inventoryColumnIndex = 0; inventoryColumnIndex < 9; ++inventoryColumnIndex)
addSlotToContainer(new Slot(inventoryPlayer, 9 + inventoryColumnIndex + inventoryRowIndex * 9, x + inventoryColumnIndex * 18, y + inventoryRowIndex * 18));
for (int hotBarIndex = 0; hotBarIndex < 9; ++hotBarIndex)
addSlotToContainer(new Slot(inventoryPlayer, hotBarIndex, 8 + hotBarIndex * 18, y + 58));
}
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int slotIndex) {
int numSlots = inventorySlots.size();
if (slotIndex < 0 || slotIndex >= numSlots)
return null;
Slot slot = (Slot) inventorySlots.get(slotIndex);
ItemStack originalStack = null;
if (slot != null && slot.getHasStack()) {
ItemStack stackInSlot = slot.getStack();
originalStack = stackInSlot.copy();
if (slotIndex >= numSlots - 9 * 4 && tryShiftItem(stackInSlot, numSlots)) {
// NOOP
} else if (slotIndex >= numSlots - 9 * 4 && slotIndex < numSlots - 9) {
if (!shiftItemStack(stackInSlot, numSlots - 9, numSlots)) {
return null;
}
} else if (slotIndex >= numSlots - 9 && slotIndex < numSlots) {
if (!shiftItemStack(stackInSlot, numSlots - 9 * 4, numSlots - 9)) {
return null;
}
} else if (!shiftItemStack(stackInSlot, numSlots - 9 * 4, numSlots)) {
return null;
}
slot.onSlotChange(stackInSlot, originalStack);
if (stackInSlot.stackSize <= 0) {
slot.putStack(null);
} else {
slot.onSlotChanged();
}
if (stackInSlot.stackSize == originalStack.stackSize) {
return null;
}
slot.onPickupFromSlot(player, stackInSlot);
}
return originalStack;
}
private boolean tryShiftItem(ItemStack stackToShift, int numSlots) {
for (int machineIndex = 0; machineIndex < numSlots - 9 * 4; machineIndex++) {
Slot slot = (Slot) inventorySlots.get(machineIndex);
if (!slot.isItemValid(stackToShift)) {
continue;
}
if (shiftItemStack(stackToShift, machineIndex, machineIndex + 1)) {
return true;
}
}
return false;
}
private boolean shiftItemStack(ItemStack stackToShift, int start, int end) {
if (!canShift)
return false;
boolean changed = false;
if (stackToShift.isStackable()) {
for (int slotIndex = start; stackToShift.stackSize > 0 && slotIndex < end; slotIndex++) {
Slot slot = (Slot) inventorySlots.get(slotIndex);
ItemStack stackInSlot = slot.getStack();
if (stackInSlot != null && canStacksMerge(stackInSlot, stackToShift)) {
int resultingStackSize = stackInSlot.stackSize + stackToShift.stackSize;
int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit());
if (resultingStackSize <= max) {
stackToShift.stackSize = 0;
stackInSlot.stackSize = resultingStackSize;
slot.onSlotChanged();
changed = true;
} else if (stackInSlot.stackSize < max) {
stackToShift.stackSize -= max - stackInSlot.stackSize;
stackInSlot.stackSize = max;
slot.onSlotChanged();
changed = true;
}
}
}
}
if (stackToShift.stackSize > 0) {
for (int slotIndex = start; stackToShift.stackSize > 0 && slotIndex < end; slotIndex++) {
Slot slot = (Slot) inventorySlots.get(slotIndex);
ItemStack stackInSlot = slot.getStack();
if (stackInSlot == null) {
int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit());
stackInSlot = stackToShift.copy();
stackInSlot.stackSize = Math.min(stackToShift.stackSize, max);
stackToShift.stackSize -= stackInSlot.stackSize;
slot.putStack(stackInSlot);
slot.onSlotChanged();
changed = true;
}
}
}
return changed;
}
private static boolean canStacksMerge(ItemStack stack1, ItemStack stack2) {
if (stack1 == null || stack2 == null) {
return false;
}
if (!stack1.isItemEqual(stack2)) {
return false;
}
if (!ItemStack.areItemStackTagsEqual(stack1, stack2)) {
return false;
}
return true;
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return inventory instanceof IInventory ? ((IInventory) inventory).isUseableByPlayer(player) : true;
}
@Override
public ItemStack slotClick(int slotNum, int mouseButton, int modifier, EntityPlayer player) {
if (slotNum < 0 || slotNum >= inventorySlots.size())
return null;
Slot slot = (Slot) inventorySlots.get(slotNum);
if (slot instanceof SlotPhantom)
return ((SlotPhantom) slot).onClick(mouseButton, player);
return super.slotClick(slotNum, mouseButton, modifier, player);
}
}