From 0d8ecc00fcfb186b5ba337ce775df501c0c36bc4 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/5] Base functionality done, todo item collapsing, auto pull/push, and proper front textures --- .../metatileentities/MetaTileEntities.java | 17 + .../MetaTileEntityDualHatch.java | 351 ++++++++++++++++++ .../resources/assets/gregtech/lang/en_us.lang | 32 ++ 3 files changed, 400 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 cdbc8171ce3..7dfc71f3c13 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -77,6 +77,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; @@ -261,6 +262,8 @@ public class 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<>(); @@ -1218,6 +1221,20 @@ public static void init() { // 1820-1849 are taken for UHV+ 4A/16A/64A Energy/Dynamo Hatches // 1850-1869 are taken for UHV+ Input/Output Buses/Hatches + + // Dual Input Hatches + for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) { + String voltageName = GTValues.VN[tier].toLowerCase(); + DUAL_INPUT_HATCH[tier] = registerMetaTileEntity(1879 + 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(); + DUAL_INPUT_HATCH[tier] = registerMetaTileEntity(1893 + tier, new MetaTileEntityDualHatch( + gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true)); + } } private static void registerSimpleMetaTileEntity(SimpleMachineMetaTileEntity[] machines, 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 c29313c2c1f..a47e6d975f8 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5363,6 +5363,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 7f1f90ba8d74cccde0ed91acba15758fd59f423a 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/5] 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 | 43 +--------- 3 files changed, 117 insertions(+), 50 deletions(-) diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 42da3a04836..18695a8c5f2 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -55,6 +55,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; @@ -959,4 +960,42 @@ public static long scaleVoltage(long voltage, int workingTier) { // Sanity check to make sure we don't accidentally create full-amp recipes. return Math.min(voltage, GTValues.VA[workingTier]); } + + 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 16a9a8bcf6d..0f61f863c7c 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; import gregtech.common.metatileentities.MetaTileEntities; @@ -54,7 +54,6 @@ import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -144,7 +143,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); } } } @@ -355,44 +354,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 4ab402abf09378dac61a1f6c0f5c0c7f3cfd8e49 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/5] 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 95e4050182e49b28987c2a14b0423411ee8ab310 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/5] 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 a5d6054c8ef1764d69d9540f5488825b620eb9d0 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/5] 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 ba6cae067e0..715415feea4 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 85519ccfda7..274ba728227 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; @@ -359,20 +358,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 0f61f863c7c..2ae1b3cf8d0 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; @@ -33,7 +32,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; @@ -100,31 +98,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);