package gregtech.api.gui; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; import gregtech.api.util.GT_Utility; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidContainerItem; import static gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine.OTHER_SLOT_COUNT; /** * NEVER INCLUDE THIS FILE IN YOUR MOD!!! *
* The Container I use for all my Basic Machines */ public class GT_Container_BasicMachine extends GT_Container_BasicTank { public boolean mFluidTransfer = false, mItemTransfer = false, mStuttering = false; public GT_Container_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity) { super(aInventoryPlayer, aTileEntity); } @Override public void addSlots(InventoryPlayer aInventoryPlayer) { addSlotToContainer(new GT_Slot_Holo(mTileEntity, 0, 8, 63, false, true, 1)); addSlotToContainer(new GT_Slot_Holo(mTileEntity, 0, 26, 63, false, true, 1)); addSlotToContainer(new GT_Slot_Render(mTileEntity, 2, 107, 63)); int tStartIndex = ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).getInputSlot(); switch (((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mInputSlotCount) { case 0: break; case 1: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); break; case 2: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); break; case 3: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); break; case 4: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 34)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 34)); break; case 5: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 34)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 34)); break; case 6: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 16)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 34)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 34)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 34)); break; case 7: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 43)); break; case 8: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 43)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 43)); break; default: addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 7)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 25)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 17, 43)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 35, 43)); addSlotToContainer(new Slot(mTileEntity, tStartIndex++, 53, 43)); break; } tStartIndex = ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).getOutputSlot(); switch (((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mOutputItems.length) { case 0: break; case 1: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); break; case 2: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 25)); break; case 3: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 25)); break; case 4: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 34)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 34)); break; case 5: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 34)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 34)); break; case 6: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 16)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 34)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 34)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 34)); break; case 7: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 43)); break; case 8: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 43)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 43)); break; default: addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 7)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 25)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 107, 43)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 125, 43)); addSlotToContainer(new GT_Slot_Output(mTileEntity, tStartIndex++, 143, 43)); break; } addSlotToContainer(new Slot(mTileEntity, 1, 80, 63)); addSlotToContainer(new Slot(mTileEntity, 3, 125, 63)); addSlotToContainer(new GT_Slot_Render(mTileEntity, tStartIndex++, 53, 63)); } @Override public ItemStack slotClick(int aSlotIndex, int aMouseclick, int aShifthold, EntityPlayer aPlayer) { GT_MetaTileEntity_BasicMachine machine = (GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity(); if (machine == null) return null; ItemStack tResultStack; switch (aSlotIndex) { case 0: machine.mFluidTransfer = !machine.mFluidTransfer; return null; case 1: if (mTileEntity.getMetaTileEntity() == null) return null; machine.mItemTransfer = !machine.mItemTransfer; return null; case 2: if (aMouseclick > 1) return null; tResultStack = pickupFluid(machine.getDrainableStack(), aPlayer, aMouseclick == 0); if (machine.getDrainableStack() != null && machine.getDrainableStack().amount == 0) machine.setDrainableStack(null); return tResultStack; default: if (aSlotIndex == OTHER_SLOT_COUNT + 1 + machine.mInputSlotCount + machine.mOutputItems.length) { if (aMouseclick > 1) return null; // input fluid slot ItemStack tStackHeld = aPlayer.inventory.getItemStack(); ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null; FluidStack tInputFluid = machine.getFillableStack(); FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackSizedOne, true); if (tFluidHeld != null && tFluidHeld.amount <= 0) tFluidHeld = null; if (tInputFluid == null) { if (tFluidHeld == null) // both null -> no op return null; return fillFluid(machine, aPlayer, tFluidHeld, aMouseclick == 0); } else { if (tFluidHeld != null && tInputFluid.amount < machine.getCapacity()) { // both nonnull and have space left for filling. // actually both pickup and fill is reasonable, but I'll go with fill here return fillFluid(machine, aPlayer, tFluidHeld, aMouseclick == 0); } else { tResultStack = pickupFluid(tInputFluid, aPlayer, aMouseclick == 0); if (tInputFluid.amount == 0) machine.setFillableStack(null); return tResultStack; } } } else { return super.slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer); } } } private ItemStack pickupFluid(FluidStack aTankStack, EntityPlayer aPlayer, boolean aProcessFullStack) { if (aTankStack == null) return null; ItemStack tStackHeld = aPlayer.inventory.getItemStack(); ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null; int tOriginalFluidAmount = aTankStack.amount; ItemStack tFilled = GT_Utility.fillFluidContainer(aTankStack, tStackSizedOne, true, false); if (tFilled == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) { IFluidContainerItem tContainerItem = (IFluidContainerItem) tStackSizedOne.getItem(); int tFilledAmount = tContainerItem.fill(tStackSizedOne, aTankStack, true); if (tFilledAmount > 0) { tFilled = tStackSizedOne; aTankStack.amount -= tFilledAmount; } } if (tFilled != null) { if (aProcessFullStack) { int tFilledAmount = tOriginalFluidAmount - aTankStack.amount; /* work out how many more items we can fill one cell is already used, so account for that the round down behavior will left over a fraction of a cell worth of fluid the user then get to decide what to do with it it will not be too fancy if it spills out partially filled cells */ int tAdditionalParallel = Math.min(tStackHeld.stackSize - 1, aTankStack.amount / tFilledAmount); aTankStack.amount -= tFilledAmount * tAdditionalParallel; tFilled.stackSize += tAdditionalParallel; } replaceCursorItemStack(aPlayer, tFilled); } return tFilled; } private ItemStack fillFluid(GT_MetaTileEntity_BasicMachine aMachine, EntityPlayer aPlayer, FluidStack aFluidHeld, boolean aProcessFullStack) { // we are not using aMachine.fill() here any more, so we need to check for fluid type here ourselves if (aMachine.getFillableStack() != null && !aMachine.getFillableStack().isFluidEqual(aFluidHeld)) return null; ItemStack tStackHeld = aPlayer.inventory.getItemStack(); ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); if (tStackSizedOne == null) return null; int tFreeSpace = aMachine.getCapacity() - (aMachine.getFillableStack() != null ? aMachine.getFillableStack().amount : 0); if (tFreeSpace <= 0) // no space left return null; // find out how much fluid can be taken // some cells cannot be partially filled ItemStack tStackEmptied = null; int tAmountTaken = 0; if (tFreeSpace >= aFluidHeld.amount) { // fully accepted - try take it from item now // IFluidContainerItem is intentionally not checked here. it will be checked later tStackEmptied = GT_Utility.getContainerForFilledItem(tStackSizedOne, false); tAmountTaken = aFluidHeld.amount; } if (tStackEmptied == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) { // either partially accepted, or is IFluidContainerItem IFluidContainerItem container = (IFluidContainerItem) tStackSizedOne.getItem(); FluidStack tDrained = container.drain(tStackSizedOne, tFreeSpace, true); if (tDrained != null && tDrained.amount > 0) { // something is actually drained - change the cell and drop it to player tStackEmptied = tStackSizedOne; tAmountTaken = tDrained.amount; } } if (tStackEmptied == null) // somehow the cell refuse to give out that amount of fluid, no op then return null; // find out how many fill can we do // same round down behavior as above // however here the fluid stack is not changed at all, so the exact code will slightly differ int tParallel = aProcessFullStack ? Math.min(tFreeSpace / tAmountTaken, tStackHeld.stackSize) : 1; if (aMachine.getFillableStack() == null) { FluidStack tNewFillableStack = aFluidHeld.copy(); tNewFillableStack.amount = tAmountTaken * tParallel; aMachine.setFillableStack(tNewFillableStack); } else { aMachine.getFillableStack().amount += tAmountTaken * tParallel; } tStackEmptied.stackSize = tParallel; replaceCursorItemStack(aPlayer, tStackEmptied); return tStackEmptied; } private void replaceCursorItemStack(EntityPlayer aPlayer, ItemStack tStackResult) { int tStackResultMaxStackSize = tStackResult.getMaxStackSize(); while (tStackResult.stackSize > tStackResultMaxStackSize) { aPlayer.inventory.getItemStack().stackSize -= tStackResultMaxStackSize; GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult.splitStack(tStackResultMaxStackSize)); } if (aPlayer.inventory.getItemStack().stackSize == tStackResult.stackSize) { // every cell is mutated. it could just stay on the cursor. aPlayer.inventory.setItemStack(tStackResult); } else { // some cells not mutated. The mutated cells must go into the inventory // or drop into the world if there isn't enough space. ItemStack tStackHeld = aPlayer.inventory.getItemStack(); tStackHeld.stackSize -= tStackResult.stackSize; GT_Utility.addItemToPlayerInventory(aPlayer, tStackResult); } } @Override public void detectAndSendChanges() { super.detectAndSendChanges(); if (mTileEntity.isClientSide() || mTileEntity.getMetaTileEntity() == null) return; mFluidTransfer = ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mFluidTransfer; mItemTransfer = ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mItemTransfer; mStuttering = ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mStuttering; for (Object crafter : this.crafters) { ICrafting var1 = (ICrafting) crafter; var1.sendProgressBarUpdate(this, 102, mFluidTransfer ? 1 : 0); var1.sendProgressBarUpdate(this, 103, mItemTransfer ? 1 : 0); var1.sendProgressBarUpdate(this, 104, mStuttering ? 1 : 0); } } @Override public void addCraftingToCrafters(ICrafting par1ICrafting) { super.addCraftingToCrafters(par1ICrafting); } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int par1, int par2) { super.updateProgressBar(par1, par2); switch (par1) { case 102: mFluidTransfer = (par2 != 0); break; case 103: mItemTransfer = (par2 != 0); break; case 104: mStuttering = (par2 != 0); break; } } @Override public int getSlotStartIndex() { return 3; } @Override public int getShiftClickStartIndex() { return 3; } @Override public int getSlotCount() { return getShiftClickSlotCount() + ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mOutputItems.length + 2; } @Override public int getShiftClickSlotCount() { return ((GT_MetaTileEntity_BasicMachine) mTileEntity.getMetaTileEntity()).mInputSlotCount; } }