diff options
author | Yang Xizhi <60341015+GlodBlock@users.noreply.github.com> | 2022-04-24 14:42:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-24 08:42:46 +0200 |
commit | f7c75cbe3675733eca0279f0c7256daf459e109d (patch) | |
tree | 0f341ea4e533dda55da04cc0de51d14c1e21478c | |
parent | 706976e60669b523a5734722a47f4dd52b2ecd26 (diff) | |
download | GT5-Unofficial-f7c75cbe3675733eca0279f0c7256daf459e109d.tar.gz GT5-Unofficial-f7c75cbe3675733eca0279f0c7256daf459e109d.tar.bz2 GT5-Unofficial-f7c75cbe3675733eca0279f0c7256daf459e109d.zip |
add quadruple input hatch (#1016)
* add quadruple input hatch
* pull all fluid slot thing to GT_Container
15 files changed, 652 insertions, 180 deletions
diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java index a14691f4b3..deee1b1d32 100644 --- a/src/main/java/gregtech/api/enums/ItemList.java +++ b/src/main/java/gregtech/api/enums/ItemList.java @@ -355,7 +355,7 @@ public enum ItemList implements IItemContainer { Schematic_2by2, Schematic_3by3, Schematic_Dust, - + Circuit_Integrated, Circuit_Board_Basic, Circuit_Board_Advanced, @@ -420,7 +420,7 @@ public enum ItemList implements IItemContainer { Steam_Valve_HV, Steam_Valve_EV, Steam_Valve_IV, - + FluidRegulator_LV, FluidRegulator_MV, FluidRegulator_HV, @@ -525,7 +525,7 @@ public enum ItemList implements IItemContainer { Field_Generator_UXV, Field_Generator_OpV, Field_Generator_MAX, - + Battery_Hull_LV, Battery_Hull_MV, Battery_Hull_HV, @@ -972,6 +972,8 @@ public enum ItemList implements IItemContainer { Hatch_Input_UV, Hatch_Input_MAX, + Hatch_Input_Multi_2x2, + Hatch_Input_Bus_ULV, Hatch_Input_Bus_LV, Hatch_Input_Bus_MV, @@ -1470,7 +1472,7 @@ public enum ItemList implements IItemContainer { Super_Chest_HV, Super_Chest_EV, Super_Chest_IV, - + Long_Distance_Pipeline_Fluid, Long_Distance_Pipeline_Item, @@ -1649,7 +1651,7 @@ public enum ItemList implements IItemContainer { Block_MSSFUEL, SFMixture, MSFMixture, - + Depleted_Naquadah_1, Depleted_Naquadah_2, Depleted_Naquadah_4, @@ -1662,10 +1664,10 @@ public enum ItemList implements IItemContainer { MNqCell_1, MNqCell_2, MNqCell_4, - + Hatch_AutoMaintenance, Machine_Multi_Cleanroom, - + Circuit_Board_Coated, Circuit_Board_Coated_Basic, Circuit_Board_Phenolic, @@ -1815,7 +1817,7 @@ public enum ItemList implements IItemContainer { Machine_LuV_CircuitAssembler, Machine_ZPM_CircuitAssembler, Machine_UV_CircuitAssembler, - + Circuit_Integrated_Good, Machine_IV_LightningRod, Machine_HV_LightningRod, @@ -1838,7 +1840,7 @@ public enum ItemList implements IItemContainer { Circuit_Parts_CapacitorXSMD, VOLUMETRIC_FLASK; - + public static final ItemList[] DYE_ONLY_ITEMS = { Color_00, diff --git a/src/main/java/gregtech/api/enums/Textures.java b/src/main/java/gregtech/api/enums/Textures.java index 5730be05e9..d86e7dfd9f 100644 --- a/src/main/java/gregtech/api/enums/Textures.java +++ b/src/main/java/gregtech/api/enums/Textures.java @@ -476,6 +476,7 @@ public class Textures { OVERLAY_PIPE, OVERLAY_PIPE_IN, OVERLAY_PIPE_OUT, + OVERLAY_INPUT_HATCH_2x2, FLUID_OUT_SIGN, FLUID_IN_SIGN, ITEM_IN_SIGN, diff --git a/src/main/java/gregtech/api/gui/GT_Container.java b/src/main/java/gregtech/api/gui/GT_Container.java index a3085b21ba..0f788d543b 100644 --- a/src/main/java/gregtech/api/gui/GT_Container.java +++ b/src/main/java/gregtech/api/gui/GT_Container.java @@ -1,5 +1,6 @@ package gregtech.api.gui; +import gregtech.api.interfaces.IFluidAccess; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.util.GT_Log; import gregtech.api.util.GT_Utility; @@ -10,6 +11,8 @@ import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; import java.util.List; @@ -558,4 +561,152 @@ public class GT_Container extends Container { } return true; } + + protected static ItemStack handleFluidSlotClick(IFluidAccess aFluidAccess, EntityPlayer aPlayer, boolean aProcessFullStack, boolean aCanDrain, boolean aCanFill) { + ItemStack tStackHeld = aPlayer.inventory.getItemStack(); + ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); + if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null; + FluidStack tInputFluid = aFluidAccess.get(); + FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackSizedOne, true); + if (tFluidHeld != null && tFluidHeld.amount <= 0) + tFluidHeld = null; + if (tInputFluid == null) { + // tank empty, consider fill only from now on + if (!aCanFill) + // cannot fill and nothing to take, bail out + return null; + if (tFluidHeld == null) + // no fluid to fill + return null; + return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack); + } + // tank not empty, both action possible + if (tFluidHeld != null && tInputFluid.amount < aFluidAccess.getCapacity()) { + // both nonnull and have space left for filling. + if (aCanFill) + // actually both pickup and fill is reasonable, but I'll go with fill here + return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack); + if (!aCanDrain) + // cannot take AND cannot fill, why make this call then? + return null; + // the slot does not allow filling, so try take some + return drainFluid(aFluidAccess, aPlayer, aProcessFullStack); + } else { + // cannot fill and there is something to take + if (!aCanDrain) + // but the slot does not allow taking, so bail out + return null; + return drainFluid(aFluidAccess, aPlayer, aProcessFullStack); + } + } + + protected static ItemStack drainFluid(IFluidAccess aFluidAccess, EntityPlayer aPlayer, boolean aProcessFullStack) { + FluidStack tTankStack = aFluidAccess.get(); + if (tTankStack == 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 = tTankStack.amount; + ItemStack tFilledContainer = GT_Utility.fillFluidContainer(tTankStack, tStackSizedOne, true, false); + if (tFilledContainer == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) { + IFluidContainerItem tContainerItem = (IFluidContainerItem) tStackSizedOne.getItem(); + int tFilledAmount = tContainerItem.fill(tStackSizedOne, tTankStack, true); + if (tFilledAmount > 0) { + tFilledContainer = tStackSizedOne; + tTankStack.amount -= tFilledAmount; + } + } + if (tFilledContainer != null) { + if (aProcessFullStack) { + int tFilledAmount = tOriginalFluidAmount - tTankStack.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, tTankStack.amount / tFilledAmount); + tTankStack.amount -= tFilledAmount * tAdditionalParallel; + tFilledContainer.stackSize += tAdditionalParallel; + } + replaceCursorItemStack(aPlayer, tFilledContainer); + } + if (tTankStack.amount <= 0) + aFluidAccess.set(null); + return tFilledContainer; + } + + protected static ItemStack fillFluid(IFluidAccess aFluidAccess, 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 (aFluidAccess.get() != null && !aFluidAccess.get().isFluidEqual(aFluidHeld)) + return null; + ItemStack tStackHeld = aPlayer.inventory.getItemStack(); + ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); + if (tStackSizedOne == null) + return null; + + int tFreeSpace = aFluidAccess.getCapacity() - (aFluidAccess.get() != null ? aFluidAccess.get().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 (aFluidAccess.get() == null) { + FluidStack tNewFillableStack = aFluidHeld.copy(); + tNewFillableStack.amount = tAmountTaken * tParallel; + aFluidAccess.set(tNewFillableStack); + } else { + aFluidAccess.get().amount += tAmountTaken * tParallel; + } + tStackEmptied.stackSize = tParallel; + replaceCursorItemStack(aPlayer, tStackEmptied); + return tStackEmptied; + } + + private static 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); + } + } + } diff --git a/src/main/java/gregtech/api/gui/GT_Container_2by2_Fluid.java b/src/main/java/gregtech/api/gui/GT_Container_2by2_Fluid.java new file mode 100644 index 0000000000..f8f4e3c886 --- /dev/null +++ b/src/main/java/gregtech/api/gui/GT_Container_2by2_Fluid.java @@ -0,0 +1,98 @@ +package gregtech.api.gui; + +import gregtech.api.interfaces.IFluidAccess; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_MultiInput; +import gregtech.api.util.GT_Utility; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class GT_Container_2by2_Fluid extends GT_ContainerMetaTile_Machine { + + public GT_Container_2by2_Fluid(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity) { + super(aInventoryPlayer, aTileEntity); + } + + /** + * Subclasses must ensure third slot (aSlotIndex==2) is drainable fluid display item slot. + * Otherwise, subclasses must intercept the appropriate the slotClick event and call super.slotClick(2, xxx) if necessary + */ + @Override + public void addSlots(InventoryPlayer aInventoryPlayer) { + addSlotToContainer(new GT_Slot_Render(mTileEntity, 0, 71, 26)); + addSlotToContainer(new GT_Slot_Render(mTileEntity, 1, 89, 26)); + addSlotToContainer(new GT_Slot_Render(mTileEntity, 2, 71, 44)); + addSlotToContainer(new GT_Slot_Render(mTileEntity, 3, 89, 44)); + } + + @Override + public ItemStack slotClick(int aSlotIndex, int aMouseclick, int aShifthold, EntityPlayer aPlayer) { + if (aSlotIndex < 4 && aSlotIndex >= 0 && aMouseclick < 2) { + if (mTileEntity.isClientSide()) { + /* + * While a logical client don't really need to process fluid cells upon click (it could have just wait + * for server side to send the result), doing so would result in every fluid interaction having a + * noticeable delay between clicking and changes happening even on single player. + * I'd imagine this lag to become only more severe when playing MP over ethernet, which would have much more latency + * than a memory connection + */ + GT_MetaTileEntity_Hatch_MultiInput tTank = (GT_MetaTileEntity_Hatch_MultiInput) mTileEntity.getMetaTileEntity(); + tTank.setDrainableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2))); + } + GT_MetaTileEntity_Hatch_MultiInput tTank = (GT_MetaTileEntity_Hatch_MultiInput) mTileEntity.getMetaTileEntity(); + MultiFluidAccess tDrainableAccess = MultiFluidAccess.from(tTank, aSlotIndex); + ItemStack tStackHeld = aPlayer.inventory.getItemStack(); + FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackHeld, true); + if (tDrainableAccess.isMatch(tFluidHeld, aSlotIndex)) + return handleFluidSlotClick(tDrainableAccess, aPlayer, aMouseclick == 0, true, !tTank.isDrainableStackSeparate()); + } + return super.slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer); + } + + @Override + public int getSlotCount() { + return 0; + } + + @Override + public int getShiftClickSlotCount() { + return 0; + } + + static class MultiFluidAccess implements IFluidAccess { + private final GT_MetaTileEntity_Hatch_MultiInput mTank; + private final int mSlot; + + public MultiFluidAccess(GT_MetaTileEntity_Hatch_MultiInput aTank, int aSlot) { + this.mTank = aTank; + this.mSlot = aSlot; + } + + public boolean isMatch(FluidStack stack, int slot) { + if (!mTank.hasFluid(stack)) return true; + if (stack == null) return true; + return stack.equals(mTank.getFluid(slot)); + } + + @Override + public void set(FluidStack stack) { + mTank.setFluid(stack, mSlot); + } + + @Override + public FluidStack get() { + return mTank.getFluid(mSlot); + } + + @Override + public int getCapacity() { + return mTank.getCapacity(); + } + + static MultiFluidAccess from(GT_MetaTileEntity_Hatch_MultiInput aTank, int aSlot) { + return new MultiFluidAccess(aTank, aSlot); + } + } +} diff --git a/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java b/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java index 8dc8813166..e26f86f746 100644 --- a/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java +++ b/src/main/java/gregtech/api/gui/GT_Container_BasicMachine.java @@ -2,6 +2,7 @@ package gregtech.api.gui; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.interfaces.IFluidAccess; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicTank; @@ -263,7 +264,7 @@ public class GT_Container_BasicMachine extends GT_Container_BasicTank { tTank.setFillableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2))); } GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity(); - IFluidAccess tFillableAccess = IFluidAccess.from(tTank, true); + BasicTankFluidAccess tFillableAccess = BasicTankFluidAccess.from(tTank, true); GT_Recipe_Map recipes = machine.getRecipeList(); //If the machine has recipes but no fluid inputs, disallow filling this slot with fluids. ItemStack tToken = handleFluidSlotClick(tFillableAccess, aPlayer, aMouseclick == 0, true, (recipes == null || recipes.hasFluidInputs())); diff --git a/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java b/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java index 79d3636068..b78f829282 100644 --- a/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java +++ b/src/main/java/gregtech/api/gui/GT_Container_BasicTank.java @@ -2,6 +2,7 @@ package gregtech.api.gui; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.interfaces.IFluidAccess; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicTank; import gregtech.api.util.GT_Utility; @@ -10,9 +11,7 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatComponentText; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; /** * NEVER INCLUDE THIS FILE IN YOUR MOD!!! @@ -54,159 +53,12 @@ public class GT_Container_BasicTank extends GT_ContainerMetaTile_Machine { tTank.setDrainableStack(GT_Utility.getFluidFromDisplayStack(tTank.getStackInSlot(2))); } GT_MetaTileEntity_BasicTank tTank = (GT_MetaTileEntity_BasicTank) mTileEntity.getMetaTileEntity(); - IFluidAccess tDrainableAccess = IFluidAccess.from(tTank, false); + BasicTankFluidAccess tDrainableAccess = BasicTankFluidAccess.from(tTank, false); return handleFluidSlotClick(tDrainableAccess, aPlayer, aMouseclick == 0, true, !tTank.isDrainableStackSeparate()); } return super.slotClick(aSlotIndex, aMouseclick, aShifthold, aPlayer); } - protected static ItemStack handleFluidSlotClick(IFluidAccess aFluidAccess, EntityPlayer aPlayer, boolean aProcessFullStack, boolean aCanDrain, boolean aCanFill) { - ItemStack tStackHeld = aPlayer.inventory.getItemStack(); - ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); - if (tStackSizedOne == null || tStackHeld.stackSize == 0) return null; - FluidStack tInputFluid = aFluidAccess.get(); - FluidStack tFluidHeld = GT_Utility.getFluidForFilledItem(tStackSizedOne, true); - if (tFluidHeld != null && tFluidHeld.amount <= 0) - tFluidHeld = null; - if (tInputFluid == null) { - // tank empty, consider fill only from now on - if (!aCanFill) - // cannot fill and nothing to take, bail out - return null; - if (tFluidHeld == null) - // no fluid to fill - return null; - return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack); - } - // tank not empty, both action possible - if (tFluidHeld != null && tInputFluid.amount < aFluidAccess.getCapacity()) { - // both nonnull and have space left for filling. - if (aCanFill) - // actually both pickup and fill is reasonable, but I'll go with fill here - return fillFluid(aFluidAccess, aPlayer, tFluidHeld, aProcessFullStack); - if (!aCanDrain) - // cannot take AND cannot fill, why make this call then? - return null; - // the slot does not allow filling, so try take some - return drainFluid(aFluidAccess, aPlayer, aProcessFullStack); - } else { - // cannot fill and there is something to take - if (!aCanDrain) - // but the slot does not allow taking, so bail out - return null; - return drainFluid(aFluidAccess, aPlayer, aProcessFullStack); - } - } - - protected static ItemStack drainFluid(IFluidAccess aFluidAccess, EntityPlayer aPlayer, boolean aProcessFullStack) { - FluidStack tTankStack = aFluidAccess.get(); - if (tTankStack == 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 = tTankStack.amount; - ItemStack tFilledContainer = GT_Utility.fillFluidContainer(tTankStack, tStackSizedOne, true, false); - if (tFilledContainer == null && tStackSizedOne.getItem() instanceof IFluidContainerItem) { - IFluidContainerItem tContainerItem = (IFluidContainerItem) tStackSizedOne.getItem(); - int tFilledAmount = tContainerItem.fill(tStackSizedOne, tTankStack, true); - if (tFilledAmount > 0) { - tFilledContainer = tStackSizedOne; - tTankStack.amount -= tFilledAmount; - } - } - if (tFilledContainer != null) { - if (aProcessFullStack) { - int tFilledAmount = tOriginalFluidAmount - tTankStack.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, tTankStack.amount / tFilledAmount); - tTankStack.amount -= tFilledAmount * tAdditionalParallel; - tFilledContainer.stackSize += tAdditionalParallel; - } - replaceCursorItemStack(aPlayer, tFilledContainer); - } - if (tTankStack.amount <= 0) - aFluidAccess.set(null); - return tFilledContainer; - } - - protected static ItemStack fillFluid(IFluidAccess aFluidAccess, 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 (aFluidAccess.get() != null && !aFluidAccess.get().isFluidEqual(aFluidHeld)) - return null; - ItemStack tStackHeld = aPlayer.inventory.getItemStack(); - ItemStack tStackSizedOne = GT_Utility.copyAmount(1, tStackHeld); - if (tStackSizedOne == null) - return null; - - int tFreeSpace = aFluidAccess.getCapacity() - (aFluidAccess.get() != null ? aFluidAccess.get().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 (aFluidAccess.get() == null) { - FluidStack tNewFillableStack = aFluidHeld.copy(); - tNewFillableStack.amount = tAmountTaken * tParallel; - aFluidAccess.set(tNewFillableStack); - } else { - aFluidAccess.get().amount += tAmountTaken * tParallel; - } - tStackEmptied.stackSize = tParallel; - replaceCursorItemStack(aPlayer, tStackEmptied); - return tStackEmptied; - } - - private static 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(); @@ -250,15 +102,6 @@ public class GT_Container_BasicTank extends GT_ContainerMetaTile_Machine { return 1; } - protected interface IFluidAccess { - void set(FluidStack stack); - FluidStack get(); - int getCapacity(); - static IFluidAccess from(GT_MetaTileEntity_BasicTank aTank, boolean aIsFillableStack) { - return new BasicTankFluidAccess(aTank, aIsFillableStack); - } - } - static class BasicTankFluidAccess implements IFluidAccess { private final GT_MetaTileEntity_BasicTank mTank; private final boolean mIsFillableStack; @@ -285,5 +128,9 @@ public class GT_Container_BasicTank extends GT_ContainerMetaTile_Machine { public int getCapacity() { return mTank.getCapacity(); } + + static BasicTankFluidAccess from(GT_MetaTileEntity_BasicTank aTank, boolean aIsFillableStack) { + return new BasicTankFluidAccess(aTank, aIsFillableStack); + } } } diff --git a/src/main/java/gregtech/api/gui/GT_GUIContainer_2by2_Fluid.java b/src/main/java/gregtech/api/gui/GT_GUIContainer_2by2_Fluid.java new file mode 100644 index 0000000000..b6c00046f7 --- /dev/null +++ b/src/main/java/gregtech/api/gui/GT_GUIContainer_2by2_Fluid.java @@ -0,0 +1,32 @@ +package gregtech.api.gui; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.StatCollector; + +import static gregtech.api.enums.GT_Values.RES_PATH_GUI; + +public class GT_GUIContainer_2by2_Fluid extends GT_GUIContainerMetaTile_Machine { + + private final String mName; + + public GT_GUIContainer_2by2_Fluid(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName) { + super(new GT_Container_2by2_Fluid(aInventoryPlayer, aTileEntity), RES_PATH_GUI + "2by2fluid.png"); + mName = aName; + } + + @Override + protected void drawGuiContainerForegroundLayer(int par1, int par2) { + fontRendererObj.drawString(StatCollector.translateToLocal("container.inventory"), 8, ySize - 96 + 2, 4210752); + fontRendererObj.drawString(mName, 8, 6, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { + super.drawGuiContainerBackgroundLayer(par1, par2, par3); + int x = (width - xSize) / 2; + int y = (height - ySize) / 2; + drawTexturedModalRect(x, y, 0, 0, xSize, ySize); + } + +} diff --git a/src/main/java/gregtech/api/interfaces/IFluidAccess.java b/src/main/java/gregtech/api/interfaces/IFluidAccess.java new file mode 100644 index 0000000000..bbe198ddcb --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IFluidAccess.java @@ -0,0 +1,12 @@ +package gregtech.api.interfaces; + +import net.minecraftforge.fluids.FluidStack; + +public interface IFluidAccess { + + void set(FluidStack stack); + + FluidStack get(); + + int getCapacity(); +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java index 972ac87d02..99c89e091a 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java @@ -24,6 +24,13 @@ public class GT_MetaTileEntity_Hatch_Input extends GT_MetaTileEntity_Hatch { "Capacity: " + GT_Utility.formatNumbers(8000*(1<<aTier)) + "L"}); } + public GT_MetaTileEntity_Hatch_Input(int aID, int aSlot, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, aSlot, new String[]{ + "Fluid Input for Multiblocks", + "Capacity: " + GT_Utility.formatNumbers(8000*(1<<aTier) / aSlot) + "L", + "Can hold " + aSlot + " types of fluid."}); + } + public GT_MetaTileEntity_Hatch_Input(String aName, int aTier, String aDescription, ITexture[][][] aTextures) { super(aName, aTier, 3, aDescription, aTextures); } @@ -32,6 +39,10 @@ public class GT_MetaTileEntity_Hatch_Input extends GT_MetaTileEntity_Hatch { super(aName, aTier, 3, aDescription, aTextures); } + public GT_MetaTileEntity_Hatch_Input(String aName, int aSlots, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aSlots, aDescription, aTextures); + } + @Override public ITexture[] getTexturesActive(ITexture aBaseTexture) { return GT_Mod.gregtechproxy.mRenderIndicatorsOnHatch ? diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java new file mode 100644 index 0000000000..39599006f2 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_MultiInput.java @@ -0,0 +1,291 @@ +package gregtech.api.metatileentity.implementations; + +import gregtech.GT_Mod; +import gregtech.api.enums.ItemList; +import gregtech.api.gui.GT_Container_2by2_Fluid; +import gregtech.api.gui.GT_GUIContainer_2by2_Fluid; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GT_Utility; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; + +import static gregtech.api.enums.Textures.BlockIcons.*; + +public class GT_MetaTileEntity_Hatch_MultiInput extends GT_MetaTileEntity_Hatch_Input { + + public FluidStack[] mStoredFluid; + public int mCapacityPer; + + public GT_MetaTileEntity_Hatch_MultiInput(int aID, int aSlot, String aName, String aNameRegional, int aTier) { + super(aID, aSlot, aName, aNameRegional, aTier); + this.mStoredFluid = new FluidStack[aSlot]; + mCapacityPer = 8000 * (1 << aTier) / aSlot; + } + + public GT_MetaTileEntity_Hatch_MultiInput(String aName, int aSlot, int aTier, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aSlot, aDescription, aTextures); + this.mStoredFluid = new FluidStack[aSlot]; + mCapacityPer = 8000 * (1 << aTier) / aSlot; + } + + @Override + public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new GT_MetaTileEntity_Hatch_MultiInput(mName, getMaxType(), mTier, mDescriptionArray, mTextures); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + super.saveNBTData(aNBT); + if (mStoredFluid != null) { + for (int i = 0; i < mStoredFluid.length; i++) { + if (mStoredFluid[i] != null) + aNBT.setTag("mFluid" + i, mStoredFluid[i].writeToNBT(new NBTTagCompound())); + } + } + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + super.loadNBTData(aNBT); + if (mStoredFluid != null) { + for (int i = 0; i < mStoredFluid.length; i++) { + if (aNBT.hasKey("mFluid" + i)) { + mStoredFluid[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag("mFluid" + i)); + } + } + } + } + + public FluidStack[] getStoredFluid() { + return mStoredFluid; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[]{aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2)}; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[]{aBaseTexture, TextureFactory.of(OVERLAY_INPUT_HATCH_2x2)}; + } + + public int getMaxType() { + return mStoredFluid.length; + } + + @Override + public FluidStack getFluid() { + for (FluidStack tFluid : mStoredFluid) { + if (tFluid != null && tFluid.amount > 0) + return tFluid; + } + return null; + } + + public FluidStack getFluid(int aSlot) { + if (mStoredFluid == null || aSlot < 0 || aSlot >= getMaxType()) return null; + return mStoredFluid[aSlot]; + } + + @Override + public int getFluidAmount() { + if (getFluid() != null) { + return getFluid().amount; + } + return 0; + } + + @Override + public int getCapacity() { + return mCapacityPer; + } + + public int getFirstEmptySlot() { + for (int i = 0; i < mStoredFluid.length; i++) { + if (mStoredFluid[i] == null || mStoredFluid[i].amount <= 0) + return i; + } + return -1; + } + + public boolean hasFluid(FluidStack aFluid) { + if (aFluid == null) return false; + for (FluidStack tFluid : mStoredFluid) { + if (aFluid.isFluidEqual(tFluid)) + return true; + } + return false; + } + + public int getFluidSlot(FluidStack tFluid) { + if (tFluid == null) return -1; + for (int i = 0; i < mStoredFluid.length; i++) { + if (tFluid.equals(mStoredFluid[i])) + return i; + } + return -1; + } + + public int getFluidAmount(FluidStack tFluid) { + int tSlot = getFluidSlot(tFluid); + if (tSlot != -1) { + return mStoredFluid[tSlot].amount; + } + return 0; + } + + public void setFluid(FluidStack aFluid, int aSlot) { + if (aSlot < 0 || aSlot >= getMaxType()) return; + mStoredFluid[aSlot] = aFluid; + } + + public void addFluid(FluidStack aFluid, int aSlot) { + if (aSlot < 0 || aSlot >= getMaxType()) return; + if (aFluid.equals(mStoredFluid[aSlot])) mStoredFluid[aSlot].amount += aFluid.amount; + if (mStoredFluid[aSlot] == null) mStoredFluid[aSlot] = aFluid.copy(); + } + + @Override + public void onPreTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide()) { + mFluid = getFluid(); + } + super.onPreTick(aBaseMetaTileEntity, aTick); + } + + @Override + public int fill(FluidStack aFluid, boolean doFill) { + if (aFluid == null || aFluid.getFluid().getID() <= 0 || aFluid.amount <= 0 || !canTankBeFilled() || !isFluidInputAllowed(aFluid)) + return 0; + if (!hasFluid(aFluid) && getFirstEmptySlot() != -1) { + int tFilled = Math.min(aFluid.amount, mCapacityPer); + if (doFill) { + FluidStack tFluid = aFluid.copy(); + tFluid.amount = tFilled; + addFluid(tFluid, getFirstEmptySlot()); + getBaseMetaTileEntity().markDirty(); + } + return tFilled; + } + if (hasFluid(aFluid)) { + int tLeft = mCapacityPer - getFluidAmount(aFluid); + int tFilled = Math.min(tLeft, aFluid.amount); + if (doFill) { + FluidStack tFluid = aFluid.copy(); + tFluid.amount = tFilled; + addFluid(tFluid, getFluidSlot(tFluid)); + getBaseMetaTileEntity().markDirty(); + } + return tFilled; + } + return 0; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (getFluid() == null || !canTankBeEmptied()) return null; + if (getFluid().amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(getFluid())); + getBaseMetaTileEntity().markDirty(); + return null; + } + FluidStack tRemove = getFluid().copy(); + tRemove.amount = Math.min(maxDrain, tRemove.amount); + if (doDrain) { + getFluid().amount -= tRemove.amount; + getBaseMetaTileEntity().markDirty(); + } + if (getFluid() == null || getFluid().amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(getFluid())); + getBaseMetaTileEntity().markDirty(); + } + return tRemove; + } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return fill(resource, doFill); + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack aFluid, boolean doDrain) { + if (getFluid() != null && aFluid != null && getFluid().isFluidEqual(aFluid)) { + if (hasFluid(aFluid) && !canTankBeEmptied()) { + FluidStack tStored = mStoredFluid[getFluidSlot(aFluid)]; + if (tStored.amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(tStored)); + getBaseMetaTileEntity().markDirty(); + return null; + } + FluidStack tRemove = tStored.copy(); + tRemove.amount = Math.min(aFluid.amount, tRemove.amount); + if (doDrain) { + tStored.amount -= tRemove.amount; + getBaseMetaTileEntity().markDirty(); + } + if (tStored.amount <= 0 && isFluidChangingAllowed()) { + setFluid(null, getFluidSlot(tStored)); + getBaseMetaTileEntity().markDirty(); + } + return tRemove; + } + } + return null; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + FluidTankInfo[] FTI = new FluidTankInfo[getMaxType()]; + for (int i = 0; i < getMaxType(); i++) { + FTI[i] = new FluidTankInfo(mStoredFluid[i], mCapacityPer); + } + return FTI; + } + + @Override + public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_GUIContainer_2by2_Fluid(aPlayerInventory, aBaseMetaTileEntity, "Quadruple Input Hatch"); + } + + @Override + public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_Container_2by2_Fluid(aPlayerInventory, aBaseMetaTileEntity); + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (aBaseMetaTileEntity.isServerSide() && mStoredFluid != null) { + for (int i = 0; i < getMaxType(); i ++) { + if (mStoredFluid[i] != null && mStoredFluid[i].amount <= 0) { + mStoredFluid[i] = null; + } + } + } + super.onPostTick(aBaseMetaTileEntity, aTick); + } + + @Override + public boolean isValidSlot(int aIndex) { + return aIndex >= 4; + } + + @Override + public void updateFluidDisplayItem() { + for (int i = 0; i < 4; i ++) { + if (getFluid(i) == null || getFluid(i).amount <= 0) { + if (ItemList.Display_Fluid.isStackEqual(mInventory[i], true, true)) + mInventory[i] = null; + } + else { + mInventory[i] = GT_Utility.getFluidDisplayStack(getFluid(i), true, !displaysStackSize()); + } + } + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java index a2d6f3a05b..6fea43e960 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java @@ -35,8 +35,7 @@ import org.lwjgl.input.Keyboard; import java.util.ArrayList; import java.util.List; -import static gregtech.api.enums.GT_Values.V; -import static gregtech.api.enums.GT_Values.VN; +import static gregtech.api.enums.GT_Values.*; import static mcp.mobius.waila.api.SpecialChars.GREEN; import static mcp.mobius.waila.api.SpecialChars.RED; import static mcp.mobius.waila.api.SpecialChars.RESET; @@ -763,12 +762,23 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity { for (GT_MetaTileEntity_Hatch_Input tHatch : mInputHatches) { tHatch.mRecipeMap = getRecipeMap(); if (isValidMetaTileEntity(tHatch)) { - FluidStack tLiquid = tHatch.getFluid(); - if (tLiquid != null && tLiquid.isFluidEqual(aLiquid)) { - tLiquid = tHatch.drain(aLiquid.amount, false); - if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { - tLiquid = tHatch.drain(aLiquid.amount, true); - return tLiquid != null && tLiquid.amount >= aLiquid.amount; + if (tHatch instanceof GT_MetaTileEntity_Hatch_MultiInput) { + if (((GT_MetaTileEntity_Hatch_MultiInput) tHatch).hasFluid(aLiquid)) { + FluidStack tLiquid = tHatch.drain(aLiquid.amount, false); + if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { + tLiquid = tHatch.drain(aLiquid.amount, true); + return tLiquid != null && tLiquid.amount >= aLiquid.amount; + } + } + } + else { + FluidStack tLiquid = tHatch.getFluid(); + if (tLiquid != null && tLiquid.isFluidEqual(aLiquid)) { + tLiquid = tHatch.drain(aLiquid.amount, false); + if (tLiquid != null && tLiquid.amount >= aLiquid.amount) { + tLiquid = tHatch.drain(aLiquid.amount, true); + return tLiquid != null && tLiquid.amount >= aLiquid.amount; + } } } } @@ -849,8 +859,21 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity { ArrayList<FluidStack> rList = new ArrayList<>(); for (GT_MetaTileEntity_Hatch_Input tHatch : mInputHatches) { tHatch.mRecipeMap = getRecipeMap(); - if (isValidMetaTileEntity(tHatch) && tHatch.getFillableStack() != null) { - rList.add(tHatch.getFillableStack()); + if (tHatch instanceof GT_MetaTileEntity_Hatch_MultiInput) { + if (isValidMetaTileEntity(tHatch)) { + for (FluidStack tFluid : ((GT_MetaTileEntity_Hatch_MultiInput) tHatch).getStoredFluid()) { + if (tFluid != null) { + //GT_Log.out.print("mf: " + tFluid + "\n"); + rList.add(tFluid); + } + } + } + } + else { + if (isValidMetaTileEntity(tHatch) && tHatch.getFillableStack() != null) { + //GT_Log.out.print("sf: " + tHatch.getFillableStack() + "\n"); + rList.add(tHatch.getFillableStack()); + } } } return rList; diff --git a/src/main/java/gregtech/loaders/postload/GT_MachineRecipeLoader.java b/src/main/java/gregtech/loaders/postload/GT_MachineRecipeLoader.java index 1f00d72099..e6acfda1cd 100644 --- a/src/main/java/gregtech/loaders/postload/GT_MachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/postload/GT_MachineRecipeLoader.java @@ -447,7 +447,9 @@ public class GT_MachineRecipeLoader implements Runnable { GT_Values.RA.addAssemblerRecipe(new ItemStack[]{GT_OreDictUnificator.get(OrePrefixes.pipeLarge, Materials.Steel, 2L), GT_OreDictUnificator.get(OrePrefixes.plate, Materials.Steel, 9L), GT_Utility.getIntegratedCircuit(24)}, Materials.Tin.getMolten(144L), ItemList.Long_Distance_Pipeline_Fluid_Pipe.get(64L), 600, 24); GT_Values.RA.addAssemblerRecipe(new ItemStack[]{GT_OreDictUnificator.get(OrePrefixes.pipeLarge, Materials.Tin, 2L), GT_OreDictUnificator.get(OrePrefixes.plate, Materials.Steel, 9L), GT_Utility.getIntegratedCircuit(24)}, Materials.Tin.getMolten(144L), ItemList.Long_Distance_Pipeline_Item_Pipe.get(64L), 600, 24); - GT_Values.RA.addAssemblerRecipe(new ItemStack[]{GT_OreDictUnificator.get(OrePrefixes.plate, Materials.Steel, 4L), GT_OreDictUnificator.get(OrePrefixes.frameGt, Materials.TungstenSteel, 1L), ItemList.Robot_Arm_IV.get(2L), GT_Utility.getIntegratedCircuit(3)}, GT_Values.NF, ItemList.Casing_Gearbox_TungstenSteel.get(1L), 200, 30); + GT_Values.RA.addAssemblerRecipe(new ItemStack[]{GT_OreDictUnificator.get(OrePrefixes.pipeQuadruple, Materials.StainlessSteel, 1L), ItemList.Hull_EV.get(1L), GT_Utility.getIntegratedCircuit(4)}, Materials.Glass.getMolten(2304L), ItemList.Hatch_Input_Multi_2x2.get(1L), 600, 24); + + GT_Values.RA.addAssemblerRecipe(new ItemStack[]{GT_OreDictUnificator.get(OrePrefixes.plate, Materials.Steel, 4L), GT_OreDictUnificator.get(OrePrefixes.frameGt, Materials.TungstenSteel, 1L), ItemList.Robot_Arm_IV.get(2L), GT_Utility.getIntegratedCircuit(3)}, GT_Values.NF, ItemList.Casing_Gearbox_TungstenSteel.get(1L), 200, 30); {//limiting life time of the variables ItemStack flask = ItemList.VOLUMETRIC_FLASK.get(1); diff --git a/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java b/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java index a3b2c416b4..d427868b0f 100644 --- a/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java +++ b/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java @@ -227,6 +227,7 @@ public class GT_Loader_MetaTileEntities implements Runnable {//TODO CHECK CIRCUI ItemList.Hatch_Input_ZPM.set(new GT_MetaTileEntity_Hatch_Input(57, "hatch.input.tier.07", "Input Hatch (ZPM)", 7).getStackForm(1L)); ItemList.Hatch_Input_UV.set(new GT_MetaTileEntity_Hatch_Input(58, "hatch.input.tier.08", "Input Hatch (UV)", 8).getStackForm(1L)); ItemList.Hatch_Input_MAX.set(new GT_MetaTileEntity_Hatch_Input(59, "hatch.input.tier.09", "Input Hatch (UHV)", 9).getStackForm(1L)); + ItemList.Hatch_Input_Multi_2x2.set(new GT_MetaTileEntity_Hatch_MultiInput(200, 4, "hatch.multi.input.tier.01", "Quadruple Input Hatch", 4).getStackForm(1L)); ItemList.Hatch_Output_ULV.set(new GT_MetaTileEntity_Hatch_Output(60, "hatch.output.tier.00", "Output Hatch (ULV)", 0).getStackForm(1L)); ItemList.Hatch_Output_LV.set(new GT_MetaTileEntity_Hatch_Output(61, "hatch.output.tier.01", "Output Hatch (LV)", 1).getStackForm(1L)); diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_INPUT_HATCH_2x2.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_INPUT_HATCH_2x2.png Binary files differnew file mode 100644 index 0000000000..530eed38b2 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_INPUT_HATCH_2x2.png diff --git a/src/main/resources/assets/gregtech/textures/gui/2by2fluid.png b/src/main/resources/assets/gregtech/textures/gui/2by2fluid.png Binary files differnew file mode 100644 index 0000000000..2f950c1008 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/gui/2by2fluid.png |