aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorHarry <harryyunull@gmail.com>2023-07-24 03:55:26 -0400
committerGitHub <noreply@github.com>2023-07-24 09:55:26 +0200
commit75633e41387b6ef37dc02b7e0cc5076936c9b3ed (patch)
tree11ecfb9b62b8d9815aeabba5f06fe372cdd7a02b /src/main
parent4a4881d79f40b8b800f9aa858542195efd1849d0 (diff)
downloadGT5-Unofficial-75633e41387b6ef37dc02b7e0cc5076936c9b3ed.tar.gz
GT5-Unofficial-75633e41387b6ef37dc02b7e0cc5076936c9b3ed.tar.bz2
GT5-Unofficial-75633e41387b6ef37dc02b7e0cc5076936c9b3ed.zip
Add Crafting Input Buffer (ME) (#2160)
* Crafting input buffer * persist data * rename and stuff * no more waiting for multis to start * rearrange ui * spotless * fixes * refactor * Crafting Input Slave * getCrafterIcon * crafting input bus * spotless * Update GT_MetaTileEntity_MultiBlockBase.java * Update GT_Loader_MetaTileEntities.java * Update GT_Loader_MetaTileEntities.java * Update GT_MetaTileEntity_MultiBlockBase.java * Update GT_MetaTileEntity_MultiBlockBase.java * Update GT_Loader_MetaTileEntities.java --------- Co-authored-by: Martin Robertz <dream-master@gmx.net>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/gregtech/api/enums/ItemList.java2
-rw-r--r--src/main/java/gregtech/api/enums/MetaTileEntityIDs.java3
-rw-r--r--src/main/java/gregtech/api/gui/modularui/GT_UITextures.java3
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java50
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java74
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_CraftingInput_ME.java701
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_CraftingInput_Slave.java180
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/IDualInputHatch.java16
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/IDualInputInventory.java11
-rw-r--r--src/main/java/gregtech/loaders/preload/GT_Loader_MetaTileEntities.java19
-rw-r--r--src/main/resources/assets/gregtech/textures/gui/overlay_slot/pattern_me.pngbin0 -> 417 bytes
11 files changed, 1022 insertions, 37 deletions
diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java
index 6d2cf37577..7f2cafc1aa 100644
--- a/src/main/java/gregtech/api/enums/ItemList.java
+++ b/src/main/java/gregtech/api/enums/ItemList.java
@@ -2001,6 +2001,8 @@ public enum ItemList implements IItemContainer {
Hatch_Input_Bus_ME,
Hatch_CraftingInput_Bus_ME,
+ Hatch_CraftingInput_Bus_ME_ItemOnly,
+ Hatch_CraftingInput_Bus_Slave,
AdvDebugStructureWriter,
Superconducting_Magnet_Solenoid_MV,
diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
index d8c5be4bce..f5140af9a1 100644
--- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
+++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java
@@ -604,6 +604,9 @@ public enum MetaTileEntityIDs {
OUTPUT_BUS_ME(2710),
INPUT_BUS_ME(2711),
OUTPUT_HATCH_ME(2713),
+ CRAFTING_INPUT_ME(2714),
+ CRAFTING_INPUT_ME_BUS(2715),
+ CRAFTING_INPUT_SLAVE(2716),
CHEST_BUFFER_ULV(9230),
CHEST_BUFFER_LV(9231),
CHEST_BUFFER_MV(9232),
diff --git a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java
index 8dda90a630..7a21dad8cd 100644
--- a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java
+++ b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java
@@ -34,6 +34,9 @@ public class GT_UITextures {
.of(GregTech.ID, "gui/slot/uplifted", 18, 18, 1);
public static final UITexture OVERLAY_SLOT_ARROW_ME = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/arrow_me");
+ public static final UITexture OVERLAY_SLOT_PATTERN_ME = UITexture
+ .fullImage(GregTech.ID, "gui/overlay_slot/pattern_me");
+
public static final UITexture OVERLAY_SLOT_BEAKER_1 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_1");
public static final UITexture OVERLAY_SLOT_BEAKER_2 = UITexture.fullImage(GregTech.ID, "gui/overlay_slot/beaker_2");
public static final UITexture OVERLAY_SLOT_BEE_DRONE = UITexture
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
index 01494828b9..938423012c 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_ExtendedPowerMultiBlockBase.java
@@ -21,6 +21,8 @@ import gregtech.api.recipe.check.CheckRecipeResult;
import gregtech.api.recipe.check.CheckRecipeResultRegistry;
import gregtech.api.util.GT_ExoticEnergyInputHelper;
import gregtech.api.util.GT_Utility;
+import gregtech.common.tileentities.machines.IDualInputHatch;
+import gregtech.common.tileentities.machines.IDualInputInventory;
/**
* Multiblock base class that allows machine to use power over int.
@@ -144,29 +146,45 @@ public abstract class GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T extends GT
setupProcessingLogic(processingLogic);
- if (isInputSeparationEnabled()) {
- for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) {
- List<ItemStack> inputItems = new ArrayList<>();
- for (int i = bus.getSizeInventory() - 1; i >= 0; i--) {
- ItemStack stored = bus.getStackInSlot(i);
- if (stored != null) {
- inputItems.add(stored);
+ // check crafting input hatches first
+ for (IDualInputHatch dualInputHatch : mDualInputHatches) {
+ for (var it = dualInputHatch.inventories(); it.hasNext();) {
+ IDualInputInventory slot = it.next();
+ processingLogic.setInputItems(slot.getItemInputs());
+ processingLogic.setInputFluids(slot.getFluidInputs());
+ result = processingLogic.process();
+ if (result.wasSuccessful()) break;
+ }
+ if (result.wasSuccessful()) break;
+ }
+
+ processingLogic.setInputFluids(getStoredFluids());
+
+ if (!result.wasSuccessful()) {
+ if (isInputSeparationEnabled()) {
+ for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) {
+ List<ItemStack> inputItems = new ArrayList<>();
+ for (int i = bus.getSizeInventory() - 1; i >= 0; i--) {
+ ItemStack stored = bus.getStackInSlot(i);
+ if (stored != null) {
+ inputItems.add(stored);
+ }
+ }
+ if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
+ inputItems.add(getControllerSlot());
}
+ processingLogic.setInputItems(inputItems.toArray(new ItemStack[0]));
+ result = processingLogic.process();
+ if (result.wasSuccessful()) break;
}
+ } else {
+ List<ItemStack> inputItems = getStoredInputs();
if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
inputItems.add(getControllerSlot());
}
- processingLogic.setInputItems(inputItems.toArray(new ItemStack[0]));
+ processingLogic.setInputItems(inputItems);
result = processingLogic.process();
- if (result.wasSuccessful()) break;
- }
- } else {
- List<ItemStack> inputItems = getStoredInputs();
- if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
- inputItems.add(getControllerSlot());
}
- processingLogic.setInputItems(inputItems);
- result = processingLogic.process();
}
// inputs are consumed by `process()`
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 6578c82c30..8d57eb9e13 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
@@ -6,10 +6,7 @@ import static mcp.mobius.waila.api.SpecialChars.GREEN;
import static mcp.mobius.waila.api.SpecialChars.RED;
import static mcp.mobius.waila.api.SpecialChars.RESET;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
@@ -84,6 +81,8 @@ import gregtech.common.items.GT_MetaGenerated_Tool_01;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_InputBus_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.multi.GT_MetaTileEntity_LargeTurbine;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
@@ -122,6 +121,7 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
public ArrayList<GT_MetaTileEntity_Hatch_Output> mOutputHatches = new ArrayList<>();
public ArrayList<GT_MetaTileEntity_Hatch_InputBus> mInputBusses = new ArrayList<>();
public ArrayList<GT_MetaTileEntity_Hatch_OutputBus> mOutputBusses = new ArrayList<>();
+ public ArrayList<IDualInputHatch> mDualInputHatches = new ArrayList<>();
public ArrayList<GT_MetaTileEntity_Hatch_Dynamo> mDynamoHatches = new ArrayList<>();
public ArrayList<GT_MetaTileEntity_Hatch_Muffler> mMufflerHatches = new ArrayList<>();
public ArrayList<GT_MetaTileEntity_Hatch_Energy> mEnergyHatches = new ArrayList<>();
@@ -488,6 +488,13 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
}
private boolean shouldCheckRecipeThisTick(long aTick) {
+ // do a recipe check if any crafting input hatch just got pushed in items
+ for (IDualInputHatch craftingInputMe : mDualInputHatches) {
+ if (craftingInputMe.justUpdated()) {
+ return true;
+ }
+ }
+
// Perform more frequent recipe change after the machine just shuts down.
long timeElapsed = aTick - mLastWorkingTick;
@@ -694,29 +701,45 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
setupProcessingLogic(processingLogic);
- if (isInputSeparationEnabled()) {
- for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) {
- List<ItemStack> inputItems = new ArrayList<>();
- for (int i = bus.getSizeInventory() - 1; i >= 0; i--) {
- ItemStack stored = bus.getStackInSlot(i);
- if (stored != null) {
- inputItems.add(stored);
+ // check crafting input hatches first
+ for (IDualInputHatch dualInputHatch : mDualInputHatches) {
+ for (var it = dualInputHatch.inventories(); it.hasNext();) {
+ IDualInputInventory slot = it.next();
+ processingLogic.setInputItems(slot.getItemInputs());
+ processingLogic.setInputFluids(slot.getFluidInputs());
+ result = processingLogic.process();
+ if (result.wasSuccessful()) break;
+ }
+ if (result.wasSuccessful()) break;
+ }
+
+ processingLogic.setInputFluids(getStoredFluids());
+
+ if (!result.wasSuccessful()) {
+ if (isInputSeparationEnabled()) {
+ for (GT_MetaTileEntity_Hatch_InputBus bus : mInputBusses) {
+ List<ItemStack> inputItems = new ArrayList<>();
+ for (int i = bus.getSizeInventory() - 1; i >= 0; i--) {
+ ItemStack stored = bus.getStackInSlot(i);
+ if (stored != null) {
+ inputItems.add(stored);
+ }
}
+ if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
+ inputItems.add(getControllerSlot());
+ }
+ processingLogic.setInputItems(inputItems.toArray(new ItemStack[0]));
+ result = processingLogic.process();
+ if (result.wasSuccessful()) break;
}
+ } else {
+ List<ItemStack> inputItems = getStoredInputs();
if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
inputItems.add(getControllerSlot());
}
- processingLogic.setInputItems(inputItems.toArray(new ItemStack[0]));
+ processingLogic.setInputItems(inputItems);
result = processingLogic.process();
- if (result.wasSuccessful()) break;
}
- } else {
- List<ItemStack> inputItems = getStoredInputs();
- if (getControllerSlot() != null && canUseControllerSlotForRecipe()) {
- inputItems.add(getControllerSlot());
- }
- processingLogic.setInputItems(inputItems);
- result = processingLogic.process();
}
// inputs are consumed by `process()`
@@ -754,7 +777,6 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
logic.setVoidProtection(protectsExcessItem(), protectsExcessFluid());
logic.setBatchSize(isBatchModeEnabled() ? getMaxBatchSize() : 1);
logic.setRecipeLocking(this, isRecipeLockingEnabled());
- logic.setInputFluids(getStoredFluids());
setProcessingLogicPower(logic);
}
@@ -1331,6 +1353,10 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
hatch.updateTexture(aBaseCasingIndex);
hatch.updateCraftingIcon(this.getMachineCraftingIcon());
}
+ if (aMetaTileEntity instanceof IDualInputHatch hatch) {
+ hatch.updateCraftingIcon(this.getMachineCraftingIcon());
+ return mDualInputHatches.add(hatch);
+ }
if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_Input) {
((GT_MetaTileEntity_Hatch_Input) aMetaTileEntity).mRecipeMap = getRecipeMap();
return mInputHatches.add((GT_MetaTileEntity_Hatch_Input) aMetaTileEntity);
@@ -1431,6 +1457,12 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity
if (aTileEntity == null) return false;
IMetaTileEntity aMetaTileEntity = aTileEntity.getMetaTileEntity();
if (aMetaTileEntity == null) return false;
+ if (aMetaTileEntity instanceof IDualInputHatch hatch) {
+ hatch.updateTexture(aBaseCasingIndex);
+ hatch.updateCraftingIcon(this.getMachineCraftingIcon());
+ return mDualInputHatches.add(hatch);
+ }
+
if (aMetaTileEntity instanceof GT_MetaTileEntity_Hatch_InputBus hatch) {
hatch.updateTexture(aBaseCasingIndex);
hatch.updateCraftingIcon(this.getMachineCraftingIcon());
diff --git a/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_CraftingInput_ME.java b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_CraftingInput_ME.java
new file mode 100644
index 0000000000..ee7a3df356
--- /dev/null
+++ b/src/main/java/gregtech/common/tileentities/machines/GT_MetaTileEntity_Hatch_CraftingInput_ME.java
@@ -0,0 +1,701 @@
+package gregtech.common.tileentities.machines;
+
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_INPUT_HATCH;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_INPUT_HATCH_ACTIVE;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.inventory.InventoryCrafting;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.Constants;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.jetbrains.annotations.NotNull;
+
+import com.glodblock.github.common.item.ItemFluidPacket;
+import com.google.common.collect.ImmutableList;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.common.internal.wrapper.BaseSlot;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotGroup;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+
+import appeng.api.AEApi;
+import appeng.api.implementations.ICraftingPatternItem;
+import appeng.api.implementations.IPowerChannelState;
+import appeng.api.networking.GridFlags;
+import appeng.api.networking.IGridNode;
+import appeng.api.networking.crafting.ICraftingPatternDetails;
+import appeng.api.networking.crafting.ICraftingProvider;
+import appeng.api.networking.crafting.ICraftingProviderHelper;
+import appeng.api.networking.events.MENetworkCraftingPatternChange;
+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.storage.data.IAEItemStack;
+import appeng.api.util.AECableType;
+import appeng.api.util.DimensionalCoord;
+import appeng.me.GridAccessException;
+import appeng.me.helpers.AENetworkProxy;
+import appeng.me.helpers.IGridProxyable;
+import appeng.util.IWideReadableNumberConverter;
+import appeng.util.Platform;
+import appeng.util.ReadableNumberConverter;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.ItemList;
+import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.interfaces.IConfigurationCircuitSupport;
+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_InputBus;
+import gregtech.api.render.TextureFactory;
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+public class GT_MetaTileEntity_Hatch_CraftingInput_ME extends GT_MetaTileEntity_Hatch_InputBus
+ implements IConfigurationCircuitSupport, IAddGregtechLogo, IAddUIWidgets, IPowerChannelState, ICraftingProvider,
+ IGridProxyable, IDualInputHatch {
+
+ // Each pattern slot in the crafting input hatch has its own internal inventory
+ public static class PatternSlot implements IDualInputInventory {
+
+ public interface SharedItemGetter {
+
+ ItemStack[] getSharedItem();
+ }
+
+ private ItemStack pattern;
+ private ICraftingPatternDetails patternDetails;
+ private List<ItemStack> itemInventory;
+ private List<FluidStack> fluidInventory;
+ private SharedItemGetter sharedItemGetter;
+
+ public PatternSlot(ItemStack pattern, World world, SharedItemGetter getter) {
+ this.pattern = pattern;
+ this.patternDetails = ((ICraftingPatternItem) Objects.requireNonNull(pattern.getItem()))
+ .getPatternForItem(pattern, world);
+ this.itemInventory = new ArrayList<>();
+ this.fluidInventory = new ArrayList<>();
+ this.sharedItemGetter = getter;
+ }
+
+ public PatternSlot(NBTTagCompound nbt, World world, SharedItemGetter getter) {
+ this.pattern = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("pattern"));
+ this.patternDetails = ((ICraftingPatternItem) Objects.requireNonNull(pattern.getItem()))
+ .getPatternForItem(pattern, world);
+ this.itemInventory = new ArrayList<>();
+ this.fluidInventory = new ArrayList<>();
+ this.sharedItemGetter = getter;
+ NBTTagList inv = nbt.getTagList("inventory", Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < inv.tagCount(); i++) {
+ itemInventory.add(ItemStack.loadItemStackFromNBT(inv.getCompoundTagAt(i)));
+ }
+ NBTTagList fluidInv = nbt.getTagList("fluidInventory", Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < fluidInv.tagCount(); i++) {
+ fluidInventory.add(FluidStack.loadFluidStackFromNBT(fluidInv.getCompoundTagAt(i)));
+ }
+ }
+
+ public boolean hasChanged(ItemStack newPattern, World world) {
+ return newPattern == null
+ || (!ItemStack.areItemStacksEqual(pattern, newPattern) && !this.patternDetails.equals(
+ ((ICraftingPatternItem) Objects.requireNonNull(pattern.getItem()))
+ .getPatternForItem(pattern, world)));
+ }
+
+ public ItemStack[] getItemInputs() {
+ return ArrayUtils.addAll(itemInventory.toArray(new ItemStack[0]), sharedItemGetter.getSharedItem());
+ }
+
+ public FluidStack[] getFluidInputs() {
+ return fluidInventory.toArray(new FluidStack[0]);
+ }
+
+ public ICraftingPatternDetails getPatternDetails() {
+ return patternDetails;
+ }
+
+ public void refund(AENetworkProxy proxy, BaseActionSource src) throws GridAccessException {
+ IMEMonitor<IAEItemStack> sg = proxy.getStorage()
+ .getItemInventory();
+ for (ItemStack itemStack : itemInventory) {
+ if (itemStack == null || itemStack.stackSize == 0) continue;
+ IAEItemStack rest = Platform.poweredInsert(
+ proxy.getEnergy(),
+ sg,
+ AEApi.instance()
+ .storage()
+ .createItemStack(itemStack),
+ src);
+ itemStack.stackSize = rest != null && rest.getStackSize() > 0 ? (int) rest.getStackSize() : 0;
+ }
+ IMEMonitor<IAEFluidStack> fsg = proxy.getStorage()
+ .getFluidInventory();
+ for (FluidStack fluidStack : fluidInventory) {
+ if (fluidStack == null || fluidStack.amount == 0) continue;
+ IAEFluidStack rest = Platform.poweredInsert(
+ proxy.getEnergy(),
+ fsg,
+ AEApi.instance()
+ .storage()
+ .createFluidStack(fluidStack),
+ src);
+ fluidStack.amount = rest != null && rest.getStackSize() > 0 ? (int) rest.getStackSize() : 0;
+ }
+ }
+
+ public void insertItemsAndFluids(InventoryCrafting inventoryCrafting) {
+ for (int i = 0; i < inventoryCrafting.getSizeInventory(); ++i) {
+ ItemStack itemStack = inventoryCrafting.getStackInSlot(i);
+ if (itemStack == null) continue;
+
+ boolean inserted = false;
+ if (itemStack.getItem() instanceof ItemFluidPacket) { // insert fluid
+ var fluidStack = ItemFluidPacket.getFluidStack(itemStack);
+ if (fluidStack == null) continue;
+ for (var fluid : fluidInventory) {
+ if (fluid.isFluidEqual(fluidStack)) {
+ fluid.amount += fluidStack.amount;
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted) {
+ fluidInventory.add(fluidStack);
+ }
+ } else { // insert item
+ for (var item : itemInventory) {
+ if (itemStack.isItemEqual(item)) {
+ item.stackSize += itemStack.stackSize;
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted) {
+ itemInventory.add(itemStack);
+ }
+ }
+ }
+ }
+
+ public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
+ nbt.setTag("pattern", pattern.writeToNBT(new NBTTagCompound()));
+
+ NBTTagList itemInventoryNbt = new NBTTagList();
+ for (ItemStack itemStack : this.itemInventory) {
+ itemInventoryNbt.appendTag(itemStack.writeToNBT(new NBTTagCompound()));
+ }
+ nbt.setTag("inventory", itemInventoryNbt);
+
+ NBTTagList fluidInventoryNbt = new NBTTagList();
+ for (FluidStack fluidStack : fluidInventory) {
+ fluidInventoryNbt.appendTag(fluidStack.writeToNBT(new NBTTagCompound()));
+ }
+ nbt.setTag("fluidInventory", fluidInventoryNbt);
+
+ return nbt;
+ }
+ }
+
+ // mInventory is used for storing patterns, circuit and manual slot (typically NC items)
+ private static final int MAX_PATTERN_COUNT = 4 * 8;
+ private static final int MAX_INV_COUNT = MAX_PATTERN_COUNT + 2;
+ private static final int SLOT_MANUAL = MAX_INV_COUNT - 1;
+ private static final int SLOT_CIRCUIT = MAX_INV_COUNT - 2;
+
+ private BaseActionSource requestSource = null;
+ private @Nullable AENetworkProxy gridProxy = null;
+
+ // holds all internal inventories
+ private PatternSlot[] internalInventory = new PatternSlot[MAX_PATTERN_COUNT];
+
+ // a hash map for faster lookup of pattern slots, not necessarily all valid.
+ private Map<ICraftingPatternDetails, PatternSlot> patternDetailsPatternSlotMap = new HashMap<>(MAX_PATTERN_COUNT);
+
+ private boolean initialPatternSyncDone = false;
+ private boolean justHadNewItems = false;
+
+ private boolean supportFluids;
+
+ public GT_MetaTileEntity_Hatch_CraftingInput_ME(int aID, String aName, String aNameRegional,
+ boolean supportFluids) {
+ super(
+ aID,
+ aName,
+ aNameRegional,
+ 1,
+ MAX_INV_COUNT,
+ new String[] { "Advanced item input for Multiblocks", "Processes patterns directly from ME",
+ supportFluids ? "It supports patterns including fluids"
+ : "It does not support patterns including fluids" });
+ disableSort = true;
+ this.supportFluids = supportFluids;
+ }
+
+ public GT_MetaTileEntity_Hatch_CraftingInput_ME(String aName, int aTier, String[] aDescription,
+ ITexture[][][] aTextures, boolean supportFluids) {
+ super(aName, aTier, MAX_INV_COUNT, aDescription, aTextures);
+ this.supportFluids = supportFluids;
+ disableSort = true;
+ }
+
+ @Override
+ public MetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new GT_MetaTileEntity_Hatch_CraftingInput_ME(mName, mTier, mDescriptionArray, mTextures, supportFluids);
+ }
+
+ @Override
+ public ITexture[] getTexturesActive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_INPUT_HATCH_ACTIVE) };
+ }
+
+ @Override
+ public ITexture[] getTexturesInactive(ITexture aBaseTexture) {
+ return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_INPUT_HATCH) };
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
+ super.onPostTick(aBaseMetaTileEntity, aTimer);
+
+ if (!initialPatternSyncDone && aTimer % 10 == 0 && getBaseMetaTileEntity().isServerSide()) {
+ try {
+ getProxy().getGrid()
+ .postEvent(new MENetworkCraftingPatternChange(this, getProxy().getNode()));
+ } catch (GridAccessException ignored) {
+ return;
+ }
+ initialPatternSyncDone = true;
+ }
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ getProxy().onReady();
+ }
+
+ @Override
+ public IGridNode getGridNode(ForgeDirection dir) {
+ return getProxy().getNode();
+ }
+
+ @Override
+ public AECableType getCableConnectionType(ForgeDirection forgeDirection) {
+ return isOutputFacing(forgeDirection) ? AECableType.SMART : AECableType.NONE;
+ }
+
+ @Override
+ public void securityBreak() {}
+
+ @Override
+ public AENetworkProxy getProxy() {
+ if (gridProxy == null) {
+ gridProxy = new AENetworkProxy(this, "proxy", ItemList.Hatch_CraftingInput_Bus_ME.get(1), true);
+ gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL);
+ if (getBaseMetaTileEntity().getWorld() != null) gridProxy.setOwner(
+ getBaseMetaTileEntity().getWorld()
+ .getPlayerEntityByName(getBaseMetaTileEntity().getOwnerName()));
+ }
+
+ return this.gridProxy;
+ }
+
+ @Override
+ public DimensionalCoord getLocation() {
+ return new DimensionalCoord(
+ getBaseMetaTileEntity().getWorld(),
+ getBaseMetaTileEntity().getXCoord(),
+ getBaseMetaTileEntity().getYCoord(),
+ getBaseMetaTileEntity().getZCoord());
+ }
+
+ @Override
+ public void gridChanged() {
+ super.gridChanged();
+ if (getProxy().isReady()) {
+ getProxy().getNode()
+ .updateState();
+ }
+ }
+
+ @Override
+ public boolean isPowered() {
+ return getProxy() != null && getProxy().isPowered();
+ }
+
+ @Override
+ public boolean isActive() {
+ return getProxy() != null && getProxy().isActive();
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+
+ // save internalInventory
+ NBTTagList internalInventoryNBT = new NBTTagList();
+ for (int i = 0; i < internalInventory.length; i++) {
+ if (internalInventory[i] != null) {
+ NBTTagCompound internalInventorySlotNBT = new NBTTagCompound();
+ internalInventorySlotNBT.setInteger("patternSlot", i);
+ internalInventorySlotNBT
+ .setTag("patternSlotNBT", internalInventory[i].writeToNBT(new NBTTagCompound()));
+ internalInventoryNBT.appendTag(internalInventorySlotNBT);
+ }
+ }
+ aNBT.setTag("internalInventory", internalInventoryNBT);
+
+ if (GregTech_API.mAE2) {
+ getProxy().writeToNBT(aNBT);
+ }
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ // load internalInventory
+ NBTTagList internalInventoryNBT = aNBT.getTagList("internalInventory", Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < internalInventoryNBT.tagCount(); i++) {
+ NBTTagCompound internalInventorySlotNBT = internalInventoryNBT.getCompoundTagAt(i);
+ int patternSlot = internalInventorySlotNBT.getInteger("patternSlot");
+ internalInventory[patternSlot] = new PatternSlot(
+ internalInventorySlotNBT.getCompoundTag("patternSlotNBT"),
+ getBaseMetaTileEntity().getWorld(),
+ this::getSharedItems);
+ }
+
+ // reconstruct patternDetailsPatternSlotMap
+ patternDetailsPatternSlotMap.clear();
+ for (PatternSlot patternSlot : internalInventory) {
+ if (patternSlot != null) {
+ patternDetailsPatternSlotMap.put(patternSlot.getPatternDetails(), patternSlot);
+ }
+ }
+
+ if (GregTech_API.mAE2) {
+ getProxy().readFromNBT(aNBT);
+ }
+ }
+
+ @Override
+ public boolean isGivingInformation() {
+ return true;
+ }
+
+ private String describePattern(ICraftingPatternDetails patternDetails) {
+ return Arrays.stream(patternDetails.getCondensedOutputs())
+ .map(
+ aeItemStack -> aeItemStack.getItem()
+ .getItemStackDisplayName(aeItemStack.getItemStack()))
+ .collect(Collectors.joining(", "));
+ }
+
+ @Override
+ public String[] getInfoData() {
+ if (GregTech_API.mAE2) {
+ var ret = new ArrayList<String>();
+ ret.add(
+ "The bus is " + ((getProxy() != null && getProxy().isActive()) ? EnumChatFormatting.GREEN + "online"
+ : EnumChatFormatting.RED + "offline" + getAEDiagnostics()) + EnumChatFormatting.RESET);
+ ret.add("Internal Inventory: ");
+ var i = 0;
+ for (var slot : internalInventory) {
+ if (slot == null) continue;
+ IWideReadableNumberConverter nc = ReadableNumberConverter.INSTANCE;
+
+ i += 1;
+ ret.add(
+ "Slot " + i
+ + " "
+ + EnumChatFormatting.BLUE
+ + describePattern(slot.patternDetails)
+ + EnumChatFormatting.RESET);
+ for (var item : slot.itemInventory) {
+ if (item == null || item.stackSize == 0) continue;
+ ret.add(
+ item.getItem()
+ .getItemStackDisplayName(item) + ": "
+ + EnumChatFormatting.GOLD
+ + nc.toWideReadableForm(item.stackSize)
+ + EnumChatFormatting.RESET);
+ }
+ for (var fluid : slot.fluidInventory) {
+ if (fluid == null || fluid.amount == 0) continue;
+ ret.add(
+ fluid.getLocalizedName() + ": "
+ + EnumChatFormatting.AQUA
+ + nc.toWideReadableForm(fluid.amount)
+ + EnumChatFormatting.RESET);
+ }
+ }
+ return ret.toArray(new String[0]);
+ } else return new String[] {};
+ }
+
+ @Override
+ public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return false;
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return false;
+ }
+
+ @Override
+ public int getCircuitSlot() {
+ return SLOT_CIRCUIT;
+ }
+
+ @Override
+ public int getCircuitSlotX() {
+ return 152;
+ }
+
+ @Override
+ public int getCircuitSlotY() {
+ return 64;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return true;
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.@NotNull Builder builder, UIBuildContext buildContext) {
+ builder.widget(
+ SlotGroup.ofItemHandler(inventoryHandler, 8)
+ .startFromSlot(0)