package crazypants.enderio.machine.gui; import java.awt.Point; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import com.enderio.core.api.common.util.IProgressTile; import com.enderio.core.common.ContainerEnder; import com.enderio.core.common.util.Util; import crazypants.enderio.machine.AbstractMachineEntity; import crazypants.enderio.machine.SlotDefinition; public abstract class AbstractMachineContainer<T extends AbstractMachineEntity> extends ContainerEnder<T> { protected Slot upgradeSlot; public AbstractMachineContainer(InventoryPlayer playerInv, T te) { super(playerInv, te); } @Override protected void addSlots(InventoryPlayer playerInv) { addMachineSlots(playerInv); final T te = getInv(); if(te.getSlotDefinition().getNumUpgradeSlots() == 1) { upgradeSlot = new Slot(te, te.getSlotDefinition().getMinUpgradeSlot(), getUpgradeOffset().x, getUpgradeOffset().y) { @Override public int getSlotStackLimit() { return 1; } @Override public boolean isItemValid(ItemStack itemStack) { return te.isItemValidForSlot(te.getSlotDefinition().getMinUpgradeSlot(), itemStack); } }; addSlotToContainer(upgradeSlot); } } @Override public Point getPlayerInventoryOffset() { return new Point(8,84); } @Override public Point getUpgradeOffset() { return new Point(12,60); } public Slot getUpgradeSlot() { return upgradeSlot; } /** * ATTN: Do not access any non-static field from this method. Your object has * not yet been constructed when it is called! */ protected abstract void addMachineSlots(InventoryPlayer playerInv); @Override public ItemStack transferStackInSlot(EntityPlayer entityPlayer, int slotNumber) { SlotDefinition slotDef = getInv().getSlotDefinition(); ItemStack copystack = null; Slot slot = (Slot) inventorySlots.get(slotNumber); if(slot != null && slot.getHasStack()) { ItemStack origStack = slot.getStack(); copystack = origStack.copy(); boolean merged = false; for(SlotRange range : getTargetSlotsForTransfer(slotNumber, slot)) { if(mergeItemStack(origStack, range.start, range.end, range.reverse)) { merged = true; break; } } if(!merged) { return null; } if (slotDef.isOutputSlot(slot.getSlotIndex())) { slot.onSlotChange(origStack, copystack); } if(origStack.stackSize == 0) { slot.putStack((ItemStack) null); } else { slot.onSlotChanged(); } if(origStack.stackSize == copystack.stackSize) { return null; } slot.onPickupFromSlot(entityPlayer, origStack); } return copystack; } protected int getIndexOfFirstPlayerInvSlot(SlotDefinition slotDef) { return slotDef.getNumSlots(); } protected SlotRange getPlayerInventorySlotRange(boolean reverse) { return new SlotRange(startPlayerSlot, endHotBarSlot, reverse); } protected SlotRange getPlayerInventoryWithoutHotbarSlotRange() { return new SlotRange(startPlayerSlot, endPlayerSlot, false); } protected SlotRange getPlayerHotbarSlotRange() { return new SlotRange(startHotBarSlot, endHotBarSlot, false); } protected void addInventorySlotRange(List<SlotRange> res, int start, int end) { for (int i = start; i < end; i++) { int slotNumber = getSlotFromInventory(getInv(), i).slotNumber; res.add(new SlotRange(slotNumber, slotNumber + 1, false)); } } protected void addInputSlotRanges(List<SlotRange> res) { SlotDefinition slotDef = getInv().getSlotDefinition(); if(slotDef.getNumInputSlots() > 0) { addInventorySlotRange(res, slotDef.getMinInputSlot(), slotDef.getMaxInputSlot() + 1); } } protected void addUpgradeSlotRanges(List<SlotRange> res) { SlotDefinition slotDef = getInv().getSlotDefinition(); if(slotDef.getNumUpgradeSlots() > 0) { addInventorySlotRange(res, slotDef.getMinUpgradeSlot(), slotDef.getMaxUpgradeSlot() + 1); } } protected void addPlayerSlotRanges(List<SlotRange> res, int slotIndex) { if (slotIndex < endPlayerSlot) { res.add(getPlayerHotbarSlotRange()); } if (slotIndex >= startHotBarSlot && slotIndex < endHotBarSlot) { res.add(getPlayerInventoryWithoutHotbarSlotRange()); } } protected List<SlotRange> getTargetSlotsForTransfer(int slotNumber, Slot slot) { if (slot.inventory == getInv()) { SlotDefinition slotDef = getInv().getSlotDefinition(); if (slotDef.isInputSlot(slot.getSlotIndex()) || slotDef.isUpgradeSlot(slot.getSlotIndex())) { return Collections.singletonList(getPlayerInventorySlotRange(false)); } if (slotDef.isOutputSlot(slot.getSlotIndex())) { return Collections.singletonList(getPlayerInventorySlotRange(true)); } } else if (slotNumber >= startPlayerSlot) { List<SlotRange> res = new ArrayList<SlotRange>(); addInputSlotRanges(res); addUpgradeSlotRanges(res); addPlayerSlotRanges(res, slotNumber); return res; } return Collections.emptyList(); } protected int getProgressScaled(int scale) { if(getInv() instanceof IProgressTile) { Util.getProgressScaled(scale, (IProgressTile) getInv()); } return 0; } public static class SlotRange { final int start; final int end; final boolean reverse; public SlotRange(int start, int end, boolean reverse) { this.start = start; this.end = end; this.reverse = reverse; } } }