aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/gregtech/api/enums/ItemList.java1
-rw-r--r--src/main/java/gregtech/api/enums/MetaTileEntityIDs.java1
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Input.java5
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java28
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java28
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java6
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java785
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/IRecipeProcessingAwareHatch.java31
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java11
-rw-r--r--src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java5
-rw-r--r--src/main/resources/assets/gregtech/lang/en_US.lang13
11 files changed, 880 insertions, 34 deletions
diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java
index 4d667cc495..1ed3057dcd 100644
--- a/src/main/java/gregtech/api/enums/ItemList.java
+++ b/src/main/java/gregtech/api/enums/ItemList.java
@@ -1997,6 +1997,7 @@ public enum ItemList implements IItemContainer {
VOLUMETRIC_FLASK,
Hatch_Input_Bus_ME,
+ Hatch_Input_ME,
Hatch_CraftingInput_Bus_ME,
Hatch_CraftingInput_Bus_ME_ItemOnly,
Hatch_CraftingInput_Bus_Slave,
diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
index 9b5abd0994..003ff381f7 100644
--- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
+++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
@@ -600,6 +600,7 @@ public enum MetaTileEntityIDs {
LONG_DISTANCE_PIPELINE_ITEM(2701),
OUTPUT_BUS_ME(2710),
INPUT_BUS_ME(2711),
+ INPUT_HATCH_ME(2712),
OUTPUT_HATCH_ME(2713),
CRAFTING_INPUT_ME(2714),
CRAFTING_INPUT_ME_BUS(2715),
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 e3b94dec47..b6eb19b5aa 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
@@ -53,6 +53,11 @@ public class GT_MetaTileEntity_Hatch_Input extends GT_MetaTileEntity_Hatch {
super(aID, aName, aNameRegional, aTier, aSlot, aDescription);
}
+ public GT_MetaTileEntity_Hatch_Input(int aID, String aName, String aNameRegional, int aTier, int allSlotCount,
+ String[] strings) {
+ super(aID, aName, aNameRegional, aTier, allSlotCount, strings);
+ }
+
public int getCapacityPerTank(int aTier, int aSlot) {
return (int) (8000L * (1L << aTier) / aSlot);
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
index e7cddffc12..5769cd82c2 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_InputBus.java
@@ -30,8 +30,6 @@ import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.modularui.IAddUIWidgets;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.MetaTileEntity;
-import gregtech.api.recipe.check.CheckRecipeResult;
-import gregtech.api.recipe.check.CheckRecipeResultRegistry;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_ClientPreference;
import gregtech.api.util.GT_OreDictUnificator;
@@ -39,9 +37,10 @@ import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
import gregtech.api.util.GT_TooltipDataCache;
import gregtech.api.util.GT_Utility;
import gregtech.api.util.extensions.ArrayExt;
+import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch;
public class GT_MetaTileEntity_Hatch_InputBus extends GT_MetaTileEntity_Hatch
- implements IConfigurationCircuitSupport, IAddUIWidgets {
+ implements IConfigurationCircuitSupport, IAddUIWidgets, IRecipeProcessingAwareHatch {
private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip";
private static final String ONE_STACK_LIMIT_TOOLTIP = "GT5U.machines.one_stack_limit.tooltip";
@@ -264,29 +263,6 @@ public class GT_MetaTileEntity_Hatch_InputBus extends GT_MetaTileEntity_Hatch
return mInventory[aIndex] == null;
}
- /**
- * Called when multiblock controller starts processing.
- * {@link #endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase)} is called on the same tick.
- */
- public void startRecipeProcessing() {}
-
- /**
- * Called when multiblock controller ends processing. {@link #startRecipeProcessing()} is called on the same tick.
- *
- * @param controller Caller of this method.
- * @return Result of the process of this method. {@code !wasSuccessful()} means the returned result should
- * overwrite the result calculated on multiblock whatever the reason is.
- */
- public CheckRecipeResult endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase controller) {
- endRecipeProcessing();
- return CheckRecipeResultRegistry.SUCCESSFUL;
- }
-
- /**
- * Simple version of {@link #endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase)}. Maybe use it instead.
- */
- public void endRecipeProcessing() {}
-
@Override
public boolean allowSelectCircuit() {
return true;
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 d9d5f4c731..1d3fa80ef5 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
@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -88,10 +89,12 @@ import gregtech.client.GT_SoundLoop;
import gregtech.common.GT_Pollution;
import gregtech.common.gui.modularui.widget.CheckRecipeResultSyncer;
import gregtech.common.items.GT_MetaGenerated_Tool_01;
+import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Output_ME;
import gregtech.common.tileentities.machines.IDualInputHatch;
import gregtech.common.tileentities.machines.IDualInputInventory;
+import gregtech.common.tileentities.machines.IRecipeProcessingAwareHatch;
import gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
@@ -1341,6 +1344,14 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
rList.add(tFluid);
}
}
+ } else if (tHatch instanceof GT_MetaTileEntity_Hatch_Input_ME) {
+ if (isValidMetaTileEntity(tHatch)) {
+ for (FluidStack fluidStack : ((GT_MetaTileEntity_Hatch_Input_ME) tHatch).getStoredFluids()) {
+ if (fluidStack == null) continue;
+
+ rList.add(fluidStack);
+ }
+ }
} else {
if (tHatch.getFillableStack() != null) {
// GT_Log.out.print("sf: " + tHatch.getFillableStack() + "\n");
@@ -1405,14 +1416,27 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
for (GT_MetaTileEntity_Hatch_InputBus hatch : filterValidMTEs(mInputBusses)) {
hatch.startRecipeProcessing();
}
+ for (GT_MetaTileEntity_Hatch_Input hatch : filterValidMTEs(mInputHatches)) {
+ if (hatch instanceof IRecipeProcessingAwareHatch aware) {
+ aware.startRecipeProcessing();
+ }
+ }
}
protected void endRecipeProcessing() {
- for (GT_MetaTileEntity_Hatch_InputBus hatch : filterValidMTEs(mInputBusses)) {
- CheckRecipeResult result = hatch.endRecipeProcessing(this);
+ Consumer<CheckRecipeResult> setResultIfFailure = result -> {
if (!result.wasSuccessful()) {
this.checkRecipeResult = result;
}
+ };
+
+ for (GT_MetaTileEntity_Hatch_InputBus hatch : filterValidMTEs(mInputBusses)) {
+ setResultIfFailure.accept(hatch.endRecipeProcessing(this));
+ }
+ for (GT_MetaTileEntity_Hatch_Input hatch : filterValidMTEs(mInputHatches)) {
+ if (hatch instanceof IRecipeProcessingAwareHatch aware) {
+ setResultIfFailure.accept(aware.endRecipeProcessing(this));
+ }
}
}
diff --git a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java
index 1e7dc28e91..0ca632f479 100644
--- a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java
+++ b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_InputBus_ME.java
@@ -99,7 +99,7 @@ public class GT_MetaTileEntity_Hatch_InputBus_ME extends GT_MetaTileEntity_Hatch
"Auto-Pull from ME mode will automatically stock the first 16 items in the ME system, updated every 5 seconds.",
"Toggle by right-clicking with screwdriver, or use the GUI.",
"Use the GUI to limit the minimum stack size for Auto-Pulling.",
- "Change ME connection behavior by right-clicking with wire cutter",
+ "Change ME connection behavior by right-clicking with wire cutter.",
"Configuration data can be copy+pasted using a data stick." });
disableSort = true;
}
@@ -614,8 +614,8 @@ public class GT_MetaTileEntity_Hatch_InputBus_ME extends GT_MetaTileEntity_Hatch
})
.addTooltips(
Arrays.asList(
- StatCollector.translateToLocal("GT5U.machines.stocking_bus.auto_pull.tooltip"),
- StatCollector.translateToLocal("GT5U.machines.stocking_bus.auto_pull.tooltip.1")))
+ StatCollector.translateToLocal("GT5U.machines.stocking_bus.auto_pull.tooltip.1"),
+ StatCollector.translateToLocal("GT5U.machines.stocking_bus.auto_pull.tooltip.2")))
.setSize(16, 16)
.setPos(80, 10))
.widget(new FakeSyncWidget.BooleanSyncer(() -> autoPullItemList, this::setAutoPullItemList))
diff --git a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java
new file mode 100644
index 0000000000..a32076ad2a
--- /dev/null
+++ b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_Input_ME.java
@@ -0,0 +1,785 @@
+package gregtech.common.tileentities.machines;
+
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_FLUID_HATCH;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_FLUID_HATCH_ACTIVE;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ChatComponentTranslation;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import com.gtnewhorizons.modularui.api.ModularUITextures;
+import com.gtnewhorizons.modularui.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.drawable.Text;
+import com.gtnewhorizons.modularui.api.math.Alignment;
+import com.gtnewhorizons.modularui.api.math.Color;
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+import com.gtnewhorizons.modularui.api.math.Size;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.api.widget.Interactable;
+import com.gtnewhorizons.modularui.common.fluid.FluidStackTank;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotGroup;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+import com.gtnewhorizons.modularui.common.widget.textfield.TextFieldWidget;
+
+import appeng.api.config.Actionable;
+import appeng.api.config.PowerMultiplier;
+import appeng.api.implementations.IPowerChannelState;
+import appeng.api.networking.GridFlags;
+import appeng.api.networking.security.BaseActionSource;
+import appeng.api.networking.security.IActionHost;
+import appeng.api.networking.security.MachineSource;
+import appeng.api.storage.IMEMonitor;
+import appeng.api.storage.data.IAEFluidStack;
+import appeng.api.util.AECableType;
+import appeng.core.localization.WailaText;
+import appeng.me.GridAccessException;
+import appeng.me.helpers.AENetworkProxy;
+import appeng.me.helpers.IGridProxyable;
+import appeng.util.item.AEFluidStack;
+import gregtech.api.enums.ItemList;
+import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.modularui.IAddGregtechLogo;
+import gregtech.api.interfaces.modularui.IAddUIWidgets;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.MetaTileEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+import gregtech.api.recipe.check.SimpleCheckRecipeResult;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GT_Utility;
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+public class GT_MetaTileEntity_Hatch_Input_ME extends GT_MetaTileEntity_Hatch_Input
+ implements IPowerChannelState, IAddGregtechLogo, IAddUIWidgets, IRecipeProcessingAwareHatch {
+
+ private static final int SLOT_COUNT = 16;
+
+ protected final FluidStack[] storedFluids = new FluidStack[SLOT_COUNT];
+ protected final FluidStack[] storedInformationFluids = new FluidStack[SLOT_COUNT];
+
+ protected final FluidStack[] shadowStoredFluids = new FluidStack[SLOT_COUNT];
+ private final int[] savedStackSizes = new int[SLOT_COUNT];
+
+ private boolean additionalConnection = false;
+
+ protected BaseActionSource requestSource = null;
+
+ @Nullable
+ protected AENetworkProxy gridProxy = null;
+
+ protected boolean autoPullFluidList = false;
+ protected int minAutoPullAmount = 1;
+ protected boolean processingRecipe = false;
+
+ protected static final int CONFIG_WINDOW_ID = 10;
+
+ protected static final FluidStack[] EMPTY_FLUID_STACK = new FluidStack[0];
+
+ public GT_MetaTileEntity_Hatch_Input_ME(int aID, String aName, String aNameRegional) {
+ super(
+ aID,
+ aName,
+ aNameRegional,
+ 1,
+ 1,
+ new String[] { "Advanced fluid input for Multiblocks", "Retrieves directly from ME",
+ "Keeps 16 fluid types in stock",
+ "Auto-Pull from ME mode will automatically stock the first 16 fluid in the ME system, updated every 5 seconds.",
+ "Toggle by right-clicking with screwdriver, or use the GUI.",
+ "Use the GUI to limit the minimum stack size for Auto-Pulling.",
+ "Change ME connection behavior by right-clicking with wire cutter.",
+ "Configuration data can be copy+pasted using a data stick." });
+ }
+
+ public GT_MetaTileEntity_Hatch_Input_ME(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, 1, aTier, aDescription, aTextures);
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new GT_MetaTileEntity_Hatch_Input_ME(mName, mTier, mDescriptionArray, mTextures);
+ }
+
+ @Override
+ public ITexture[] getTexturesActive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_FLUID_HATCH_ACTIVE) };
+ }
+
+ @Override
+ public ITexture[] getTexturesInactive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_FLUID_HATCH) };
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
+ if (aTimer % 100 == 0 && autoPullFluidList) {
+ refreshFluidList();
+ }
+ super.onPostTick(aBaseMetaTileEntity, aTimer);
+ }
+
+ private void refreshFluidList() {
+ AENetworkProxy proxy = getProxy();
+ if (proxy == null || !proxy.isActive()) {
+ return;
+ }
+
+ try {
+ IMEMonitor<IAEFluidStack> sg = proxy.getStorage()
+ .getFluidInventory();
+ Iterator<IAEFluidStack> iterator = sg.getStorageList()
+ .iterator();
+
+ int index = 0;
+ while (iterator.hasNext() && index < SLOT_COUNT) {
+ IAEFluidStack currItem = iterator.next();
+ if (currItem.getStackSize() >= minAutoPullAmount) {
+ FluidStack fluidStack = GT_Utility.copyAmount(1, currItem.getFluidStack());
+ storedFluids[index] = fluidStack;
+ index++;
+ }
+ }
+
+ for (int i = index; i < SLOT_COUNT; i++) {
+ storedFluids[i] = null;
+ }
+ } catch (final GridAccessException ignored) {}
+ }
+
+ @Override
+ public boolean displaysStackSize() {
+ return true;
+ }
+
+ public FluidStack[] getStoredFluids() {
+ if (!processingRecipe) {
+ return EMPTY_FLUID_STACK;
+ }
+
+ AENetworkProxy proxy = getProxy();
+ if (proxy == null || !proxy.isActive()) {
+ return EMPTY_FLUID_STACK;
+ }
+
+ updateAllInformationSlots();
+
+ for (int i = 0; i < SLOT_COUNT; i++) {
+ if (storedFluids[i] == null) {
+ shadowStoredFluids[i] = null;
+ continue;
+ }
+
+ FluidStack fluidStackWithAmount = storedInformationFluids[i];
+ // Nothing in stock, no need to save anything
+ if (fluidStackWithAmount == null) continue;
+
+ shadowStoredFluids[i] = fluidStackWithAmount;
+ savedStackSizes[i] = fluidStackWithAmount.amount;
+ }
+
+ return shadowStoredFluids;
+ }
+
+ @Override
+ public void startRecipeProcessing() {
+ processingRecipe = true;
+ }
+
+ @Override
+ public CheckRecipeResult endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase controller) {
+ CheckRecipeResult checkRecipeResult = CheckRecipeResultRegistry.SUCCESSFUL;
+ AENetworkProxy proxy = getProxy();
+
+ try {
+ IMEMonitor<IAEFluidStack> sg = proxy.getStorage()
+ .getFluidInventory();
+
+ for (int i = 0; i < SLOT_COUNT; ++i) {
+ FluidStack oldStack = shadowStoredFluids[i];
+ int oldAmount = savedStackSizes[i];
+ if (oldStack == null || oldAmount == 0) continue;
+
+ int toExtract = oldAmount - oldStack.amount;
+ if (toExtract <= 0) continue;
+
+ IAEFluidStack request = AEFluidStack.create(storedFluids[i]);
+ request.setStackSize(toExtract);
+ IAEFluidStack extractionResult = sg.extractItems(request, Actionable.MODULATE, getRequestSource());
+ proxy.getEnergy()
+ .extractAEPower(toExtract, Actionable.MODULATE, PowerMultiplier.CONFIG);
+
+ if (extractionResult == null || extractionResult.getStackSize() != toExtract) {
+ controller.criticalStopMachine();
+ checkRecipeResult = SimpleCheckRecipeResult
+ .ofFailurePersistOnShutdown("stocking_hatch_fail_extraction");
+ }
+ }
+ } catch (GridAccessException e) {
+ throw new RuntimeException(e);
+ }
+
+ for (int i = 0; i < SLOT_COUNT; i++) {
+ shadowStoredFluids[i] = null;
+ savedStackSizes[i] = 0;
+ }
+
+ processingRecipe = false;
+ return checkRecipeResult;
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ getProxy().onReady();
+ }
+
+ @Override
+ public AECableType getCableConnectionType(ForgeDirection forgeDirection) {
+ return isOutputFacing(forgeDirection) ? AECableType.SMART : AECableType.NONE;
+ }
+
+ public void setAdditionalConnectionOption() {
+ if (additionalConnection) {
+ getProxy().setValidSides(EnumSet.complementOf(EnumSet.of(ForgeDirection.UNKNOWN)));
+ } else {
+ getProxy().setValidSides(EnumSet.of(getBaseMetaTileEntity().getFrontFacing()));
+ }
+ }
+
+ @Override
+ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer aPlayer,
+ float aX, float aY, float aZ) {
+ additionalConnection = !additionalConnection;
+ setAdditionalConnectionOption();
+ aPlayer.addChatComponentMessage(
+ new ChatComponentTranslation("GT5U.hatch.additionalConnection." + additionalConnection));
+ return true;
+ }
+
+ @Override
+ public AENetworkProxy getProxy() {
+ if (gridProxy == null) {
+ if (getBaseMetaTileEntity() instanceof IGridProxyable) {
+ gridProxy = new AENetworkProxy(
+ (IGridProxyable) getBaseMetaTileEntity(),
+ "proxy",
+ ItemList.Hatch_Input_ME.get(1),
+ true);
+ gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL);
+ setAdditionalConnectionOption();
+ if (getBaseMetaTileEntity().getWorld() != null) gridProxy.setOwner(
+ getBaseMetaTileEntity().getWorld()
+ .getPlayerEntityByName(getBaseMetaTileEntity().getOwnerName()));
+ }
+ }
+ return this.gridProxy;
+ }
+
+ @Override
+ public boolean isPowered() {
+ return getProxy() != null && getProxy().isPowered();
+ }
+
+ @Override
+ public boolean isActive() {
+ return getProxy() != null && getProxy().isActive();
+ }
+
+ private void setAutoPullFluidList(boolean pullFluidList) {
+ autoPullFluidList = pullFluidList;
+ if (!autoPullFluidList) {
+ Arrays.fill(storedFluids, null);
+ } else {
+ refreshFluidList();
+ }
+ updateAllInformationSlots();
+ }
+
+ private void updateAllInformationSlots() {
+ for (int index = 0; index < SLOT_COUNT; index++) {
+ updateInformationSlot(index);
+ }
+ }
+
+ public void updateInformationSlot(int index) {
+ if (index < 0 || index >= SLOT_COUNT) {
+ return;
+ }
+
+ FluidStack fluidStack = storedFluids[index];
+ if (fluidStack == null) {
+ storedInformationFluids[index] = null;
+ return;
+ }
+
+ AENetworkProxy proxy = getProxy();
+ if (proxy == null || !proxy.isActive()) {
+ storedInformationFluids[index] = null;
+ return;
+ }
+
+ try {
+ IMEMonitor<IAEFluidStack> sg = proxy.getStorage()
+ .getFluidInventory();
+ IAEFluidStack request = AEFluidStack.create(fluidStack);
+ request.setStackSize(Integer.MAX_VALUE);
+ IAEFluidStack result = sg.extractItems(request, Actionable.SIMULATE, getRequestSource());
+ FluidStack resultFluid = (result != null) ? result.getFluidStack() : null;
+ storedInformationFluids[index] = resultFluid;
+ } catch (final GridAccessException ignored) {}
+ }
+
+ private BaseActionSource getRequestSource() {
+ if (requestSource == null) requestSource = new MachineSource((IActionHost) getBaseMetaTileEntity());
+ return requestSource;
+ }
+
+ public FluidStack getMatchingFluidStack(FluidStack fluidStack) {
+ if (fluidStack == null) return null;
+
+ for (int i = 0; i < storedFluids.length; i++) {
+ if (storedFluids[i] == null) {
+ continue;
+ }
+
+ if (GT_Utility.areFluidsEqual(fluidStack, storedFluids[i], false)) {
+ updateInformationSlot(i);
+ if (storedInformationFluids[i] != null) {
+ shadowStoredFluids[i] = storedInformationFluids[i];
+ savedStackSizes[i] = storedInformationFluids[i].amount;
+ return shadowStoredFluids[i];
+ }
+
+ shadowStoredFluids[i] = null;
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public FluidStack getShadowFluidStack(int index) {
+ if (index < 0 || index >= storedFluids.length) {
+ return null;
+ }
+
+ return shadowStoredFluids[index];
+ }
+
+ public int getFluidSlot(FluidStack fluidStack) {
+ if (fluidStack == null) return -1;
+
+ for (int i = 0; i < storedFluids.length; i++) {
+ if (storedFluids[i] == null) {
+ continue;
+ }
+
+ if (GT_Utility.areFluidsEqual(fluidStack, storedFluids[i], false)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ @Override
+ public boolean canTankBeEmptied() {
+ return false;
+ }
+
+ @Override
+ public boolean canTankBeFilled() {
+ return false;
+ }
+
+ @Override
+ public boolean doesEmptyContainers() {
+ return false;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return false;
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+
+ NBTTagList nbtTagList = new NBTTagList();
+ for (int i = 0; i < SLOT_COUNT; i++) {
+ FluidStack fluidStack = storedFluids[i];
+ if (fluidStack == null) {
+ continue;
+ }
+ NBTTagCompound fluidTag = fluidStack.writeToNBT(new NBTTagCompound());
+ if (storedInformationFluids[i] != null)
+ fluidTag.setInteger("informationAmount", storedInformationFluids[i].amount);
+ nbtTagList.appendTag(fluidTag);
+ }
+
+ aNBT.setTag("storedFluids", nbtTagList);
+ aNBT.setBoolean("autoPull", autoPullFluidList);
+ aNBT.setInteger("minAmount", minAutoPullAmount);
+ aNBT.setBoolean("additionalConnection", additionalConnection);
+ getProxy().writeToNBT(aNBT);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ if (aNBT.hasKey("storedFluids")) {
+ NBTTagList nbtTagList = aNBT.getTagList("storedFluids", 10);
+ int c = Math.min(nbtTagList.tagCount(), SLOT_COUNT);
+ for (int i = 0; i < c; i++) {
+ NBTTagCompound nbtTagCompound = nbtTagList.getCompoundTagAt(i);
+ FluidStack fluidStack = GT_Utility.loadFluid(nbtTagCompound);
+ storedFluids[i] = fluidStack;
+
+ if (nbtTagCompound.hasKey("informationAmount")) {
+ int informationAmount = nbtTagCompound.getInteger("informationAmount");
+ storedInformationFluids[i] = GT_Utility.copyAmount(informationAmount, fluidStack);
+ }
+ }
+ }
+
+ minAutoPullAmount = aNBT.getInteger("minAmount");
+ autoPullFluidList = aNBT.getBoolean("autoPull");
+ additionalConnection = aNBT.getBoolean("additionalConnection");
+ getProxy().readFromNBT(aNBT);
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ setAutoPullFluidList(!autoPullFluidList);
+ aPlayer.addChatMessage(
+ new ChatComponentTranslation(
+ "GT5U.machines.stocking_hatch.auto_pull_toggle." + (autoPullFluidList ? "enabled" : "disabled")));
+ }
+
+ @Override
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side,
+ float aX, float aY, float aZ) {
+ if (!(aPlayer instanceof EntityPlayerMP))
+ return super.onRightclick(aBaseMetaTileEntity, aPlayer, side, aX, aY, aZ);
+ ItemStack dataStick = aPlayer.inventory.getCurrentItem();
+ if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true))
+ return super.onRightclick(aBaseMetaTileEntity, aPlayer, side, aX, aY, aZ);
+ if (!dataStick.hasTagCompound() || !"stockingHatch".equals(dataStick.stackTagCompound.getString("type")))
+ return false;
+
+ NBTTagCompound nbt = dataStick.stackTagCompound;
+
+ setAutoPullFluidList(nbt.getBoolean("autoPull"));
+ minAutoPullAmount = nbt.getInteger("minAmount");
+ additionalConnection = nbt.getBoolean("additionalConnection");
+ if (!autoPullFluidList) {
+ NBTTagList stockingFluids = nbt.getTagList("fluidsToStock", 10);
+ for (int i = 0; i < stockingFluids.tagCount(); i++) {
+ storedFluids[i] = GT_Utility.loadFluid(stockingFluids.getCompoundTagAt(i));
+ }
+ }
+
+ setAdditionalConnectionOption();
+ aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.stocking_bus.loaded"));
+ return true;
+ }
+
+ @Override
+ public void onLeftclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ if (!(aPlayer instanceof EntityPlayerMP)) return;
+
+ ItemStack dataStick = aPlayer.inventory.getCurrentItem();
+ if (!ItemList.Tool_DataStick.isStackEqual(dataStick, false, true)) return;
+
+ NBTTagCompound tag = new NBTTagCompound();
+ tag.setString("type", "stockingHatch");
+ tag.setBoolean("autoPull", autoPullFluidList);
+ tag.setInteger("minAmount", minAutoPullAmount);
+ tag.setBoolean("additionalConnection", additionalConnection);
+
+ NBTTagList stockingFluids = new NBTTagList();
+ if (!autoPullFluidList) {
+ for (int index = 0; index < SLOT_COUNT; index++) {
+ FluidStack fluidStack = storedFluids[index];
+ if (fluidStack == null) {
+ continue;
+ }
+ stockingFluids.appendTag(fluidStack.writeToNBT(new NBTTagCompound()));
+ }
+ tag.setTag("fluidsToStock", stockingFluids);
+ }
+ dataStick.stackTagCompound = tag;
+ dataStick.setStackDisplayName("Stocking Input Hatch Configuration");
+ aPlayer.addChatMessage(new ChatComponentTranslation("GT5U.machines.stocking_bus.saved"));
+ }
+
+ @Override
+ public void onExplosion() {
+ for (int i = 0; i < SLOT_COUNT; i++) {
+ mInventory[i] = null;
+ }
+ }
+
+ public boolean containsSuchStack(FluidStack tStack) {
+ for (int i = 0; i < 16; ++i) {
+ if (GT_Utility.areFluidsEqual(storedFluids[i], tStack, false)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int getGUIHeight() {
+ return 179;
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ buildContext.addSyncedWindow(CONFIG_WINDOW_ID, this::createStackSizeConfigurationWindow);
+
+ builder.widget(
+ SlotGroup.ofFluidTanks(
+ IntStream.range(0, SLOT_COUNT)
+ .mapToObj(index -> createTankForFluidStack(storedFluids, index, 1))
+ .collect(Collectors.toList()),
+ 4)
+ .phantom(true)
+ .widgetCreator((slotIndex, h) -> (FluidSlotWidget) new FluidSlotWidget(h) {
+
+ @Override
+ protected void tryClickPhantom(ClickData clickData, ItemStack cursorStack) {
+ if (clickData.mouseButton != 0 || autoPullFluidList) return;
+
+ FluidStack heldFluid = getFluidForPhantomItem(cursorStack);
+ if (cursorStack == null) {
+ storedFluids[slotIndex] = null;
+ } else {
+ if (containsSuchStack(heldFluid)) return;
+ storedFluids[slotIndex] = heldFluid;
+ }
+ if (getBaseMetaTileEntity().isServerSide()) {
+ updateInformationSlot(slotIndex);
+ detectAndSendChanges(false);
+ }
+ }
+
+ @Override
+ protected void tryScrollPhantom(int direction) {}
+
+ @Override
+ public IDrawable[] getBackground() {
+ IDrawable slot;
+ if (autoPullFluidList) {
+ slot = GT_UITextures.SLOT_DARK_GRAY;
+ } else {
+ slot = ModularUITextures.FLUID_SLOT;
+ }
+ return new IDrawable[] { slot, GT_UITextures.OVERLAY_SLOT_ARROW_ME };
+ }
+
+ @Override
+ public void buildTooltip(List<Text> tooltip) {
+ FluidStack fluid = getContent();
+ if (fluid != null) {
+ addFluidNameInfo(tooltip, fluid);
+
+ if (!autoPullFluidList) {
+ tooltip.add(Text.localised("modularui.phantom.single.clear"));
+ }
+ } else {
+ tooltip.add(
+ Text.localised("modularui.fluid.empty")
+ .format(EnumChatFormatting.WHITE));
+ }
+
+ if (autoPullFluidList) {
+ tooltip.add(Text.localised("GT5U.machines.stocking_bus.cannot_set_slot"));
+ }
+ }
+ }.setUpdateTooltipEveryTick(true))
+ .build()
+ .setPos(new Pos2d(7, 9)));
+
+ builder.widget(
+ SlotGroup.ofFluidTanks(
+ IntStream.range(0, SLOT_COUNT)
+ .mapToObj(index -> createTankForFluidStack(storedInformationFluids, index, Integer.MAX_VALUE))
+ .collect(Collectors.toList()),
+ 4)
+ .phantom(true)
+ .widgetCreator((slotIndex, h) -> (FluidSlotWidget) new FluidSlotWidget(h) {
+
+ @Override
+ protected void tryClickPhantom(ClickData clickData, ItemStack cursorStack) {}
+
+ @Override
+ protected void tryScrollPhantom(int direction) {}
+
+ @Override
+ public void buildTooltip(List<Text> tooltip) {
+ FluidStack fluid = getContent();
+ if (fluid != null) {
+ addFluidNameInfo(tooltip, fluid);
+ tooltip.add(Text.localised("modularui.fluid.phantom.amount", fluid.amount));
+ addAdditionalFluidInfo(tooltip, fluid);
+ if (!Interactable.hasShiftDown()) {
+ tooltip.add(Text.EMPTY);
+ tooltip.add(Text.localised("modularui.tooltip.shift"));
+ }
+ } else {
+ tooltip.add(
+ Text.localised("modularui.fluid.empty")
+ .format(EnumChatFormatting.WHITE));
+ }
+ }
+ }.setUpdateTooltipEveryTick(true))
+ .background(GT_UITextures.SLOT_DARK_GRAY)
+ .controlsAmount(true)
+ .build()
+ .setPos(new Pos2d(97, 9)));
+
+ builder.widget(
+ new DrawableWidget().setDrawable(GT_UITextures.PICTURE_ARROW_DOUBLE)
+ .setPos(82, 30)
+ .setSize(12, 12))
+ .widget(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (clickData.mouseButton == 0) {
+ setAutoPullFluidList(!autoPullFluidList);
+ } else if (clickData.mouseButton == 1 && !widget.isClient()) {
+ widget.getContext()
+ .openSyncedWindow(CONFIG_WINDOW_ID);
+ }
+ })
+ .setPlayClickSound(true)
+ .setBackground(() -> {
+ if (autoPullFluidList) {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED,
+ GT_UITextures.OVERLAY_BUTTON_AUTOPULL_ME };
+ } else {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD,
+ GT_UITextures.OVERLAY_BUTTON_AUTOPULL_ME_DISABLED };
+ }
+ })
+ .addTooltips(
+ Arrays.asList(
+ StatCollector.translateToLocal("GT5U.machines.stocking_hatch.auto_pull.tooltip.1"),
+ StatCollector.translateToLocal("GT5U.machines.stocking_hatch.auto_pull.tooltip.2")))
+ .setSize(16, 16)
+ .setPos(80, 10))
+ .widget(new FakeSyncWidget.BooleanSyncer(() -> autoPullFluidList, this::setAutoPullFluidList))
+ .widget(TextWidget.dynamicString(() -> {
+ boolean isActive = isActive();
+ boolean isPowered = isPowered();
+ boolean isBooting = isBooting();
+ EnumChatFormatting color = (isActive && isPowered) ? EnumChatFormatting.GREEN
+ : EnumChatFormatting.DARK_RED;
+ return color + WailaText.getPowerState(isActive, isPowered, isBooting);
+ })
+ .setTextAlignment(Alignment.Center)
+ .setSize(90, 9)
+ .setPos(43, 84));
+ }
+
+ private FluidStackTank createTankForFluidStack(FluidStack[] fluidStacks, int slotIndex, int capacity) {
+ return new FluidStackTank(() -> fluidStacks[slotIndex], (stack) -> {
+ if (getBaseMetaTileEntity().isServerSide()) {
+ return;
+ }
+
+ fluidStacks[slotIndex] = stack;
+ }, capacity);
+ }
+
+ protected ModularWindow createStackSizeConfigurationWindow(final EntityPlayer player) {
+ final int WIDTH = 78;
+ final int HEIGHT = 40;
+ final int PARENT_WIDTH = getGUIWidth();
+ final int PARENT_HEIGHT = getGUIHeight();
+ ModularWindow.Builder builder = ModularWindow.builder(WIDTH, HEIGHT);
+ builder.setBackground(GT_UITextures.BACKGROUND_SINGLEBLOCK_DEFAULT);
+ builder.setGuiTint(getGUIColorization());
+ builder.setDraggable(true);
+ builder.setPos(
+ (size, window) -> Alignment.Center.getAlignedPos(size, new Size(PARENT_WIDTH, PARENT_HEIGHT))
+ .add(
+ Alignment.TopRight.getAlignedPos(new Size(PARENT_WIDTH, PARENT_HEIGHT), new Size(WIDTH, HEIGHT))
+ .add(WIDTH - 3, 0)));
+ builder.widget(
+ TextWidget.localised("GT5U.machines.stocking_hatch.min_amount")
+ .setPos(3, 2)
+ .setSize(74, 14))
+ .widget(
+ new TextFieldWidget().setSetterInt(val -> minAutoPullAmount = val)
+ .setGetterInt(() -> minAutoPullAmount)
+ .setNumbers(1, Integer.MAX_VALUE)
+ .setOnScrollNumbers(1, 4, 64)
+ .setTextAlignment(Alignment.Center)
+ .setTextColor(Color.WHITE.normal)
+ .setSize(36, 18)
+ .setPos(19, 18)
+ .setBackground(GT_UITextures.BACKGROUND_TEXT_FIELD));
+ return builder.build();
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(
+ new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo())
+ .setSize(17, 17)
+ .setPos(80, 63));
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ NBTTagCompound tag = accessor.getNBTData();
+ boolean autopull = tag.getBoolean("autoPull");
+ int minSize = tag.getInteger("minAmount");
+ currenttip.add(
+ StatCollector.translateToLocal("GT5U.waila.stocking_bus.auto_pull." + (autopull ? "enabled" : "disabled")));
+ if (autopull) {
+ currenttip.add(
+ StatCollector.translateToLocalFormatted(
+ "GT5U.waila.stocking_hatch.min_amount",
+ GT_Utility.formatNumbers(minSize)));
+ }
+ super.getWailaBody(itemStack, currenttip, accessor, config);
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ tag.setBoolean("autoPull", autoPullFluidList);
+ tag.setInteger("minAmount", minAutoPullAmount);
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ }
+
+}
diff --git a/src/main/java/gregtech/common/tileentities/machines/IRecipeProcessingAwareHatch.java b/src/main/java/gregtech/common/tileentities/machines/IRecipeProcessingAwareHatch.java
new file mode 100644
index 0000000000..d78400b30e
--- /dev/null
+++ b/src/main/java/gregtech/common/tileentities/machines/IRecipeProcessingAwareHatch.java
@@ -0,0 +1,31 @@
+package gregtech.common.tileentities.machines;
+
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
+import gregtech.api.recipe.check.CheckRecipeResult;
+import gregtech.api.recipe.check.CheckRecipeResultRegistry;
+
+public interface IRecipeProcessingAwareHatch {
+
+ /**
+ * Called when multiblock controller starts processing.
+ * {@link #endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase)} is called on the same tick.
+ */
+ default void startRecipeProcessing() {}
+
+ /**
+ * Called when multiblock controller ends processing. {@link #startRecipeProcessing()} is called on the same tick.
+ *
+ * @param controller Caller of this method.
+ * @return Result of the process of this method. {@code !wasSuccessful()} means the returned result should
+ * overwrite the result calculated on multiblock whatever the reason is.
+ */
+ default CheckRecipeResult endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase controller) {
+ endRecipeProcessing();
+ return CheckRecipeResultRegistry.SUCCESSFUL;
+ }
+
+ /**
+ * Simple version of {@link #endRecipeProcessing(GT_MetaTileEntity_MultiBlockBase)}. Maybe use it instead.
+ */
+ default void endRecipeProcessing() {}
+}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java
index 117aa46b3f..e9f80b6824 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_AssemblyLine.java
@@ -58,6 +58,7 @@ import gregtech.api.util.GT_Recipe;
import gregtech.api.util.GT_Recipe.GT_Recipe_AssemblyLine;
import gregtech.api.util.GT_Utility;
import gregtech.api.util.IGT_HatchAdder;
+import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME;
public class GT_MetaTileEntity_AssemblyLine
extends GT_MetaTileEntity_EnhancedMultiBlockBase<GT_MetaTileEntity_AssemblyLine> implements ISurvivalConstructable {
@@ -278,6 +279,13 @@ public class GT_MetaTileEntity_AssemblyLine
}
tFluids[i] = tRecipe.mFluidInputs[i].amount;
tFluidSlot[i] = tMultiHatch.getFluidSlot(tRecipe.mFluidInputs[i]);
+ } else if (mInputHatches.get(i) instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) {
+ FluidStack fluidStack = meHatch.getMatchingFluidStack(tRecipe.mFluidInputs[i]);
+ if (fluidStack == null || fluidStack.amount < tRecipe.mFluidInputs[i].amount) {
+ continue nextDataStick;
+ }
+ tFluids[i] = tRecipe.mFluidInputs[i].amount;
+ tFluidSlot[i] = meHatch.getFluidSlot(tRecipe.mFluidInputs[i]);
} else {
FluidStack fluidInHatch = mInputHatches.get(i).mFluid;
if (!GT_Utility.areFluidsEqual(fluidInHatch, tRecipe.mFluidInputs[i], true)
@@ -331,6 +339,9 @@ public class GT_MetaTileEntity_AssemblyLine
if (tMultiHatch.getFluid(tFluidSlot[i]).amount <= 0) {
tMultiHatch.setFluid(null, tFluidSlot[i]);
}
+ } else if (mInputHatches.get(i) instanceof GT_MetaTileEntity_Hatch_Input_ME meHatch) {
+ FluidStack fluidStack = meHatch.getShadowFluidStack(tFluidSlot[i]);
+ fluidStack.amount = Math.max(0, fluidStack.amount - tFluids[i]);
} else {
mInputHatches.get(i).mFluid.amount -= tFluids[i];
if (mInputHatches.get(i).mFluid.amount <= 0) {
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 0da8ec7ac0..971bafc8f8 100644
--- a/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java
+++ b/src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java
@@ -161,6 +161,7 @@ import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_HV;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_IV;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_LV;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_LuV;
+import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_ME;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_MV;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_UHV;
import static gregtech.api.enums.MetaTileEntityIDs.INPUT_HATCH_ULV;
@@ -511,6 +512,7 @@ import gregtech.common.tileentities.machines.GT_MetaTileEntity_BasicHull_SteelBr
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_CraftingInput_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_CraftingInput_Slave;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_InputBus_ME;
+import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Input_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Output_ME;
import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_AdvSeismicProspector;
@@ -2316,6 +2318,9 @@ public class GT_Loader_MetaTileEntities implements Runnable { // TODO CHECK CIRC
ItemList.Hatch_Input_Bus_ME.set(
new GT_MetaTileEntity_Hatch_InputBus_ME(INPUT_BUS_ME.ID, "hatch.input_bus.me", "Stocking Input Bus (ME)")
.getStackForm(1L));
+ ItemList.Hatch_Input_ME.set(
+ new GT_MetaTileEntity_Hatch_Input_ME(INPUT_HATCH_ME.ID, "hatch.input.me", "Stocking Input Hatch (ME)")
+ .getStackForm(1L));
ItemList.Hatch_Output_ME.set(
new GT_MetaTileEntity_Hatch_Output_ME(OUTPUT_HATCH_ME.ID, "hatch.output.me", "Output Hatch (ME)")
.getStackForm(1L));
diff --git a/src/main/resources/assets/gregtech/lang/en_US.lang b/src/main/resources/assets/gregtech/lang/en_US.lang
index 520c949178..1a6505a731 100644
--- a/src/main/resources/assets/gregtech/lang/en_US.lang
+++ b/src/main/resources/assets/gregtech/lang/en_US.lang
@@ -334,12 +334,17 @@ GT5U.machines.allow_nbt.tooltip=Allow items with NBT
GT5U.machines.allow_nbt.tooltip.extended=§7By default, all items with NBT are blocked.
GT5U.machines.ignore_nbt.tooltip=Ignore item NBT
GT5U.machines.ignore_nbt.tooltip.extended=§7By default, item NBT must match.
-GT5U.machines.stocking_bus.cannot_set_slot=§8Cannot set slot while auto-pull mode
-GT5U.machines.stocking_bus.auto_pull.tooltip=Click to toggle automatic item pulling from ME.
-GT5U.machines.stocking_bus.auto_pull.tooltip.1=Right-Click to edit minimum stack size for item pulling.
+GT5U.machines.stocking_bus.cannot_set_slot=§8Cannot set slot while auto-pull mode is enabled
+GT5U.machines.stocking_bus.auto_pull.tooltip.1=Click to toggle automatic item pulling from ME.
+GT5U.machines.stocking_bus.auto_pull.tooltip.2=Right-Click to edit minimum stack size for item pulling.
GT5U.machines.stocking_bus.min_stack_size=Min Stack Size
GT5U.machines.stocking_bus.auto_pull_toggle.enabled=Automatic Item Pull Enabled
GT5U.machines.stocking_bus.auto_pull_toggle.disabled=Automatic Item Pull Disabled
+GT5U.machines.stocking_hatch.auto_pull.tooltip.1=Click to toggle automatic fluid pulling from ME.
+GT5U.machines.stocking_hatch.auto_pull.tooltip.2=Right-Click to edit minimum amount for fluid pulling.
+GT5U.machines.stocking_hatch.min_amount=Min Amount
+GT5U.machines.stocking_hatch.auto_pull_toggle.enabled=Automatic Fluid Pull Enabled
+GT5U.machines.stocking_hatch.auto_pull_toggle.disabled=Automatic Fluid Pull Disabled
GT5U.machines.stocking_bus.saved=Saved Config to Data Stick
GT5U.machines.stocking_bus.loaded=Loaded Config From Data Stick
@@ -419,6 +424,7 @@ GT5U.gui.text.drill_chunks_left=Drilling chunk: §a%s / %s
GT5U.gui.text.drill_offline_reason=Drill Offline: %s
GT5U.gui.text.drill_offline_generic=Drill Offline
GT5U.gui.text.stocking_bus_fail_extraction=§4Failed to extract expected amount of items from stocking bus. This can be caused by attaching multiple storage buses to the same inventory.
+GT5U.gui.text.stocking_hatch_fail_extraction=§4Failed to extract expected amount of fluids from stocking hatch. This can be caused by attaching multiple storage fluid buses to the same tank.
GT5U.item.programmed_circuit.select.header=Reprogram Circuit
@@ -551,6 +557,7 @@ GT5U.waila.energy.produce_with_amperage=Probably generates: §a%s§r EU/t (%sA %
GT5U.waila.stocking_bus.auto_pull.enabled=Auto-Pull from ME: Enabled
GT5U.waila.stocking_bus.auto_pull.disabled=Auto-Pull from ME: Disabled
GT5U.waila.stocking_bus.min_stack_size=Minimum Stack Size: %s
+GT5U.waila.stocking_hatch.min_amount=Minimum Amount: %s
achievement.flintpick=First Tools
achievement.flintpick.desc=Craft a flint pick