From 4251dffd4d36403a4e3f4600a72bde2a5ea540f6 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:42:05 -0400 Subject: [PATCH 1/8] Base functionality done, todo item collapsing, auto pull/push, and proper front textures --- .../metatileentities/MetaTileEntities.java | 3 + .../MetaTileEntityRegistration.java | 15 + .../MetaTileEntityDualHatch.java | 351 ++++++++++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 32 ++ 4 files changed, 401 insertions(+) create mode 100644 src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 4e866e8df5c..30704f63403 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -65,6 +65,7 @@ import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityCleaningMaintenanceHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityComputationHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDataAccessHatch; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDualHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityEnergyHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityFluidHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityItemBus; @@ -246,6 +247,8 @@ private MetaTileEntities() {} public static MetaTileEntityHPCACooler HPCA_HEAT_SINK_COMPONENT; public static MetaTileEntityHPCACooler HPCA_ACTIVE_COOLER_COMPONENT; public static MetaTileEntityHPCABridge HPCA_BRIDGE_COMPONENT; + public static MetaTileEntityDualHatch[] DUAL_INPUT_HATCH = new MetaTileEntityDualHatch[GTValues.V.length - 1]; + public static MetaTileEntityDualHatch[] DUAL_OUTPUT_HATCH = new MetaTileEntityDualHatch[GTValues.V.length - 1]; // Used for addons if they wish to disable certain tiers of machines private static final Map MID_TIER = new HashMap<>(); diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java index 675718df713..4075015890f 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java @@ -69,6 +69,7 @@ import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityCleaningMaintenanceHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityComputationHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDataAccessHatch; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDualHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityEnergyHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityFluidHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityItemBus; @@ -1098,5 +1099,19 @@ private static void multiblockParts() { MetaTileEntities.FLUID_EXPORT_HATCH_ME = MetaTileEntities.registerMetaTileEntity(11533, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); } + + // Dual Input Hatches + for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { + String voltageName = GTValues.VN[tier].toLowerCase(); + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11534 + tier, new MetaTileEntityDualHatch( + gregtechId(String.format("%s.%s", "dual_input_hatch", voltageName)), tier, false)); + } + + // Dual Output Hatches + for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { + String voltageName = GTValues.VN[tier].toLowerCase(); + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11548 + tier, new MetaTileEntityDualHatch( + gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true)); + } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java new file mode 100644 index 00000000000..2206b943c40 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -0,0 +1,351 @@ +package gregtech.common.metatileentities.multi.multiblockpart; + +import gregtech.api.GTValues; +import gregtech.api.capability.DualHandler; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IControllable; +import gregtech.api.capability.IGhostSlotConfigurable; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.items.itemhandlers.GTItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.widget.GhostCircuitSlotWidget; +import gregtech.client.renderer.texture.Textures; +import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.mui.widget.GTFluidSlot; + +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.items.IItemHandlerModifiable; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; +import com.cleanroommc.modularui.widgets.layout.Grid; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MetaTileEntityDualHatch extends MetaTileEntityMultiblockNotifiablePart implements + IMultiblockAbilityPart, + IControllable, + IGhostSlotConfigurable { + + @Nullable + protected GhostCircuitItemStackHandler circuitInventory; + @Nullable + private IItemHandlerModifiable actualImportItems; + private DualHandler dualHandler; + + private boolean workingEnabled; + private boolean autoCollapse; + + public MetaTileEntityDualHatch(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { + super(metaTileEntityId, tier, isExportHatch); + initializeInventory(); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityDualHatch(metaTileEntityId, getTier(), isExportHatch); + } + + @Override + protected void initializeInventory() { + super.initializeInventory(); + if (hasGhostCircuitInventory()) { + circuitInventory = new GhostCircuitItemStackHandler(this); + circuitInventory.addNotifiableMetaTileEntity(this); + actualImportItems = new ItemHandlerList(Arrays.asList(super.getImportItems(), circuitInventory)); + } else { + actualImportItems = null; + } + dualHandler = new DualHandler(isExportHatch ? getExportItems() : getImportItems(), + isExportHatch ? getExportFluids() : getImportFluids(), isExportHatch); + } + + @Override + public IItemHandlerModifiable getImportItems() { + return actualImportItems == null ? super.getImportItems() : actualImportItems; + } + + protected IFluidTank[] createTanks() { + int size = 1 + Math.min(GTValues.UHV, getTier()); + IFluidTank[] tanks = new IFluidTank[size]; + for (int index = 0; index < tanks.length; index++) { + tanks[index] = new NotifiableFluidTank(getTankSize(), null, isExportHatch); + } + return tanks; + } + + protected int getItemSize() { + int sizeRoot = 1 + Math.min(GTValues.UHV, getTier()); + return sizeRoot * sizeRoot; + } + + protected int getTankSize() { + return 8_000 * Math.min(Integer.MAX_VALUE, 1 << getTier()); + } + + @Override + protected IItemHandlerModifiable createImportItemHandler() { + return isExportHatch ? new GTItemStackHandler(this, 0) : + new NotifiableItemStackHandler(this, getItemSize(), null, false); + } + + @Override + protected IItemHandlerModifiable createExportItemHandler() { + return isExportHatch ? new NotifiableItemStackHandler(this, getItemSize(), null, true) : + new GTItemStackHandler(this, 0); + } + + @Override + protected FluidTankList createImportFluidHandler() { + return isExportHatch ? new FluidTankList(false) : new FluidTankList(false, createTanks()); + } + + @Override + protected FluidTankList createExportFluidHandler() { + return isExportHatch ? new FluidTankList(false, createTanks()) : new FluidTankList(false); + } + + @Override + public boolean hasGhostCircuitInventory() { + return !this.isExportHatch; + } + + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory == null || this.circuitInventory.getCircuitValue() == config) { + return; + } + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); + } + } + + @Override + public @Nullable MultiblockAbility getAbility() { + return isExportHatch ? MultiblockAbility.EXPORT_ITEMS : MultiblockAbility.IMPORT_ITEMS; + } + + @Override + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(dualHandler); + } + + @Override + public boolean usesMui2() { + return true; + } + + @SuppressWarnings("DuplicatedCode") + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + int rowSize = (int) Math.sqrt(getItemSize()); + guiSyncManager.registerSlotGroup("item_inv", rowSize); + + int backgroundWidth = Math.max( + 9 * 18 + 18 + 14 + 5, // Player Inv width + rowSize * 18 + 14 + 18); // Bus Inv width + int backgroundHeight = 18 + 18 * rowSize + 94; + + List> widgets = new ArrayList<>(); + for (int i = 0; i < rowSize; i++) { + widgets.add(new ArrayList<>()); + for (int j = 0; j < rowSize; j++) { + int index = i * rowSize + j; + IItemHandlerModifiable handler = isExportHatch ? exportItems : importItems; + widgets.get(i).add(new ItemSlot() + .slot(SyncHandlers.itemSlot(handler, index) + .slotGroup("item_inv") + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (onlyAmountChanged && + handler instanceof GTItemStackHandler gtHandler) { + gtHandler.onContentsChanged(index); + } + }) + .accessibility(!isExportHatch, true))); + } + + IFluidTank tankHandler = (isExportHatch ? exportFluids : importFluids).getTankAt(i); + widgets.get(i).add(new GTFluidSlot() + .syncHandler(GTFluidSlot.sync(tankHandler) + .accessibility(true, !isExportHatch))); + } + + BooleanSyncValue workingStateValue = new BooleanSyncValue(() -> workingEnabled, val -> workingEnabled = val); + guiSyncManager.syncValue("working_state", workingStateValue); + BooleanSyncValue collapseStateValue = new BooleanSyncValue(() -> autoCollapse, val -> autoCollapse = val); + guiSyncManager.syncValue("collapse_state", collapseStateValue); + + boolean hasGhostCircuit = hasGhostCircuitInventory() && this.circuitInventory != null; + + return GTGuis.createPanel(this, backgroundWidth, backgroundHeight) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)).child(new Grid() + .top(18).height(rowSize * 18) + .minElementMargin(0, 0) + .minColWidth(18).minRowHeight(18) + .alignX(0.5f) + .matrix(widgets)) + .child(Flow.column() + .pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5) + .width(18).height(18 * 4 + 5) + .child(GTGuiTextures.getLogo(getUITheme()).asWidget().size(17).top(18 * 3 + 5)) + .child(new ToggleButton() + .top(18 * 2) + .value(new BoolValue.Dynamic(workingStateValue::getBoolValue, + workingStateValue::setBoolValue)) + .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) + .tooltipBuilder(t -> t.setAutoUpdate(true) + .addLine(isExportHatch ? + (workingStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled")) : + (workingStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_input.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_input.tooltip.disabled"))))) + .child(new ToggleButton() + .top(18) + .value(new BoolValue.Dynamic(collapseStateValue::getBoolValue, + collapseStateValue::setBoolValue)) + .overlay(GTGuiTextures.BUTTON_AUTO_COLLAPSE) + .tooltipBuilder(t -> t.setAutoUpdate(true) + .addLine(collapseStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled")))) + .childIf(hasGhostCircuit, new GhostCircuitSlotWidget() + .slot(SyncHandlers.itemSlot(circuitInventory, 0)) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) + .childIf(!hasGhostCircuit, new Widget<>() + .background(GTGuiTextures.SLOT, GTGuiTextures.BUTTON_X) + .tooltip(t -> t.addLine( + IKey.lang("gregtech.gui.configurator_slot.unavailable.tooltip"))))); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + SimpleOverlayRenderer renderer = isExportHatch ? Textures.PIPE_OUT_OVERLAY : Textures.PIPE_IN_OVERLAY; + renderer.renderSided(getFrontFacing(), renderState, translation, pipeline); + SimpleOverlayRenderer overlay = isExportHatch ? Textures.ITEM_HATCH_OUTPUT_OVERLAY : + Textures.ITEM_HATCH_INPUT_OVERLAY; + overlay.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(workingEnabled); + buf.writeBoolean(autoCollapse); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.workingEnabled = buf.readBoolean(); + this.autoCollapse = buf.readBoolean(); + } + + @Override + public void setWorkingEnabled(boolean workingEnabled) { + this.workingEnabled = workingEnabled; + World world = getWorld(); + if (world != null && !world.isRemote) { + writeCustomData(GregtechDataCodes.WORKING_ENABLED, buf -> buf.writeBoolean(workingEnabled)); + } + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.WORKING_ENABLED) { + this.workingEnabled = buf.readBoolean(); + } else if (dataId == GregtechDataCodes.TOGGLE_COLLAPSE_ITEMS) { + this.autoCollapse = buf.readBoolean(); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + + data.setBoolean("workingEnabled", workingEnabled); + data.setBoolean("autoCollapse", autoCollapse); + + if (circuitInventory != null) { + circuitInventory.write(data); + } + + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + + this.workingEnabled = data.getBoolean("workingEnabled"); + this.autoCollapse = data.getBoolean("autoCollapse"); + + if (circuitInventory != null) { + circuitInventory.read(data); + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + if (this.isExportHatch) + tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); + else + tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + tooltip.add(I18n.format("gregtech.universal.tooltip.item_storage_capacity", getItemSize())); + tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", getTankSize())); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + @Override + public void addToolUsages(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { + tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers")); + tooltip.add(I18n.format("gregtech.tool_action.screwdriver.auto_collapse")); + tooltip.add(I18n.format("gregtech.tool_action.wrench.set_facing")); + super.addToolUsages(stack, world, tooltip, advanced); + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 7005216bff6..65f54b1ef93 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5498,6 +5498,38 @@ gregtech.machine.computation_hatch.receiver.tooltip=Computation Data Input for M gregtech.machine.research_station.object_holder.name=Object Holder gregtech.machine.research_station.object_holder.tooltip=Advanced Holding Mechanism for Research Station +gregtech.machine.dual_input_hatch.ulv.name=ULV Dual Input Hatch +gregtech.machine.dual_input_hatch.lv.name=LV Dual Input Hatch +gregtech.machine.dual_input_hatch.mv.name=MV Dual Input Hatch +gregtech.machine.dual_input_hatch.hv.name=HV Dual Input Hatch +gregtech.machine.dual_input_hatch.ev.name=EV Dual Input Hatch +gregtech.machine.dual_input_hatch.iv.name=IV Dual Input Hatch +gregtech.machine.dual_input_hatch.luv.name=LuV Dual Input Hatch +gregtech.machine.dual_input_hatch.zpm.name=ZPM Dual Input Hatch +gregtech.machine.dual_input_hatch.uv.name=UV Dual Input Hatch +gregtech.machine.dual_input_hatch.uhv.name=UHV Dual Input Hatch +gregtech.machine.dual_input_hatch.uev.name=UEV Dual Input Hatch +gregtech.machine.dual_input_hatch.uiv.name=UIV Dual Input Hatch +gregtech.machine.dual_input_hatch.uxv.name=UXV Dual Input Hatch +gregtech.machine.dual_input_hatch.opv.name=OpV Dual Input Hatch +gregtech.machine.dual_input_hatch.max.name=MAX Dual Input Hatch + +gregtech.machine.dual_output_hatch.ulv.name=ULV Dual Output Hatch +gregtech.machine.dual_output_hatch.lv.name=LV Dual Output Hatch +gregtech.machine.dual_output_hatch.mv.name=MV Dual Output Hatch +gregtech.machine.dual_output_hatch.hv.name=HV Dual Output Hatch +gregtech.machine.dual_output_hatch.ev.name=EV Dual Output Hatch +gregtech.machine.dual_output_hatch.iv.name=IV Dual Output Hatch +gregtech.machine.dual_output_hatch.luv.name=LuV Dual Output Hatch +gregtech.machine.dual_output_hatch.zpm.name=ZPM Dual Output Hatch +gregtech.machine.dual_output_hatch.uv.name=UV Dual Output Hatch +gregtech.machine.dual_output_hatch.uhv.name=UHV Dual Output Hatch +gregtech.machine.dual_output_hatch.uev.name=UEV Dual Output Hatch +gregtech.machine.dual_output_hatch.uiv.name=UIV Dual Output Hatch +gregtech.machine.dual_output_hatch.uxv.name=UXV Dual Output Hatch +gregtech.machine.dual_output_hatch.opv.name=OpV Dual Output Hatch +gregtech.machine.dual_output_hatch.max.name=MAX Dual Output Hatch + # laser hatches gregtech.machine.laser_hatch.source_256a.iv.name=IV 256A Laser Source Hatch gregtech.machine.laser_hatch.source_256a.luv.name=LuV 256A Laser Source Hatch From 7ef48b8226914ca082c63881b2ce3132eb364159 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 11 Apr 2025 18:07:16 -0400 Subject: [PATCH 2/8] Move the item bus's inventory collapsing method into GTUtility and use it in the dual hatch. Also implement auto pull/push --- .../java/gregtech/api/util/GTUtility.java | 39 +++++++++ .../MetaTileEntityDualHatch.java | 85 +++++++++++++++++-- .../multiblockpart/MetaTileEntityItemBus.java | 42 +-------- 3 files changed, 117 insertions(+), 49 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 3c0e0ece01c..22c4e4c2674 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -56,6 +56,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import com.google.common.util.concurrent.AtomicDouble; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; @@ -1029,4 +1030,42 @@ public static boolean areFluidStacksEqual(@Nullable FluidStack a, @Nullable Flui if (a == null) return false; return a.isFluidEqual(b); } + + public static void collapseInventorySlotContents(IItemHandlerModifiable inventory) { + // Gather a snapshot of the provided inventory + Object2IntMap inventoryContents = GTHashMaps.fromItemHandler(inventory, true); + + List inventoryItemContents = new ArrayList<>(); + + // Populate the list of item stacks in the inventory with apportioned item stacks, for easy replacement + for (Object2IntMap.Entry e : inventoryContents.object2IntEntrySet()) { + ItemStack stack = e.getKey(); + int count = e.getIntValue(); + int maxStackSize = stack.getMaxStackSize(); + while (count >= maxStackSize) { + ItemStack copy = stack.copy(); + copy.setCount(maxStackSize); + inventoryItemContents.add(copy); + count -= maxStackSize; + } + if (count > 0) { + ItemStack copy = stack.copy(); + copy.setCount(count); + inventoryItemContents.add(copy); + } + } + + for (int i = 0; i < inventory.getSlots(); i++) { + ItemStack stackToMove; + // Ensure that we are not exceeding the List size when attempting to populate items + if (i >= inventoryItemContents.size()) { + stackToMove = ItemStack.EMPTY; + } else { + stackToMove = inventoryItemContents.get(i); + } + + // Populate the slots + inventory.setStackInSlot(i, stackToMove); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index 2206b943c40..a729deb4118 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -19,19 +19,25 @@ import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.widget.GhostCircuitSlotWidget; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.items.IItemHandlerModifiable; +import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; @@ -67,8 +73,8 @@ public class MetaTileEntityDualHatch extends MetaTileEntityMultiblockNotifiableP private IItemHandlerModifiable actualImportItems; private DualHandler dualHandler; - private boolean workingEnabled; - private boolean autoCollapse; + private boolean workingEnabled = true; + private boolean autoCollapse = false; public MetaTileEntityDualHatch(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { super(metaTileEntityId, tier, isExportHatch); @@ -139,6 +145,29 @@ protected FluidTankList createExportFluidHandler() { return isExportHatch ? new FluidTankList(false, createTanks()) : new FluidTankList(false); } + @Override + public void update() { + super.update(); + + if (!getWorld().isRemote && getOffsetTimer() % 5 == 0) { + if (workingEnabled) { + if (isExportHatch) { + pushItemsIntoNearbyHandlers(getFrontFacing()); + pushFluidsIntoNearbyHandlers(getFrontFacing()); + } else { + pullItemsFromNearbyHandlers(getFrontFacing()); + pullFluidsFromNearbyHandlers(getFrontFacing()); + } + } + + IItemHandlerModifiable itemHandler = isExportHatch ? getExportItems() : super.getImportItems(); + if (!isAttachedToMultiBlock() || (isExportHatch ? getNotifiedItemOutputList().contains(itemHandler) : + getNotifiedItemInputList().contains(itemHandler))) { + GTUtility.collapseInventorySlotContents(itemHandler); + } + } + } + @Override public boolean hasGhostCircuitInventory() { return !this.isExportHatch; @@ -210,7 +239,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) BooleanSyncValue collapseStateValue = new BooleanSyncValue(() -> autoCollapse, val -> autoCollapse = val); guiSyncManager.syncValue("collapse_state", collapseStateValue); - boolean hasGhostCircuit = hasGhostCircuitInventory() && this.circuitInventory != null; + boolean hasGhostCircuit = hasGhostCircuitInventory() && circuitInventory != null; return GTGuis.createPanel(this, backgroundWidth, backgroundHeight) .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) @@ -275,8 +304,8 @@ public void writeInitialSyncData(PacketBuffer buf) { @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); - this.workingEnabled = buf.readBoolean(); - this.autoCollapse = buf.readBoolean(); + workingEnabled = buf.readBoolean(); + autoCollapse = buf.readBoolean(); } @Override @@ -293,16 +322,53 @@ public boolean isWorkingEnabled() { return workingEnabled; } + @SuppressWarnings("DuplicatedCode") + public void setAutoCollapse(boolean inverted) { + autoCollapse = inverted; + if (!getWorld().isRemote) { + if (autoCollapse) { + if (isExportHatch) { + addNotifiedOutput(getExportItems()); + } else { + addNotifiedInput(getImportItems()); + } + } + writeCustomData(GregtechDataCodes.TOGGLE_COLLAPSE_ITEMS, + packetBuffer -> packetBuffer.writeBoolean(autoCollapse)); + notifyBlockUpdate(); + markDirty(); + } + } + + public boolean isAutoCollapse() { + return autoCollapse; + } + @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == GregtechDataCodes.WORKING_ENABLED) { - this.workingEnabled = buf.readBoolean(); + workingEnabled = buf.readBoolean(); } else if (dataId == GregtechDataCodes.TOGGLE_COLLAPSE_ITEMS) { - this.autoCollapse = buf.readBoolean(); + autoCollapse = buf.readBoolean(); } } + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + setAutoCollapse(!autoCollapse); + + if (!getWorld().isRemote) { + if (autoCollapse) { + playerIn.sendStatusMessage(new TextComponentTranslation("gregtech.bus.collapse_true"), true); + } else { + playerIn.sendStatusMessage(new TextComponentTranslation("gregtech.bus.collapse_false"), true); + } + } + return true; + } + @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); @@ -332,10 +398,11 @@ public void readFromNBT(NBTTagCompound data) { @Override public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { - if (this.isExportHatch) + if (isExportHatch) { tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); - else + } else { tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + } tooltip.add(I18n.format("gregtech.universal.tooltip.item_storage_capacity", getItemSize())); tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", getTankSize())); tooltip.add(I18n.format("gregtech.universal.enabled")); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 127977cb343..c48fa2e6d17 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -15,7 +15,7 @@ import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.widget.GhostCircuitSlotWidget; -import gregtech.api.util.GTHashMaps; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; @@ -140,7 +140,7 @@ public void update() { IItemHandlerModifiable inventory = (isExportHatch ? this.getExportItems() : super.getImportItems()); if (!isAttachedToMultiBlock() || (isExportHatch ? this.getNotifiedItemOutputList().contains(inventory) : this.getNotifiedItemInputList().contains(inventory))) { - collapseInventorySlotContents(inventory); + GTUtility.collapseInventorySlotContents(inventory); } } } @@ -337,44 +337,6 @@ public boolean hasGhostCircuitInventory() { return !this.isExportHatch; } - private static void collapseInventorySlotContents(IItemHandlerModifiable inventory) { - // Gather a snapshot of the provided inventory - Object2IntMap inventoryContents = GTHashMaps.fromItemHandler(inventory, true); - - List inventoryItemContents = new ArrayList<>(); - - // Populate the list of item stacks in the inventory with apportioned item stacks, for easy replacement - for (Object2IntMap.Entry e : inventoryContents.object2IntEntrySet()) { - ItemStack stack = e.getKey(); - int count = e.getIntValue(); - int maxStackSize = stack.getMaxStackSize(); - while (count >= maxStackSize) { - ItemStack copy = stack.copy(); - copy.setCount(maxStackSize); - inventoryItemContents.add(copy); - count -= maxStackSize; - } - if (count > 0) { - ItemStack copy = stack.copy(); - copy.setCount(count); - inventoryItemContents.add(copy); - } - } - - for (int i = 0; i < inventory.getSlots(); i++) { - ItemStack stackToMove; - // Ensure that we are not exceeding the List size when attempting to populate items - if (i >= inventoryItemContents.size()) { - stackToMove = ItemStack.EMPTY; - } else { - stackToMove = inventoryItemContents.get(i); - } - - // Populate the slots - inventory.setStackInSlot(i, stackToMove); - } - } - @Override public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { From aeedf2b26bb2f68bc567f710d8fbd8c0661bcc98 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 11 Apr 2025 20:40:59 -0400 Subject: [PATCH 3/8] Fix auto collapse always being on --- .../multiblockpart/MetaTileEntityDualHatch.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index a729deb4118..b14a5e06f63 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -160,10 +160,12 @@ public void update() { } } - IItemHandlerModifiable itemHandler = isExportHatch ? getExportItems() : super.getImportItems(); - if (!isAttachedToMultiBlock() || (isExportHatch ? getNotifiedItemOutputList().contains(itemHandler) : - getNotifiedItemInputList().contains(itemHandler))) { - GTUtility.collapseInventorySlotContents(itemHandler); + if (autoCollapse()) { + IItemHandlerModifiable itemHandler = isExportHatch ? getExportItems() : super.getImportItems(); + if (!isAttachedToMultiBlock() || (isExportHatch ? getNotifiedItemOutputList().contains(itemHandler) : + getNotifiedItemInputList().contains(itemHandler))) { + GTUtility.collapseInventorySlotContents(itemHandler); + } } } } @@ -340,7 +342,7 @@ public void setAutoCollapse(boolean inverted) { } } - public boolean isAutoCollapse() { + public boolean autoCollapse() { return autoCollapse; } From dabe1139eaa9acd7b8c50cf16168642d3778341a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 11 Apr 2025 18:48:19 -0700 Subject: [PATCH 4/8] pass adding/removing notifiable mte to delegates return dual handler as import items notify dual handler on circuit change use dual handler tanks for ui --- .../gregtech/api/capability/DualHandler.java | 30 +++++++++++++++++++ .../MetaTileEntityDualHatch.java | 26 +++++++++------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/capability/DualHandler.java b/src/main/java/gregtech/api/capability/DualHandler.java index 015017c769e..2dfae8d866d 100644 --- a/src/main/java/gregtech/api/capability/DualHandler.java +++ b/src/main/java/gregtech/api/capability/DualHandler.java @@ -1,6 +1,7 @@ package gregtech.api.capability; import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.ItemStackHashStrategy; @@ -8,6 +9,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.IFluidTankProperties; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import org.jetbrains.annotations.NotNull; @@ -158,11 +160,39 @@ public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { if (metaTileEntity == null || this.notifiableEntities.contains(metaTileEntity)) return; this.notifiableEntities.add(metaTileEntity); + if (getItemDelegate() instanceof INotifiableHandler handler) { + handler.addNotifiableMetaTileEntity(metaTileEntity); + } else if (getItemDelegate() instanceof ItemHandlerList list) { + for (IItemHandler handler : list.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiableHandler) { + notifiableHandler.addNotifiableMetaTileEntity(metaTileEntity); + } + } + } + for (ITankEntry entry : getFluidDelegate()) { + if (entry.getDelegate() instanceof INotifiableHandler handler) { + handler.addNotifiableMetaTileEntity(metaTileEntity); + } + } } @Override public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { this.notifiableEntities.remove(metaTileEntity); + if (getItemDelegate() instanceof INotifiableHandler handler) { + handler.removeNotifiableMetaTileEntity(metaTileEntity); + } else if (getItemDelegate() instanceof ItemHandlerList list) { + for (IItemHandler handler : list.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiableHandler) { + notifiableHandler.removeNotifiableMetaTileEntity(metaTileEntity); + } + } + } + for (ITankEntry entry : getFluidDelegate()) { + if (entry.getDelegate() instanceof INotifiableHandler handler) { + handler.removeNotifiableMetaTileEntity(metaTileEntity); + } + } } public @NotNull IItemHandlerModifiable getItemDelegate() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index b14a5e06f63..91a22673631 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -91,18 +91,19 @@ protected void initializeInventory() { super.initializeInventory(); if (hasGhostCircuitInventory()) { circuitInventory = new GhostCircuitItemStackHandler(this); - circuitInventory.addNotifiableMetaTileEntity(this); - actualImportItems = new ItemHandlerList(Arrays.asList(super.getImportItems(), circuitInventory)); + actualImportItems = new ItemHandlerList(Arrays.asList(this.importItems, circuitInventory)); } else { - actualImportItems = null; + actualImportItems = this.importItems; } - dualHandler = new DualHandler(isExportHatch ? getExportItems() : getImportItems(), - isExportHatch ? getExportFluids() : getImportFluids(), isExportHatch); + dualHandler = new DualHandler( + isExportHatch ? this.exportItems : this.actualImportItems, + isExportHatch ? getExportFluids() : getImportFluids(), + isExportHatch); } @Override public IItemHandlerModifiable getImportItems() { - return actualImportItems == null ? super.getImportItems() : actualImportItems; + return dualHandler; } protected IFluidTank[] createTanks() { @@ -217,20 +218,19 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) widgets.add(new ArrayList<>()); for (int j = 0; j < rowSize; j++) { int index = i * rowSize + j; - IItemHandlerModifiable handler = isExportHatch ? exportItems : importItems; + IItemHandlerModifiable handler = isExportHatch ? getExportItems() : getImportItems(); widgets.get(i).add(new ItemSlot() .slot(SyncHandlers.itemSlot(handler, index) .slotGroup("item_inv") .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (onlyAmountChanged && - handler instanceof GTItemStackHandler gtHandler) { + if (onlyAmountChanged && handler instanceof GTItemStackHandler gtHandler) { gtHandler.onContentsChanged(index); } }) .accessibility(!isExportHatch, true))); } - IFluidTank tankHandler = (isExportHatch ? exportFluids : importFluids).getTankAt(i); + IFluidTank tankHandler = dualHandler.getTankAt(i); widgets.get(i).add(new GTFluidSlot() .syncHandler(GTFluidSlot.sync(tankHandler) .accessibility(true, !isExportHatch))); @@ -278,7 +278,11 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled")))) .childIf(hasGhostCircuit, new GhostCircuitSlotWidget() - .slot(SyncHandlers.itemSlot(circuitInventory, 0)) + .slot(SyncHandlers.itemSlot(circuitInventory, 0) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + // add the dual handler to the notified list + dualHandler.onContentsChanged(); + })) .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) .childIf(!hasGhostCircuit, new Widget<>() .background(GTGuiTextures.SLOT, GTGuiTextures.BUTTON_X) From 272c7121244fdd68e41b77a212603dc192f1cd4b Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 11 Apr 2025 23:09:22 -0400 Subject: [PATCH 5/8] Refactor some notifiable stuff to try and unify it a little bit --- .../gregtech/api/capability/DualHandler.java | 24 +++++++- .../IMultipleNotifiableHandler.java | 11 ++++ .../api/capability/impl/ItemHandlerList.java | 19 ++++++- .../impl/MultiblockRecipeLogic.java | 7 ++- .../MetaTileEntityFluidHatch.java | 15 ----- .../multiblockpart/MetaTileEntityItemBus.java | 27 --------- ...etaTileEntityMultiblockNotifiablePart.java | 56 ++++++++++++++----- .../appeng/MetaTileEntityMEInputBus.java | 24 -------- 8 files changed, 97 insertions(+), 86 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/IMultipleNotifiableHandler.java diff --git a/src/main/java/gregtech/api/capability/DualHandler.java b/src/main/java/gregtech/api/capability/DualHandler.java index 2dfae8d866d..ec95ce0e931 100644 --- a/src/main/java/gregtech/api/capability/DualHandler.java +++ b/src/main/java/gregtech/api/capability/DualHandler.java @@ -12,12 +12,15 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import com.google.common.collect.ImmutableList; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler { +public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler, + IMultipleNotifiableHandler { @NotNull private static final ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingAll(); @@ -203,6 +206,25 @@ public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { return fluidDelegate; } + @Override + public @NotNull Collection getBackingNotifiers() { + ImmutableList.Builder handlerList = ImmutableList.builder(); + + if (itemDelegate instanceof IMultipleNotifiableHandler multipleNotifiableHandler) { + handlerList.addAll(multipleNotifiableHandler.getBackingNotifiers()); + } else if (itemDelegate instanceof INotifiableHandler notifiableHandler) { + handlerList.add(notifiableHandler); + } + + for (var tank : fluidDelegate) { + if (tank instanceof INotifiableHandler notifiableHandler) { + handlerList.add(notifiableHandler); + } + } + + return handlerList.build(); + } + public static class DualEntry implements ITankEntry, INotifiableHandler { @NotNull diff --git a/src/main/java/gregtech/api/capability/IMultipleNotifiableHandler.java b/src/main/java/gregtech/api/capability/IMultipleNotifiableHandler.java new file mode 100644 index 00000000000..e146596cd96 --- /dev/null +++ b/src/main/java/gregtech/api/capability/IMultipleNotifiableHandler.java @@ -0,0 +1,11 @@ +package gregtech.api.capability; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public interface IMultipleNotifiableHandler { + + @NotNull + Collection getBackingNotifiers(); +} diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index 4f45f7b6d45..932c66dab74 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -1,9 +1,13 @@ package gregtech.api.capability.impl; +import gregtech.api.capability.IMultipleNotifiableHandler; +import gregtech.api.capability.INotifiableHandler; + import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; @@ -15,7 +19,7 @@ /** * Efficiently delegates calls into multiple item handlers */ -public class ItemHandlerList implements IItemHandlerModifiable { +public class ItemHandlerList implements IItemHandlerModifiable, IMultipleNotifiableHandler { private final Int2ObjectMap handlerBySlotIndex = new Int2ObjectOpenHashMap<>(); private final Object2IntMap baseIndexOffset = new Object2IntArrayMap<>(); @@ -93,6 +97,19 @@ public Collection getBackingHandlers() { return Collections.unmodifiableCollection(baseIndexOffset.keySet()); } + @Override + public @NotNull Collection getBackingNotifiers() { + ImmutableList.Builder notifiableHandlers = ImmutableList.builder(); + + for (var handler : getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiableHandler) { + notifiableHandlers.add(notifiableHandler); + } + } + + return notifiableHandlers.build(); + } + private boolean invalidSlot(int slot) { return slot < 0 && slot >= this.getSlots(); } diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 5ec88c42708..0141c97efb5 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -4,6 +4,7 @@ import gregtech.api.capability.DualHandler; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.IMultiblockController; +import gregtech.api.capability.IMultipleNotifiableHandler; import gregtech.api.capability.IMultipleRecipeMaps; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.metatileentity.multiblock.MultiblockAbility; @@ -146,9 +147,9 @@ protected boolean canWorkWithInputs() { Iterator invalidatedIter = invalidatedInputList.iterator(); while (invalidatedIter.hasNext()) { IItemHandler invalidatedHandler = invalidatedIter.next(); - if (invalidatedHandler instanceof ItemHandlerList) { - for (IItemHandler ih : ((ItemHandlerList) invalidatedHandler).getBackingHandlers()) { - if (ih == bus) { + if (invalidatedHandler instanceof IMultipleNotifiableHandler multipleNotifiableHandler) { + for (var notifiableHandler : multipleNotifiableHandler.getBackingNotifiers()) { + if (notifiableHandler == bus) { canWork = true; invalidatedIter.remove(); break; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 0ac556580e0..e674911e9c4 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -16,7 +16,6 @@ import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.widget.GhostCircuitSlotWidget; @@ -370,20 +369,6 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager, .bindPlayerInventory(); } - @Override - public void addToMultiBlock(MultiblockControllerBase controllerBase) { - super.addToMultiBlock(controllerBase); - if (hasGhostCircuitInventory()) - this.circuitInventory.addNotifiableMetaTileEntity(controllerBase); - } - - @Override - public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { - super.removeFromMultiBlock(controllerBase); - if (hasGhostCircuitInventory()) - this.circuitInventory.removeNotifiableMetaTileEntity(controllerBase); - } - @Override public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index c48fa2e6d17..a4acc3e6705 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -11,7 +11,6 @@ import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.widget.GhostCircuitSlotWidget; @@ -30,7 +29,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import codechicken.lib.raytracer.CuboidRayTraceResult; @@ -97,31 +95,6 @@ public IItemHandlerModifiable getImportItems() { return this.actualImportItems == null ? super.getImportItems() : this.actualImportItems; } - @Override - public void addToMultiBlock(MultiblockControllerBase controllerBase) { - super.addToMultiBlock(controllerBase); - if (hasGhostCircuitInventory() && this.actualImportItems instanceof ItemHandlerList) { - for (IItemHandler handler : ((ItemHandlerList) this.actualImportItems).getBackingHandlers()) { - if (handler instanceof INotifiableHandler notifiable) { - notifiable.addNotifiableMetaTileEntity(controllerBase); - notifiable.addToNotifiedList(this, handler, isExportHatch); - } - } - } - } - - @Override - public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { - super.removeFromMultiBlock(controllerBase); - if (hasGhostCircuitInventory() && this.actualImportItems instanceof ItemHandlerList) { - for (IItemHandler handler : ((ItemHandlerList) this.actualImportItems).getBackingHandlers()) { - if (handler instanceof INotifiableHandler notifiable) { - notifiable.removeNotifiableMetaTileEntity(controllerBase); - } - } - } - } - @Override public void update() { super.update(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java index 7efd88c5471..fbb3af3b58c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java @@ -1,9 +1,13 @@ package gregtech.common.metatileentities.multi.multiblockpart; +import gregtech.api.capability.IMultipleNotifiableHandler; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.ItemHandlerList; +import gregtech.api.metatileentity.multiblock.AbilityInstances; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import net.minecraft.util.ResourceLocation; @@ -49,28 +53,50 @@ private FluidTankList getFluidHandlers() { } private List getPartHandlers() { - List handlerList = new ArrayList<>(); + List notifiableHandlers = new ArrayList<>(); - for (var notif : getItemHandlers()) { - if (notif.size() > 0) { - handlerList.add(notif); + if (this instanceof IMultiblockAbilityPartabilityPart) { + List> abilities = abilityPart.getAbilities(); + for (var ability : abilities) { + AbilityInstances instances = new AbilityInstances(ability); + abilityPart.registerAbilities(instances); + for (var handler : instances) { + if (handler instanceof IMultipleNotifiableHandler multipleNotifiableHandler) { + notifiableHandlers.addAll(multipleNotifiableHandler.getBackingNotifiers()); + } else if (handler instanceof IMultipleTankHandler multipleTankHandler) { + for (var tank : multipleTankHandler.getFluidTanks()) { + if (tank instanceof INotifiableHandler notifiableTank) { + notifiableHandlers.add(notifiableTank); + } + } + } else if (handler instanceof INotifiableHandler notifiableHandler) { + notifiableHandlers.add(notifiableHandler); + } + } + } + } else { + for (var notif : getItemHandlers()) { + if (notif.size() > 0) { + notifiableHandlers.add(notif); + } } - } - if (this.fluidInventory.getTankProperties().length > 0) { - FluidTankList fluidTankList = getFluidHandlers(); - if (fluidTankList != null) { - for (IFluidTank fluidTank : fluidTankList) { - if (fluidTank instanceof IMultipleTankHandler.ITankEntry entry) { - fluidTank = entry.getDelegate(); - } - if (fluidTank instanceof INotifiableHandler) { - handlerList.add((INotifiableHandler) fluidTank); + if (this.fluidInventory.getTankProperties().length > 0) { + FluidTankList fluidTankList = getFluidHandlers(); + if (fluidTankList != null) { + for (IFluidTank fluidTank : fluidTankList) { + if (fluidTank instanceof IMultipleTankHandler.ITankEntry entry) { + fluidTank = entry.getDelegate(); + } + if (fluidTank instanceof INotifiableHandler) { + notifiableHandlers.add((INotifiableHandler) fluidTank); + } } } } } - return handlerList; + + return notifiableHandlers; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 23f1ab2899b..089197c2dd7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -5,7 +5,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IGhostSlotConfigurable; -import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.GhostCircuitItemStackHandler; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.capability.impl.NotifiableItemStackHandler; @@ -18,7 +17,6 @@ import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemConfigWidget; @@ -38,7 +36,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import appeng.api.config.Actionable; @@ -161,27 +158,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEnti return new MetaTileEntityMEInputBus(metaTileEntityId); } - @Override - public void addToMultiBlock(MultiblockControllerBase controllerBase) { - super.addToMultiBlock(controllerBase); - for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { - if (handler instanceof INotifiableHandler notifiable) { - notifiable.addNotifiableMetaTileEntity(controllerBase); - notifiable.addToNotifiedList(this, handler, false); - } - } - } - - @Override - public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { - super.removeFromMultiBlock(controllerBase); - for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { - if (handler instanceof INotifiableHandler notifiable) { - notifiable.removeNotifiableMetaTileEntity(controllerBase); - } - } - } - @Override protected final ModularUI createUI(EntityPlayer player) { ModularUI.Builder builder = createUITemplate(player); From d7983cfb88816d6b8eb4a3eeffff3d4419b7adb3 Mon Sep 17 00:00:00 2001 From: WALHAY Date: Tue, 11 Aug 2026 17:25:20 +0300 Subject: [PATCH 6/8] Attempt on fixing notifications --- .../gregtech/api/capability/DualHandler.java | 3 +-- .../MetaTileEntityRegistration.java | 4 ++-- .../MetaTileEntityDualHatch.java | 21 ++++++++----------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/java/gregtech/api/capability/DualHandler.java b/src/main/java/gregtech/api/capability/DualHandler.java index ec95ce0e931..a1cccf83fd3 100644 --- a/src/main/java/gregtech/api/capability/DualHandler.java +++ b/src/main/java/gregtech/api/capability/DualHandler.java @@ -19,8 +19,7 @@ import java.util.Collection; import java.util.List; -public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler, - IMultipleNotifiableHandler { +public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler, IMultipleNotifiableHandler { @NotNull private static final ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingAll(); diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java index 4075015890f..2bb1a012f17 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java @@ -1103,14 +1103,14 @@ private static void multiblockParts() { // Dual Input Hatches for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { String voltageName = GTValues.VN[tier].toLowerCase(); - MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11534 + tier, new MetaTileEntityDualHatch( + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11591 + tier, new MetaTileEntityDualHatch( gregtechId(String.format("%s.%s", "dual_input_hatch", voltageName)), tier, false)); } // Dual Output Hatches for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { String voltageName = GTValues.VN[tier].toLowerCase(); - MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11548 + tier, new MetaTileEntityDualHatch( + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11605 + tier, new MetaTileEntityDualHatch( gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true)); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index 91a22673631..4d79d634a0c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -45,16 +45,18 @@ import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; +import com.cleanroommc.modularui.widgets.slot.ItemSlot; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -188,8 +190,9 @@ public void setGhostCircuitConfig(int config) { } @Override - public @Nullable MultiblockAbility getAbility() { - return isExportHatch ? MultiblockAbility.EXPORT_ITEMS : MultiblockAbility.IMPORT_ITEMS; + public @NotNull List> getAbilities() { + // for import only items as it will thinks as twice more inputs otherwise + return isExportHatch ? Arrays.asList(MultiblockAbility.EXPORT_ITEMS, MultiblockAbility.EXPORT_FLUIDS) : Arrays.asList(MultiblockAbility.IMPORT_ITEMS); } @Override @@ -204,7 +207,7 @@ public boolean usesMui2() { @SuppressWarnings("DuplicatedCode") @Override - public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { int rowSize = (int) Math.sqrt(getItemSize()); guiSyncManager.registerSlotGroup("item_inv", rowSize); @@ -245,7 +248,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) return GTGuis.createPanel(this, backgroundWidth, backgroundHeight) .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) - .child(SlotGroupWidget.playerInventory().left(7).bottom(7)).child(new Grid() + .child(SlotGroupWidget.playerInventory(false).left(7).bottom(7)).child(new Grid() .top(18).height(rowSize * 18) .minElementMargin(0, 0) .minColWidth(18).minRowHeight(18) @@ -277,13 +280,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .addLine(collapseStateValue.getBoolValue() ? IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled")))) - .childIf(hasGhostCircuit, new GhostCircuitSlotWidget() - .slot(SyncHandlers.itemSlot(circuitInventory, 0) - .changeListener((newItem, onlyAmountChanged, client, init) -> { - // add the dual handler to the notified list - dualHandler.onContentsChanged(); - })) - .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) + .childIf(hasGhostCircuit, new GhostCircuitSlotWidget().slot(circuitInventory, 0).background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) .childIf(!hasGhostCircuit, new Widget<>() .background(GTGuiTextures.SLOT, GTGuiTextures.BUTTON_X) .tooltip(t -> t.addLine( From a1422bd8327b78b6b02ca5315716d06030906432 Mon Sep 17 00:00:00 2001 From: WALHAY Date: Tue, 11 Aug 2026 17:34:07 +0300 Subject: [PATCH 7/8] Fix dual handler notification implementation: add missing entry --- src/main/java/gregtech/api/capability/DualHandler.java | 5 ++++- .../metatileentities/MetaTileEntityRegistration.java | 10 ++++++---- .../multi/multiblockpart/MetaTileEntityDualHatch.java | 8 +++++--- .../MetaTileEntityMultiblockNotifiablePart.java | 2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/gregtech/api/capability/DualHandler.java b/src/main/java/gregtech/api/capability/DualHandler.java index a1cccf83fd3..2fd6c93c66e 100644 --- a/src/main/java/gregtech/api/capability/DualHandler.java +++ b/src/main/java/gregtech/api/capability/DualHandler.java @@ -19,7 +19,8 @@ import java.util.Collection; import java.util.List; -public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler, IMultipleNotifiableHandler { +public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler, + IMultipleNotifiableHandler { @NotNull private static final ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingAll(); @@ -218,6 +219,8 @@ public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { for (var tank : fluidDelegate) { if (tank instanceof INotifiableHandler notifiableHandler) { handlerList.add(notifiableHandler); + } else if (tank.getDelegate() instanceof INotifiableHandler notifiableHandler) { + handlerList.add(notifiableHandler); } } diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java index 2bb1a012f17..a985ab09bd7 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityRegistration.java @@ -1103,15 +1103,17 @@ private static void multiblockParts() { // Dual Input Hatches for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { String voltageName = GTValues.VN[tier].toLowerCase(); - MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11591 + tier, new MetaTileEntityDualHatch( - gregtechId(String.format("%s.%s", "dual_input_hatch", voltageName)), tier, false)); + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11591 + tier, + new MetaTileEntityDualHatch( + gregtechId(String.format("%s.%s", "dual_input_hatch", voltageName)), tier, false)); } // Dual Output Hatches for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { String voltageName = GTValues.VN[tier].toLowerCase(); - MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11605 + tier, new MetaTileEntityDualHatch( - gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true)); + MetaTileEntities.DUAL_INPUT_HATCH[tier] = MetaTileEntities.registerMetaTileEntity(11605 + tier, + new MetaTileEntityDualHatch( + gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true)); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index 4d79d634a0c..1283390aaab 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -56,7 +56,6 @@ import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.slot.ItemSlot; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -192,7 +191,8 @@ public void setGhostCircuitConfig(int config) { @Override public @NotNull List> getAbilities() { // for import only items as it will thinks as twice more inputs otherwise - return isExportHatch ? Arrays.asList(MultiblockAbility.EXPORT_ITEMS, MultiblockAbility.EXPORT_FLUIDS) : Arrays.asList(MultiblockAbility.IMPORT_ITEMS); + return isExportHatch ? Arrays.asList(MultiblockAbility.EXPORT_ITEMS, MultiblockAbility.EXPORT_FLUIDS) : + Arrays.asList(MultiblockAbility.IMPORT_ITEMS); } @Override @@ -280,7 +280,9 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager, .addLine(collapseStateValue.getBoolValue() ? IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") : IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled")))) - .childIf(hasGhostCircuit, new GhostCircuitSlotWidget().slot(circuitInventory, 0).background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) + .childIf(hasGhostCircuit, + new GhostCircuitSlotWidget().slot(circuitInventory, 0).background(GTGuiTextures.SLOT, + GTGuiTextures.INT_CIRCUIT_OVERLAY)) .childIf(!hasGhostCircuit, new Widget<>() .background(GTGuiTextures.SLOT, GTGuiTextures.BUTTON_X) .tooltip(t -> t.addLine( diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java index fbb3af3b58c..91526e9f7dd 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java @@ -67,6 +67,8 @@ private List getPartHandlers() { for (var tank : multipleTankHandler.getFluidTanks()) { if (tank instanceof INotifiableHandler notifiableTank) { notifiableHandlers.add(notifiableTank); + } else if (tank.getDelegate() instanceof INotifiableHandler notifiableTank) { + notifiableHandlers.add(notifiableTank); } } } else if (handler instanceof INotifiableHandler notifiableHandler) { From 171b981d20f27641cd306280bd5a246c21f28221 Mon Sep 17 00:00:00 2001 From: WALHAY Date: Tue, 11 Aug 2026 19:47:38 +0300 Subject: [PATCH 8/8] Add placeholders for dual hatches overlay --- .../client/renderer/texture/Textures.java | 4 ++++ .../multiblockpart/MetaTileEntityDualHatch.java | 4 ++-- .../overlay/machine/overlay_dual_hatch_input.png | Bin 0 -> 675 bytes .../overlay/machine/overlay_dual_hatch_output.png | Bin 0 -> 668 bytes 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_dual_hatch_input.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_dual_hatch_output.png diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index 76f91891093..96f970a5be6 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -348,6 +348,10 @@ public class Textures { "overlay/machine/overlay_item_hatch_input"); public static final SimpleOverlayRenderer WATER_OVERLAY = new SimpleOverlayRenderer( "overlay/machine/overlay_water"); + public static final SimpleOverlayRenderer DUAL_HATCH_OUTPUT_OVERLAY = new SimpleOverlayRenderer( + "overlay/machine/overlay_dual_hatch_output"); + public static final SimpleOverlayRenderer DUAL_HATCH_INPUT_OVERLAY = new SimpleOverlayRenderer( + "overlay/machine/overlay_dual_hatch_input"); public static final ICubeRenderer BRONZE_FIREBOX = new SidedCubeRenderer("casings/firebox/overlay/bronze"); public static final ICubeRenderer BRONZE_FIREBOX_ACTIVE = new FireboxActiveRenderer( diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java index 1283390aaab..a38625c3d3f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDualHatch.java @@ -294,8 +294,8 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, super.renderMetaTileEntity(renderState, translation, pipeline); SimpleOverlayRenderer renderer = isExportHatch ? Textures.PIPE_OUT_OVERLAY : Textures.PIPE_IN_OVERLAY; renderer.renderSided(getFrontFacing(), renderState, translation, pipeline); - SimpleOverlayRenderer overlay = isExportHatch ? Textures.ITEM_HATCH_OUTPUT_OVERLAY : - Textures.ITEM_HATCH_INPUT_OVERLAY; + SimpleOverlayRenderer overlay = isExportHatch ? Textures.DUAL_HATCH_OUTPUT_OVERLAY : + Textures.DUAL_HATCH_INPUT_OVERLAY; overlay.renderSided(getFrontFacing(), renderState, translation, pipeline); } diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_dual_hatch_input.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_dual_hatch_input.png new file mode 100644 index 0000000000000000000000000000000000000000..68127bc52d693e99e69b0278c4c733353e3b327b GIT binary patch literal 675 zcmV;U0$lxxP)EX>4Tx04R}tkv&MmKpe$iQ$>-AphZL+GE@h#AX>yxs#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwM<*vm7b)?7NufoI2gm(*ckglc4iM^PrkWj-fT~$W zG8Ppx*;TRY6$1J(h;c+DX6o_OVj7;~>mEM7-i3LV_qjhuuaYwv;1h}Gm~L3a8^kl4 zmd<&fILL~ULVQjb`5 zkz)ZBsE`~#_#gc4*33^&xk-U2(D`E9AEQ9mF3_mi_V=-EH%AO zrG<`wzHQ**x~0i`z~v4w^rTCM_CX>@2HM@dakSAh-}0001bNklEX>4Tx04R}tkv&MmKpe$iQ$>-AphZL+GE@h#AX>yxs#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwM<*vm7b)?7NufoI2gm(*ckglc4iM^PrkWj-fT~$W zG8Ppx*;TRY6$1J(h;c+DX6o_OVj7;~>mEM7-i3LV_qjhuuaYwv;1h}Gm~L3a8^kl4 zmd<&fILL~ULVQjb`5 zkz)ZBsE`~#_#gc4*33^&xk-U2(D`E9AEQ9mF3_mi_V=-EH%AO zrG<`wzHQ**x~0i`z~v4w^rTCM_CX>@2HM@dakSAh-}0001UNkl