From abc910b032f27316d51b8c0983c9d730a4bb955e Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:33:08 -0500 Subject: [PATCH 01/15] Port many blocks to MUI2 (#2624) --- .../electric/MetaTileEntityBatteryBuffer.java | 47 ++++++-- .../electric/MetaTileEntityBlockBreaker.java | 51 +++++--- .../electric/MetaTileEntityFisher.java | 62 +++++++--- .../multi/MetaTileEntityPumpHatch.java | 98 ++++++++++----- .../MetaTileEntityMachineHatch.java | 52 +++++--- .../MetaTileEntityMufflerHatch.java | 51 +++++--- .../MetaTileEntityObjectHolder.java | 63 +++++++--- .../MetaTileEntityReservoirHatch.java | 113 ++++++++++-------- .../MetaTileEntityRotorHolder.java | 35 ++++-- .../MetaTileEntitySteamHatch.java | 97 ++++++++++----- .../storage/MetaTileEntityBuffer.java | 64 +++++++--- 11 files changed, 505 insertions(+), 228 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBatteryBuffer.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBatteryBuffer.java index 22060a1716b..88caa0adc19 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBatteryBuffer.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBatteryBuffer.java @@ -6,19 +6,16 @@ import gregtech.api.capability.IControllable; import gregtech.api.capability.IElectricItem; import gregtech.api.capability.impl.EnergyContainerBatteryBuffer; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.*; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.PipelineUtil; import gregtech.common.ConfigHolder; 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.util.EnumFacing; @@ -37,6 +34,15 @@ 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.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -137,27 +143,42 @@ protected void initializeInventory() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(inventorySize); int colSize = rowSize; if (inventorySize == 8) { rowSize = 4; colSize = 2; } - Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, - 18 + 18 * colSize + 94) - .label(6, 6, getMetaFullName()); + + guiSyncManager.registerSlotGroup("item_inv", rowSize); int index = 0; + List> widgets = new ArrayList<>(); for (int y = 0; y < colSize; y++) { + widgets.add(new ArrayList<>()); for (int x = 0; x < rowSize; x++) { - builder.widget(new SlotWidget(importItems, index++, 88 - rowSize * 9 + x * 18, 18 + y * 18, true, true) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.BATTERY_OVERLAY)); + widgets.get(y).add(new ItemSlot().slot(SyncHandlers.itemSlot(this.importItems, index++) + .slotGroup("item_inv")) + .background(GTGuiTextures.SLOT, GTGuiTextures.BATTERY_OVERLAY)); } } - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * colSize + 12); - return builder.build(getHolder(), entityPlayer); + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 18 + 18 * colSize + 94) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(new Grid() + .top(18).height(colSize * 18).width(rowSize * 18) + .minElementMargin(0, 0) + .minColWidth(18).minRowHeight(18) + .alignX(0.5f) + .matrix(widgets)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java index 52855de6e03..9e5a81f5299 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java @@ -1,14 +1,11 @@ package gregtech.common.metatileentities.electric; import gregtech.api.GTValues; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuis; import gregtech.api.util.BlockUtility; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GregFakePlayer; @@ -38,8 +35,18 @@ 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.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -247,20 +254,34 @@ protected IItemHandlerModifiable createExportItemHandler() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(getInventorySize()); - Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 18 + 18 * rowSize + 94) - .label(10, 5, getMetaFullName()); - - for (int y = 0; y < rowSize; y++) { - for (int x = 0; x < rowSize; x++) { - int index = y * rowSize + x; - builder.widget(new SlotWidget(exportItems, index, 89 - rowSize * 9 + x * 18, 18 + y * 18, true, false) - .setBackgroundTexture(GuiTextures.SLOT)); + guiSyncManager.registerSlotGroup("item_inv", rowSize); + + 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; + widgets.get(i).add(new ItemSlot().slot(SyncHandlers.itemSlot(exportItems, index) + .slotGroup("item_inv").accessibility(false, true))); } } - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * rowSize + 12); - return builder.build(getHolder(), entityPlayer); + + return GTGuis.createPanel(this, 176, 18 + 18 * rowSize + 94) + .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)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java index d0c2f925a81..c32f2ce65a2 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java @@ -1,13 +1,12 @@ package gregtech.common.metatileentities.electric; import gregtech.api.GTValues; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.unification.OreDictUnifier; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; @@ -15,7 +14,6 @@ import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; @@ -30,9 +28,19 @@ 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.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; public class MetaTileEntityFisher extends TieredMetaTileEntity { @@ -57,25 +65,41 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - int rowSize = (int) Math.sqrt(inventorySize); + public boolean usesMui2() { + return true; + } - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, - 18 + 18 * rowSize + 94) - .label(10, 5, getMetaFullName()) - .widget(new SlotWidget(importItems, 0, 18, 18, true, true) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.STRING_SLOT_OVERLAY)); - - for (int y = 0; y < rowSize; y++) { - for (int x = 0; x < rowSize; x++) { - int index = y * rowSize + x; - builder.widget(new SlotWidget(exportItems, index, 89 - rowSize * 9 + x * 18, 18 + y * 18, true, false) - .setBackgroundTexture(GuiTextures.SLOT)); + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + int rowSize = (int) Math.sqrt(inventorySize); + guiSyncManager.registerSlotGroup("item_in", 1); + guiSyncManager.registerSlotGroup("item_out", rowSize); + + 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; + widgets.get(i).add(new ItemSlot() + .slot(SyncHandlers.itemSlot(exportItems, index) + .slotGroup("item_out") + .accessibility(false, true))); } } - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * rowSize + 12); - return builder.build(getHolder(), entityPlayer); + return GTGuis.createPanel(this, 176, 18 + 18 * rowSize + 94) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(importItems, 0) + .slotGroup("item_in")) + .background(GTGuiTextures.SLOT, GTGuiTextures.STRING_SLOT_OVERLAY) + .pos(7 + 9, 9 * (rowSize + 1))) + .child(new Grid() + .top(18).alignX(0.5f) + .height(rowSize * 18) + .minElementMargin(0, 0) + .minColWidth(18).minRowHeight(18) + .matrix(widgets)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java index dc158cd074a..bbdfff7ae9d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java @@ -2,29 +2,28 @@ import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.FluidContainerSlotWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuiTheme; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.sync.GTFluidSyncHandler; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; +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.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -32,6 +31,16 @@ 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.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -108,27 +117,60 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createTankUI(exportFluids.getTankAt(0), getMetaFullName(), entityPlayer) - .build(getHolder(), entityPlayer); - } - - public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { - ModularUI.Builder builder = ModularUI.defaultBuilder(); - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY); - TankWidget tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setHideTooltip(true).setAlwaysShowFull(true); - builder.widget(tankWidget); - builder.label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF); - builder.dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF); - builder.dynamicLabel(11, 40, tankWidget::getFluidLocalizedName, 0xFFFFFF); - return builder.label(6, 6, title) - .widget(new FluidContainerSlotWidget(importItems, 0, 90, 17, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) - .widget(new SlotWidget(exportItems, 0, 90, 54, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) - .bindPlayerInventory(entityPlayer.inventory); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 2); + + GTFluidSyncHandler tankSyncHandler = GTFluidSlot.sync(this.exportFluids.getTankAt(0)) + .showAmount(false) + .accessibility(true, false); + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(GTGuiTextures.DISPLAY.asWidget() + .left(7).top(16) + .size(81, 55)) + .child(GTGuiTextures.TANK_ICON.asWidget() + .left(92).top(36) + .size(14, 15)) + .child(new RichTextWidget() + .size(75, 47) + .pos(10, 20) + .textColor(Color.WHITE.main) + .alignment(Alignment.TopLeft) + .autoUpdate(true) + .textBuilder(richText -> { + richText.addLine(IKey.lang("gregtech.gui.fluid_amount")); + String name = tankSyncHandler.getFluidLocalizedName(); + if (name == null) return; + + richText.addLine(IKey.str(name)); + richText.addLine(IKey.str(tankSyncHandler.getFormattedFluidAmount())); + })) + .child(new GTFluidSlot().syncHandler(tankSyncHandler) + .pos(69, 52) + .disableBackground()) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.importItems, 0) + .slotGroup("item_inv") + .filter(itemStack -> FluidUtil.getFluidHandler(itemStack) != null)) + .background(GTGuiTextures.SLOT, GTGuiTextures.IN_SLOT_OVERLAY) + .pos(90, 16)) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.exportItems, 0) + .slotGroup("item_inv") + .accessibility(false, true)) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .pos(90, 53)); + } + + @Override + public GTGuiTheme getUITheme() { + return GTGuiTheme.PRIMITIVE; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java index 312f7cb9d56..46f47cf3928 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java @@ -1,9 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart; import gregtech.api.capability.impl.NotifiableItemStackHandler; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.BlockableSlotWidget; import gregtech.api.metatileentity.IMachineHatchMultiblock; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -11,12 +8,12 @@ import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; import gregtech.client.renderer.texture.Textures; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -25,6 +22,15 @@ 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.drawable.GuiDraw; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,17 +68,35 @@ protected IItemHandlerModifiable createImportItemHandler() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, - 18 + 18 + 94) - .label(10, 5, getMetaFullName()); - - builder.widget(new BlockableSlotWidget(machineHandler, 0, 81, 18, true, true) - .setIsBlocked(this::isSlotBlocked) - .setBackgroundTexture(GuiTextures.SLOT)); + public boolean usesMui2() { + return true; + } - return builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 + 12).build(getHolder(), - entityPlayer); + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 1); + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 18 + 18 + 94) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(machineHandler, 0) + .slotGroup("item_inv")) + .tooltip(t -> t.setAutoUpdate(false)) + .onUpdateListener(itemSlot -> { + RichTooltip tooltip = itemSlot.tooltip(); + tooltip.buildTooltip(); + if (isSlotBlocked()) { + tooltip.clearText(); + } + }) + .overlay((context, x, y, width, height, widgetTheme) -> { + if (isSlotBlocked()) { + GuiDraw.drawRect(x, y, width, height, 0x80404040); + } + }) + .left(79).top(18)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index 4634293686a..d001b65d06a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -2,9 +2,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.IMufflerHatch; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; @@ -13,6 +10,7 @@ import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.client.particle.VanillaParticleEffects; @@ -21,7 +19,6 @@ import net.minecraft.block.state.IBlockState; 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.util.ResourceLocation; @@ -33,10 +30,20 @@ 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.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; public class MetaTileEntityMufflerHatch extends MetaTileEntityMultiblockPart implements @@ -158,26 +165,38 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - int rowSize = (int) Math.sqrt(this.inventory.getSlots()); - return createUITemplate(entityPlayer, rowSize, rowSize == 10 ? 9 : 0) - .build(getHolder(), entityPlayer); + public boolean usesMui2() { + return true; } - private ModularUI.Builder createUITemplate(EntityPlayer player, int rowSize, int xOffset) { - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176 + xOffset * 2, - 18 + 18 * rowSize + 94) - .label(10, 5, getMetaFullName()); + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + int rowSize = (int) Math.sqrt(this.inventory.getSlots()); + int xOffset = rowSize == 10 ? 9 : 0; + guiSyncManager.registerSlotGroup("item_inv", rowSize); + + List> widgets = new ArrayList<>(); for (int y = 0; y < rowSize; y++) { + widgets.add(new ArrayList<>()); for (int x = 0; x < rowSize; x++) { int index = y * rowSize + x; - builder.widget(new SlotWidget(inventory, index, - (88 - rowSize * 9 + x * 18) + xOffset, 18 + y * 18, true, false) - .setBackgroundTexture(GuiTextures.SLOT)); + widgets.get(y).add(new ItemSlot().slot(SyncHandlers.itemSlot(this.inventory, index) + .slotGroup("item_inv") + .accessibility(false, true))); } } - return builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7 + xOffset, 18 + 18 * rowSize + 12); + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176 + xOffset * 2, 18 + 18 * rowSize + 94) + .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)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index c55fcbfeaa8..d358d7eccc7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -4,9 +4,6 @@ import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.IObjectHolder; import gregtech.api.capability.impl.NotifiableItemStackHandler; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.BlockableSlotWidget; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IDataItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; @@ -15,11 +12,12 @@ 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.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; 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; @@ -31,6 +29,14 @@ 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.drawable.GuiDraw; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,18 +61,43 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return ModularUI.defaultBuilder() - .label(5, 5, getMetaFullName()) - .image(46, 18, 84, 60, GuiTextures.PROGRESS_BAR_RESEARCH_STATION_BASE) - .widget(new BlockableSlotWidget(heldItems, 0, 79, 39) - .setIsBlocked(this::isSlotBlocked) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.RESEARCH_STATION_OVERLAY)) - .widget(new BlockableSlotWidget(heldItems, 1, 15, 39) - .setIsBlocked(this::isSlotBlocked) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.DATA_ORB_OVERLAY)) - .bindPlayerInventory(entityPlayer.inventory) - .build(getHolder(), entityPlayer); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 2); + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(GTGuiTextures.PROGRESS_BAR_RESEARCH_STATION_BASE.asWidget() + .left(46).top(18) + .size(84, 60)) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(heldItems, 0) + .slotGroup("item_inv") + .filter(itemStack -> !isSlotBlocked())) + .background(GTGuiTextures.SLOT, GTGuiTextures.RESEARCH_STATION_OVERLAY) + .overlay((context, x, y, width, height, widgetTheme) -> { + if (isSlotBlocked()) { + GuiDraw.drawRect(x, y, width, height, 0x80404040); + } + }) + .left(79).top(39)) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(heldItems, 1) + .slotGroup("item_inv") + .filter(itemStack -> !isSlotBlocked())) + .background(GTGuiTextures.SLOT, GTGuiTextures.DATA_ORB_OVERLAY) + .overlay((context, x, y, width, height, widgetTheme) -> { + if (isSlotBlocked()) { + GuiDraw.drawRect(x, y, width, height, 0x80404040); + } + }) + .left(15).top(39)); } private boolean isSlotBlocked() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index e8cf6d7b59b..e91f6e4f05d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -4,29 +4,27 @@ import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.NotifiableFluidTank; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; 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.sync.GTFluidSyncHandler; import gregtech.client.renderer.texture.Textures; +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.util.EnumFacing; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -35,11 +33,20 @@ 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.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.function.Consumer; public class MetaTileEntityReservoirHatch extends MetaTileEntityMultiblockNotifiablePart implements IMultiblockAbilityPart { @@ -117,51 +124,55 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createTankUI(fluidTank, getMetaFullName(), entityPlayer).build(getHolder(), entityPlayer); - } - - public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { - // Create base builder/widget references - ModularUI.Builder builder = ModularUI.defaultBuilder(); - TankWidget tankWidget; - - // Add input/output-specific widgets - tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, false); - - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) - .widget(new SlotWidget(exportItems, 0, 90, 53, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)); - - // Add general widgets - return builder.label(6, 6, title) - .label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF) - .widget(new AdvancedTextWidget(11, 30, getFluidAmountText(tankWidget), 0xFFFFFF)) - .widget(new AdvancedTextWidget(11, 40, getFluidNameText(tankWidget), 0xFFFFFF)) - .widget(tankWidget) - .widget(new FluidContainerSlotWidget(importItems, 0, 90, 16, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) - .bindPlayerInventory(entityPlayer.inventory); - } - - private Consumer> getFluidNameText(TankWidget tankWidget) { - return (list) -> { - TextComponentTranslation translation = tankWidget.getFluidTextComponent(); - if (translation != null) { - list.add(translation); - } - }; + public boolean usesMui2() { + return true; } - private Consumer> getFluidAmountText(TankWidget tankWidget) { - return (list) -> { - String fluidAmount = tankWidget.getFormattedFluidAmount(); - if (!fluidAmount.isEmpty()) { - list.add(new TextComponentString(fluidAmount)); - } - }; + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 2); + + GTFluidSyncHandler tankSyncHandler = GTFluidSlot.sync(this.fluidTank) + .showAmount(false) + .accessibility(true, false); + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(GTGuiTextures.DISPLAY.asWidget() + .left(7).top(16) + .size(81, 55)) + .child(GTGuiTextures.TANK_ICON.asWidget() + .left(92).top(36) + .size(14, 15)) + .child(new RichTextWidget() + .size(75, 47) + .pos(10, 20) + .textColor(Color.WHITE.main) + .alignment(Alignment.TopLeft) + .autoUpdate(true) + .textBuilder(richText -> { + richText.addLine(IKey.lang("gregtech.gui.fluid_amount")); + String name = tankSyncHandler.getFluidLocalizedName(); + if (name == null) return; + + richText.addLine(IKey.str(name)); + richText.addLine(IKey.str(tankSyncHandler.getFormattedFluidAmount())); + })) + .child(new GTFluidSlot().syncHandler(tankSyncHandler) + .pos(69, 52) + .disableBackground()) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.importItems, 0) + .slotGroup("item_inv") + .filter(itemStack -> FluidUtil.getFluidHandler(itemStack) != null)) + .background(GTGuiTextures.SLOT, GTGuiTextures.IN_SLOT_OVERLAY) + .pos(90, 16)) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.exportItems, 0) + .slotGroup("item_inv") + .accessibility(false, true)) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .pos(90, 53)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index 1fd863b864f..7f3c732270e 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -5,13 +5,13 @@ import gregtech.api.capability.impl.MultiblockFuelRecipeLogic; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.damagesources.DamageSources; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; 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.util.RelativeDirection; import gregtech.client.renderer.texture.Textures; import gregtech.common.items.behaviors.AbstractMaterialPartBehavior; @@ -37,6 +37,13 @@ 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.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -73,12 +80,24 @@ public IItemHandlerModifiable getImportItems() { } @Override - protected ModularUI createUI(@NotNull EntityPlayer entityPlayer) { - return ModularUI.defaultBuilder() - .label(6, 6, getMetaFullName()) - .slot(inventory, 0, 79, 36, GuiTextures.SLOT, GuiTextures.TURBINE_OVERLAY) - .bindPlayerInventory(entityPlayer.inventory) - .build(getHolder(), entityPlayer); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 1); + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(inventory, 0) + .slotGroup("item_inv") + .changeListener( + (newItem, onlyAmountChanged, client, init) -> inventory.onContentsChanged(0))) + .background(GTGuiTextures.SLOT, GTGuiTextures.TURBINE_OVERLAY) + .left(79).top(36)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java index abccdb7183a..cdcad82843f 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java +++ b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java @@ -4,31 +4,30 @@ import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.FluidContainerSlotWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; 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.GTGuiTheme; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.sync.GTFluidSyncHandler; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; +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.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -36,6 +35,16 @@ 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.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -124,30 +133,56 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createTankUI(importFluids.getTankAt(0), getMetaFullName(), entityPlayer) - .build(getHolder(), entityPlayer); - } - - public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND_STEAM.get(IS_STEEL), 176, 166); - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY_STEAM.get(IS_STEEL)); - TankWidget tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setHideTooltip(true).setAlwaysShowFull(true); - builder.widget(tankWidget); - builder.shouldColor(false); - builder.label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF); - builder.dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF); - builder.dynamicLabel(11, 40, tankWidget::getFluidLocalizedName, 0xFFFFFF); - return builder.label(6, 6, title) - .widget(new FluidContainerSlotWidget(importItems, 0, 90, 17, false) - .setBackgroundTexture(GuiTextures.SLOT_STEAM.get(IS_STEEL), - GuiTextures.IN_SLOT_OVERLAY_STEAM.get(IS_STEEL))) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) // todo tank icon - .widget(new SlotWidget(exportItems, 0, 90, 54, true, false) - .setBackgroundTexture(GuiTextures.SLOT_STEAM.get(IS_STEEL), - GuiTextures.OUT_SLOT_OVERLAY_STEAM.get(IS_STEEL))) - .bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT_STEAM.get(IS_STEEL), 7, 83); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + guiSyncManager.registerSlotGroup("item_inv", 2); + + GTFluidSyncHandler tankSyncHandler = GTFluidSlot.sync(this.importFluids.getTankAt(0)) + .showAmount(false); + + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child((IS_STEEL ? GTGuiTextures.DISPLAY_STEEL : GTGuiTextures.DISPLAY_BRONZE).asWidget() + .left(7).top(16) + .size(81, 55)) + .child(GTGuiTextures.TANK_ICON.asWidget() + .left(92).top(36) + .size(14, 15)) + .child(new RichTextWidget() + .size(75, 47) + .pos(10, 20) + .textColor(Color.WHITE.main) + .alignment(Alignment.TopLeft) + .autoUpdate(true) + .textBuilder(richText -> { + richText.addLine(IKey.lang("gregtech.gui.fluid_amount")); + String name = tankSyncHandler.getFluidLocalizedName(); + if (name == null) return; + + richText.addLine(IKey.str(name)); + richText.addLine(IKey.str(tankSyncHandler.getFormattedFluidAmount())); + })) + .child(new GTFluidSlot().syncHandler(tankSyncHandler) + .pos(69, 52) + .disableBackground()) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.importItems, 0) + .slotGroup("item_inv") + .filter(itemStack -> FluidUtil.getFluidHandler(itemStack) != null)) + .pos(90, 16)) + .child(new ItemSlot().slot(SyncHandlers.itemSlot(this.exportItems, 0) + .slotGroup("item_inv") + .accessibility(false, true)) + .pos(90, 53)); + } + + @Override + public GTGuiTheme getUITheme() { + return IS_STEEL ? GTGuiTheme.STEEL : GTGuiTheme.BRONZE; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java index 1ecb31c1821..e7a94663d21 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java @@ -2,19 +2,17 @@ import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.renderer.texture.TextureAtlasSprite; 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.util.EnumFacing; @@ -28,11 +26,21 @@ import codechicken.lib.render.pipeline.ColourMultiplier; 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.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; public class MetaTileEntityBuffer extends MetaTileEntity implements ITieredMetaTileEntity { @@ -72,25 +80,47 @@ public Pair getParticleTexture() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int invTier = tier + 2; - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, - 176, Math.max(166, 18 + 18 * invTier + 94));// 176, 166 - for (int i = 0; i < this.fluidTankList.getTanks(); i++) { - builder.widget(new TankWidget(this.fluidTankList.getTankAt(i), 176 - 8 - 18, 18 + 18 * i, 18, 18) - .setAlwaysShowFull(true) - .setBackgroundTexture(GuiTextures.FLUID_SLOT) - .setContainerClicking(true, true)); - } + guiSyncManager.registerSlotGroup("item_inv", invTier); + + List> slotWidgets = new ArrayList<>(); for (int y = 0; y < invTier; y++) { + slotWidgets.add(new ArrayList<>()); for (int x = 0; x < invTier; x++) { int index = y * invTier + x; - builder.slot(itemStackHandler, index, 8 + x * 18, 18 + y * 18, GuiTextures.SLOT); + slotWidgets.get(y) + .add(new ItemSlot().slot(SyncHandlers.itemSlot(itemStackHandler, index).slotGroup("item_inv"))); } } - return builder.label(6, 6, getMetaFullName()) - .bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 8, 18 + 18 * invTier + 12) - .build(getHolder(), entityPlayer); + + List> tankWidgets = new ArrayList<>(); + for (int i = 0; i < this.fluidTankList.getTanks(); i++) { + tankWidgets.add(new ArrayList<>()); + tankWidgets.get(i).add(new GTFluidSlot().syncHandler(this.fluidTankList.getTankAt(i))); + } + + // TODO: Change the position of the name when it's standardized. + return GTGuis.createPanel(this, 176, Math.max(166, 18 + 18 * invTier + 94)) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(SlotGroupWidget.playerInventory().left(7).bottom(7)) + .child(new Grid() + .top(18).height(18 * invTier) + .left(7) + .minElementMargin(0, 0) + .minColWidth(18).minRowHeight(18) + .matrix(slotWidgets)) + .child(new Grid() + .top(18).height(18 * invTier) + .left(144 + 7) + .minElementMargin(0, 0) + .minColWidth(18).minRowHeight(18) + .matrix(tankWidgets)); } @Override From 508c3c5a876a7c85e0410329063e8a6991a7fbab Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:39:03 -0700 Subject: [PATCH 02/15] Show required energy in Quantum controller when out of power (#2707) Co-authored-by: M-W-K <31022105+M-W-K@users.noreply.github.com> --- .../integration/hwyla/HWYLAModule.java | 19 ++- .../provider/QuantumStorageProvider.java | 113 ++++++++++++++++++ .../provider/QuantumStorageProvider.java | 12 +- .../resources/assets/gregtech/lang/en_us.lang | 1 + 4 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 src/main/java/gregtech/integration/hwyla/provider/QuantumStorageProvider.java diff --git a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java index a604d6331e1..f93bdf6ee1a 100644 --- a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java +++ b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java @@ -4,7 +4,23 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.hwyla.provider.*; +import gregtech.integration.hwyla.provider.ActiveTransformerDataProvider; +import gregtech.integration.hwyla.provider.BatteryBufferDataProvider; +import gregtech.integration.hwyla.provider.BlockOreDataProvider; +import gregtech.integration.hwyla.provider.ControllableDataProvider; +import gregtech.integration.hwyla.provider.ConverterDataProvider; +import gregtech.integration.hwyla.provider.DiodeDataProvider; +import gregtech.integration.hwyla.provider.ElectricContainerDataProvider; +import gregtech.integration.hwyla.provider.LampDataProvider; +import gregtech.integration.hwyla.provider.MaintenanceDataProvider; +import gregtech.integration.hwyla.provider.MultiRecipeMapDataProvider; +import gregtech.integration.hwyla.provider.MultiblockDataProvider; +import gregtech.integration.hwyla.provider.PrimitivePumpDataProvider; +import gregtech.integration.hwyla.provider.QuantumStorageProvider; +import gregtech.integration.hwyla.provider.RecipeLogicDataProvider; +import gregtech.integration.hwyla.provider.SteamBoilerDataProvider; +import gregtech.integration.hwyla.provider.TransformerDataProvider; +import gregtech.integration.hwyla.provider.WorkableDataProvider; import gregtech.modules.GregTechModules; import net.minecraft.item.ItemStack; @@ -42,6 +58,7 @@ public void register(IWailaRegistrar registrar) { LampDataProvider.INSTANCE.register(registrar); ActiveTransformerDataProvider.INSTANCE.register(registrar); BatteryBufferDataProvider.INSTANCE.register(registrar); + QuantumStorageProvider.INSTANCE.register(registrar); } /** Render an ItemStack. */ diff --git a/src/main/java/gregtech/integration/hwyla/provider/QuantumStorageProvider.java b/src/main/java/gregtech/integration/hwyla/provider/QuantumStorageProvider.java new file mode 100644 index 00000000000..509c890405d --- /dev/null +++ b/src/main/java/gregtech/integration/hwyla/provider/QuantumStorageProvider.java @@ -0,0 +1,113 @@ +package gregtech.integration.hwyla.provider; + +import gregtech.api.GTValues; +import gregtech.api.capability.IQuantumController; +import gregtech.api.capability.IQuantumStorage; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.GTUtility; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaDataProvider; +import mcp.mobius.waila.api.IWailaRegistrar; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class QuantumStorageProvider implements IWailaDataProvider { + + public static final QuantumStorageProvider INSTANCE = new QuantumStorageProvider(); + + public void register(@NotNull IWailaRegistrar registrar) { + registrar.registerBodyProvider(this, IGregTechTileEntity.class); + registrar.registerNBTProvider(this, IGregTechTileEntity.class); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.quantum_storage"); + } + + @NotNull + @Override + public NBTTagCompound getNBTData(EntityPlayerMP player, TileEntity te, NBTTagCompound tag, World world, + BlockPos pos) { + if (te instanceof IGregTechTileEntity gtte) { + if (gtte.getMetaTileEntity() instanceof IQuantumStoragestorage && + (storage.getType() == IQuantumStorage.Type.ITEM || + storage.getType() == IQuantumStorage.Type.FLUID)) { + var controller = storage.getQuantumController(); + int status = 0; + + if (controller != null) { + if (controller.isPowered()) { + status = 1; + } else { + status = 2; + } + } + + NBTTagCompound subTag = new NBTTagCompound(); + subTag.setInteger("Connection", status); + tag.setTag("gregtech.IQuantumStorageController", subTag); + } + } + + return tag; + } + + @NotNull + @Override + public List getWailaBody(ItemStack itemStack, List tooltip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + if (!config.getConfig("gregtech.quantum_storage") || + !(accessor.getTileEntity() instanceof IGregTechTileEntity gtte)) { + return tooltip; + } + + if (gtte.getMetaTileEntity() instanceof IQuantumController controller) { + String eutText = configureEnergyUsage(controller.getEnergyUsage() / 10); + if (controller.getCount(IQuantumStorage.Type.ENERGY) == 0) { + tooltip.add(I18n.format("gregtech.top.quantum_controller.no_hatches")); + tooltip.add(I18n.format("gregtech.top.energy_required") + eutText); + } else if (!controller.isPowered()) { + tooltip.add(I18n.format("gregtech.top.quantum_controller.no_power")); + tooltip.add(I18n.format("gregtech.top.energy_required") + eutText); + } else { + tooltip.add(I18n.format("gregtech.top.energy_consumption") + eutText); + } + } else if (gtte.getMetaTileEntity() instanceof IQuantumStoragestorage && + (storage.getType() == IQuantumStorage.Type.ITEM || + storage.getType() == IQuantumStorage.Type.FLUID)) { + if (accessor.getNBTData().hasKey("gregtech.IQuantumStorageController")) { + NBTTagCompound tag = accessor.getNBTData() + .getCompoundTag("gregtech.IQuantumStorageController"); + int connection = tag.getInteger("Connection"); + String status; + + switch (connection) { + case 1 -> status = I18n.format("gregtech.top.quantum_status.powered"); + case 2 -> status = I18n.format("gregtech.top.quantum_status.connected"); + default -> status = I18n.format("gregtech.top.quantum_status.disconnected"); + } + + status = I18n.format("gregtech.top.quantum_status.label") + + status; + + tooltip.add(status); + } + } + + return tooltip; + } + + public String configureEnergyUsage(long EUs) { + return TextFormatting.RED.toString() + EUs + " EU/t" + TextFormatting.GREEN + + " (" + GTValues.VNF[GTUtility.getTierByVoltage(EUs)] + TextFormatting.GREEN + ")"; + } +} diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java index 792be0ac4e5..c831488cc9c 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java @@ -31,13 +31,15 @@ public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer play if (blockState.getBlock().hasTileEntity(blockState) && world.getTileEntity(data.getPos()) instanceof IGregTechTileEntity gtte) { if (gtte.getMetaTileEntity() instanceof IQuantumController controller) { + String eutText = configureEnergyUsage(controller.getEnergyUsage() / 10); if (controller.getCount(IQuantumStorage.Type.ENERGY) == 0) { probeInfo.text("{*gregtech.top.quantum_controller.no_hatches*}"); + probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_required*} " + eutText); } else if (!controller.isPowered()) { probeInfo.text("{*gregtech.top.quantum_controller.no_power*}"); + probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_required*} " + eutText); } else { - long usage = controller.getEnergyUsage(); - configureEnergyUsage(usage / 10, probeInfo); + probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_consumption*} " + eutText); } } else if (gtte.getMetaTileEntity() instanceof IQuantumStoragestorage && (storage.getType() == IQuantumStorage.Type.ITEM || @@ -59,10 +61,8 @@ public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer play "{*" + status + "*}"; } - public void configureEnergyUsage(long EUs, IProbeInfo probeInfo) { - if (EUs == 0) return; - String text = TextFormatting.RED.toString() + EUs + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN + + public String configureEnergyUsage(long EUs) { + return TextFormatting.RED.toString() + EUs + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN + " (" + GTValues.VNF[GTUtility.getTierByVoltage(EUs)] + TextFormatting.GREEN + ")"; - probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_consumption*} " + text); } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index eef80763ada..c282f52c966 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -68,6 +68,7 @@ gregtech.top.working_disabled=Working Disabled gregtech.top.energy_consumption=Using gregtech.top.energy_production=Producing +gregtech.top.energy_required=Requires gregtech.top.transform_up=Step Up gregtech.top.transform_down=Step Down From 219277ee750cca15c92a002e73abd4ded90ea4bb Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Fri, 31 Jan 2025 20:40:27 -0700 Subject: [PATCH 03/15] Fix Power Substation JEI preview (#2708) --- .../MetaTileEntityPowerSubstation.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java index 7814f3dccc9..abf7a3d31d4 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java @@ -9,8 +9,17 @@ import gregtech.api.capability.impl.EnergyContainerList; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.*; -import gregtech.api.pattern.*; +import gregtech.api.metatileentity.multiblock.IBatteryData; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.IProgressBarMultiblock; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockDisplayText; +import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.util.BlockInfo; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -48,7 +57,11 @@ import java.math.BigInteger; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; import java.util.function.Supplier; import static gregtech.api.util.RelativeDirection.*; @@ -247,7 +260,7 @@ protected BlockPattern createStructurePattern() { @Override public List getMatchingShapes() { List shapeInfo = new ArrayList<>(); - MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder() + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .aisle("CCCCC", "CCCCC", "GGGGG", "GGGGG", "GGGGG") .aisle("CCCCC", "CCCCC", "GBBBG", "GBBBG", "GGGGG") .aisle("CCCCC", "CCCCC", "GBBBG", "GBBBG", "GGGGG") From b9e8b4962662a7df97922e0cbebeaa4f3fedc7de Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Fri, 31 Jan 2025 22:42:41 -0500 Subject: [PATCH 04/15] Fix the cleanroom multiblock overriding the cleanroom provider set by cleaning hatches. (#2706) --- .../WorkableTieredMetaTileEntity.java | 8 ++++++- .../multiblock/DummyCleanroom.java | 7 +++++++ .../multiblock/ICleanroomProvider.java | 9 ++++++++ .../multiblock/ICleanroomReceiver.java | 9 +++++++- .../RecipeMapMultiblockController.java | 12 +++++++++-- .../electric/MetaTileEntityCleanroom.java | 6 +++++- .../MetaTileEntityProcessingArray.java | 21 ++++++++++++++----- ...etaTileEntityCleaningMaintenanceHatch.java | 5 ++--- 8 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java index 5e648be0f60..88651b9e9cc 100644 --- a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java @@ -47,6 +47,7 @@ public abstract class WorkableTieredMetaTileEntity extends TieredMetaTileEntity public final boolean handlesRecipeOutputs; + @Nullable private ICleanroomProvider cleanroom; public WorkableTieredMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap recipeMap, @@ -210,7 +211,12 @@ public ICleanroomProvider getCleanroom() { } @Override - public void setCleanroom(ICleanroomProvider provider) { + public void setCleanroom(@NotNull ICleanroomProvider provider) { this.cleanroom = provider; } + + @Override + public void unsetCleanroom() { + this.cleanroom = null; + } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/DummyCleanroom.java b/src/main/java/gregtech/api/metatileentity/multiblock/DummyCleanroom.java index 6b51624ed4c..eba7d877af3 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/DummyCleanroom.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/DummyCleanroom.java @@ -64,4 +64,11 @@ public void setCleanAmount(int amount) {} @Override public void adjustCleanAmount(int amount) {} + + // Have a higher priority than the cleanroom multiblock (which doesn't override getPriority so it'll return 0) + // doesn't replace the set cleanroom in multiblocks. + @Override + public int getPriority() { + return Integer.MAX_VALUE; + } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomProvider.java b/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomProvider.java index ea9c6a65324..39f223bee38 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomProvider.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomProvider.java @@ -49,4 +49,13 @@ public interface ICleanroomProvider { * @return the tier {@link gregtech.api.GTValues#V} of energy the cleanroom uses at minimum */ int getEnergyTier(); + + /** + * Get the priority of this cleanroom provider to determine which should be used. + * + * @return the priority this cleanroom provider should have over other cleanrooms. + */ + default int getPriority() { + return 0; + } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomReceiver.java b/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomReceiver.java index af729726b23..c6bfa155936 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomReceiver.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/ICleanroomReceiver.java @@ -1,5 +1,6 @@ package gregtech.api.metatileentity.multiblock; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -19,5 +20,11 @@ public interface ICleanroomReceiver { * * @param provider the cleanroom to assign to this machine */ - void setCleanroom(ICleanroomProvider provider); + void setCleanroom(@NotNull ICleanroomProvider provider); + + /** + * Set the receiver's reference to null. Use instead of passing {@code null} to + * {@link ICleanroomReceiver#setCleanroom(ICleanroomProvider)} + */ + void unsetCleanroom(); } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4949074c91a..06032732857 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -51,6 +51,7 @@ public abstract class RecipeMapMultiblockController extends MultiblockWithDispla private boolean isDistinct = false; + @Nullable private ICleanroomProvider cleanroom; public RecipeMapMultiblockController(ResourceLocation metaTileEntityId, RecipeMap recipeMap) { @@ -320,7 +321,14 @@ public ICleanroomProvider getCleanroom() { } @Override - public void setCleanroom(ICleanroomProvider provider) { - this.cleanroom = provider; + public void setCleanroom(@NotNull ICleanroomProvider provider) { + if (cleanroom == null || provider.getPriority() > cleanroom.getPriority()) { + this.cleanroom = provider; + } + } + + @Override + public void unsetCleanroom() { + this.cleanroom = null; } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java index 22c6909ca35..99f1d89726e 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -150,7 +150,11 @@ public void invalidateStructure() { resetTileAbilities(); this.cleanroomLogic.invalidate(); this.cleanAmount = MIN_CLEAN_AMOUNT; - cleanroomReceivers.forEach(receiver -> receiver.setCleanroom(null)); + cleanroomReceivers.forEach(receiver -> { + if (receiver.getCleanroom() == this) { + receiver.unsetCleanroom(); + } + }); cleanroomReceivers.clear(); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java index 4759bb1dec7..0a06b0fb546 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java @@ -239,13 +239,20 @@ public int getItemOutputLimit() { } @Override - public void setCleanroom(ICleanroomProvider provider) { + public void setCleanroom(@NotNull ICleanroomProvider provider) { super.setCleanroom(provider); // Sync Cleanroom Change to Internal Workable MTE ((ProcessingArrayWorkable) this.recipeMapWorkable).updateCleanroom(); } + @Override + public void unsetCleanroom() { + super.unsetCleanroom(); + + ((ProcessingArrayWorkable) this.recipeMapWorkable).updateCleanroom(); + } + @SuppressWarnings("InnerClassMayBeStatic") protected class ProcessingArrayWorkable extends MultiblockRecipeLogic { @@ -269,8 +276,8 @@ public void invalidate() { super.invalidate(); // invalidate mte's cleanroom reference - if (mte != null && mte instanceof ICleanroomReceiver) { - ((ICleanroomReceiver) mte).setCleanroom(null); + if (mte != null && mte instanceof ICleanroomReceiver cleanroomMTE) { + cleanroomMTE.unsetCleanroom(); } // Reset locally cached variables upon invalidation @@ -284,7 +291,7 @@ public void invalidate() { /** * Checks if a provided Recipe Map is valid to be used in the processing array - * Will filter out anything in the config blacklist, and also any non-singleblock machines + * Will filter out anything in the config blacklist, and also any non-single block machines * * @param recipeMap The recipeMap to check * @return {@code true} if the provided recipeMap is valid for use @@ -360,7 +367,11 @@ private void updateCleanroom() { receiver.setCleanroom(DUMMY_CLEANROOM); } else { ICleanroomProvider provider = ((RecipeMapMultiblockController) metaTileEntity).getCleanroom(); - if (provider != null) receiver.setCleanroom(provider); + if (provider == null) { + receiver.unsetCleanroom(); + } else { + receiver.setCleanroom(provider); + } } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCleaningMaintenanceHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCleaningMaintenanceHatch.java index c7e24cb6649..5996b8ab11f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCleaningMaintenanceHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCleaningMaintenanceHatch.java @@ -52,9 +52,8 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @Override public void addToMultiBlock(MultiblockControllerBase controllerBase) { super.addToMultiBlock(controllerBase); - if (controllerBase instanceof ICleanroomReceiver && - ((ICleanroomReceiver) controllerBase).getCleanroom() == null) { - ((ICleanroomReceiver) controllerBase).setCleanroom(DUMMY_CLEANROOM); + if (controllerBase instanceof ICleanroomReceiver cleanroomReceiver) { + cleanroomReceiver.setCleanroom(DUMMY_CLEANROOM); } } From 0fe986550ee20a26a9ee7faf5008212371fbfe3b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 1 Feb 2025 20:25:34 -0700 Subject: [PATCH 05/15] Update to MUI2 RC3 (#2702) --- dependencies.gradle | 2 +- src/main/java/gregtech/GregTechMod.java | 3 +- src/main/java/gregtech/api/mui/GTGuis.java | 4 + .../java/gregtech/api/mui/LocaleAccessor.java | 20 +++ .../java/gregtech/api/mui/StateOverlay.java | 22 --- src/main/java/gregtech/api/mui/UnboxFix.java | 8 - .../api/mui/sync/GTFluidSyncHandler.java | 5 +- .../gregtech/common/covers/CoverConveyor.java | 3 - .../gregtech/common/covers/CoverPump.java | 3 - .../covers/ender/CoverAbstractEnderLink.java | 18 ++- .../covers/filter/BaseFilterContainer.java | 15 +- .../gregtech/mixins/minecraft/L18nMixin.java | 21 +++ .../mixins/minecraft/LocaleMixin.java | 23 +++ .../mixins/mui2/ClientEventHandlerMixin.java | 79 ---------- .../gregtech/mixins/mui2/ItemSlotSHMixin.java | 141 ------------------ .../gregtech/mixins/mui2/LangKeyMixin.java | 31 ++++ .../mixins/mui2/PanelSyncHandlerMixin.java | 47 ------ .../mixins/mui2/PanelSyncManagerMixin.java | 36 ----- .../gregtech/mixins/mui2/StyledTextMixin.java | 119 --------------- .../gregtech/mixins/mui2/TextWidgetMixin.java | 57 ------- .../mixins/mui2/ToggleButtonMixin.java | 22 --- .../gregtech/mixins/mui2/TooltipMixin.java | 100 ------------- .../resources/mixins.gregtech.minecraft.json | 2 + src/main/resources/mixins.gregtech.mui2.json | 13 +- 24 files changed, 124 insertions(+), 670 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/LocaleAccessor.java delete mode 100644 src/main/java/gregtech/api/mui/StateOverlay.java delete mode 100644 src/main/java/gregtech/api/mui/UnboxFix.java create mode 100644 src/main/java/gregtech/mixins/minecraft/L18nMixin.java create mode 100644 src/main/java/gregtech/mixins/minecraft/LocaleMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/LangKeyMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/StyledTextMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java delete mode 100644 src/main/java/gregtech/mixins/mui2/TooltipMixin.java diff --git a/dependencies.gradle b/dependencies.gradle index 91d6a5d5c7e..ec6767e637c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,7 +40,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:2.5.0-rc2") { transitive = false } + api("com.cleanroommc:modularui:2.5.0-rc3") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") api("appeng:ae2-uel:v0.56.4") { transitive = false } diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 04fcd09786c..5334d5afe13 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -31,7 +31,8 @@ acceptedMinecraftVersions = "[1.12.2,1.13)", version = GTInternalTags.VERSION, dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + - "required-after:modularui@[2.3,);" + "required-after:mixinbooter@[8.0,);" + "after:appliedenergistics2;" + + "required-after:modularui@[2.5.0-rc,);" + "required-after:mixinbooter@[8.0,);" + + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[1.2.0,);" + "after:theoneprobe;" + "after:hwyla;") diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index 9f9989b2601..568f925cb6f 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -9,6 +9,7 @@ import net.minecraft.item.ItemStack; +import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.factory.GuiManager; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; @@ -103,6 +104,9 @@ public PopupPanel(@NotNull String name, int width, int height, boolean disableBe .onMousePressed(mouseButton -> { if (mouseButton == 0 || mouseButton == 1) { this.closeIfOpen(true); + if (isSynced() && getSyncHandler() instanceof IPanelHandler handler) { + handler.deleteCachedPanel(); + } return true; } return false; diff --git a/src/main/java/gregtech/api/mui/LocaleAccessor.java b/src/main/java/gregtech/api/mui/LocaleAccessor.java new file mode 100644 index 00000000000..2fee169f215 --- /dev/null +++ b/src/main/java/gregtech/api/mui/LocaleAccessor.java @@ -0,0 +1,20 @@ +package gregtech.api.mui; + +import net.minecraft.client.resources.Locale; + +// todo remove in next mui2 version +public interface LocaleAccessor { + + String gregtech$getRawKey(String s); + + ThreadLocal accessor = new ThreadLocal<>(); + + static String getRawKey(String s) { + if (accessor.get() == null) return s; + return accessor.get().gregtech$getRawKey(s); + } + + static void setLocale(Locale locale) { + accessor.set((LocaleAccessor) locale); + } +} diff --git a/src/main/java/gregtech/api/mui/StateOverlay.java b/src/main/java/gregtech/api/mui/StateOverlay.java deleted file mode 100644 index fefdc7fc477..00000000000 --- a/src/main/java/gregtech/api/mui/StateOverlay.java +++ /dev/null @@ -1,22 +0,0 @@ -package gregtech.api.mui; - -import com.cleanroommc.modularui.api.drawable.IDrawable; -import com.cleanroommc.modularui.widgets.ToggleButton; - -import java.util.function.Consumer; - -public interface StateOverlay { - - StateOverlay overlay(boolean selected, IDrawable... overlay); - - StateOverlay hoverOverlay(boolean selected, IDrawable... overlay); - - static ToggleButton cast(ToggleButton button, Consumer function) { - function.accept((StateOverlay) button); - return button; - } - - static ToggleButton create(Consumer function) { - return cast(new ToggleButton(), function); - } -} diff --git a/src/main/java/gregtech/api/mui/UnboxFix.java b/src/main/java/gregtech/api/mui/UnboxFix.java deleted file mode 100644 index 48f1bda2f20..00000000000 --- a/src/main/java/gregtech/api/mui/UnboxFix.java +++ /dev/null @@ -1,8 +0,0 @@ -package gregtech.api.mui; - -public interface UnboxFix { - - void gregTech$useDefaultTextColor(boolean b); - - void gregTech$useDefaultShadow(boolean b); -} diff --git a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java index 1886be86d31..4571c26e93d 100644 --- a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java @@ -52,11 +52,10 @@ public GTFluidSyncHandler(IFluidTank tank) { @Override public void detectAndSendChanges(boolean init) { var current = getFluid(); - if (current == null && lastFluid == null) return; - if (current == null || lastFluid == null || lastFluid.getFluid() != current.getFluid()) { + if (init || current == null || lastFluid == null || current.isFluidEqual(lastFluid)) { lastFluid = current == null ? null : current.copy(); syncToClient(UPDATE_TANK, buffer -> NetworkUtils.writeFluidStack(buffer, current)); - } else if (current.amount != lastFluid.amount) { + } else if (lastFluid != null && current.amount != lastFluid.amount) { lastFluid.amount = current.amount; syncToClient(UPDATE_AMOUNT, buffer -> buffer.writeInt(current.amount)); } diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 1fa4e43dffe..b037492f993 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -43,7 +43,6 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IDrawable; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; @@ -545,7 +544,6 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncMana .onMousePressed(mouseButton -> { int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); throughput.setValue(val, true, true); - Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) @@ -560,7 +558,6 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncMana .onMousePressed(mouseButton -> { int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); throughput.setValue(val, true, true); - Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index b57e5a33545..659b916e80b 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -41,7 +41,6 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IDrawable; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; @@ -226,7 +225,6 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { .onMousePressed(mouseButton -> { int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); throughput.setValue(val); - Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) @@ -241,7 +239,6 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { .onMousePressed(mouseButton -> { int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); throughput.setValue(val); - Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index 4ed97afcc0e..552c6bb4075 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -26,7 +26,6 @@ import codechicken.lib.raytracer.CuboidRayTraceResult; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.Rectangle; @@ -50,8 +49,9 @@ import org.jetbrains.annotations.Nullable; import org.lwjgl.input.Keyboard; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; -import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; @@ -149,8 +149,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { var name = new StringSyncValue(this::getColorStr, this::updateColor); - // todo unneeded cast in mui2 rc3 - var entrySelectorSH = (PanelSyncHandler) syncManager.panel("entry_selector", entrySelector(getType()), true); + var entrySelectorSH = syncManager.panel("entry_selector", entrySelector(getType()), true); return Flow.column().coverChildrenHeight().top(24) .margin(7, 0).widthRel(1f) @@ -173,6 +172,7 @@ protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { .onMousePressed(i -> { if (entrySelectorSH.isPanelOpen()) { entrySelectorSH.closePanel(); + entrySelectorSH.deleteCachedPanel(); } else { entrySelectorSH.openPanel(); } @@ -284,14 +284,19 @@ public void writeToNBT(@NotNull NBTTagCompound nbt) { protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { return (syncManager, syncHandler) -> { - Set names = VirtualEnderRegistry.getEntryNames(getOwner(), type); + List rows = new ArrayList<>(); + for (String name : VirtualEnderRegistry.getEntryNames(getOwner(), type)) { + rows.add(createRow(name, syncManager, type)); + } return GTGuis.createPopupPanel("entry_selector", 168, 112) .child(IKey.lang("cover.generic.ender.known_channels") .color(UI_TITLE_COLOR) .asWidget() .top(6) .left(4)) - .child(ListWidget.builder(names, name -> createRow(name, syncManager, type)) + .child(new ListWidget<>() + .children(rows) + // .builder(names, name -> createRow(name, syncManager, type)) .background(GTGuiTextures.DISPLAY.asIcon() .width(168 - 8) .height(112 - 20)) @@ -391,7 +396,6 @@ protected IWidget createRow(final String name, final PanelSyncManager syncManage getOwner() == null ? "null" : getOwner().toString()); NetworkUtils.writeStringSafe(buffer, name); }); - Interactable.playButtonClickSound(); return true; })); } diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java index 7bb6c7473e3..524998ec460 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -10,12 +10,13 @@ import net.minecraft.util.math.MathHelper; import net.minecraftforge.items.ItemStackHandler; +import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.factory.GuiData; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.utils.Alignment; -import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ButtonWidget; @@ -24,8 +25,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - public abstract class BaseFilterContainer extends ItemStackHandler { private int maxTransferSize = 1; @@ -213,7 +212,7 @@ public void handleLegacyNBT(NBTTagCompound nbt) { /** Uses Cleanroom MUI */ public IWidget initUI(GuiData data, PanelSyncManager manager) { - PanelSyncHandler panel = (PanelSyncHandler) manager.panel("filter_panel", (syncManager, syncHandler) -> { + IPanelHandler panel = manager.panel("filter_panel", (syncManager, syncHandler) -> { var filter = hasFilter() ? getFilter() : BaseFilter.ERROR_FILTER; filter.setMaxTransferSize(getMaxTransferSize()); return filter.createPopupPanel(syncManager); @@ -253,17 +252,13 @@ public IWidget initUI(GuiData data, PanelSyncManager manager) { } public void writeInitialSyncData(PacketBuffer packetBuffer) { - packetBuffer.writeItemStack(this.getFilterStack()); + NetworkUtils.writeItemStack(packetBuffer, this.getFilterStack()); packetBuffer.writeInt(this.maxTransferSize); packetBuffer.writeInt(this.transferSize); } public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { - var stack = ItemStack.EMPTY; - try { - stack = packetBuffer.readItemStack(); - } catch (IOException ignore) {} - this.setFilterStack(stack); + this.setFilterStack(NetworkUtils.readItemStack(packetBuffer)); this.setMaxTransferSize(packetBuffer.readInt()); this.setTransferSize(packetBuffer.readInt()); } diff --git a/src/main/java/gregtech/mixins/minecraft/L18nMixin.java b/src/main/java/gregtech/mixins/minecraft/L18nMixin.java new file mode 100644 index 00000000000..26d67c82e0b --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/L18nMixin.java @@ -0,0 +1,21 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.mui.LocaleAccessor; + +import net.minecraft.client.resources.I18n; +import net.minecraft.client.resources.Locale; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// todo remove in next mui2 version +@Mixin(I18n.class) +public abstract class L18nMixin { + + @Inject(method = "setLocale", at = @At("HEAD")) + private static void getLocale(Locale i18nLocaleIn, CallbackInfo ci) { + LocaleAccessor.setLocale(i18nLocaleIn); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/LocaleMixin.java b/src/main/java/gregtech/mixins/minecraft/LocaleMixin.java new file mode 100644 index 00000000000..b93f29b02e6 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/LocaleMixin.java @@ -0,0 +1,23 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.mui.LocaleAccessor; + +import net.minecraft.client.resources.Locale; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Map; + +// todo remove in next mui2 version +@Mixin(Locale.class) +public abstract class LocaleMixin implements LocaleAccessor { + + @Shadow + Map properties; + + @Override + public String gregtech$getRawKey(String s) { + return this.properties.get(s); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java deleted file mode 100644 index 678de031802..00000000000 --- a/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java +++ /dev/null @@ -1,79 +0,0 @@ -package gregtech.mixins.mui2; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import net.minecraftforge.client.event.GuiScreenEvent; - -import com.cleanroommc.modularui.ClientEventHandler; -import com.cleanroommc.modularui.api.IMuiScreen; -import com.cleanroommc.modularui.core.mixin.GuiScreenAccessor; -import com.cleanroommc.modularui.screen.ClientScreenHandler; -import com.cleanroommc.modularui.screen.ModularScreen; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.IOException; - -@Mixin(value = ClientEventHandler.class, remap = false) -@SuppressWarnings("UnstableApiUsage") -public abstract class ClientEventHandlerMixin { - - @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleMouseInput()V")) - private static void fixMouseInput(GuiScreen instance) { - int button = Mouse.getEventButton(); - if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { - ModularScreen ms = screen.getScreen(); - if (Mouse.getEventButtonState()) { - acc.setEventButton(button); - acc.setLastMouseEvent(Minecraft.getSystemTime()); - ms.onMousePressed(button); - - } else if (button != -1) { - acc.setEventButton(-1); - ms.onMouseRelease(button); - - } else if (acc.getEventButton() != -1 && acc.getLastMouseEvent() > 0L) { - long l = Minecraft.getSystemTime() - acc.getLastMouseEvent(); - ms.onMouseDrag(button, l); - } - } - } - - @Inject(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", - at = @At("TAIL")) - private static void fixScrollJei(GuiScreenEvent.MouseInputEvent.Pre event, CallbackInfo ci) throws IOException { - if (!event.isCanceled()) - ClientScreenHandler.onGuiInputLow(event); - } - - @Unique - private static Character gregTech$lastChar = null; - - @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$KeyboardInputEvent$Pre;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleKeyboardInput()V")) - private static void fixKeyInput(GuiScreen instance) { - if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { - char c0 = Keyboard.getEventCharacter(); - int key = Keyboard.getEventKey(); - boolean state = Keyboard.getEventKeyState(); - if (state) { - gregTech$lastChar = c0; - screen.getScreen().onKeyPressed(c0, key); - } else { - // releasing a key - // for some reason when you press E after joining a world the button will not trigger the press event, - // but only the release event, causing this to be null - if (gregTech$lastChar == null) return; - // when the key is released, the event char is empty - screen.getScreen().onKeyRelease(gregTech$lastChar, key); - } - } - } -} diff --git a/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java b/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java deleted file mode 100644 index 5d53a35d3d0..00000000000 --- a/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java +++ /dev/null @@ -1,141 +0,0 @@ -package gregtech.mixins.mui2; - -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.ItemHandlerHelper; - -import com.cleanroommc.modularui.network.NetworkUtils; -import com.cleanroommc.modularui.screen.ModularContainer; -import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.ItemSlotSH; -import com.cleanroommc.modularui.value.sync.SyncHandler; -import com.cleanroommc.modularui.widgets.slot.ModularSlot; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.IOException; - -@Mixin(value = ItemSlotSH.class, remap = false) -public abstract class ItemSlotSHMixin extends SyncHandler { - - @Unique - private boolean gregTech$registered; - - @Shadow - protected abstract void phantomScroll(MouseData mouseData); - - @Shadow - public abstract void setEnabled(boolean enabled, boolean sync); - - @Shadow - public abstract boolean isPhantom(); - - @Shadow - private ItemStack lastStoredPhantomItem; - - @Shadow - public abstract ModularSlot getSlot(); - - @Shadow - public abstract void incrementStackCount(int amount); - - @WrapOperation(method = "init", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/screen/ModularContainer;registerSlot(Ljava/lang/String;Lcom/cleanroommc/modularui/widgets/slot/ModularSlot;)V")) - protected void wrapRegister(ModularContainer instance, String slotGroup, ModularSlot modularSlot, - Operation original) { - if (!gregTech$registered) { - original.call(instance, slotGroup, modularSlot); - gregTech$registered = true; - } - } - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#90 - */ - @Overwrite - public void readOnServer(int id, PacketBuffer buf) throws IOException { - if (id == 2) { - phantomClick(MouseData.readPacket(buf)); - } else if (id == 3) { - phantomScroll(MouseData.readPacket(buf)); - } else if (id == 4) { - setEnabled(buf.readBoolean(), false); - } else if (id == 5) { - if (!isPhantom()) return; - gregTech$phantomClick(MouseData.create(0), buf.readItemStack()); - } - } - - @Inject(method = "readOnClient", at = @At("HEAD")) - protected void handlePhantomScroll(int id, PacketBuffer buf, CallbackInfo ci) { - if (id == 3) { - this.lastStoredPhantomItem = NetworkUtils.readItemStack(buf); - getSlot().putStack(this.lastStoredPhantomItem.copy()); - } - } - - @Inject(method = "phantomScroll", at = @At("TAIL")) - protected void syncPhantomScroll(MouseData mouseData, CallbackInfo ci) { - syncToClient(3, buffer -> NetworkUtils.writeItemStack(buffer, this.lastStoredPhantomItem)); - } - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#90 - */ - @Overwrite - protected void phantomClick(MouseData mouseData) { - gregTech$phantomClick(mouseData, getSyncManager().getCursorItem()); - } - - @Unique - protected void gregTech$phantomClick(MouseData mouseData, ItemStack cursorStack) { - ItemStack slotStack = getSlot().getStack(); - ItemStack stackToPut; - if (!cursorStack.isEmpty() && !slotStack.isEmpty() && - !ItemHandlerHelper.canItemStacksStack(cursorStack, slotStack)) { - stackToPut = cursorStack.copy(); - if (mouseData.mouseButton == 1) { - stackToPut.setCount(1); - } - stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); - getSlot().putStack(stackToPut); - this.lastStoredPhantomItem = stackToPut.copy(); - } else if (slotStack.isEmpty()) { - if (cursorStack.isEmpty()) { - if (mouseData.mouseButton == 1 && !this.lastStoredPhantomItem.isEmpty()) { - stackToPut = this.lastStoredPhantomItem.copy(); - } else { - return; - } - } else { - stackToPut = cursorStack.copy(); - } - if (mouseData.mouseButton == 1) { - stackToPut.setCount(1); - } - stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); - getSlot().putStack(stackToPut); - this.lastStoredPhantomItem = stackToPut.copy(); - } else { - if (mouseData.mouseButton == 0) { - if (mouseData.shift) { - getSlot().putStack(ItemStack.EMPTY); - } else { - incrementStackCount(-1); - } - } else if (mouseData.mouseButton == 1) { - incrementStackCount(1); - } - } - } -} diff --git a/src/main/java/gregtech/mixins/mui2/LangKeyMixin.java b/src/main/java/gregtech/mixins/mui2/LangKeyMixin.java new file mode 100644 index 00000000000..7c219710609 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/LangKeyMixin.java @@ -0,0 +1,31 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.LocaleAccessor; + +import com.cleanroommc.modularui.drawable.text.BaseKey; +import com.cleanroommc.modularui.drawable.text.LangKey; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +// todo remove in next mui2 version +@Mixin(value = LangKey.class, remap = false) +public abstract class LangKeyMixin extends BaseKey { + + @Redirect(method = "getFormatted", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/resources/I18n;format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;")) + public String getTranslateKey(String translateKey, Object[] parameters) { + return LocaleAccessor.getRawKey(translateKey) + .replace("\\n", "\n") + .replace("/n", "\n"); + } + + @ModifyExpressionValue(method = "get", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/resources/I18n;format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;")) + public String switchNewLines(String original) { + return original.replace("/n", "\n"); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java deleted file mode 100644 index 99a850b1c10..00000000000 --- a/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java +++ /dev/null @@ -1,47 +0,0 @@ -package gregtech.mixins.mui2; - -import com.cleanroommc.modularui.api.widget.ISynced; -import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.value.sync.ModularSyncManager; -import com.cleanroommc.modularui.value.sync.PanelSyncHandler; -import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widget.WidgetTree; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.concurrent.atomic.AtomicInteger; - -@Mixin(value = PanelSyncHandler.class, remap = false) -public abstract class PanelSyncHandlerMixin { - - @Shadow - private PanelSyncManager syncManager; - - @Shadow - public abstract boolean isPanelOpen(); - - @Redirect(method = "openPanel(Z)V", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/widget/WidgetTree;collectSyncValues(Lcom/cleanroommc/modularui/value/sync/PanelSyncManager;Lcom/cleanroommc/modularui/screen/ModularPanel;)V")) - protected void redirectCollectValues(PanelSyncManager syncManager, ModularPanel panel) { - AtomicInteger id = new AtomicInteger(0); - String syncKey = ModularSyncManager.AUTO_SYNC_PREFIX + panel.getName(); - WidgetTree.foreachChildBFS(panel, widget -> { - if (widget instanceof ISyncedsynced) { - if (synced.isSynced() && !this.syncManager.hasSyncHandler(synced.getSyncHandler())) { - this.syncManager.syncValue(syncKey, id.getAndIncrement(), synced.getSyncHandler()); - } - } - return true; - }, false); - } - - @Inject(method = "openPanel(Z)V", at = @At("HEAD"), cancellable = true) - protected void openCheck(boolean syncToServer, CallbackInfo ci) { - if (isPanelOpen()) ci.cancel(); - } -} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java deleted file mode 100644 index 9bea0ab1af2..00000000000 --- a/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package gregtech.mixins.mui2; - -import gregtech.api.util.GTLog; - -import net.minecraft.network.PacketBuffer; - -import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.value.sync.SyncHandler; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Map; - -@Mixin(value = PanelSyncManager.class, remap = false) -public abstract class PanelSyncManagerMixin { - - @Shadow - @Final - private Map syncHandlers; - - @Shadow - private String panelName; - - @Inject(method = "receiveWidgetUpdate", at = @At("HEAD"), cancellable = true) - public void injectCheck(String mapKey, int id, PacketBuffer buf, CallbackInfo ci) { - if (!this.syncHandlers.containsKey(mapKey)) { - GTLog.logger.warn("[ModularUI] SyncHandler \"{}\" does not exist for panel \"{}\"! ID was {}.", mapKey, - panelName, id); - ci.cancel(); - } - } -} diff --git a/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java b/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java deleted file mode 100644 index 41c269111ab..00000000000 --- a/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java +++ /dev/null @@ -1,119 +0,0 @@ -package gregtech.mixins.mui2; - -import gregtech.api.mui.UnboxFix; - -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import com.cleanroommc.modularui.api.drawable.IKey; -import com.cleanroommc.modularui.drawable.text.AnimatedText; -import com.cleanroommc.modularui.drawable.text.StyledText; -import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.utils.Alignment; -import com.cleanroommc.modularui.widgets.TextWidget; -import com.llamalad7.mixinextras.sugar.Local; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = StyledText.class, remap = false) -public abstract class StyledTextMixin implements UnboxFix { - - @Shadow - @Final - private IKey key; - - @Shadow - private Alignment alignment; - - @Shadow - private Integer color; - - @Shadow - private float scale; - - @Shadow - private Boolean shadow; - - @Unique - private boolean gregTech$defaultTextColor = true; - - @Unique - private boolean gregTech$defaultShadow = true; - - @Override - public void gregTech$useDefaultTextColor(boolean b) { - gregTech$defaultTextColor = b; - } - - @Override - public void gregTech$useDefaultShadow(boolean b) { - gregTech$defaultShadow = b; - } - - @Inject(method = "color", at = @At("HEAD")) - private void setDefault(int color, CallbackInfoReturnable cir) { - gregTech$useDefaultTextColor(false); - } - - @Inject(method = "shadow", at = @At("HEAD")) - private void setDefault(boolean shadow, CallbackInfoReturnable cir) { - gregTech$useDefaultShadow(false); - } - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#86 - */ - @Overwrite - public TextWidget asWidget() { - var text = new TextWidget(this.key) - .alignment(this.alignment) - .scale(this.scale); - - ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); - ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); - - return text.color(color == null ? 0 : color) - .shadow(shadow != null && shadow); - } - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#86 - */ - @Overwrite - public AnimatedText withAnimation() { - var text = new AnimatedText(this.key) - .alignment(this.alignment) - .scale(this.scale); - - ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); - ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); - - return text.color(color == null ? 0 : color) - .shadow(shadow != null && shadow); - } - - @SideOnly(Side.CLIENT) - @ModifyArg(method = "draw", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) - public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { - return gregTech$defaultTextColor ? theme.getTextColor() : color; - } - - @SideOnly(Side.CLIENT) - @ModifyArg(method = "draw", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) - public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { - return gregTech$defaultShadow ? theme.getTextShadow() : shadow; - } -} diff --git a/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java b/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java deleted file mode 100644 index 40320a51020..00000000000 --- a/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java +++ /dev/null @@ -1,57 +0,0 @@ -package gregtech.mixins.mui2; - -import gregtech.api.mui.UnboxFix; - -import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.TextWidget; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.sugar.Local; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -@Mixin(value = TextWidget.class, remap = false) -public abstract class TextWidgetMixin extends Widget implements UnboxFix { - - @Unique - private boolean gregTech$defaultTextColor = true; - - @Unique - private boolean gregTech$defaultShadow = true; - - @Override - public void gregTech$useDefaultTextColor(boolean b) { - gregTech$defaultTextColor = b; - } - - @Override - public void gregTech$useDefaultShadow(boolean b) { - gregTech$defaultShadow = b; - } - - @Override - public boolean canHover() { - return hasTooltip(); - } - - @ModifyReturnValue(method = { "getDefaultHeight", "getDefaultWidth" }, at = @At("TAIL")) - public int clamp(int r) { - return Math.max(1, r); - } - - @ModifyArg(method = "draw", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) - public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { - return gregTech$defaultTextColor ? theme.getTextColor() : color; - } - - @ModifyArg(method = "draw", - at = @At(value = "INVOKE", - target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) - public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { - return gregTech$defaultShadow ? theme.getTextShadow() : shadow; - } -} diff --git a/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java b/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java deleted file mode 100644 index 3838ecf5805..00000000000 --- a/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package gregtech.mixins.mui2; - -import gregtech.api.mui.StateOverlay; - -import com.cleanroommc.modularui.api.drawable.IDrawable; -import com.cleanroommc.modularui.widgets.AbstractCycleButtonWidget; -import com.cleanroommc.modularui.widgets.ToggleButton; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(value = ToggleButton.class, remap = false) -public class ToggleButtonMixin extends AbstractCycleButtonWidget implements StateOverlay { - - public StateOverlay overlay(boolean selected, IDrawable... overlay) { - this.overlay = addToArray(this.overlay, overlay, selected ? 1 : 0); - return (StateOverlay) getThis(); - } - - public StateOverlay hoverOverlay(boolean selected, IDrawable... overlay) { - this.hoverOverlay = addToArray(this.hoverOverlay, overlay, selected ? 1 : 0); - return (StateOverlay) getThis(); - } -} diff --git a/src/main/java/gregtech/mixins/mui2/TooltipMixin.java b/src/main/java/gregtech/mixins/mui2/TooltipMixin.java deleted file mode 100644 index 7883e8b12de..00000000000 --- a/src/main/java/gregtech/mixins/mui2/TooltipMixin.java +++ /dev/null @@ -1,100 +0,0 @@ -package gregtech.mixins.mui2; - -import com.cleanroommc.modularui.drawable.text.RichText; -import com.cleanroommc.modularui.screen.RichTooltip; -import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; -import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.RichTextWidget; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.function.Consumer; - -@Mixin(value = RichTooltip.class, remap = false) -public abstract class TooltipMixin { - - @Shadow - private boolean dirty; - - @Shadow - @Final - private RichText text; - - @Shadow - private Consumer tooltipBuilder; - - @Shadow - public abstract RichTooltip getThis(); - - @Shadow - public abstract void markDirty(); - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#83 - */ - @Overwrite - public void buildTooltip() { - this.dirty = false; - if (this.tooltipBuilder != null) { - this.text.clearText(); - this.tooltipBuilder.accept(getThis()); - } - } - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#83 - */ - @Overwrite - public RichTooltip tooltipBuilder(Consumer tooltipBuilder) { - Consumer existingBuilder = this.tooltipBuilder; - if (existingBuilder != null) { - this.tooltipBuilder = tooltip -> { - existingBuilder.accept(getThis()); - tooltipBuilder.accept(getThis()); - }; - } else { - this.tooltipBuilder = tooltipBuilder; - } - markDirty(); - return getThis(); - } - - @Mixin(value = RichTextWidget.class, remap = false) - private static abstract class RichTextWidgetMixin extends Widget { - - @Shadow - private boolean autoUpdate; - - @Shadow - private boolean dirty; - - @Shadow - @Final - private RichText text; - - @Shadow - private Consumer builder; - - /** - * @author GTCEu - Ghzdude - * @reason Implement MUI2 PR#83 - */ - @Overwrite - public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { - super.draw(context, widgetTheme); - if (this.autoUpdate || this.dirty) { - if (this.builder != null) { - this.text.clearText(); - this.builder.accept(this.text); - } - this.dirty = false; - } - this.text.drawAtZero(context, getArea(), widgetTheme); - } - } -} diff --git a/src/main/resources/mixins.gregtech.minecraft.json b/src/main/resources/mixins.gregtech.minecraft.json index 85676f99055..41a4c44b26e 100644 --- a/src/main/resources/mixins.gregtech.minecraft.json +++ b/src/main/resources/mixins.gregtech.minecraft.json @@ -18,8 +18,10 @@ "client": [ "BlockMixin", "EntityRendererMixin", + "L18nMixin", "LayerArmorBaseMixin", "LayerCustomHeadMixin", + "LocaleMixin", "RecipeRepairItemMixin", "RegionRenderCacheBuilderMixin", "RenderChunkMixin", diff --git a/src/main/resources/mixins.gregtech.mui2.json b/src/main/resources/mixins.gregtech.mui2.json index cb97f2be00c..427113e6ac8 100644 --- a/src/main/resources/mixins.gregtech.mui2.json +++ b/src/main/resources/mixins.gregtech.mui2.json @@ -7,18 +7,9 @@ "injectors": { "maxShiftBy": 10 }, - "mixins": [ - "ItemSlotSHMixin", - "PanelSyncHandlerMixin", - "PanelSyncManagerMixin", - "StyledTextMixin", - "TextWidgetMixin", - "ToggleButtonMixin", - "TooltipMixin", - "TooltipMixin$RichTextWidgetMixin" - ], + "mixins": [], "client": [ - "ClientEventHandlerMixin" + "LangKeyMixin" ], "server": [] } From 7dd3cad6feac0d877e6e30ef0068645531fee863 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 2 Feb 2025 18:17:07 -0700 Subject: [PATCH 06/15] Implement Bucket Behavior to Cells (#2660) --- .../items/metaitem/stats/IItemBehaviour.java | 16 +- .../metaitem/stats/ItemFluidContainer.java | 216 +++++++++++++++++- .../java/gregtech/common/items/MetaItem1.java | 19 +- .../resources/assets/gregtech/lang/en_us.lang | 1 + 4 files changed, 240 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/api/items/metaitem/stats/IItemBehaviour.java b/src/main/java/gregtech/api/items/metaitem/stats/IItemBehaviour.java index eb2b743d176..55121079639 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/IItemBehaviour.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/IItemBehaviour.java @@ -38,7 +38,7 @@ default EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockP default ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { - return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + return pass(player.getHeldItem(hand)); } default void addInformation(ItemStack itemStack, List lines) {} @@ -50,8 +50,20 @@ default Multimap getAttributeModifiers(EntityEquipmen } default ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { - return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + return pass(player.getHeldItem(hand)); } default void addPropertyOverride(@NotNull Item item) {} + + default ActionResult pass(ItemStack stack) { + return ActionResult.newResult(EnumActionResult.PASS, stack); + } + + default ActionResult success(ItemStack stack) { + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + } + + default ActionResult fail(ItemStack stack) { + return ActionResult.newResult(EnumActionResult.FAIL, stack); + } } diff --git a/src/main/java/gregtech/api/items/metaitem/stats/ItemFluidContainer.java b/src/main/java/gregtech/api/items/metaitem/stats/ItemFluidContainer.java index b206c683512..f94c0202b74 100644 --- a/src/main/java/gregtech/api/items/metaitem/stats/ItemFluidContainer.java +++ b/src/main/java/gregtech/api/items/metaitem/stats/ItemFluidContainer.java @@ -1,15 +1,54 @@ package gregtech.api.items.metaitem.stats; +import gregtech.api.util.GTUtility; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fluids.IFluidBlock; +import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandlerItem; +import net.minecraftforge.fluids.capability.wrappers.BlockLiquidWrapper; +import net.minecraftforge.fluids.capability.wrappers.BlockWrapper; +import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ItemFluidContainer implements IItemContainerItemProvider, IItemBehaviour { -public class ItemFluidContainer implements IItemContainerItemProvider { + private final boolean isBucket; + + public ItemFluidContainer(boolean isBucket) { + this.isBucket = isBucket; + } + + public ItemFluidContainer() { + this(false); + } @Override public ItemStack getContainerItem(ItemStack itemStack) { - IFluidHandlerItem handler = itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + IFluidHandlerItem handler = FluidUtil.getFluidHandler(itemStack); if (handler != null) { FluidStack drained = handler.drain(1000, false); if (drained == null || drained.amount != 1000) return ItemStack.EMPTY; @@ -18,4 +57,175 @@ public ItemStack getContainerItem(ItemStack itemStack) { } return itemStack; } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + if (isBucket) { + lines.add(I18n.format("behaviour.cell_bucket.tooltip")); + } + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + if (!isBucket) return pass(stack); + + ItemStack cellStack = GTUtility.copy(1, stack); + + var cellHandler = FluidUtil.getFluidHandler(cellStack); + if (cellHandler == null) return pass(stack); + + var result = rayTrace(world, player, true); + if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) { + return pass(stack); + } + + var pos = result.getBlockPos(); + + // can the player modify the clicked block + if (!world.isBlockModifiable(player, pos)) { + return fail(stack); + } + + // can player edit + if (!player.canPlayerEdit(pos, result.sideHit, cellStack)) { + return fail(stack); + } + + // prioritize filling the cell if there's space, otherwise place fluid + if (fillCell(cellStack, world, pos, result.sideHit, player)) { + addToPlayerInventory(stack, cellHandler.getContainer(), player, hand); + return success(stack); + + } else { + result = rayTrace(world, player, false); + if (result == null || result.typeOfHit != RayTraceResult.Type.BLOCK) { + return pass(stack); + } + pos = result.getBlockPos(); + + if (tryPlace(cellHandler, world, pos.offset(result.sideHit), result.sideHit, player)) { + addToPlayerInventory(stack, cellHandler.getContainer(), player, hand); + return success(stack); + } + } + + return pass(stack); + } + + private static boolean tryPlace(IFluidHandlerItem cellHandler, World world, BlockPos pos, EnumFacing side, + EntityPlayer player) { + var cellFluid = cellHandler.drain(Fluid.BUCKET_VOLUME, false); + if (cellFluid == null || !cellFluid.getFluid().canBePlacedInWorld()) + return false; + + IFluidHandler blockHandler = getOrCreate(cellFluid, world, pos, side); + + // check that we can place the fluid at the destination + IBlockState destBlockState = world.getBlockState(pos); + Material destMaterial = destBlockState.getMaterial(); + boolean isDestNonSolid = !destMaterial.isSolid(); + boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos); + + if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable) { + // Non-air, solid, unreplacable block. We can't put fluid here. + return false; + } + + // check vaporize + if (world.provider.doesWaterVaporize() && cellFluid.getFluid().doesVaporize(cellFluid)) { + cellHandler.drain(Fluid.BUCKET_VOLUME, true); + cellFluid.getFluid().vaporize(player, world, pos, cellFluid); + return true; + } + + // fill block + int filled = blockHandler.fill(cellFluid, false); + + if (filled != Fluid.BUCKET_VOLUME) return false; + + playSound(cellFluid, true, player); + boolean consume = !player.isSpectator() && !player.isCreative(); + blockHandler.fill(cellHandler.drain(Fluid.BUCKET_VOLUME, consume), true); + return true; + } + + private static boolean fillCell(ItemStack cellStack, World world, BlockPos pos, EnumFacing side, + EntityPlayer player) { + IFluidHandler blockHandler = FluidUtil.getFluidHandler(world, pos, side); + if (blockHandler == null) return false; + + IFluidHandlerItem cellHandler = FluidUtil.getFluidHandler(cellStack); + if (cellHandler == null) return false; + + FluidStack stack = blockHandler.drain(Fluid.BUCKET_VOLUME, false); + int filled = cellHandler.fill(stack, false); + + if (filled != Fluid.BUCKET_VOLUME) return false; + + playSound(stack, false, player); + boolean consume = !player.isSpectator() && !player.isCreative(); + cellHandler.fill(blockHandler.drain(Fluid.BUCKET_VOLUME, true), consume); + return true; + } + + // copied and adapted from Item.java + @Nullable + private static RayTraceResult rayTrace(World worldIn, EntityPlayer player, boolean hitFluids) { + Vec3d lookPos = player.getPositionVector() + .add(0, player.getEyeHeight(), 0); + + Vec3d lookOffset = player.getLookVec() + .scale(player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue()); + + return worldIn.rayTraceBlocks(lookPos, lookPos.add(lookOffset), + hitFluids, !hitFluids, false); + } + + @NotNull + private static IFluidHandler createHandler(FluidStack stack, World world, BlockPos pos) { + Block block = stack.getFluid().getBlock(); + if (block instanceof IFluidBlock) { + return new FluidBlockWrapper((IFluidBlock) block, world, pos); + } else if (block instanceof BlockLiquid) { + return new BlockLiquidWrapper((BlockLiquid) block, world, pos); + } else { + return new BlockWrapper(block, world, pos); + } + } + + private static IFluidHandler getOrCreate(FluidStack stack, World world, BlockPos pos, EnumFacing side) { + IFluidHandler handler = FluidUtil.getFluidHandler(world, pos, side); + if (handler != null) return handler; + return createHandler(stack, world, pos); + } + + private static void addToPlayerInventory(ItemStack playerStack, ItemStack resultStack, EntityPlayer player, + EnumHand hand) { + if (playerStack.getCount() > resultStack.getCount()) { + playerStack.shrink(resultStack.getCount()); + if (!player.inventory.addItemStackToInventory(resultStack) && !player.world.isRemote) { + EntityItem dropItem = player.entityDropItem(resultStack, 0); + if (dropItem != null) dropItem.setPickupDelay(0); + } + } else { + player.setHeldItem(hand, resultStack); + } + } + + /** + * Play the appropriate fluid interaction sound for the fluid.
+ * Must be called on server to work correctly + **/ + private static void playSound(FluidStack fluid, boolean fill, EntityPlayer player) { + if (fluid == null || player.world.isRemote) return; + SoundEvent soundEvent; + if (fill) { + soundEvent = fluid.getFluid().getFillSound(fluid); + } else { + soundEvent = fluid.getFluid().getEmptySound(fluid); + } + player.world.playSound(null, player.posX, player.posY + 0.5, player.posZ, + soundEvent, SoundCategory.PLAYERS, 1.0F, 1.0F); + } } diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 3cf94c8a5b5..cae98881402 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -191,46 +191,51 @@ public void registerSubItems() { // Fluid Cells: ID 78-88 FLUID_CELL = addItem(78, "fluid_cell") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, false), - new ItemFluidContainer()) + new ItemFluidContainer(true)) .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_UNIVERSAL = addItem(79, "fluid_cell.universal") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, true), - new ItemFluidContainer()) + new ItemFluidContainer(true)) .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STEEL = addItem(80, "large_fluid_cell.steel") .addComponents(new FilteredFluidStats(8000, Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, - false, false, true), new ItemFluidContainer()) + false, false, true), + new ItemFluidContainer(true)) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Steel, M * 4))) // ingot * 4 .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_ALUMINIUM = addItem(81, "large_fluid_cell.aluminium") .addComponents(new FilteredFluidStats(32000, Materials.Aluminium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, - false, false, true), new ItemFluidContainer()) + false, false, true), + new ItemFluidContainer(true)) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Aluminium, M * 4))) // ingot * 4 .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STAINLESS_STEEL = addItem(82, "large_fluid_cell.stainless_steel") .addComponents(new FilteredFluidStats(64000, Materials.StainlessSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, - true, true, false, true), new ItemFluidContainer()) + true, true, false, true), + new ItemFluidContainer(true)) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.StainlessSteel, M * 6))) // ingot * 6 .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TITANIUM = addItem(83, "large_fluid_cell.titanium") .addComponents(new FilteredFluidStats(128000, Materials.Titanium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true, - false, false, true), new ItemFluidContainer()) + false, false, true), + new ItemFluidContainer(true)) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Titanium, M * 6))) // ingot * 6 .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TUNGSTEN_STEEL = addItem(84, "large_fluid_cell.tungstensteel") .addComponents(new FilteredFluidStats(512000, Materials.TungstenSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, - true, false, false, true), new ItemFluidContainer()) + true, false, false, true), + new ItemFluidContainer(true)) .setMaxStackSize(32) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 8))) // ingot * 8 .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index c282f52c966..65b2dc37bf0 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4784,6 +4784,7 @@ behaviour.softhammer=Activates and Deactivates Machines behaviour.hammer=Turns on and off Muffling for Machines (by hitting them) behaviour.wrench=Rotates Blocks on Rightclick behaviour.boor.by=by %s +behaviour.cell_bucket.tooltip=Can pickup or place fluids behaviour.paintspray.solvent.tooltip=Can remove color from things behaviour.paintspray.white.tooltip=Can paint things in White behaviour.paintspray.orange.tooltip=Can paint things in Orange From 8f90f804342b22f229b4274a436b153005f2c1a8 Mon Sep 17 00:00:00 2001 From: TechLord22 <37029404+TechLord22@users.noreply.github.com> Date: Mon, 3 Feb 2025 16:40:12 -0500 Subject: [PATCH 07/15] Optimize JEI multiblock preview allocations (#2629) Co-authored-by: bruberu <80226372+bruberu@users.noreply.github.com> Co-authored-by: Maya <10861407+serenibyss@users.noreply.github.com> --- .../renderer/scene/ISceneRenderHook.java | 17 ----- .../renderer/scene/WorldSceneRenderer.java | 67 +++++++------------ .../AdvancedMonitorPluginBehavior.java | 2 +- .../MultiblockInfoRecipeWrapper.java | 9 ++- 4 files changed, 31 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/gregtech/client/renderer/scene/ISceneRenderHook.java diff --git a/src/main/java/gregtech/client/renderer/scene/ISceneRenderHook.java b/src/main/java/gregtech/client/renderer/scene/ISceneRenderHook.java deleted file mode 100644 index e6674c9b4d2..00000000000 --- a/src/main/java/gregtech/client/renderer/scene/ISceneRenderHook.java +++ /dev/null @@ -1,17 +0,0 @@ -package gregtech.client.renderer.scene; - -import net.minecraft.util.BlockRenderLayer; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/25 - * @Description: Scene Render State hooks. - * This is where you decide whether or not this group of pos should be rendered. What other requirements - * do you have for rendering. - */ -public interface ISceneRenderHook { - - void apply(boolean isTESR, int pass, BlockRenderLayer layer); -} diff --git a/src/main/java/gregtech/client/renderer/scene/WorldSceneRenderer.java b/src/main/java/gregtech/client/renderer/scene/WorldSceneRenderer.java index d5947edf46d..cb0dacd1c63 100644 --- a/src/main/java/gregtech/client/renderer/scene/WorldSceneRenderer.java +++ b/src/main/java/gregtech/client/renderer/scene/WorldSceneRenderer.java @@ -25,6 +25,8 @@ import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.vec.Vector3; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.GLU; @@ -33,8 +35,6 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.function.Consumer; import javax.vecmath.Vector3f; @@ -61,7 +61,7 @@ public abstract class WorldSceneRenderer { .order(ByteOrder.nativeOrder()).asFloatBuffer(); public final World world; - public final Map, ISceneRenderHook> renderedBlocksMap; + public final Collection renderedBlocks = new ObjectOpenHashSet<>(); private Consumer beforeRender; private Consumer afterRender; private Consumer onLookingAt; @@ -73,7 +73,6 @@ public abstract class WorldSceneRenderer { public WorldSceneRenderer(World world) { this.world = world; - renderedBlocksMap = new LinkedHashMap<>(); } public WorldSceneRenderer setBeforeWorldRender(Consumer callback) { @@ -86,9 +85,9 @@ public WorldSceneRenderer setAfterWorldRender(Consumer callb return this; } - public WorldSceneRenderer addRenderedBlocks(Collection blocks, ISceneRenderHook renderHook) { + public WorldSceneRenderer addRenderedBlocks(@Nullable Collection blocks) { if (blocks != null) { - this.renderedBlocksMap.put(blocks, renderHook); + this.renderedBlocks.addAll(blocks); } return this; } @@ -240,31 +239,24 @@ protected void drawWorld() { for (BlockRenderLayer layer : BlockRenderLayer.values()) { ForgeHooksClient.setRenderLayer(layer); int pass = layer == BlockRenderLayer.TRANSLUCENT ? 1 : 0; + setDefaultPassRenderState(pass); - renderedBlocksMap.forEach((renderedBlocks, hook) -> { - if (hook != null) { - hook.apply(false, pass, layer); - } else { - setDefaultPassRenderState(pass); - } + BufferBuilder buffer = Tessellator.getInstance().getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + BlockRendererDispatcher blockrendererdispatcher = mc.getBlockRendererDispatcher(); - BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - BlockRendererDispatcher blockrendererdispatcher = mc.getBlockRendererDispatcher(); - - for (BlockPos pos : renderedBlocks) { - IBlockState state = world.getBlockState(pos); - Block block = state.getBlock(); - if (block == Blocks.AIR) continue; - state = state.getActualState(world, pos); - if (block.canRenderInLayer(state, layer)) { - blockrendererdispatcher.renderBlock(state, pos, world, buffer); - } + for (BlockPos pos : renderedBlocks) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + if (block == Blocks.AIR) continue; + state = state.getActualState(world, pos); + if (block.canRenderInLayer(state, layer)) { + blockrendererdispatcher.renderBlock(state, pos, world, buffer); } + } - Tessellator.getInstance().draw(); - Tessellator.getInstance().getBuffer().setTranslation(0, 0, 0); - }); + Tessellator.getInstance().draw(); + Tessellator.getInstance().getBuffer().setTranslation(0, 0, 0); } } finally { ForgeHooksClient.setRenderLayer(oldRenderLayer); @@ -276,22 +268,15 @@ protected void drawWorld() { // render TESR for (int pass = 0; pass < 2; pass++) { ForgeHooksClient.setRenderPass(pass); - int finalPass = pass; - renderedBlocksMap.forEach((renderedBlocks, hook) -> { - if (hook != null) { - hook.apply(true, finalPass, null); - } else { - setDefaultPassRenderState(finalPass); - } - for (BlockPos pos : renderedBlocks) { - TileEntity tile = world.getTileEntity(pos); - if (tile != null) { - if (tile.shouldRenderInPass(finalPass)) { - TileEntityRendererDispatcher.instance.render(tile, pos.getX(), pos.getY(), pos.getZ(), 0); - } + setDefaultPassRenderState(pass); + for (BlockPos pos : renderedBlocks) { + TileEntity tile = world.getTileEntity(pos); + if (tile != null) { + if (tile.shouldRenderInPass(pass)) { + TileEntityRendererDispatcher.instance.render(tile, pos.getX(), pos.getY(), pos.getZ(), 0); } } - }); + } } ForgeHooksClient.setRenderPass(-1); GlStateManager.enableDepth(); diff --git a/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java b/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java index 7c3da2f0166..694dcc04f5e 100644 --- a/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java @@ -104,7 +104,7 @@ private void createWorldScene() { TrackedDummyWorld dummyWorld = new TrackedDummyWorld(world); dummyWorld.setRenderFilter(pos -> validPos.contains(pos)); worldSceneRenderer = new FBOWorldSceneRenderer(dummyWorld, FBO); - worldSceneRenderer.addRenderedBlocks(validPos, null); + worldSceneRenderer.addRenderedBlocks(validPos); center = new Vector3f((minX + maxX) / 2f + 0.5f, (minY + maxY) / 2f + 0.5f, (minZ + maxZ) / 2f + 0.5f); worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java index b746f67a2cd..1e5dd465b99 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java @@ -217,7 +217,7 @@ private void setNextLayer(int newLayer) { if (renderer != null) { TrackedDummyWorld world = ((TrackedDummyWorld) renderer.world); resetCenter(world); - renderer.renderedBlocksMap.clear(); + renderer.renderedBlocks.clear(); int minY = (int) world.getMinPos().getY(); Collection renderBlocks; if (newLayer == -1) { @@ -226,7 +226,7 @@ private void setNextLayer(int newLayer) { renderBlocks = world.renderedBlocks.stream().filter(pos -> pos.getY() - minY == newLayer) .collect(Collectors.toSet()); } - renderer.addRenderedBlocks(renderBlocks, null); + renderer.addRenderedBlocks(renderBlocks); } } @@ -593,7 +593,7 @@ private MBPattern initializePattern(@NotNull MultiblockShapeInfo shapeInfo, @Not Vector3f minPos = world.getMinPos(); center = new Vector3f(minPos.x + size.x / 2, minPos.y + size.y / 2, minPos.z + size.z / 2); - worldSceneRenderer.addRenderedBlocks(world.renderedBlocks, null); + worldSceneRenderer.addRenderedBlocks(world.renderedBlocks); worldSceneRenderer.setOnLookingAt(ray -> {}); worldSceneRenderer.setAfterWorldRender(renderer -> { @@ -607,8 +607,7 @@ private MBPattern initializePattern(@NotNull MultiblockShapeInfo shapeInfo, @Not renderBlockOverLay(selected, 255, 0, 0); }); world.updateEntities(); - world.setRenderFilter( - pos -> worldSceneRenderer.renderedBlocksMap.keySet().stream().anyMatch(c -> c.contains(pos))); + world.setRenderFilter(worldSceneRenderer.renderedBlocks::contains); Map predicateMap = new HashMap<>(); if (controllerBase != null) { From e5c8da610bd67173d0cc6291a38cbbb86cd819f2 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:40:26 -0700 Subject: [PATCH 08/15] Improve Logging (again) for Unread Packet Data (#2705) --- .../api/metatileentity/MetaTileEntity.java | 8 +-- .../metatileentity/SyncedTileEntityBase.java | 15 ++--- .../interfaces/ISyncedTileEntity.java | 58 ++++++++++++++----- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index c89fe48379d..862d2b5f351 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -1083,10 +1083,8 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { if (trait == null) { GTLog.logger.warn("Could not find MTETrait for id: {} at position {}.", traitNetworkId, getPos()); } else { + ISyncedTileEntity.addCode(internalId, trait); trait.receiveCustomData(internalId, buf); - - // this should be fine, as nothing else is read after this - ISyncedTileEntity.checkCustomData(internalId, buf, trait); } } else if (dataId == COVER_ATTACHED_MTE) { CoverSaveHandler.readCoverPlacement(buf, this); @@ -1102,10 +1100,8 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { Cover cover = getCoverAtSide(coverSide); int internalId = buf.readVarInt(); if (cover != null) { + ISyncedTileEntity.addCode(internalId, cover); cover.readCustomData(internalId, buf); - - // this should be fine, as nothing else is read after this - ISyncedTileEntity.checkCustomData(internalId, buf, cover); } } else if (dataId == UPDATE_SOUND_MUFFLED) { this.muffled = buf.readBoolean(); diff --git a/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java b/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java index 9b42003a0dc..fbcf0a179fe 100644 --- a/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java +++ b/src/main/java/gregtech/api/metatileentity/SyncedTileEntityBase.java @@ -1,7 +1,6 @@ package gregtech.api.metatileentity; import gregtech.api.block.BlockStateTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.interfaces.ISyncedTileEntity; import gregtech.api.network.PacketDataList; @@ -80,12 +79,9 @@ public final void onDataPacket(@NotNull NetworkManager net, @NotNull SPacketUpda for (String discriminatorKey : entryTag.getKeySet()) { ByteBuf backedBuffer = Unpooled.copiedBuffer(entryTag.getByteArray(discriminatorKey)); int dataId = Integer.parseInt(discriminatorKey); + ISyncedTileEntity.addCode(dataId, this); receiveCustomData(dataId, new PacketBuffer(backedBuffer)); - - MetaTileEntity mte = null; - if (this instanceof IGregTechTileEntity gtte) - mte = gtte.getMetaTileEntity(); - ISyncedTileEntity.checkCustomData(dataId, backedBuffer, mte == null ? this : mte); + ISyncedTileEntity.checkData(backedBuffer); } } } @@ -105,11 +101,8 @@ public final void handleUpdateTag(@NotNull NBTTagCompound tag) { super.readFromNBT(tag); // deserializes Forge data and capabilities byte[] updateData = tag.getByteArray("d"); ByteBuf backedBuffer = Unpooled.copiedBuffer(updateData); + ISyncedTileEntity.track(this); receiveInitialSyncData(new PacketBuffer(backedBuffer)); - - MetaTileEntity mte = null; - if (this instanceof IGregTechTileEntity gtte) - mte = gtte.getMetaTileEntity(); - ISyncedTileEntity.checkInitialData(backedBuffer, mte == null ? this : mte); + ISyncedTileEntity.checkData(backedBuffer); } } diff --git a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java index 97bff58419b..47b28ba4a03 100644 --- a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java @@ -10,6 +10,8 @@ import net.minecraft.util.math.BlockPos; import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -20,6 +22,8 @@ public interface ISyncedTileEntity { Consumer NO_OP = buf -> {}; + IntList datacodes = new IntArrayList(); + ThreadLocal tracked = ThreadLocal.withInitial(() -> null); /** * Used to sync data from Server -> Client. @@ -119,26 +123,25 @@ default void writeCustomData(int discriminator) { */ void receiveCustomData(int discriminator, @NotNull PacketBuffer buf); - static void checkCustomData(int discriminator, @NotNull ByteBuf buf, Object obj) { - if (buf.readableBytes() == 0) return; - - GTLog.logger.error( - "Class {} failed to finish reading receiveCustomData with discriminator {} and {} bytes remaining", - stringify(obj), GregtechDataCodes.getNameFor(discriminator), buf.readableBytes()); - - buf.clear(); // clear to prevent further logging - } - - static void checkInitialData(@NotNull ByteBuf buf, Object obj) { - if (buf.readableBytes() == 0) return; - - GTLog.logger.error("Class {} failed to finish reading initialSyncData with {} bytes remaining", - stringify(obj), buf.readableBytes()); + static void checkData(@NotNull ByteBuf buf) { + if (buf.readableBytes() != 0) { + if (datacodes.isEmpty()) { + GTLog.logger.error("Class {} failed to finish reading initialSyncData with {} bytes remaining", + stringify(tracked.get()), buf.readableBytes()); + } else { + GTLog.logger.error( + "Class {} failed to finish reading receiveCustomData at code path [{}] with {} bytes remaining", + stringify(tracked.get()), getCodePath(), buf.readableBytes()); + } + } - buf.clear(); // clear to prevent further logging + reset(); } static String stringify(Object obj) { + if (obj instanceof IGregTechTileEntity gtte && gtte.getMetaTileEntity() != null) + obj = gtte.getMetaTileEntity(); + StringBuilder builder = new StringBuilder(obj.getClass().getSimpleName()); BlockPos pos = null; @@ -158,4 +161,27 @@ static String stringify(Object obj) { return builder.toString(); } + + static void addCode(int code, Object trackedObject) { + datacodes.add(code); + track(trackedObject); + } + + static void track(Object trackedObject) { + tracked.set(trackedObject); + } + + static String getCodePath() { + var builder = new StringBuilder(); + for (int i = 0; i < datacodes.size(); i++) { + builder.append(GregtechDataCodes.getNameFor(datacodes.get(i))); + if (i < datacodes.size() - 1) builder.append(" > "); + } + return builder.toString(); + } + + static void reset() { + datacodes.clear(); + tracked.remove(); + } } From 0f12184d652415a3c50e5d25173ece2de1409d80 Mon Sep 17 00:00:00 2001 From: ALongStringOfNumbers <31759736+ALongStringOfNumbers@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:42:02 -0700 Subject: [PATCH 09/15] =?UTF-8?q?Prevent=20Grid=20from=20rendering=20when?= =?UTF-8?q?=20holding=20a=20cover=20when=20block=20takes=20no=20=E2=80=A6?= =?UTF-8?q?=20(#2710)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/metatileentity/MetaTileEntity.java | 2 +- .../metatileentities/MetaTileEntityClipboard.java | 5 +++++ .../storage/MetaTileEntityWorkbench.java | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 862d2b5f351..eada02187ab 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -737,7 +737,7 @@ public boolean canPlaceCoverOnSide(@NotNull EnumFacing side) { } @Override - public final boolean acceptsCovers() { + public boolean acceptsCovers() { return covers.size() < EnumFacing.VALUES.length; } diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java index a50a2978aae..02fbe96793d 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java @@ -529,6 +529,11 @@ public boolean canPlaceCoverOnSide(@NotNull EnumFacing side) { return false; } + @Override + public boolean acceptsCovers() { + return false; + } + @Override public boolean canRenderMachineGrid(@NotNull ItemStack mainHandStack, @NotNull ItemStack offHandStack) { return false; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index bbfb8c2685e..44c92f8e11a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -5,8 +5,16 @@ import gregtech.api.gui.ModularUI.Builder; import gregtech.api.gui.Widget.ClickData; import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AbstractWidgetGroup; +import gregtech.api.gui.widgets.ClickButtonWidget; +import gregtech.api.gui.widgets.CraftingStationInputWidgetGroup; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.SimpleTextWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TabGroup; import gregtech.api.gui.widgets.TabGroup.TabLocation; +import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.gui.widgets.tab.ItemTabInfo; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -254,6 +262,11 @@ public boolean canPlaceCoverOnSide(@NotNull EnumFacing side) { return false; } + @Override + public boolean acceptsCovers() { + return false; + } + @Override public boolean canRenderMachineGrid(@NotNull ItemStack mainHandStack, @NotNull ItemStack offHandStack) { return false; From 71a2fe152bdc0714bddaa9457f68a8e71bed47ae Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:43:31 +1100 Subject: [PATCH 10/15] Fix Catalysts in Dichlorobenzidine and Diaminobenzidine (#2668) --- .../recipe/chemistry/PolymerRecipes.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/PolymerRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/PolymerRecipes.java index 7a1531eeb7c..7144f197c50 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/PolymerRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/PolymerRecipes.java @@ -366,28 +366,29 @@ private static void polybenzimidazoleProcess() { .buildAndRegister(); // 3,3-Diaminobenzidine - LARGE_CHEMICAL_RECIPES.recipeBuilder().EUt(VA[IV]).duration(100) + CHEMICAL_RECIPES.recipeBuilder().EUt(VA[IV]).duration(100) .fluidInputs(Dichlorobenzidine.getFluid(1000)) .fluidInputs(Ammonia.getFluid(2000)) - .notConsumable(dust, Zinc) + .input(dustTiny, Copper) .fluidOutputs(Diaminobenzidine.getFluid(1000)) .fluidOutputs(HydrochloricAcid.getFluid(2000)) .buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder().EUt(VA[EV]).duration(200) - .input(dustTiny, Copper) + LARGE_CHEMICAL_RECIPES.recipeBuilder().EUt(VA[IV]).duration(900) + .fluidInputs(Dichlorobenzidine.getFluid(9000)) + .fluidInputs(Ammonia.getFluid(18000)) + .input(dust, Copper) + .fluidOutputs(Diaminobenzidine.getFluid(9000)) + .fluidOutputs(HydrochloricAcid.getFluid(18000)) + .buildAndRegister(); + + LARGE_CHEMICAL_RECIPES.recipeBuilder().EUt(VA[EV]).duration(200) .fluidInputs(Nitrochlorobenzene.getFluid(2000)) .fluidInputs(Hydrogen.getFluid(2000)) + .notConsumable(dust, Zinc) .fluidOutputs(Dichlorobenzidine.getFluid(1000)) .buildAndRegister(); - LARGE_CHEMICAL_RECIPES.recipeBuilder().EUt(VA[EV]).duration(1800) - .input(dust, Copper) - .fluidInputs(Nitrochlorobenzene.getFluid(18000)) - .fluidInputs(Hydrogen.getFluid(18000)) - .fluidOutputs(Dichlorobenzidine.getFluid(9000)) - .buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder().EUt(VA[HV]).duration(100) .fluidInputs(NitrationMixture.getFluid(2000)) .fluidInputs(Chlorobenzene.getFluid(1000)) From 225a53fcd741f94264876a3955b43e4c8a316733 Mon Sep 17 00:00:00 2001 From: Ko_no <90126004+MrKono@users.noreply.github.com> Date: Tue, 4 Feb 2025 06:44:16 +0900 Subject: [PATCH 11/15] Add block recipes for materials that has only dust and block (#2628) --- .../loaders/recipe/handlers/MaterialRecipeHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index 3b048b093c6..56b9ea27cb4 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -160,6 +160,11 @@ public static void processDust(OrePrefix dustPrefix, Material mat, DustProperty .inputs(dustStack) .outputs(OreDictUnifier.get(OrePrefix.plate, mat)) .buildAndRegister(); + } else if (!OreDictUnifier.get(block, mat).isEmpty()) { + COMPRESSOR_RECIPES.recipeBuilder() + .input(dust, mat, (int) (block.getMaterialAmount(mat) / M)) + .output(block, mat) + .duration(300).EUt(2).buildAndRegister(); } // Some Ores with Direct Smelting Results have neither ingot nor gem properties From 32d2c2dab64a971d9e5df96c87e73d0f99147c88 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:47:40 -0700 Subject: [PATCH 12/15] Fix Negative EUt in TOP (#2666) --- .../capability/impl/AbstractRecipeLogic.java | 35 +++++++++++++++---- .../capability/impl/BoilerRecipeLogic.java | 7 ++++ .../impl/MultiblockFuelRecipeLogic.java | 16 ++------- .../impl/MultiblockRecipeLogic.java | 28 ++------------- .../capability/impl/RecipeLogicEnergy.java | 29 ++------------- .../multiblock/FuelMultiblockController.java | 2 +- .../multiblock/MultiblockDisplayText.java | 2 +- 7 files changed, 44 insertions(+), 75 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index 455ae3afd47..23018a736ca 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.IMultiblockController; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.IWorkable; @@ -101,17 +102,27 @@ public AbstractRecipeLogic(MetaTileEntity tileEntity, RecipeMap recipeMap, bo /** * @return the energy container's energy input per second */ - protected abstract long getEnergyInputPerSecond(); + protected long getEnergyInputPerSecond() { + return getEnergyContainer().getInputPerSec(); + } /** * @return the energy container's current stored energy */ - protected abstract long getEnergyStored(); + protected long getEnergyStored() { + return getEnergyContainer().getEnergyStored(); + } /** * @return the energy container's maximum energy capacity */ - protected abstract long getEnergyCapacity(); + protected long getEnergyCapacity() { + return getEnergyContainer().getEnergyCapacity(); + } + + protected IEnergyContainer getEnergyContainer() { + return IEnergyContainer.DEFAULT; + } /** * Draw energy from the energy container @@ -120,12 +131,22 @@ public AbstractRecipeLogic(MetaTileEntity tileEntity, RecipeMap recipeMap, bo * @param simulate whether to simulate energy extraction or not * @return true if the energy can/was drained, otherwise false */ - protected abstract boolean drawEnergy(long recipeEUt, boolean simulate); + protected boolean drawEnergy(long recipeEUt, boolean simulate) { + // this should be the ONLY time eut is negative! + if (consumesEnergy()) recipeEUt = -recipeEUt; + long resultEnergy = getEnergyStored() + recipeEUt; + if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { + if (!simulate) getEnergyContainer().changeEnergy(recipeEUt); + return true; + } else return false; + } /** * @return the maximum voltage the machine can use/handle for recipe searching */ - public abstract long getMaxVoltage(); + public long getMaxVoltage() { + return Math.max(getEnergyContainer().getInputVoltage(), getEnergyContainer().getOutputVoltage()); + } /** * @@ -941,7 +962,7 @@ public String[] getAvailableOverclockingTiers() { protected void setupRecipe(@NotNull Recipe recipe) { this.progressTime = 1; setMaxProgress(ocResult.duration()); - this.recipeEUt = consumesEnergy() ? ocResult.eut() : -ocResult.eut(); + this.recipeEUt = ocResult.eut(); int recipeTier = GTUtility.getTierByVoltage(recipe.getEUt()); int machineTier = getOverclockForTier(getMaximumOverclockVoltage()); @@ -1226,7 +1247,7 @@ public void deserializeNBT(@NotNull NBTTagCompound compound) { if (progressTime > 0) { this.isActive = true; this.maxProgressTime = compound.getInteger("MaxProgress"); - this.recipeEUt = compound.getLong("RecipeEUt"); + this.recipeEUt = Math.abs(compound.getLong("RecipeEUt")); NBTTagList itemOutputsList = compound.getTagList("ItemOutputs", Constants.NBT.TAG_COMPOUND); this.itemOutputs = new ArrayList<>(itemOutputsList.tagCount()); for (int i = 0; i < itemOutputsList.tagCount(); i++) { diff --git a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java index 28b2ee7afd0..a2163db4637 100644 --- a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java @@ -1,6 +1,7 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; +import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.IMultiblockController; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.recipes.Recipe; @@ -330,6 +331,12 @@ public long getMaxVoltage() { return 0; } + @Override + protected IEnergyContainer getEnergyContainer() { + GTLog.logger.error("Large Boiler called getEnergyContainer(), this should not be possible!"); + return super.getEnergyContainer(); + } + /** * @param fluidHandler the handler to drain from * @param amount the amount to drain diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java index 30c5e5410e3..4c374985014 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java @@ -95,19 +95,9 @@ protected long boostProduction(long production) { } @Override - protected boolean drawEnergy(long recipeEUt, boolean simulate) { - long euToDraw = boostProduction(recipeEUt); - long resultEnergy = getEnergyStored() - euToDraw; - if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { - if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); - return true; - } - return false; - } - - @Override - public long getInfoProviderEUt() { - return boostProduction(super.getInfoProviderEUt()); + protected void setupRecipe(@NotNull Recipe recipe) { + super.setupRecipe(recipe); + this.recipeEUt = boostProduction(this.recipeEUt); } @Override diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index ff95f0fbb0c..728ed138cc9 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -384,35 +384,11 @@ protected void performMufflerOperations() { } } - @Override - protected long getEnergyInputPerSecond() { - return getEnergyContainer().getInputPerSec(); - } - - @Override - protected long getEnergyStored() { - return getEnergyContainer().getEnergyStored(); - } - - @Override - protected long getEnergyCapacity() { - return getEnergyContainer().getEnergyCapacity(); - } - - @Override - protected boolean drawEnergy(long recipeEUt, boolean simulate) { - long resultEnergy = getEnergyStored() - recipeEUt; - if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { - if (!simulate) getEnergyContainer().changeEnergy(-recipeEUt); - return true; - } else return false; - } - @Override public long getMaxVoltage() { IEnergyContainer energyContainer = getEnergyContainer(); if (!consumesEnergy()) { - // Generators + // Generator Multiblocks long voltage = energyContainer.getOutputVoltage(); long amperage = energyContainer.getOutputAmperage(); if (energyContainer instanceof EnergyContainerList && amperage == 1) { @@ -424,7 +400,7 @@ public long getMaxVoltage() { } return voltage; } else { - // Machines + // Machine Multiblocks if (energyContainer instanceof EnergyContainerList energyList) { long highestVoltage = energyList.getHighestInputVoltage(); if (energyList.getNumHighestInputContainers() > 1) { diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java index 8460b2a7aa7..f94b239ecc6 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java @@ -25,33 +25,8 @@ public RecipeLogicEnergy(MetaTileEntity tileEntity, RecipeMap recipeMap, } @Override - protected long getEnergyInputPerSecond() { - return energyContainer.get().getInputPerSec(); - } - - @Override - protected long getEnergyStored() { - return energyContainer.get().getEnergyStored(); - } - - @Override - protected long getEnergyCapacity() { - return energyContainer.get().getEnergyCapacity(); - } - - @Override - protected boolean drawEnergy(long recipeEUt, boolean simulate) { - long resultEnergy = getEnergyStored() - recipeEUt; - if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { - if (!simulate) energyContainer.get().changeEnergy(-recipeEUt); - return true; - } - return false; - } - - @Override - public long getMaxVoltage() { - return Math.max(energyContainer.get().getInputVoltage(), energyContainer.get().getOutputVoltage()); + protected IEnergyContainer getEnergyContainer() { + return energyContainer.get(); } @Override diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java index 790a150ec0c..fb3a1993fc2 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java @@ -72,7 +72,7 @@ protected boolean isDynamoTierTooLow() { IEnergyContainer energyContainer = recipeMapWorkable.getEnergyContainer(); if (energyContainer != null && energyContainer.getEnergyCapacity() > 0) { long maxVoltage = Math.max(energyContainer.getInputVoltage(), energyContainer.getOutputVoltage()); - return maxVoltage < -recipeMapWorkable.getRecipeEUt(); + return maxVoltage < recipeMapWorkable.getRecipeEUt(); } } return false; diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java index 9127d5ca68c..e7b5d68e6d2 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java @@ -155,7 +155,7 @@ public Builder addEnergyUsageExactLine(long energyUsage) { */ public Builder addEnergyProductionLine(long maxVoltage, long recipeEUt) { if (!isStructureFormed) return this; - if (maxVoltage != 0 && maxVoltage >= -recipeEUt) { + if (maxVoltage != 0 && maxVoltage >= recipeEUt) { String energyFormatted = TextFormattingUtil.formatNumbers(maxVoltage); // wrap in text component to keep it from being formatted ITextComponent voltageName = new TextComponentString( From ae65dfe7efb3a3289b23d5c397b8963a7e854dc0 Mon Sep 17 00:00:00 2001 From: Maya <10861407+serenibyss@users.noreply.github.com> Date: Mon, 3 Feb 2025 15:57:39 -0600 Subject: [PATCH 13/15] High-tier fixes (#2497) --- src/main/java/gregtech/api/GTValues.java | 13 ++- .../metatileentities/MetaTileEntities.java | 105 +++++++++++------- .../MetaTileEntityEnergyHatch.java | 8 +- .../MetaTileEntityFluidHatch.java | 20 +++- .../multiblockpart/MetaTileEntityItemBus.java | 23 +++- .../MetaTileEntityLaserHatch.java | 6 +- .../MetaTileEntityMufflerHatch.java | 2 +- .../MetaTileEntityMultiFluidHatch.java | 29 ++++- .../resources/assets/gregtech/lang/en_us.lang | 70 ++++++++++++ .../items/metaitems/conveyor.module.uiv.png | Bin 5230 -> 1977 bytes .../items/metaitems/conveyor.module.uxv.png | Bin 5232 -> 1971 bytes .../items/metaitems/electric.motor.uiv.png | Bin 5290 -> 2013 bytes .../items/metaitems/electric.motor.uxv.png | Bin 5324 -> 2019 bytes .../items/metaitems/electric.piston.uiv.png | Bin 5502 -> 2048 bytes .../items/metaitems/electric.piston.uxv.png | Bin 5465 -> 2043 bytes .../items/metaitems/electric.pump.uiv.png | Bin 5546 -> 2131 bytes .../items/metaitems/electric.pump.uxv.png | Bin 5564 -> 2117 bytes .../textures/items/metaitems/emitter.uiv.png | Bin 5815 -> 2342 bytes .../textures/items/metaitems/emitter.uxv.png | Bin 5840 -> 2335 bytes .../items/metaitems/field.generator.uiv.png | Bin 6648 -> 2851 bytes .../items/metaitems/field.generator.uxv.png | Bin 6641 -> 2869 bytes .../items/metaitems/robot.arm.uiv.png | Bin 5471 -> 2085 bytes .../items/metaitems/robot.arm.uxv.png | Bin 5500 -> 2080 bytes .../textures/items/metaitems/sensor.uiv.png | Bin 5764 -> 2327 bytes .../textures/items/metaitems/sensor.uxv.png | Bin 5787 -> 2326 bytes 25 files changed, 220 insertions(+), 56 deletions(-) diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 9d3bb3f2534..b530c0d468d 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -122,11 +122,12 @@ public class GTValues { * The short names for the voltages, formatted for text */ public static final String[] VNF = new String[] { - DARK_GRAY + "ULV", GRAY + "LV", AQUA + "MV", - GOLD + "HV", DARK_PURPLE + "EV", DARK_BLUE + "IV", - LIGHT_PURPLE + "LuV", RED + "ZPM", DARK_AQUA + "UV", - DARK_RED + "UHV", GREEN + "UEV", DARK_GREEN + "UIV", - YELLOW + "UXV", BLUE + "OpV", RED.toString() + BOLD + "MAX" }; + RED + "ULV", GRAY + "LV", GOLD + "MV", + YELLOW + "HV", DARK_GRAY + "EV", WHITE + "IV", + LIGHT_PURPLE + "LuV", AQUA + "ZPM", DARK_GREEN + "UV", + DARK_RED + "UHV", DARK_BLUE + "UEV", DARK_GREEN.toString() + BOLD + "UIV", + DARK_PURPLE.toString() + BOLD + "UXV", DARK_RED.toString() + BOLD + "OpV", + RED.toString() + BOLD + "MAX" }; /** * The short names for the voltages, up to max Long, formatted for text @@ -146,7 +147,7 @@ public class GTValues { * Color values for the voltages */ public static final int[] VC = new int[] { 0xC80000, 0xDCDCDC, 0xFF6400, 0xFFFF1E, 0x808080, 0xF0F0F5, 0xE99797, - 0x7EC3C4, 0x7EB07E, 0xBF74C0, 0x0B5CFE, 0x914E91, 0x488748, 0x8C0000, 0x2828F5 }; + 0x7EC3C4, 0x7EB07E, 0xBF74C0, 0x0B5CFE, 0x488748, 0x914E91, 0x8C0000, 0x2828F5 }; /** * The long names for the voltages diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index dbe94985456..1f13381b386 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.capability.FeCompat; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity; import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; @@ -206,24 +207,24 @@ public class MetaTileEntities { public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; // MULTIBLOCK PARTS SECTION - public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV - public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; - public static final MetaTileEntityFluidHatch[] FLUID_IMPORT_HATCH = new MetaTileEntityFluidHatch[GTValues.UHV + 1]; - public static final MetaTileEntityFluidHatch[] FLUID_EXPORT_HATCH = new MetaTileEntityFluidHatch[GTValues.UHV + 1]; - public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_IMPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV - public static final MetaTileEntityMultiFluidHatch[] NONUPLE_IMPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV - public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV - public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV + public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.V.length - 1]; // All tiers but MAX + public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.V.length - 1]; + public static final MetaTileEntityFluidHatch[] FLUID_IMPORT_HATCH = new MetaTileEntityFluidHatch[GTValues.V.length - 1]; + public static final MetaTileEntityFluidHatch[] FLUID_EXPORT_HATCH = new MetaTileEntityFluidHatch[GTValues.V.length - 1]; + public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_IMPORT_HATCH = new MetaTileEntityMultiFluidHatch[11]; // EV+ + public static final MetaTileEntityMultiFluidHatch[] NONUPLE_IMPORT_HATCH = new MetaTileEntityMultiFluidHatch[11]; // EV+ + public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[11]; // EV+ + public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[11]; // EV+ public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[11]; // EV+ + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[10]; // IV+ public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[11]; // EV+ + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[10]; // IV+ + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[10]; // IV+ + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[10]; // IV+ public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, ZPM, UV - public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV + public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UHV + 1]; // LV-UHV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static MetaTileEntityQuantumStorageController QUANTUM_STORAGE_CONTROLLER; public static MetaTileEntityQuantumProxy QUANTUM_STORAGE_PROXY; @@ -378,6 +379,7 @@ public class MetaTileEntities { public static MetaTileEntityLDFluidEndpoint LONG_DIST_FLUID_ENDPOINT; public static MetaTileEntityAlarm ALARM; + // todo public static MetaTileEntityConverter[][] ENERGY_CONVERTER = new MetaTileEntityConverter[4][GTValues.V.length]; //spotless:on @@ -783,7 +785,8 @@ public static void init() { // MISC MTE's START: IDs 1150-2000 // Import/Export Buses/Hatches, IDs 1150-1209 - for (int i = 0; i < ITEM_IMPORT_BUS.length; i++) { + endPos = GregTechAPI.isHighTier() ? ITEM_IMPORT_BUS.length : GTValues.UHV; + for (int i = 0; i < endPos; i++) { String voltageName = GTValues.VN[i].toLowerCase(); ITEM_IMPORT_BUS[i] = new MetaTileEntityItemBus(gregtechId("item_bus.import." + voltageName), i, false); ITEM_EXPORT_BUS[i] = new MetaTileEntityItemBus(gregtechId("item_bus.export." + voltageName), i, true); @@ -792,15 +795,22 @@ public static void init() { FLUID_EXPORT_HATCH[i] = new MetaTileEntityFluidHatch(gregtechId("fluid_hatch.export." + voltageName), i, true); - registerMetaTileEntity(1150 + i, ITEM_IMPORT_BUS[i]); - registerMetaTileEntity(1165 + i, ITEM_EXPORT_BUS[i]); - registerMetaTileEntity(1180 + i, FLUID_IMPORT_HATCH[i]); - registerMetaTileEntity(1195 + i, FLUID_EXPORT_HATCH[i]); + if (i <= GTValues.UHV) { + registerMetaTileEntity(1150 + i, ITEM_IMPORT_BUS[i]); + registerMetaTileEntity(1165 + i, ITEM_EXPORT_BUS[i]); + registerMetaTileEntity(1180 + i, FLUID_IMPORT_HATCH[i]); + registerMetaTileEntity(1195 + i, FLUID_EXPORT_HATCH[i]); + } else { + registerMetaTileEntity(1850 + i, ITEM_IMPORT_BUS[i]); + registerMetaTileEntity(1855 + i, ITEM_EXPORT_BUS[i]); + registerMetaTileEntity(1860 + i, FLUID_IMPORT_HATCH[i]); + registerMetaTileEntity(1865 + i, FLUID_EXPORT_HATCH[i]); + } } // IDs 1190, 1191, 1205, and 1206 reserved for multi-fluid hatches - // Energy Input/Output Hatches, IDs 1210-1269 + // Energy Input/Output Hatches, IDs 1210-1269, 1800-1829 endPos = GregTechAPI.isHighTier() ? ENERGY_INPUT_HATCH.length - 1 : Math.min(ENERGY_INPUT_HATCH.length - 1, GTValues.UV + 2); for (int i = 0; i < endPos; i++) { @@ -810,21 +820,23 @@ public static void init() { ENERGY_OUTPUT_HATCH[i] = registerMetaTileEntity(1225 + i, new MetaTileEntityEnergyHatch(gregtechId("energy_hatch.output." + voltageName), i, 2, true)); - if (i >= GTValues.IV && i <= GTValues.UHV) { - ENERGY_INPUT_HATCH_4A[i + 1 - GTValues.IV] = registerMetaTileEntity(1240 + i - GTValues.IV, + if (i >= GTValues.IV) { + int baseId = (i <= GTValues.UHV ? 1240 : 1820); + + ENERGY_INPUT_HATCH_4A[i + 1 - GTValues.IV] = registerMetaTileEntity(baseId + i - GTValues.IV, new MetaTileEntityEnergyHatch(gregtechId("energy_hatch.input_4a." + voltageName), i, 4, false)); - ENERGY_INPUT_HATCH_16A[i - GTValues.IV] = registerMetaTileEntity(1245 + i - GTValues.IV, + ENERGY_INPUT_HATCH_16A[i - GTValues.IV] = registerMetaTileEntity(baseId + 5 + i - GTValues.IV, new MetaTileEntityEnergyHatch(gregtechId("energy_hatch.input_16a." + voltageName), i, 16, false)); - ENERGY_OUTPUT_HATCH_4A[i + 1 - GTValues.IV] = registerMetaTileEntity(1250 + i - GTValues.IV, + ENERGY_OUTPUT_HATCH_4A[i + 1 - GTValues.IV] = registerMetaTileEntity(baseId + 10 + i - GTValues.IV, new MetaTileEntityEnergyHatch(gregtechId("energy_hatch.output_4a." + voltageName), i, 4, true)); - ENERGY_OUTPUT_HATCH_16A[i - GTValues.IV] = registerMetaTileEntity(1255 + i - GTValues.IV, + ENERGY_OUTPUT_HATCH_16A[i - GTValues.IV] = registerMetaTileEntity(baseId + 15 + i - GTValues.IV, new MetaTileEntityEnergyHatch(gregtechId("energy_hatch.output_16a." + voltageName), i, 16, true)); - SUBSTATION_ENERGY_INPUT_HATCH[i - GTValues.IV] = registerMetaTileEntity(1260 + i - GTValues.IV, + SUBSTATION_ENERGY_INPUT_HATCH[i - GTValues.IV] = registerMetaTileEntity(baseId + 20 + i - GTValues.IV, new MetaTileEntitySubstationEnergyHatch(gregtechId("substation_hatch.input_64a." + voltageName), i, 64, false)); - SUBSTATION_ENERGY_OUTPUT_HATCH[i - GTValues.IV] = registerMetaTileEntity(1265 + i - GTValues.IV, + SUBSTATION_ENERGY_OUTPUT_HATCH[i - GTValues.IV] = registerMetaTileEntity(baseId + 25 + i - GTValues.IV, new MetaTileEntitySubstationEnergyHatch( gregtechId("substation_hatch.output_64a." + voltageName), i, 64, true)); } @@ -860,8 +872,7 @@ public static void init() { } // Battery Buffer, IDs 1315-1360 - endPos = GregTechAPI.isHighTier() ? BATTERY_BUFFER[0].length - 1 : - Math.min(BATTERY_BUFFER[0].length - 1, GTValues.UHV + 1); + endPos = GregTechAPI.isHighTier() ? BATTERY_BUFFER[0].length : GTValues.UHV + 1; int[] batteryBufferSlots = new int[] { 4, 8, 16 }; for (int slot = 0; slot < batteryBufferSlots.length; slot++) { BATTERY_BUFFER[slot] = new MetaTileEntityBatteryBuffer[endPos]; @@ -875,7 +886,7 @@ public static void init() { } // Charger, IDs 1375-1389 - endPos = GregTechAPI.isHighTier() ? CHARGER.length - 1 : Math.min(CHARGER.length - 1, GTValues.UHV + 1); + endPos = GregTechAPI.isHighTier() ? CHARGER.length : GTValues.UHV + 1; for (int i = 0; i < endPos; i++) { String chargerId = "charger." + GTValues.VN[i].toLowerCase(); MetaTileEntityCharger charger = new MetaTileEntityCharger(gregtechId(chargerId), i, 4); @@ -1111,9 +1122,10 @@ public static void init() { CLEANING_MAINTENANCE_HATCH = registerMetaTileEntity(1401, new MetaTileEntityCleaningMaintenanceHatch(gregtechId("maintenance_hatch_cleanroom_auto"))); - // Muffler Hatches, IDs 1657-1664 + // Muffler Hatches, IDs 1657-1665 for (int i = 0; i < MUFFLER_HATCH.length - 1; i++) { int tier = i + 1; + if (!GregTechAPI.isHighTier() && tier == GTValues.UHV) continue; // requires UHV motor to craft, so skip String voltageName = GTValues.VN[tier].toLowerCase(); MUFFLER_HATCH[tier] = new MetaTileEntityMufflerHatch(gregtechId("muffler_hatch." + voltageName), tier); @@ -1129,11 +1141,20 @@ public static void init() { CREATIVE_TANK = registerMetaTileEntity(1669, new MetaTileEntityCreativeTank(gregtechId("creative_tank"))); // Energy Converter, IDs 1670-1729 - endPos = GregTechAPI.isHighTier() ? ENERGY_CONVERTER[0].length - 1 : - Math.min(ENERGY_CONVERTER[0].length - 1, GTValues.UHV + 1); + endPos = GregTechAPI.isHighTier() ? ENERGY_CONVERTER[0].length : GTValues.UHV + 1; int[] amps = { 1, 4, 8, 16 }; for (int i = 0; i < endPos; i++) { for (int j = 0; j < 4; j++) { + // Check to make sure this is a valid amount of power to be able to convert. + // Tests if both: + // - The maximum amount of EU/t of this converter can turn into FE without overflowing + // - Max int FE/t can convert to the full amount of EU/t without being short + // This is done because these ratios are configured separately. + long eu = amps[j] * GTValues.V[i]; + long euToFe = FeCompat.toFeLong(eu, FeCompat.ratio(false)); + long feToEu = FeCompat.toEu(Integer.MAX_VALUE, FeCompat.ratio(true)); + if (euToFe > Integer.MAX_VALUE || feToEu < eu) continue; + String id = "energy_converter." + GTValues.VN[i].toLowerCase() + "." + amps[j]; MetaTileEntityConverter converter = new MetaTileEntityConverter(gregtechId(id), i, amps[j]); ENERGY_CONVERTER[j][i] = registerMetaTileEntity(1670 + j + i * 4, converter); @@ -1171,7 +1192,7 @@ public static void init() { // IDs 1752-1756 are taken by AE2 parts - // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1799 + // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1819 // EV hatches separate because of old names/IDs QUADRUPLE_IMPORT_HATCH[0] = registerMetaTileEntity(1190, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.import_4x"), GTValues.EV, 4, false)); @@ -1181,19 +1202,23 @@ public static void init() { new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.export_4x"), GTValues.EV, 4, true)); NONUPLE_EXPORT_HATCH[0] = registerMetaTileEntity(1206, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.export_9x"), GTValues.EV, 9, true)); - for (int i = GTValues.IV; i <= GTValues.UHV; i++) { + for (int i = GTValues.IV; i <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); i++) { int index = i - GTValues.IV; + int startId = i > GTValues.UHV ? 1800 : 1780; String tierName = GTValues.VN[i].toLowerCase(); - QUADRUPLE_IMPORT_HATCH[index + 1] = registerMetaTileEntity(1780 + index, + QUADRUPLE_IMPORT_HATCH[index + 1] = registerMetaTileEntity(startId + index, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.import_4x." + tierName), i, 4, false)); - NONUPLE_IMPORT_HATCH[index + 1] = registerMetaTileEntity(1785 + index, + NONUPLE_IMPORT_HATCH[index + 1] = registerMetaTileEntity(startId + 5 + index, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.import_9x." + tierName), i, 9, false)); - QUADRUPLE_EXPORT_HATCH[index + 1] = registerMetaTileEntity(1790 + index, + QUADRUPLE_EXPORT_HATCH[index + 1] = registerMetaTileEntity(startId + 10 + index, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.export_4x." + tierName), i, 4, true)); - NONUPLE_EXPORT_HATCH[index + 1] = registerMetaTileEntity(1795 + index, + NONUPLE_EXPORT_HATCH[index + 1] = registerMetaTileEntity(startId + 15 + index, new MetaTileEntityMultiFluidHatch(gregtechId("fluid_hatch.export_9x." + tierName), i, 9, true)); } + // 1820-1849 are taken for UHV+ 4A/16A/64A Energy/Dynamo Hatches + // 1850-1869 are taken for UHV+ Input/Output Buses/Hatches + /* * FOR ADDON DEVELOPERS: * diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java index fd79fc8811d..5d0b13fc491 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java @@ -177,7 +177,7 @@ public boolean canRenderFrontFaceX() { @Override public void getSubItems(CreativeTabs creativeTab, NonNullList subItems) { // override here is gross, but keeps things in order despite - // IDs being out of order, due to EV 4A hatches being added later + // IDs being out of order, due to EV 4A and UEV+ 4A+ hatches being added later if (this == MetaTileEntities.ENERGY_INPUT_HATCH[0]) { for (MetaTileEntityEnergyHatch hatch : MetaTileEntities.ENERGY_INPUT_HATCH) { if (hatch != null) subItems.add(hatch.getStackForm()); @@ -203,7 +203,11 @@ public void getSubItems(CreativeTabs creativeTab, NonNullList subItem for (MetaTileEntityEnergyHatch hatch : MetaTileEntities.SUBSTATION_ENERGY_OUTPUT_HATCH) { if (hatch != null) subItems.add(hatch.getStackForm()); } - } + } else if (this.getClass() != MetaTileEntityEnergyHatch.class && + this.getClass() != MetaTileEntitySubstationEnergyHatch.class) { + // let subclasses fall through this override + super.getSubItems(creativeTab, subItems); + } } @Override 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 153c93bdb12..4cb1dd3003e 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -13,14 +13,17 @@ import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.metatileentities.MetaTileEntities; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; @@ -185,7 +188,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } protected int getInventorySize() { - return INITIAL_INVENTORY_SIZE * (1 << Math.min(9, getTier())); + return INITIAL_INVENTORY_SIZE * Math.min(Integer.MAX_VALUE, 1 << getTier()); } @Override @@ -338,6 +341,21 @@ private void setLocked(boolean locked) { fluidTank.onContentsChanged(); } + @Override + public void getSubItems(CreativeTabs creativeTab, NonNullList subItems) { + if (this == MetaTileEntities.FLUID_IMPORT_HATCH[0]) { + for (var hatch : MetaTileEntities.FLUID_IMPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + for (var hatch : MetaTileEntities.FLUID_EXPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + } else if (this.getClass() != MetaTileEntityFluidHatch.class) { + // let subclasses fall through this override + super.getSubItems(creativeTab, subItems); + } + } + protected class HatchFluidTank extends NotifiableFluidTank implements IFilteredFluidContainer, IFilter { public HatchFluidTank(int capacity, MetaTileEntity entityToNotify, boolean isExport) { 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 a549ccbf81f..37c145eab75 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart; +import gregtech.api.GTValues; import gregtech.api.capability.*; import gregtech.api.capability.impl.GhostCircuitItemStackHandler; import gregtech.api.capability.impl.ItemHandlerList; @@ -16,14 +17,17 @@ import gregtech.api.util.GTHashMaps; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; 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.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; @@ -180,7 +184,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } private int getInventorySize() { - int sizeRoot = 1 + Math.min(9, getTier()); + int sizeRoot = 1 + Math.min(GTValues.UHV, getTier()); return sizeRoot * sizeRoot; } @@ -453,4 +457,21 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t tooltip.add(I18n.format("gregtech.tool_action.wrench.set_facing")); super.addToolUsages(stack, world, tooltip, advanced); } + + @Override + public void getSubItems(CreativeTabs creativeTab, NonNullList subItems) { + // override here is gross, but keeps things in order despite + // IDs being out of order, due to UEV+ being added later + if (this == MetaTileEntities.ITEM_IMPORT_BUS[0]) { + for (var hatch : MetaTileEntities.ITEM_IMPORT_BUS) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + for (var hatch : MetaTileEntities.ITEM_EXPORT_BUS) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + } else if (this.getClass() != MetaTileEntityItemBus.class) { + // let subclasses fall through this override + super.getSubItems(creativeTab, subItems); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index f47d35c0377..3d594d4827d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -29,7 +29,7 @@ import java.util.List; import static gregtech.api.GTValues.V; -import static gregtech.api.GTValues.VN; +import static gregtech.api.GTValues.VNF; public class MetaTileEntityLaserHatch extends MetaTileEntityMultiblockPart implements IMultiblockAbilityPart, IDataInfoProvider { @@ -95,10 +95,10 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.machine.laser_hatch.tooltip2")); if (isOutput) { - tooltip.add(I18n.format("gregtech.universal.tooltip.voltage_out", V[tier], VN[tier])); + tooltip.add(I18n.format("gregtech.universal.tooltip.voltage_out", V[tier], VNF[tier])); tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_out_till", amperage)); } else { - tooltip.add(I18n.format("gregtech.universal.tooltip.voltage_in", V[tier], VN[tier])); + tooltip.add(I18n.format("gregtech.universal.tooltip.voltage_in", V[tier], VNF[tier])); tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in_till", amperage)); } tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", buffer.getEnergyCapacity())); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index d001b65d06a..3788ac57732 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -56,7 +56,7 @@ public class MetaTileEntityMufflerHatch extends MetaTileEntityMultiblockPart imp public MetaTileEntityMufflerHatch(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); - this.recoveryChance = Math.max(1, tier * 10); + this.recoveryChance = (int) Math.ceil((tier - 1.0f) / 8 * 100); this.inventory = new GTItemStackHandler(this, (int) Math.pow(tier + 1, 2)); this.frontFaceFree = false; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java index 6ac0ad4ee05..ff1b2341f32 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java @@ -1,6 +1,5 @@ package gregtech.common.metatileentities.multi.multiblockpart; -import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; @@ -13,13 +12,16 @@ import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.metatileentities.MetaTileEntities; import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; @@ -59,7 +61,7 @@ public MetaTileEntityMultiFluidHatch(ResourceLocation metaTileEntityId, int tier this.numSlots = numSlots; // Quadruple: 1/4th the capacity of a fluid hatch of this tier // Nonuple: 1/8th the capacity of a fluid hatch of this tier - this.tankSize = (BASE_TANK_SIZE * (1 << Math.min(GTValues.UHV, tier))) / (numSlots == 4 ? 4 : 8); + this.tankSize = BASE_TANK_SIZE * (1 << tier) / (numSlots == 4 ? 4 : 8); FluidTank[] fluidsHandlers = new FluidTank[numSlots]; for (int i = 0; i < fluidsHandlers.length; i++) { fluidsHandlers[i] = new NotifiableFluidTank(tankSize, this, isExportHatch); @@ -227,4 +229,27 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .coverChildren()) .bindPlayerInventory(); } + + @Override + public void getSubItems(CreativeTabs creativeTab, NonNullList subItems) { + // override here is gross, but keeps things in order despite + // IDs being out of order, due to IV+ hatches being added later + if (this == MetaTileEntities.QUADRUPLE_IMPORT_HATCH[0]) { + for (var hatch : MetaTileEntities.QUADRUPLE_IMPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + for (var hatch : MetaTileEntities.QUADRUPLE_EXPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + for (var hatch : MetaTileEntities.NONUPLE_IMPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + for (var hatch : MetaTileEntities.NONUPLE_EXPORT_HATCH) { + if (hatch != null) subItems.add(hatch.getStackForm()); + } + } else if (this.getClass() != MetaTileEntityMultiFluidHatch.class) { + // let subclasses fall through this override + super.getSubItems(creativeTab, subItems); + } + } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 65b2dc37bf0..56a674d293b 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5043,6 +5043,11 @@ gregtech.machine.item_bus.import.luv.name=LuV Input Bus gregtech.machine.item_bus.import.zpm.name=ZPM Input Bus gregtech.machine.item_bus.import.uv.name=UV Input Bus gregtech.machine.item_bus.import.uhv.name=UHV Input Bus +gregtech.machine.item_bus.import.uev.name=UEV Input Bus +gregtech.machine.item_bus.import.uiv.name=UIV Input Bus +gregtech.machine.item_bus.import.uxv.name=UXV Input Bus +gregtech.machine.item_bus.import.opv.name=OpV Input Bus +gregtech.machine.item_bus.import.max.name=MAX Input Bus gregtech.machine.item_bus.export.tooltip=Item Output for Multiblocks @@ -5056,6 +5061,11 @@ gregtech.machine.item_bus.export.luv.name=LuV Output Bus gregtech.machine.item_bus.export.zpm.name=ZPM Output Bus gregtech.machine.item_bus.export.uv.name=UV Output Bus gregtech.machine.item_bus.export.uhv.name=UHV Output Bus +gregtech.machine.item_bus.export.uev.name=UEV Output Bus +gregtech.machine.item_bus.export.uiv.name=UIV Output Bus +gregtech.machine.item_bus.export.uxv.name=UXV Output Bus +gregtech.machine.item_bus.export.opv.name=OpV Output Bus +gregtech.machine.item_bus.export.max.name=MAX Output Bus gregtech.bus.collapse_true=Bus will collapse Items gregtech.bus.collapse_false=Bus will not collapse Items @@ -5072,6 +5082,11 @@ gregtech.machine.fluid_hatch.import.luv.name=LuV Input Hatch gregtech.machine.fluid_hatch.import.zpm.name=ZPM Input Hatch gregtech.machine.fluid_hatch.import.uv.name=UV Input Hatch gregtech.machine.fluid_hatch.import.uhv.name=UHV Input Hatch +gregtech.machine.fluid_hatch.import.uev.name=UEV Input Hatch +gregtech.machine.fluid_hatch.import.uiv.name=UIV Input Hatch +gregtech.machine.fluid_hatch.import.uxv.name=UXV Input Hatch +gregtech.machine.fluid_hatch.import.opv.name=OpV Input Hatch +gregtech.machine.fluid_hatch.import.max.name=MAX Input Hatch gregtech.machine.fluid_hatch.export.tooltip=Fluid Output for Multiblocks @@ -5081,6 +5096,11 @@ gregtech.machine.fluid_hatch.import_4x.luv.name=LuV Quadruple Input Hatch gregtech.machine.fluid_hatch.import_4x.zpm.name=ZPM Quadruple Input Hatch gregtech.machine.fluid_hatch.import_4x.uv.name=UV Quadruple Input Hatch gregtech.machine.fluid_hatch.import_4x.uhv.name=UHV Quadruple Input Hatch +gregtech.machine.fluid_hatch.import_4x.uev.name=UEV Quadruple Input Hatch +gregtech.machine.fluid_hatch.import_4x.uiv.name=UIV Quadruple Input Hatch +gregtech.machine.fluid_hatch.import_4x.uxv.name=UXV Quadruple Input Hatch +gregtech.machine.fluid_hatch.import_4x.opv.name=OpV Quadruple Input Hatch +gregtech.machine.fluid_hatch.import_4x.max.name=MAX Quadruple Input Hatch gregtech.machine.fluid_hatch.import_9x.name=EV Nonuple Input Hatch gregtech.machine.fluid_hatch.import_9x.iv.name=IV Nonuple Input Hatch @@ -5088,6 +5108,11 @@ gregtech.machine.fluid_hatch.import_9x.luv.name=LuV Nonuple Input Hatch gregtech.machine.fluid_hatch.import_9x.zpm.name=ZPM Nonuple Input Hatch gregtech.machine.fluid_hatch.import_9x.uv.name=UV Nonuple Input Hatch gregtech.machine.fluid_hatch.import_9x.uhv.name=UHV Nonuple Input Hatch +gregtech.machine.fluid_hatch.import_9x.uev.name=UEV Nonuple Input Hatch +gregtech.machine.fluid_hatch.import_9x.uiv.name=UIV Nonuple Input Hatch +gregtech.machine.fluid_hatch.import_9x.uxv.name=UXV Nonuple Input Hatch +gregtech.machine.fluid_hatch.import_9x.opv.name=OpV Nonuple Input Hatch +gregtech.machine.fluid_hatch.import_9x.max.name=MAX Nonuple Input Hatch gregtech.machine.fluid_hatch.export_4x.name=EV Quadruple Output Hatch gregtech.machine.fluid_hatch.export_4x.iv.name=IV Quadruple Output Hatch @@ -5095,6 +5120,11 @@ gregtech.machine.fluid_hatch.export_4x.luv.name=LuV Quadruple Output Hatch gregtech.machine.fluid_hatch.export_4x.zpm.name=ZPM Quadruple Output Hatch gregtech.machine.fluid_hatch.export_4x.uv.name=UV Quadruple Output Hatch gregtech.machine.fluid_hatch.export_4x.uhv.name=UHV Quadruple Output Hatch +gregtech.machine.fluid_hatch.export_4x.uev.name=UEV Quadruple Output Hatch +gregtech.machine.fluid_hatch.export_4x.uiv.name=UIV Quadruple Output Hatch +gregtech.machine.fluid_hatch.export_4x.uxv.name=UXV Quadruple Output Hatch +gregtech.machine.fluid_hatch.export_4x.opv.name=OpV Quadruple Output Hatch +gregtech.machine.fluid_hatch.export_4x.max.name=MAX Quadruple Output Hatch gregtech.machine.fluid_hatch.export_9x.name=EV Nonuple Output Hatch gregtech.machine.fluid_hatch.export_9x.iv.name=IV Nonuple Output Hatch @@ -5102,6 +5132,11 @@ gregtech.machine.fluid_hatch.export_9x.luv.name=LuV Nonuple Output Hatch gregtech.machine.fluid_hatch.export_9x.zpm.name=ZPM Nonuple Output Hatch gregtech.machine.fluid_hatch.export_9x.uv.name=UV Nonuple Output Hatch gregtech.machine.fluid_hatch.export_9x.uhv.name=UHV Nonuple Output Hatch +gregtech.machine.fluid_hatch.export_9x.uev.name=UEV Nonuple Output Hatch +gregtech.machine.fluid_hatch.export_9x.uiv.name=UIV Nonuple Output Hatch +gregtech.machine.fluid_hatch.export_9x.uxv.name=UXV Nonuple Output Hatch +gregtech.machine.fluid_hatch.export_9x.opv.name=OpV Nonuple Output Hatch +gregtech.machine.fluid_hatch.export_9x.max.name=MAX Nonuple Output Hatch gregtech.machine.fluid_hatch.export.ulv.name=ULV Output Hatch gregtech.machine.fluid_hatch.export.lv.name=LV Output Hatch @@ -5113,6 +5148,11 @@ gregtech.machine.fluid_hatch.export.luv.name=LuV Output Hatch gregtech.machine.fluid_hatch.export.zpm.name=ZPM Output Hatch gregtech.machine.fluid_hatch.export.uv.name=UV Output Hatch gregtech.machine.fluid_hatch.export.uhv.name=UHV Output Hatch +gregtech.machine.fluid_hatch.export.uev.name=UEV Output Hatch +gregtech.machine.fluid_hatch.export.uiv.name=UIV Output Hatch +gregtech.machine.fluid_hatch.export.uxv.name=UXV Output Hatch +gregtech.machine.fluid_hatch.export.opv.name=OpV Output Hatch +gregtech.machine.fluid_hatch.export.max.name=MAX Output Hatch gregtech.machine.energy_hatch.input.tooltip=Energy Input for Multiblocks @@ -5140,12 +5180,22 @@ gregtech.machine.energy_hatch.input_4a.luv.name=LuV 4A Energy Hatch gregtech.machine.energy_hatch.input_4a.zpm.name=ZPM 4A Energy Hatch gregtech.machine.energy_hatch.input_4a.uv.name=UV 4A Energy Hatch gregtech.machine.energy_hatch.input_4a.uhv.name=UHV 4A Energy Hatch +gregtech.machine.energy_hatch.input_4a.uev.name=UEV 4A Energy Hatch +gregtech.machine.energy_hatch.input_4a.uiv.name=UIV 4A Energy Hatch +gregtech.machine.energy_hatch.input_4a.uxv.name=UXV 4A Energy Hatch +gregtech.machine.energy_hatch.input_4a.opv.name=OpV 4A Energy Hatch +gregtech.machine.energy_hatch.input_4a.max.name=MAX 4A Energy Hatch gregtech.machine.energy_hatch.input_16a.iv.name=IV 16A Energy Hatch gregtech.machine.energy_hatch.input_16a.luv.name=LuV 16A Energy Hatch gregtech.machine.energy_hatch.input_16a.zpm.name=ZPM 16A Energy Hatch gregtech.machine.energy_hatch.input_16a.uv.name=UV 16A Energy Hatch gregtech.machine.energy_hatch.input_16a.uhv.name=UHV 16A Energy Hatch +gregtech.machine.energy_hatch.input_16a.uev.name=UEV 16A Energy Hatch +gregtech.machine.energy_hatch.input_16a.uiv.name=UIV 16A Energy Hatch +gregtech.machine.energy_hatch.input_16a.uxv.name=UXV 16A Energy Hatch +gregtech.machine.energy_hatch.input_16a.opv.name=OpV 16A Energy Hatch +gregtech.machine.energy_hatch.input_16a.max.name=MAX 16A Energy Hatch gregtech.machine.substation_hatch.input.tooltip=Energy Input for the Power Substation @@ -5154,6 +5204,11 @@ gregtech.machine.substation_hatch.input_64a.luv.name=LuV 64A Substation Energy H gregtech.machine.substation_hatch.input_64a.zpm.name=ZPM 64A Substation Energy Hatch gregtech.machine.substation_hatch.input_64a.uv.name=UV 64A Substation Energy Hatch gregtech.machine.substation_hatch.input_64a.uhv.name=UHV 64A Substation Energy Hatch +gregtech.machine.substation_hatch.input_64a.uev.name=UEV 64A Substation Energy Hatch +gregtech.machine.substation_hatch.input_64a.uiv.name=UIV 64A Substation Energy Hatch +gregtech.machine.substation_hatch.input_64a.uxv.name=UXV 64A Substation Energy Hatch +gregtech.machine.substation_hatch.input_64a.opv.name=OpV 64A Substation Energy Hatch +gregtech.machine.substation_hatch.input_64a.max.name=MAX 64A Substation Energy Hatch gregtech.machine.energy_hatch.output.tooltip=Energy Output for Multiblocks @@ -5181,12 +5236,22 @@ gregtech.machine.energy_hatch.output_4a.luv.name=LuV 4A Dynamo Hatch gregtech.machine.energy_hatch.output_4a.zpm.name=ZPM 4A Dynamo Hatch gregtech.machine.energy_hatch.output_4a.uv.name=UV 4A Dynamo Hatch gregtech.machine.energy_hatch.output_4a.uhv.name=UHV 4A Dynamo Hatch +gregtech.machine.energy_hatch.output_4a.uev.name=UEV 4A Dynamo Hatch +gregtech.machine.energy_hatch.output_4a.uiv.name=UIV 4A Dynamo Hatch +gregtech.machine.energy_hatch.output_4a.uxv.name=UXV 4A Dynamo Hatch +gregtech.machine.energy_hatch.output_4a.opv.name=OpV 4A Dynamo Hatch +gregtech.machine.energy_hatch.output_4a.max.name=MAX 4A Dynamo Hatch gregtech.machine.energy_hatch.output_16a.iv.name=IV 16A Dynamo Hatch gregtech.machine.energy_hatch.output_16a.luv.name=LuV 16A Dynamo Hatch gregtech.machine.energy_hatch.output_16a.zpm.name=ZPM 16A Dynamo Hatch gregtech.machine.energy_hatch.output_16a.uv.name=UV 16A Dynamo Hatch gregtech.machine.energy_hatch.output_16a.uhv.name=UHV 16A Dynamo Hatch +gregtech.machine.energy_hatch.output_16a.uev.name=UEV 16A Dynamo Hatch +gregtech.machine.energy_hatch.output_16a.uiv.name=UIV 16A Dynamo Hatch +gregtech.machine.energy_hatch.output_16a.uxv.name=UXV 16A Dynamo Hatch +gregtech.machine.energy_hatch.output_16a.opv.name=OpV 16A Dynamo Hatch +gregtech.machine.energy_hatch.output_16a.max.name=MAX 16A Dynamo Hatch gregtech.machine.substation_hatch.output.tooltip=Energy Output for the Power Substation @@ -5195,6 +5260,11 @@ gregtech.machine.substation_hatch.output_64a.luv.name=LuV 64A Substation Dynamo gregtech.machine.substation_hatch.output_64a.zpm.name=ZPM 64A Substation Dynamo Hatch gregtech.machine.substation_hatch.output_64a.uv.name=UV 64A Substation Dynamo Hatch gregtech.machine.substation_hatch.output_64a.uhv.name=UHV 64A Substation Dynamo Hatch +gregtech.machine.substation_hatch.output_64a.uev.name=UEV 64A Substation Dynamo Hatch +gregtech.machine.substation_hatch.output_64a.uiv.name=UIV 64A Substation Dynamo Hatch +gregtech.machine.substation_hatch.output_64a.uxv.name=UXV 64A Substation Dynamo Hatch +gregtech.machine.substation_hatch.output_64a.opv.name=OpV 64A Substation Dynamo Hatch +gregtech.machine.substation_hatch.output_64a.max.name=MAX 64A Substation Dynamo Hatch gregtech.machine.rotor_holder.tooltip1=Rotor Holder for Multiblocks gregtech.machine.rotor_holder.tooltip2=Holds Rotor in place so it will not fly away diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/conveyor.module.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/conveyor.module.uiv.png index 06323251106722cb1aa8c13309fe103e180e735d..9ea51add5e47eba136ef41ff03f5009c9ebfee63 100644 GIT binary patch delta 1301 zcmZWn4NMbf7`{?y3$+6$DmunWI~*$4-t~HSy<1zTw9-1Eoj5laoLt*GIH3jG6B$#B z{B(>g^XGKQ=G3_?Ok@!iNop`-llc?vK(`nYof$(m=i(0c}k>eAMpaqZ4) z(`KT4f1)O|e`NEyiTk%FLW8E+X=`#iF2Cq$^cz;_G#^}#9>{300onJcxuq#RKM*TR zKKE_B@{{jCU&hdh*ny&Rm!`?uzVC@1%^X#XUN1g9cHEgsCE3*GSF(EdTSkixcA5Lv z4!)N+9&OvXWN=1N+sO^`E-;$%af#89d68?r+j?|pZs-~~*wA@m?#8>b!#$_Y>V{cG z_D8lnOIS8@X8P+*%^5c(^RexmruR;2!=_Kl7949YAA74{4w*ib`dHduQFU$JsfjNS zC34?HZk>kGE+zf>#_)u>?#jdDv<;GjA9nPYi5at_8|(dJ`uRRZSs9M5OO5<2lI&S} za+z_y{k1bCzcv1iJnWcuJ|yS59|WsDyLwM#zwq_*__yC>L)*W)@fUXc)|%ay_pU$w z!17QOX$}l@Mwkcy0LiuXl|cZIPmga=$h&$Q03_bvUzRvU3O*>YiWMnJJ|bC^DBMc^ zAIVF6mQ=&Lr1?BA&Ep58^Z1+6g?y%LK5v()LkMO-C z-VNcX$E{M<`)Z4eNrykkQGO5Yu$oi?qG4Gt$+#($fKeJmJroA&4Q>o{qXrnn2m&Es z0>yAI@$|hjz*ew+s@huPS?8nuoWR46%aU_21cM=%@q)M)#X&u)(}4yL>;(-tg6k+4 zfxUWM#b+na3Mq>m#V*p~a+p*)4WybZUDXuF)C7Dc)l$~Ku6_z#&id$5j`G!-R4}H8 zQQSZnFakn!I6gJ8f(``P8h@M$hBSyk$FU4U3MvI{6!)YBKhaJW255?_3GioiuSum< z@dYU_CMx%(_^h5C%zM)JJnvyvnbyr94$M zr=BZ_9YB7Sy#c~7@Bk~;*_bg~v zQgqX!G5E+k;n>2#?)$$S>J#~88tB*YmRND$uE$-W&d#QbO-n^A6S?!dWMFvj>N)1v zqbQ`Vm$YAp&WHBL^6gpSEohdfJi(!?l2BzMSBJLLqRQy0vyyEiV`Go@9>%VQ?j5Pz z+B4pu4z8NlPDV;wTUs7BCrHyPwR`d_TwC7+j%16Z&lR{v4nv#8vs;{djG`aI7rUUw zVK}Ftz@F8e(DW$<*!C6mN!y%98K`m17cDc#hx~aM(($2N#t${R<7D B&msT- literal 5230 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 literal 5290 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 j>nKCBY8`H>4HHxd^}KO8zU=ev5nKKX7Q-OB diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/electric.piston.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/electric.piston.uiv.png index d5cea012ff32d3ce7f383c9c5aa6b2a2d31e2e7d..70b1edddf91ab26ab3ea96d086f10e6438d2902e 100644 GIT binary patch delta 1342 zcmZvb2~ZPP7{@o|3JH{mAgDpYQW20Pn`C!$NP-vw#0o^AtyF5=>=9Q;h{=k0H7bQc zOD(cBRy^pm4h2+nir9D*s(6hcs2%HgFt%35>R9pWsI*{{LTBtu-^`mg-|u_hH{bt1 z?~Np{71hP3@~RlU-elD4B_>B1&6H9Akl4Rv^NgHsQ$+QvrrCyMuw1nCtZ8RTjZ}#!!HJhU47ap(UPf6*JFsaHr2cG)D8D~TccMRfVgM)qyjahnV& z8P)vA$cVY?E2Do8Ov38f)Q-ntD?i#+oP2oWqTBOlPSiy7hm8bvSxW9EoF3kNz@P2( zJUj!7t_9qG=gP3Id|)V8v^ub@wyCSwkJcIYV;#SZyKpqLxLAoU3-jFI1@4-2YF=7W z&f916?yP;T7-|Z+;1aU?Uph;6{Q8WSb8&CD@`vMbaQ!zA{=fzwF4=j#arv>A8ACiz zrK7vWLwf)K2)5@GIRQW@@@?L}`0tkifd2#TMPNQJl*j1{*~QoGFpO0tc)CQXLPs0HPzFvv*+6UJB}W2FjM+-lc?G7OQSN;M3t z5DbxH3XoeUh>Dc33{7kD9Smh-ah55wc`t%ooghZ*Gt9TrM#beYPPWXkLiaEBCLAQK zDWI0VhQ?qi!~G(NoF{RzhH_RzEXHjXiqwKqaEvhjV-%&J%{1jxPQe(2z?ckDQMef* z2s27634%1sNRWG9n5Z9XvV1Y+9aav@J4xRRY30N_1*Rj5$wkaxt@$AeWHdPk}B8K zp7!>Vo(FS&T6o4Sd1DvSaP^PB9^dS!?UDx<6}7oTC;Nfbbi#rCpT^ax2PeiF=CVh& z*F{=l_J&!Y9Z%y*8u#rnF}n1l4bKPKu9hy`e&FN~F>o1*dNZr}V#T@jpO_4tv2exB zmb9v5M^$A`-il_h(*0Czy(8UwDDi_}SNX{F!oWYj(@ywISlW0fs$p|w=NICZ`Q~z^ z-<^mf;McrMH#So9XGpe9Q+0~<@9my!pRp4Q_d;})^4qO_1@QI@F&B9tSu!nrSm``} z|MX_Pn^uW+*~^>!9yZ2mg4SFQ2ip#3xyj_{uf{J3>KchUx$e>6s}udehxH34jGKA{ S5|(?vFkm#~Wwy;)wEk}!d+rDT literal 5502 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 OPqv#kt7y^snEwKsc!2x> diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/electric.piston.uxv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/electric.piston.uxv.png index 53296aa30108c21fea9aeed7a865826684c06fe8..2ba45f126c470b7d34282c6e6ff0c64da6521714 100644 GIT binary patch delta 1382 zcmZuwYfuwc6y6L55-Eb-6owk%y05IKG&*t*ucuKaEFY)fV`Of*#r$eLO9!*@- zisW6_r!ER*0sGqS@*Ta`#PWR%Q$~+yrA}U zYxkkaev!XF`)uFQ+{pyrkfeS6wZnUK{*31R+K!5zHM1Uc*VfPPc_pLvj3;70)E&Mp zC)GIl7pCUnhC{vt?_H>8_1?~ewGZPqws!p>zibgDZZgc$Z4|`D#=Kcw6MsK+2D+7z z9R59W^}0`sW*+&Vq;K(@SJg4T$iKrnO3Us}>l*#?t8vWnw!yP-)HVLS{L7=-s@`E? zlqa;gZdXT92(2}?pof2(aIsxfRD>xjBinB9LO;(svmkXw<{Rg7Zm)l$7~VDhqBnwR zdFCo>xb=vadFenjcH(3rymj}$V{~Y6MdS4yD~~?Y4fEP+oTv7-(QN<#2pySATmTRe z63~X3T~eS+1bKL$x0MKF+?td6u43bA%xNdaY_oJX`CPs z+=Rds0kZ3aNhK&uA}SM3LUI|5LkLYOAl!_QkWzt>FiM#y(kuhTq**=B?z9qI-4-iR zN=Y5IQc#>>%+6Em@{Af#E`ft#UOBTFpyCk(16+(4s#xJr0i^U zrp3jvR{aMD&0k1WXhq(!W&|1%M9VE=7h|Ym)P(s(E*DWnkzf!sFDGoJ6sZBF{~{Kf ziy>@g%Ba_XTsn!xLaJ$nTyBz^Xb7het{D{0eW^$a!sG;un&q@YiO@kki$s8IQN$!K zjH{Ix1S{1rcVg+wwMqk%F;;A_)>P^Lohx;W_tHd-{o@6?KtGR*I9*_RtQ128qBOUI zFqct`n6i-?FX#l*w2vG7eE`6lYSil%sd5jpvYbr8n4cxO;gnXEM0XX6$~KA~>HS;@(k=lmTf e{up}R=>wMaM#pO#h3qlz@&iUgj=p(rN%cPvR|EC{ literal 5465 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 Ih9>3x3;w?*y8r+H literal 5546 zcmeHKXH-+!7EVy+S>3;`jb1O;iLAfh+PO$d-e8Ue8)ibxkk1ZgsY z4W(H?2OSht`iP1O=*S2<=vdG}ff?RS#J1l2ajiH1%vv`&_w2pDz4y2GIVWe2kGH#? zwuv?j2Ge7B(EXra1LdQs4t<-COad_240vq7TB#opjSz{299|@dkj98W1gPL~U@*nK zwlzUj19rL-L)PNy@DP~U?ugZb^ntST9$WTP{X0e+4X@APX{+V+!L0KB?0C>Okr02q zIx3WK#X#Q_U3X1uA@z2~V75N#)Od50yr8K~7LQ|h-Fxfbc*d#usp2(Vi#mBVWB+Cg zrw56G@jH2ksTm6s=N+nBc=h?U*LBYKor7B_E&=cBcJ>CY>&SjGb}*{TzEYPv-2eQn z(djkR!OGUQOsc3>KJD~COOvHEEHuHrqkT*Moqa|IuT#s06PI^u1dQH(!pJ`E{-U{U zJ*xTsm3|NXHRJN$^sT3El>Xh)>K&a{*jyPNlqh(XCVa7aJOm$@5dymfV18%vr5kf_ zR}Td170r03+sWuk#Xkz5%bcyc51Y>C7JKNPr;v|jmHX%Mi`5cS^MJ6ctqIRf1H$H> zU%9x?{%G~`#_-w59P9e(IG~u!cSy>uw&qk!_qVh^JZo-Y!Qf4eSo5RHrBANT7U5=A z!C6+M3T!;Gn{;%GVO+r|>q&TVk-1Hp@g9U7X71gahYfqIYZ8jx>&5A%0*xX~|4rK# z>C7lH30k#XADDwQIBH-8r>tw9ubn;`0?#~D3%_TTcJx(ZCjso3XE)Cs7jM|FzN}L{ zNWC(DB+)!7X`W|)?9j!Tp%=!U_@BN!!`vkuo5VC+)}EMyKrZ#o43_;)EH4l5HYNuf zdzsU+%5hCuSniIYon=P4emC;@^1FGaRqQrg*^Zai74Hm_j8T=PH*N)Xr&CK3(>-nK@StJcydZtR09=n!p9%;DDvFCW`x{>1x3eQZYSgebixA26cv#Yqr zZShc&{`@O<=M@*85$z0M$Wk(d5;wX;FT(o=(TT3cn9v^0Vp%-rrRH0`eOo#Yo^LlC zF_Vm2jv&>?Y0;o8gECh?m(#QDQD{+2?=$O)#XHj$G2U<}Z)!cX7o=!tdK%HuefwL> z!nwQ4pB`xvhfExd4^^=4SM{YmA^m7^b0RimXK->vFH5J#n8#S5ZG6BxX5hpb%^{Sm zYgPznIWMJ<;jnAsPm7XP_U|a)x(gbc+Vx(|X)m=}8S#9s_q3wEV{$^pi~kCBs?covWKoL)XuV@44~YGe&L9zC8=C#ibv}xtHcpCbs3Zm(1>+ ze|@GmzE&NZQD9vo} z`_ahwZq)o!&zmzAu%q}{*{d<*KG5i?FIKu@D^@nzuLMCZ_1Df z_2d&dULE(P(~=Y`$1@N!wkk#gUs-K9GVu1H8SZh{$r}8*z@^UOV6EG}YK=y`!Lwk~ zYuEMlFNkMvDFn@E#4<3y^ z#=9nuc)Bh{$_=8f`5dxI#F*A5BDHz*fsmDm#d-!3n=w;^`d+7z zycx_LuGy7-3ArEPymQA=Ppd|^WceXu9cxP3_&bgD4Rmxu$YQM6rbtb%YFJ}3{y}x^ zYomcsKYM-YPxkH2Sc7{rOo+|z9p(8=S_X0I6>s)8_-Sw)8K-J%p3Lg3*9!?bO8{q{ z>xHWq=-$m*Z|$+-+R*k<{MZqj&aFDqQ!$c=f`K=1kDDhlNtZ4!!ul0GlNCls*LFOA zP%t>L1$Hi8+<4K=v>7_JOnA`gwAO1Sg(c*p0k)6{q7{4*bb7&H4o(UYz={B+2qwto z38=^y^$kb_k4;6cA$noGL^Lpr=MgIg{bRiYSg{c-G8^gSsO_MjKmdGD3Lq5xNP&c+ zpdwYc6lkoR#vluSM<$aoSX+#(Eeg^=Nn!+2K!FlSER+x*FzBF!CFY5wJfQ%g z!~~c^nUsn|LUP2%`1m3(uTSs-$rK9^9~cE7!r;(Y44;qr(n2D2l|vv?0sW(eBmg?( zF@B&#C=;_lS2-wPjH;%czu4YzPWVCgDH;OG1G} zHVZ|twIiYcJAjNL*fX(stQ{6>Yfn%?u~`&1p_mUq<>c`JE{G8cxGI5?aEh}JgNn38 zV?WRML;_L{WI#o(CRAM}?3N;YwJ1RRlMPbT27Bq9-K|5+&z6ic8^RAS<= zX#59UWmzatG7zzVvQHrZl?9Xwg(e08sZbms6h=~!%8(FBOI3R#96l7qgC~JBVw4>} z)${&f)Q7hZOCXY`5+M+(wxs~94^AY29Av8;L3STRtS~^p1)=pl)leVjdH+x>I~;+< z206AUjxC;vBCtWI-u6s;6vQsu4ohNzcrxj0bcv87jRwS^GZ)Gf$_8p6RW=AK6_wUs zYe$EHN}jOL+Q#BgSW*BE4^@?-91|&6ED|%7Fh;qmKW6NJ`5#UkR0>~g1CZT^IcR%< zb}P)M?P`iMC5`{$XQ~$eq6Y~2yOVF?_d8wR>G~!HzDfCecYUYpn;7^evcGq3etpCo~_r3aK+!xYJdaBG`Lc{Z?qCCGrT8z+gIt$_M^S-ogLk*;{7*s%E;4PENSH@@&~LZYdK;0dY-C*A-iD{xW$ow!x%-q%E%iB6I2l9%zv$2X~`hpx|^2{(7R7~0WqTvU?iCYL(~zchP6UDTTWpAC`xOSG|# z&GpT6UwYOC5~-D@)~{h}4(n00h5R1)OBtz3 zwRBI^Ui$N!r`K=I3%C@RyZ6Gw$Z_3Ua+OYIq;!@wN#(G)_z0{Z!)nwEDWYrjvqql8% zxNy#nB{~HcI|_YP2W0jCb@pn@UyQ9_pFYCNzojY}OmVZI*BrbHKXa^Befin@vRgZL z8oXSDJ>=b|vr+%_K6B2gia##jnYJSHO8?v4j??05NW33L-#u0qjN$4{uW;G8EvWqz4{do8c+ZI@&0f9Ia_goEY)SVWs@87EW(WRI$xeyB~j(dp!g+GDwu2Y zS<6Vj1-Z3%FXyh>Eph(P|5fg%Z}D(+9NBzki_9b5M=yPkKiT6ilgR3-Y^N@_b%o<2 z_jRl7_7|S3*7kGjPyLn?` z%uP%AcidrQo9A;h$VSt{`-I=qhVRC|mhoJu=Pp_Qvp9Rs<1dUJ7uN`xA2_IJFlqUl zuV(MxWzD@kzkJV6$6t&)nu`vv+>y3}fq{Xuz$3Dlfq`2Pgc<8o;wLgNu)LXkg3X_i zcd|IU3o|d5!sHlsCl(;BFnK<^JdZ*}ZcbjYRYh)rukR!dIhNd9eWl4?*zG5qbLdP? z=TMtGkwbg(0S?W{Z#a}w(=3ckf!I(t+1Mma*Tf_#Q8&rd&{Egf*x1A@IoUGNG|5Z} zXd=)oE6=>*lEl2^R8JRMC7_62W@d_&k$G~OS!$Aru3>VTv95_>VzRDfqEU*jxpAVY zS(;@^VoIv9(&Q>mWiJCubHmg`19RO})0AXg6C*QI-9)oQOI;I-Bm-juGXn!73lk-U zlw>Qn{G!~%5?iIr+{E-${erx7B?Wg+-vBGe08d*bBRvD9$sahypkg7Jxv9Y=iMa)~ zN`_`8hNk8gmL`S<=BB2G7D|)#xWq*jN;1>Zto(~IQ}ap^OEUBGfC`l+CveHyg2D>~ zY#^TV$Sf|&FRHYI2?HgHQqrt~Qwx!Vpn^G>lQ(jS1}PMmxR#YzC1)h&rKhIYD(Ndh zMKZAjl$oJPa!P8Nk#3riagwe{N-8j*Es`vBfnHBBGcZq1HMTTYnykgGF*$-;PSwCr z*TB@uz(7esAIW+feH156p2#g+4{9?<1QO7?cQCl~HzU|`Jiba4!^@ZTHc=y%9LBdP$jcAo31|7Bf2dowiQvQKvZ!gTel=A0u=Ipj6?Z@8tOnjg1 z{rUdvf&GW%_?|wK@8@YgeNt=QOwEbist}@fV){#wGBpd#BW6 zmTb6}ZLZE&$#KxEA#P*4n#>}Nu24zlQ0OGG`r~K8V~;nQ^l14h zuGnyFlcW0Qj>Bqq1gyLL))^bk@R_%CS2Ta*zMad~glSFsS~q`QPm<7^W|`dE)8;*Q zoVNL9&!ZzVuiAy)dC2+d>#k`w0&eH0Hoo3$le4d-hguPgf&- zOMMs&X5{Y17 z^~Mc99@*I7Vnxd@tgpHia|`H^$I`A}Z>Xr8W8oa<*Wy38c7*0xpFDfXPMDt6SX(%^+~(yh8Vx?9UtLwE$6V)lLNc|wNH+L*q@wZ= z7>!A_y7D2sBgIPAzdW;fQD3BT=#6sPL1TlP+ecnLsSeKzt(&)NaBpkB^UBig#w}nZ z?xf$?Fl#bH!8zWUQZYGX#-e@y0LgDLdm3&ziD7QxJc2wm(f zZ&*nx^>2kvx1$bn@|f91um97uzcqcZVPs?Y@#USx%>fqZ+gQu%J;H>wX?;VRuvT75>zvgw?M&5SomY3&Uq=&7D@%}}Uj92k3 zSLNv$LmBP6uO?eGZxJ^D`8I+}<t}kqy^>JBOQWhAFc7&DA=dO;s zJh)-SKymBc8R1pMrYXt4%5O})9}tv2lC*vq9e?eQ&H@g_E8^bEc;xLadP`lMfy|A( zFHW#PZRjBgIMj7KqKy?mTeqX;c7bD5V9(|7(|h%=y>zph{$_hfMlIp9n^)L5#F@F(hagVNpD3oo$8~zlUhx_pp_{+ZPx{Vh+WfQQSdW}5Skrqg2 zkIL+g3W=j3<17-^oGqjd^o%Vry4~l`wES@Uu0hvDQBch&v9{{a3e|k4g2gd|$NP*q z?T7x;ZPVoO=+55+Pf3Tr(?I#LH=|f{`uY^s07cL0UP5MXl{X9q-z;=?_I7u6{=6eX z`(Vzx)P-&ryv-9v4=iELM@E^fzU-ZAmx!5mLZ4M+6294Qx`%i;ZjOr?)j{3y6BuUO87KQ{p;gY%)|sWY zhc5P9ES$4)=bO~tqQ%h?BGW^^9?Gdj84 zuk2Vi#-)S<19(_Zylm?>L!@Pj4ykYUc=E9IJp0D;`n3J z8>fwegHI8`i52(Yjig_I2#(e!m`85ih$??J}(%I=U={&=D2D_Mr15A~e94a6zfEL-Xfh6&x)$iQW5Jbig0+y_yaI zh(HB^P>UkPa=My<)Z)^izGfJML}*165e#Gi+Z*95k%0&znux}tSZZMu9_gTuu$S=# zbPm(y69n|dK!zz4QaT2sQmN1?0$L&q#o%Z(8U~BU;PEI(0ws?YD*!c0ET5@?_=v#- zX2ojY;R&n2%baiKY zf6>rT5GoW&wOSC_-$^Qjg0EzK=bL6m8_u_mKNt=%tsNi6bgz;=7A_Kk;moJ1bhmKPyGhUT`X4sVjif0 zg22&22!}$(Veu3k4@IL8$Pfh706aVoMWu4NWImBX#qlWLKzPZ7P*nnv-+HBi;zLkW z8kNN7lOPnL01GuZ0g6fjDJUL^N5d1yBrXxaYoYi&x{E|60-$sXML;Nsk%~jL6B@$l zPTuYeBp!|ZI^rD(C=uj{av4EydAporg6bs#11_BC+%vU0bWFR#zAvBuW@q4oW#pgxZa z{~=ibfQ42c4UYo&BrcRJGQ==Qq@nl}A^=dRSOGx*e2*@d2ox$n20Dd8kwVcx1*DAz zVXLKb-uKd~Fi^u27Fyd_912VE#S!RO8XX7qNpvh0iTM;TMzg9vM{JMzA5QGG0^e){ zklx2JXnTQnE6kVe>Jw)g8vn)Lr(FDt79i-KMt+FjpLG4C>xUTlA>p6Z^^>k2V&I2_ ze^%H3jV}GK7amXy{R>h-*O^~(M{A+0(0J}rSElAp1cSYGJ{=3aCP>`^`a9y(r27_1qo0qt z>htN<@{U^Gp7+n}a?dVgH>tKqCsa>eD^#iG!XNeYT%m7Krh6XT{b7M4%hV_`vUF}J zswF5V+qNO(KqdU`DSMH1q#4uH$00ZbKVfx1uWjkrRe#MW-(hXTXlP7-OB!aIbk#RT zOv$t3=7LlUOBkWi{_xFg(}K7p?AdA(Y5e3PfdU)GA&I|FE>=j+Rwhn9vZH<^D=^Mv z9luX)v^?LgVa@jVbG5#;39fk`#ud#Sc6*iT7v__`Kht`|n0u;??d9+HX1$VS($zg+ zw6u3=8prH|PEbCp|A;@Y1y)g^&dVt`zkaNIWZH5T>+SGxLwiH@h5J{lj2!p$6x-?_ zxZOWwdNW)wc3d5tOmT7Y5&hliIEnXG(U*ag2t^fc4 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/emitter.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/emitter.uiv.png index 0f7dba778e7a84edec7a25da86cef20860fe489d..cf81fe668948c042766127149aadf76c1d120543 100644 GIT binary patch delta 1581 zcmb7@eM}Q~7{{+7Qr-sh4MAq=5d=4`z23FG_STk_g0xt$6YUV|#@+P}tMvUS$kbMi z=-j4@7hPP2bGm^q^KIb7;LFshQy8!qW1^B6r|~6Dor5^ZSof>2#Z3R%FS+~O^ZcIY zp6`90=ME#yV?Rlk#6S>~i=>o8kZ85jXtbJ*Mv2w$;hZ%rIOy3VRK=!=ltO*1G_>>j ziq4@w9u9@Nb!n-KvYW5I#)RE!8z%kWZrAQf4Mot@ek!9pq4g)tys~YsWqlW2yE`WJ zoQmu&?!1yDUi(99S6k+db9PY&~2oRuo z82|RlRg-=lGhMZjmmc~prD6FN`|C&6Ro$$3E1ewQlk!*GiR#6-r=1=8>cD9Jc>9BM zXzG>Ndvh-j>4SZP@u^G4?E9$sggu7SoA;{@-FdaQBiU{zl(i}C*FJ26G`=16DfBs9q$n^6!V~OuiPDMAi+#gUqe6XnL>KAoKpBe^5?W_E! zceQiv0Pl9IWloXJX8Um6x*c6REEY?Fu^=ZWr>-s-?g-bm)oL^vnM|hDYVCG=(}kvm zdl%YU>^iO1>+u>4hWX9&eLmm7z(6R{+8V44R#a4wBpK=KJkl50(i@4y=p*k1*PMw2 zIwJiLjbT_xNeNBU{gAC63iy0p`vN;Amzzu`99Njl;EvmD?^sGpsVd4?Ul{4NUUcDkr)R_1kA!;)fisg*QX%{my9 zq9dlYhT=I8s)H>~cWpf^Oi4%&0i{YDL-COq8|x1M8qqX4D#bx6@8mdgmfy*`c`6D@ z2g_lA!b=+cEX8~Lb3C3J9UQGEiRQriVZMMc2r4ZlP0j#_TJo=Z1bsQ{i@JztFP^Pu z4XJTT0(?=BCn;vQR)7k!4tT`LETr7ktV0I_=+_b_XDb{W!^kN$!Z54`Q4oL)t#E)I zI0!k$;+zVl0LuKtT)~=@J`*S9IEmp1sw7eHU9#sCjcEFx)iDZZ6iO6PJ8%`EP^wu( zgA<@SM$xpIb5IUk{!jHOfb+`=Yh}@~8(}ewLH06i!*S1z>of7g-r0pSfTfkyM@Q4e z@>JByulG{SVwRV%ZotbAhw}B6w?AtF|A}BOG|b5@U$B17E2q$;!ui|Ul3nT4{%@Zo zU5i9Ax|N%tnVbC&rQhlPyp(ca`{?8R*OdVYbZ`6VT-)dsizJ4O8S^e?SH9bkwY>S( zg04G*$Mnlah0x58b1rTf=qx0A(mF3SWOaydMuLa)dt1Z5uRnkHez*^7@tvG|UN_2J u*ByGKpSJa&s`2of;ZNI^lux|AC!F&5Xs)$oTxBfK2bqh?3ilOMt^6BdHd59A literal 5815 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 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/emitter.uxv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/emitter.uxv.png index d1cf0492679d8a18729786e02c77a48beaa71033..88b8b259e888e5e7c59a3b29147a2cdaa3dbcdb1 100644 GIT binary patch delta 1533 zcmb`FdrVVT9LFz1pcEJkWGX`~mrX#q^geoTA8U&RDlOwRU>(jnx%c)KtG4uUd5CBc zBUUzz^F}k0sf$_gHNgZ(>Z+nJ9~lU2#yMqV8@iy&rkg^hB<$`o+_EhExpQ(}pY!{j z-|u|S8HSF;?pve?1^^%xiY^6!pq;kt>|$efwxrlyWwmW$gpHvCAG~hpE1uuXx8>=V zgEcX(YsH7sebPjnYYNHm9{+xO|Mb&G)80YNf|w1jwT&#M8yyN0nz8%Az{!R6dLU_n zOeht1URSOz{Mf#A^oIRpVBt_Ne=@iKPNc~9dFMb^;#kz!gMzE~&J`t+A^K!(%98Hm zy0P5$Q`#Qa;Fk1X2Yd(e2IF#lmm4BZK?CB0g=%BsO?JoQon1o--f?KK{zPxW*2fE) zJFk3!-m*m{?bWC2nnm&P^WSXRvGAABG-5xS(fwO={kB%~^0O@!_sUl;Qq3QV{v)iX za^v{2E7PBxna5u6KfDUZ+zI*Vty|ODn$fB7n1;~y_uG2R!B(xYgXq5h(r_TkY?kBI z(f)6PLJ#L(E>Wi$-ni!dvGI3osx5NZ8^Lxw^KAU+?nIE`%THtF7cV8j`;YxRNj!SE z;n2vD+H=ozQ$hY6?!FU#t6vcONO69d-efYp*V59vr#C-8KPx*cB_*Y{wkFUR=&J5g zDwR^HRIOH<&F0hVPaiWM)2P+XDyL4TYg^Oia=9iaC;84!Z%uVgd3m`?rQ-Yh&yMn~ z!#p3X<=55hy3Bh5`~*OuD4Lg-M^V%SV446tE|=51){G*E!C=5Jnb9cpn91~ZenA0Q zL1t%V3%S8CT<7J538Nad2m{WR6qfRH7WJI;9|$yb4~vBp!kvcI9sr1lnQ1|%lh0QJ zK!~3k4=oCc;)t-E;3%<#+Y**FPZ%ZKg|MaE4`CTxoG6nsiPE`d(K7CgXa)D3D2#*fCwQ&a0O0a7=bF4C<1Z?;sx;%)@HS;irhBF!IG@4${`qnoL9V9Gb7JTQO{n^ zVDqq5?#tEO5enEM zCYOy2L<*62$}b!4tr#KhvOb6rP+vPO@Vv4Ok9 zXYYO;cj(DT{lv`*pRzGwPs)wk4M|Vx`_{F$Oj-kXdw{3gys0Y&=3RXB;o-p-%lU}4 zQhc0r2KxBz4d2u)JBwU<2%Ps{f90#D4sZ(a98FoX`EdISLUMpnUzpRLRnhb(@61Pr literal 5840 zcmeHKc|26>8y^ZGl5*RWF_tXNKGQ7Bl(iWQk}RP*GjnDPW@%=aLCY_dC9YCYLTR~# zB8ozrgre)Zx2s*;2<5773rX=iGg?2t`%j2YO$mH+DQfpIPK*{?Vfi^BV?}1qS;D;U|OwGpqX|^E2%?Pt6EkLljjnTKq2i-Sd0e zCj;l-1P(VQ5}#h52it+R^~PL3r!zMzr>ZfJBC>?{nE2e%dFgNFJJ`Zh6o+QTc9bn> zuQ*-!eA2bCh&4m@-K$G*MHhqbG*|UsI9O|_|LdgD?tAf>^x?EH%K@j#&Kzn;_7A<_ zB5c+VTHy=mG&Z9x-Tt9*e}IwR%2|2qOlBB3m5PoRS!avxMy1;RC%niuA;8r?nP0fH zmI2xcnn0>ndT20Qnq3i6pr4xE;vV*UDC?w@xX(ko^?Guu5Bl}vN#}R?W87OBOeE6{ zDl|AYq^J9|-Ml)F)-az}FIeIdn3y0s>F8&faQj>+m%lMU^MEtnntIw^hjr|phRx;Q z4A)L|(KwcP9CNjJ>C7~Z49(5P`7=VAeJ_!hnZU2%;=?TnS&bHT*Nb|lbm+ae;rU)J z?}G^u3zNYUF7GDWCm-s$9o(0zs7pyj#SYzcc(&pB5u1Wbb;Vr?)65yk=DMjS3s)y3 zyD~EnN5X6RImyNxFWpFMrMHp_ID2H{_&Isa^rS_UUVkHc!w-S$b=^D`75P2d{&x8W zgOw4-i?S1aBdV%h&G(W~0#BJ+-Kg#z(Z*ZuYr1erLIY&I*w+ zH^vlS)Z|m1w7on&vt*MFqSB36T-7zTZH8ZKO|&yTXj|E0q^o}YkBa0qky{3v9^NSw z>BvfNG;WV8^6kb{DlUZ|*#_C&_ZYTlRrQ~0Mwz?g1HP8m?NW`=|32IsvURvuD!q0%I2W6%pdj~EK< z=gs@0dVaVZa7%`a<6nzt#~uiAw={dX{k?Oc=cs+}a&7)^RhYv`L+ouir$C*6il1eF zWSY|A-06=4vhMZHrmT#Mau}`MyXlDi7%*#|Bib#9txNNr7mRXw3C;C^P+%bQv zR+3APiFUC}&!Wqt_E@6xNdKdjOoO3jDxE3cje9Z>`qp{{|L}|AW%;vmoksF>$b|Q? zK}n4do=NITlOIeup7c(vy#Qg}*RX3(q72MPkqz`%&N+7yZH;VwYBDDys!%y2Hur^z zPv26zz+~nK3clvj-Ob1?`zo*xHvqriWmetJNt2M~n4dXohrFVsrQ8udSS47P-jmOo zw(?DhrT0jGO?KVE?w#+9i(-GTQ@RA#*rYlHJd@>*M&7bI*3@l^)@pijkejl^4=>tAO>udY9=2-ic~os=yS?3eFndfmczZyRzieB1?em!Lam_2YhapxsO z7TjrTf}Mv=y?a_r-b{U4>W%tex<> zKkshZ1U=c_3!o=h5X+0o5ercOSIh=cN}&XL!ogsUOOz6T6A8-UY>+Py(GbsSFCyRq zE)5Y#WMNnm7cgAFh?9aV;=KJiagiJf7qNt{=cuGY076g>z?H%%k&LROA=J23=v+07 zM!?l3@<g zhkwjZC}FWa!HZ-cRDkqAD**`_i^8CVLiCp&GPzp}1o9!Fzx9y$LoWhoKTsx)mU2M1 z7*Hg)_!5H4`Q$H&mPV=Ra5-o&3KT-7GAJtctB}i>EZpZyX4G`POayZOg!`5CNA7B4$cn|Hx{5i`s`QwyG=wTXl`G~5xK#Bi35UV5*#tZi zOCpnz1Of(+q;T16Bni(U6BlDB6g&_70*Wb;$pH}uR6#-DC;@~65J`A|L?9vA7!nRi z;Ihd`07K#-xdaZL!d}ed@Hm(+Abg|(s4Ib}FSAlXaUrP1WHONikT^&ZfyjfPNMt0N zLuMn1PyhhK!(m7iiW-W`p}LEuLI5hKKnU!4+~qr6zVU0ZW8PLmCkAI1K)?Q2;2FL7k|=#9~nR30zfKs1O-Q zSU}aM5P;eP;zD(if`D8s^%skyXb4pTaFwUJz2S}%MPUeJkVUMj<3IHL3UJ-T)x<3j zB~VYn;p(=f0-T8;G9U)zssllO6H}aUK*R^3`};#feH<73O|b}E9*2Vk$Vd(cq#y|- zNL)673zeTs!s0+YZ!rd#p!W$~Cg#Z%fE0A%LrftyPy?yiz-`o0+J2pjA{JwY`D5`^=!?T6F+?f`gFycuDB=J-hd{(2$z1$mB!NfbcKbI& zz~SG6e3QQ4<@zqyH!1K<#^1Z^yIkL-z&9Cx@2-DLF1^otI#2|?=qaEbTi}VeR?u!w zo9(&GRlVEPOpZ}OqfkVPuE&#Prr-l z>f}#uIlmjrn77=taZ}%(<)PB*`fGor8S0+!?20gVl1S)Ic?d?Kb5czTBdO|IPus7y zg(ZgBq3v#t&rSDC)i}>~xNmRBZ#}wlb)kNB&-H>$%KGl{4Q8F=@#8vWVOij{2cuUp zl1jgn&5?ZKoJ8{mzvXoMwX@yN*p4O7u8zHBIcnbG@@6S&@9s&OiNIBVyKRE~#$7{0 zvtSN|4i&MtjGg;BZBZb2E&(s3Ps-VG^A?Ode%0dvM`-* zW?xf!WMJ;=xV+5HBVjMzcaF}c^yaTBVsy?@E}=R8(#?&}sV|>XIw>fA^g!m_H!#Y& zt>L{dc4&9rykOycdw&Qx^fRTn_;9h^ooh^bS=mCq(N7&uPTvkatI>Gp&8w~G$uU1K zc$&Z0R4ZoXd2U49T=U5n(2`ud)w+zg2kkr@P85_2L;l)uu&HTNIqk7t(9Og5$E7>> zRqbzub&=D56P*zd=B89Hx69%l^4-}I-(sBHdWkyi#Cm$?w5*qF`W~f@wT>G|?uQJ# R#b>JO$#nB}Ep=X-@L#>>=LG-& diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/field.generator.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/field.generator.uiv.png index e6159ba128e39b738697a96465bf42d7b3b39627..87801dd380938ff4af42c3c5ae1e5269d934099b 100644 GIT binary patch delta 1774 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 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/robot.arm.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/robot.arm.uiv.png index 04b59430f919931d566db416a5d98e61bdabfb74..1c07f760c0cf4fdddeff7b35b4309e4991e61599 100644 GIT binary patch delta 1408 zcmZWp3rtg27`~lQ3I$sg1(9hj(E)PX+sD0q$YWT#wko9}8Z~IRy}cK!w3POOsAzcv zMB^CaMiGW=IAn-CmH`<)c};Yahtn+>&^Xk|aH5XsoGj>W1rxKK3gJC@Z9zmH{G?`j%PN4BT+?+ts} zTX+qvyzz$2*P>f4=Md%jii)Tb{l9 zR2$I-0Dz}WyV(H%Y_4lF8iFpQ1AyBjs+t+c@S*->#?12Z;!$#sRc`djqxO0%p(;HD z)HRPNY91?$Qn8j(7S;-?f)zqtVFfvjgv2N^LKq0iFgYlNU=wJ>F%u|32?YYfau_2} zJ}=W^i;Y$4tPT>jVz@3Qf=?p?v)QDC5ge9DWC%zQ5CKYY0t1Z*gn%Zw5mDf{!YGz2 z-rkS1o0H8}G$ke#OSj-wlGdSYp6no0j>=&PC_``rl!}Z9tpLkG1U4Zu6c?iqCgM|7 zo(r5jjV{)pj5g>Z_+kOXpDqn4C`qK+EfM^+W@~!p44PoJ;Oj}$VvFF55UB{3DIlrq z6iH<>jE%V6VNSKWq(qQFLd%h6f>6>PX=f<;rX_mgT&c3-D4A-fv|e*euA#bC`1DA$ zW(VEb9r+ff8+H?+T#u){1I>UbW}bsoXOK!1o0fN=8Mui*17h1zYcg(%;0yUwhu5NI z2#m@Vs7wmV#A1jZtO*B=s2B#thzSu(QGy^am`^d;!CPhoc5TO9X&|u}ghcdnCWs_T z5u}tNAOtHRI-l?zOX0%*+6))|KM|F~_I0|VP1ECJKB6UPqLQXsa1wP@QJFRr+liAr z+)A6b^P?g=_fHlB07I{fiB6EmHI!V?cSGFE!f=lb>SI*Sg!jpK&DrPfL+;zE9(D~i z953Ev@XO38(&DD^S*G3tC3UZ|s}BsM*Hw4dTc7r3|4(J@ zeQ7QJ>x^(&Ft&v%^(^wcH??qF|NUv3`=T>Bt%)kz5}@=wIo6R6bShY#BM(M4J}E8V zI#4lBT)Uh)WSMQ8^A9vmW{`q9;n}ikJqa%Z(w;X<-^$`nO z%E@zE&pUT~`+_;?SGX%AIy7W^_t5T#Z0uJ3;hf(qtGFxkdd#ZSn@M$5hb86LHHJl* zl^oPxsVk8;TwRb~51lRR_R6|5$Uc#t)|(xA^Vkv5(=5)>rZpA%E|6gl; zE^Oo63oZyQ;vM3%a+6*ZU;NTB7}Dh39F~`Gu%~tL^`_c@v5wckQ_peV>k}6TO6Jm^ O0H9OrV;WZ_<^BsD{TR~# literal 5471 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 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/robot.arm.uxv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/robot.arm.uxv.png index b6d8e1effb317ffb3b9be4eac1686aa2cea06fa7..420a17cce0dbd6459e9b1219ae83fb56d693b408 100644 GIT binary patch delta 1414 zcmZuxYfuwc6yA(LUNFQ~1qEqXgcf0wO?LB~B#3|zL@t1gFNbML$|;wJ@vXh>JVO0 zbluI_`gLac60zXRp`OOjvJ@clIW{YgbNrHGS=N4&>-I0E##5oaXWulYcHanOZT{(a zPjh&GQ2$V7*ZsEaaLhj?O7mgFiTcF;)Wc1h_7cw*@uNMPtJ6L2r*7_8!)=0kI6Jdc z+VE>+#j}mgy|dg8Ax~Mu*;%e#QfzdPzjo^E~81@mtB59eR^Y8NV(WneJh-EMe zp;D;?LQ$y<(&4xa5-a2wu0v56L1Z8m#}12D7(^n21jZnVUM`1F1!{ogda)G3#8Qz| zC(?_II0{l`cJy+i#E2p~NTKlYFg*rg1_Xs9h|!=!bP9t}3WI!uUb(eBksq|8iZ z8eykdtN(*1h0nuFe30AMiSaewj$(puCsQ1x64Ot_vSSY108WDX&oFZ#Zcu~5w+Laj zlbBhLYm?O=9ZoV67yLJPAjHg zg_C^TOxI%r-3gka5k@xvFtpm_#KrRLLsjir=U`r^P{qto-bJk+4aCp?YHkDKdy4sv zIW3N+m4kh!=d~=E8$7@B^`g9M4*rGT?6cG2G7?8A%|2I4dx592T{qOq9ZuWzvKTp4 zi#fx7KJya$_CoBX4<3ZxX>f4{vNnB{&*=Chz4J=9o8^pLhXfR`czY{&;Son_u9h9R zbF^^w_Qb#8hQ@{Uchc*dIK#Qyx;g0$x>qMRHFwt=UoY-=15Re_)4p2=_as5|=KyF^ LvXT$aUs?VyrtA~D literal 5500 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 QE@>s4?cMCot`6M$Us?W;jQ{`u diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/sensor.uiv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/sensor.uiv.png index 03589241faaaebc904a4494ac2b2035595c1e580..affa834cbfafe62fa6581edd3d9171f5f413e08b 100644 GIT binary patch delta 1607 zcmcIjYfuwc7~K?kgP@hCpm7m|$R@kVZjw!T6d^)XFbFD)SlncHVSxllRzQ42p=xBX zQg@_dNBbUpRVYOqs1FnhqEJ9P9a|OOj2&mGznR^8@A=OC?)lE# z`!4js%(@`86952_kWU5xh_*9{iF#dPqF8S!rkNs2NDS_K|E-iR{j42)!xF6oEb}ex z)gO$u%R(?N(^+aee0y8p_@7V4Z3D3Zz6Ie8*F%k4&FWQh>8?lpM*}Ohz`Ri+IK!jm zJ3Kq>6VvA5?@dQf1rB!dN0a-mdAZrYZRtM|a@YIrqtpxcPcIK4oV8(b3+A*QPPm)g zcr31?bYNrjZ~gXtO9tLdws&vxJO=f9)ThPhLVjSYpKU)e7;Jk84OAZK4Bq@KU`I>O zCHYmxd)|B6=!6|^etxsktEvMZyF@AXveMS4K9yVc=SbRX*4@u~J4iEY&}YK6Bd_pb zM9=saUrl4rwvAkXeXlwHvhwP9T-opoci&AejkOIOIZkw(u1VSY^NgWW-Z?ocY`st0 z4Ux-7%eq&@M5Qe4wLRGShvG$p*O1MVZF+7kJaBJRlydpYnW}T==fQgq{W_+6GE#8x z`p4y`pC`N!wN+cXjC_8Hp*e{NwpG=W1-hLBR_mB2Wby7#KJ|JY0^* zvp&ya8kr3zHw5_m&kqZOVK}=Xdt=+i+VizisVuWTv!JP9cjxZ(`t&soYqqp+5yTWV z6{YM<$vKo`ZZ_}f+*8+8CxBjOdq#u-WmlwS@UIK?>k>Q7YJ}KNy)YXfTyqH z6CDpbvmOAP+qia@*aE<38-J-cHw+PQE2FuX2K=Ai)Ok{`@7HG|GQQWXw7^PIAYS=&-Asoil5K2-A zq{c8BGO9?GN=~X^6vIHFj&O!XXSTA0*+}Vb(Gf9|&809_w%D>E?j*ve|lSPfyEENLamC=#3kjroK*k0N71*-M0Zg>m7CQX$7lL;;~VMM5Zy;gA|N z2tOlcplQ?q!-xXpCOjj#Xs;lfLW3wYs9-aufniWA`+r0sxDYA>4ap4{0-=Huh)~NZ zi1NY+K@l#;F@@o!s1O@2XnB>Q7}kbcm88% z%a29nSMED6{HyCSy)C0+`e%JBTYzq2?@d&4<6iVdOrlSx8)mp9MMIZ%UVL2p>7wR5 n(>trkV|BX=es?LEkZ4CmqH#&pjq$_zf-pd*O-pKAw65xJMcZO) literal 5764 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 diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/sensor.uxv.png b/src/main/resources/assets/gregtech/textures/items/metaitems/sensor.uxv.png index 2971a3642263489104c49ea38946d8b85e4c4a25..e06f44a606e4084ef40035c8b126cf8efe850bd0 100644 GIT binary patch delta 1534 zcmb_cYfuwc6y69VAtV?TG$_=tOs!frWRvXXQ3wt1XbCA;Mq6yzY<6+g1WZ;1R03E7 z*jg!DsI9e9r-Khvtmv4IFBCD`swc1g%DKh@ZNAhbu+b0_u8jU#EHm|tRq{*7a%Z7cwCv#h@r6ZSWX=A5efEv{Z-(fCy2d}_9nV>EYevh+xBGnQ zW1f3w@Qx;-TQIf@hl%wZ)`vh-kxywuqZ1_jVvGUxx(Ro{nqL9 z=vgUqTTOoyKUNOc3D3F$=!PfGC13sikdyM`?uqKA6XEiz?R}5X{(FnJT;96!$P>db z$FtVaywgK^008jMOIhFqfB^C6=In_$x*P!fJWLBWjU!@$c?muufs}cd7w5~KQf3Qp zI@83HF@wBV2H{6C1b+szk^ee#j6aL%BJSZ4qt@Xa|mk;7zMsSsFzr$g)yZZMQ{i~Py|vba5bdC z)oKV)!4^zGuuYIwkO>gZWHJL@nXZ&WazrO*>yP?>-^LzFKoAUf*5o;cF%jf=5)*agz_N%x`n7wKLm)%zaxbF8FN@P#!#|8VAj)Xn+ zP8xLY-reU)h4y$qken>`NX`dbyXMLnx_^h)xv#RO=2=%qM@Lh$kL#4MUQ!?_4EZMA z?4vK@O&fgBmbOo-sI2;IxXb6K_KxPf;h!l_k_4D0j*i$g!PR0%O_M6mrUjWCH~b5EgzPRuwM{hOf)6z Ijms|m8?Q4q&;S4c literal 5787 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 Date: Mon, 3 Feb 2025 16:11:40 -0700 Subject: [PATCH 14/15] Fix off by one in for Hatch Registration (#2711) --- .../java/gregtech/common/metatileentities/MetaTileEntities.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 1f13381b386..5e213673e81 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -785,7 +785,7 @@ public static void init() { // MISC MTE's START: IDs 1150-2000 // Import/Export Buses/Hatches, IDs 1150-1209 - endPos = GregTechAPI.isHighTier() ? ITEM_IMPORT_BUS.length : GTValues.UHV; + endPos = GregTechAPI.isHighTier() ? ITEM_IMPORT_BUS.length : GTValues.UHV + 1; for (int i = 0; i < endPos; i++) { String voltageName = GTValues.VN[i].toLowerCase(); ITEM_IMPORT_BUS[i] = new MetaTileEntityItemBus(gregtechId("item_bus.import." + voltageName), i, false); From 8e9efb7691ae7c4303a11af6a81db0b4b7203514 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:30:30 -0700 Subject: [PATCH 15/15] Fix Filter Popup Panels deleting cached panel (#2718) --- src/main/java/gregtech/api/mui/GTGuis.java | 73 ++++++++++++++----- .../covers/ender/CoverAbstractEnderLink.java | 4 +- .../filter/OreDictionaryItemFilter.java | 2 +- .../covers/filter/SimpleFluidFilter.java | 2 +- .../covers/filter/SimpleItemFilter.java | 2 +- .../common/covers/filter/SmartItemFilter.java | 2 +- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index 568f925cb6f..f955cd922f8 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -72,47 +72,82 @@ public static ModularPanel defaultPanel(MetaItem.MetaValueItem valueItem) { return createPanel(valueItem.unlocalizedName); } - public static ModularPanel createPopupPanel(String name, int width, int height) { - return createPopupPanel(name, width, height, false, false); + public static PopupPanel createPopupPanel(String name, int width, int height) { + return defaultPopupPanel(name) + .size(width, height); } - public static ModularPanel createPopupPanel(String name, int width, int height, boolean disableBelow, - boolean closeOnOutsideClick) { - return new PopupPanel(name, width, height, disableBelow, closeOnOutsideClick); + public static PopupPanel createPopupPanel(String name, int width, int height, boolean deleteCachedPanel) { + return createPopupPanel(name, width, height) + .deleteCachedPanel(deleteCachedPanel); } - public static ModularPanel defaultPopupPanel(String name) { - return defaultPopupPanel(name, false, false); + public static PopupPanel defaultPopupPanel(String name) { + return new PopupPanel(name) + .size(DEFAULT_WIDTH, DEFAULT_HIEGHT); } - public static ModularPanel defaultPopupPanel(String name, boolean disableBelow, - boolean closeOnOutsideClick) { - return new PopupPanel(name, DEFAULT_WIDTH, DEFAULT_HIEGHT, disableBelow, closeOnOutsideClick); + public static PopupPanel defaultPopupPanel(String name, boolean disableBelow, + boolean closeOnOutsideClick, boolean deleteCachedPanel) { + return defaultPopupPanel(name) + .disablePanelsBelow(disableBelow) + .closeOnOutOfBoundsClick(closeOnOutsideClick) + .deleteCachedPanel(deleteCachedPanel); } - private static class PopupPanel extends ModularPanel { + public static class PopupPanel extends ModularPanel { - private final boolean disableBelow; - private final boolean closeOnOutsideClick; + private boolean disableBelow; + private boolean closeOnOutsideClick; + private boolean deleteCachedPanel; - public PopupPanel(@NotNull String name, int width, int height, boolean disableBelow, - boolean closeOnOutsideClick) { + private PopupPanel(@NotNull String name) { super(name); - size(width, height).align(Alignment.Center); + align(Alignment.Center); background(GTGuiTextures.BACKGROUND_POPUP); child(ButtonWidget.panelCloseButton().top(5).right(5) .onMousePressed(mouseButton -> { if (mouseButton == 0 || mouseButton == 1) { this.closeIfOpen(true); - if (isSynced() && getSyncHandler() instanceof IPanelHandler handler) { - handler.deleteCachedPanel(); - } return true; } return false; })); + } + + @Override + public void onClose() { + super.onClose(); + if (deleteCachedPanel && isSynced() && getSyncHandler() instanceof IPanelHandler handler) { + handler.deleteCachedPanel(); + } + } + + public PopupPanel disablePanelsBelow(boolean disableBelow) { this.disableBelow = disableBelow; + return this; + } + + public PopupPanel closeOnOutOfBoundsClick(boolean closeOnOutsideClick) { this.closeOnOutsideClick = closeOnOutsideClick; + return this; + } + + public PopupPanel deleteCachedPanel(boolean deleteCachedPanel) { + this.deleteCachedPanel = deleteCachedPanel; + return this; + } + + @Override + public PopupPanel size(int w, int h) { + super.size(w, h); + return this; + } + + @Override + public PopupPanel size(int val) { + super.size(val); + return this; } @Override diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index 552c6bb4075..3bde5ee79d9 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -288,7 +288,7 @@ protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { for (String name : VirtualEnderRegistry.getEntryNames(getOwner(), type)) { rows.add(createRow(name, syncManager, type)); } - return GTGuis.createPopupPanel("entry_selector", 168, 112) + return GTGuis.createPopupPanel("entry_selector", 168, 112, true) .child(IKey.lang("cover.generic.ender.known_channels") .color(UI_TITLE_COLOR) .asWidget() @@ -310,7 +310,7 @@ protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { protected PanelSyncHandler.IPanelBuilder entryDescription(String key, T entry) { return (syncManager, syncHandler) -> { var sync = new StringSyncValue(entry::getDescription, entry::setDescription); - return GTGuis.createPopupPanel(key, 168, 36 + 6) + return GTGuis.createPopupPanel(key, 168, 36 + 6, true) .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) .color(UI_TITLE_COLOR) .asWidget() diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 0d91fd97cf8..d12a346724a 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -75,7 +75,7 @@ public void initUI(Consumer widgetGroup) {} @Override public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("ore_dict_filter", 188, 76) + return GTGuis.createPopupPanel("ore_dict_filter", 188, 76, false) .padding(7) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22)); diff --git a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java index b36acc61283..f91d5105799 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -39,7 +39,7 @@ public void configureFilterTanks(int amount) { @Override public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("simple_fluid_filter", 98, 81) + return GTGuis.createPopupPanel("simple_fluid_filter", 98, 81, false) .padding(4) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22)); diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index d69e6de7649..dbeabae9c0b 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -94,7 +94,7 @@ public void initUI(Consumer widgetGroup) { @Override public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("simple_item_filter", 98, 81) + return GTGuis.createPopupPanel("simple_item_filter", 98, 81, false) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22).left(4)); } diff --git a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java index d7cbf29c463..b86f37b0cde 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -98,7 +98,7 @@ public void initUI(Consumer widgetGroup) { @Override public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("smart_item_filter", 98 + 27, 81) + return GTGuis.createPopupPanel("smart_item_filter", 98 + 27, 81, false) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22).left(4)); }