diff --git a/src/main/java/gregtech/api/cover/CoverUIFactory.java b/src/main/java/gregtech/api/cover/CoverUIFactory.java index 1716cbeda27..8d8fe0ec860 100644 --- a/src/main/java/gregtech/api/cover/CoverUIFactory.java +++ b/src/main/java/gregtech/api/cover/CoverUIFactory.java @@ -13,7 +13,10 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.ApiStatus; + @Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.10") public final class CoverUIFactory extends UIFactory { public static final CoverUIFactory INSTANCE = new CoverUIFactory(); diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index b557e38cced..4cf44149d9f 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -1,7 +1,5 @@ package gregtech.api.cover; -import gregtech.api.gui.IUIHolder; -import gregtech.api.gui.ModularUI; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; @@ -17,6 +15,7 @@ import com.cleanroommc.modularui.api.IGuiHolder; import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; @@ -30,30 +29,36 @@ import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.function.BooleanSupplier; +import java.util.function.Supplier; -public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { +public interface CoverWithUI extends Cover, IGuiHolder, gregtech.api.gui.IUIHolder { @ApiStatus.Experimental default boolean usesMui2() { - return false; + // this is gonna cause problems if implementing classes expect this to be false + // all of our covers use mui2 though + return true; } default void openUI(EntityPlayerMP player) { if (usesMui2()) { CoverGuiFactory.open(player, this); } else { + // todo remove in 2.10 CoverUIFactory.INSTANCE.openUI(this, player); } } @Deprecated - default ModularUI createUI(EntityPlayer player) { + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + default gregtech.api.gui.ModularUI createUI(EntityPlayer player) { return null; } @@ -104,11 +109,22 @@ default void markAsDirty() { * Create the Title bar widget for a Cover. */ static Flow createTitleRow(ItemStack stack) { + return createTitleRow(() -> stack); + } + + /** + * Create the Title bar widget for a Cover. + */ + static Flow createTitleRow(Supplier stack) { + ItemDrawable itemDrawable = new ItemDrawable(); return Flow.row() .pos(4, 4) .height(16).coverChildrenWidth() - .child(new ItemDrawable(stack).asWidget().size(16).marginRight(4)) - .child(IKey.str(stack.getDisplayName()) + .child(new Widget<>() + .overlay(new DynamicDrawable(() -> itemDrawable.setItem(stack.get()))) + .size(16) + .marginRight(4)) + .child(IKey.dynamic(() -> stack.get().getDisplayName()) .color(UI_TITLE_COLOR) .asWidget().heightRel(1.0f)); } diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 998ad9c1d03..80baa6244bf 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -458,6 +458,22 @@ private static String id(String path) { public static final UITexture RESEARCH_STATION_OVERLAY = fullImage( "textures/gui/overlay/research_station_overlay.png", ColorType.DEFAULT); + // Texture Areas + public static final UITexture[] BUTTON_FLUID = slice("textures/blocks/cover/cover_interface_fluid_button.png", 18, + 36, null); + public static final UITexture[] BUTTON_ITEM = slice("textures/blocks/cover/cover_interface_item_button.png", 18, 36, + null); + public static final UITexture[] BUTTON_ENERGY = slice("textures/blocks/cover/cover_interface_energy_button.png", 18, + 36, null); + public static final UITexture[] BUTTON_MACHINE = slice("textures/blocks/cover/cover_interface_machine_button.png", + 18, 36, null); + public static final UITexture[] BUTTON_INTERFACE = slice( + "textures/blocks/cover/cover_interface_computer_button.png", 18, 36, null); + public static final UITexture COVER_INTERFACE_MACHINE_ON_PROXY = fullImage( + "textures/blocks/cover/cover_interface_machine_on_proxy.png"); + public static final UITexture COVER_INTERFACE_MACHINE_OFF_PROXY = fullImage( + "textures/blocks/cover/cover_interface_machine_off_proxy.png"); + // BUTTONS public static final UITexture BUTTON = new UITexture.Builder() diff --git a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java index bccbfd49be0..8f511e86f49 100644 --- a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java @@ -304,6 +304,8 @@ public void handleClick(MouseData data) { public void readOnServer(int id, PacketBuffer buf) { if (id == TRY_CLICK_CONTAINER) { var data = MouseData.readPacket(buf); + if (canLockFluid()) + toggleLockFluid(); if (isPhantom()) { tryClickPhantom(data); } else { @@ -316,14 +318,6 @@ public void readOnServer(int id, PacketBuffer buf) { setFluid(fluid); } else if (id == PHANTOM_SCROLL) { tryScrollPhantom(MouseData.readPacket(buf)); - } else if (id == LOCK_FLUID) { - boolean locked = buf.readBoolean(); - var fluidStack = NetworkUtils.readFluidStack(buf); - if (fluidStack == null) { - this.lockHandler.accept(locked); - } else { - this.jeiHandler.accept(fluidStack); - } } } @@ -341,19 +335,26 @@ public void tryClickPhantom(MouseData data) { } } else { FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); - if ((this.showAmountOnSlot.getAsBoolean() || currentFluid == null) && cellFluid != null) { + if (!GTUtility.areFluidStacksEqual(cellFluid, currentFluid)) { + + // drain existing + if (this.canDrainSlot()) { + int amt = data.shift ? Integer.MAX_VALUE : 1000; + this.tank.drain(amt, true); + } + + // then fill if (this.canFillSlot()) { - if (!this.showAmountOnSlot.getAsBoolean()) { - cellFluid.amount = 1; + FluidStack fill; + if (this.showAmountOnSlot.getAsBoolean() && !GTUtility.isEmpty(cellFluid)) { + fill = GTUtility.copy(cellFluid); + } else { + fill = GTUtility.copy(1, cellFluid); } - if (this.tank.fill(cellFluid, true) > 0) { - this.phantomFluid = cellFluid.copy(); + if (fill == null || this.tank.fill(fill, true) > 0) { + this.phantomFluid = fill; } } - } else { - if (this.canDrainSlot()) { - this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); - } } } } diff --git a/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java b/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java index 3d8ccd78224..f4c5e861908 100644 --- a/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java +++ b/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java @@ -7,7 +7,6 @@ import net.minecraft.world.World; import net.minecraft.world.storage.MapStorage; import net.minecraft.world.storage.WorldSavedData; -import net.minecraftforge.fluids.IFluidTank; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,18 +90,6 @@ private static VirtualRegistryMap getRegistry(UUID owner) { return VIRTUAL_REGISTRIES.computeIfAbsent(owner, key -> new VirtualRegistryMap()); } - // remove if tank app is removed - public static Map> createTankMap() { - Map> map = new HashMap<>(); - for (var uuid : VIRTUAL_REGISTRIES.keySet()) { - map.put(uuid, new HashMap<>()); - for (var name : getEntryNames(uuid, EntryTypes.ENDER_FLUID)) { - map.get(uuid).put(name, getEntry(uuid, EntryTypes.ENDER_FLUID, name)); - } - } - return map; - } - @Override public final void readFromNBT(NBTTagCompound nbt) { if (nbt.hasKey(PUBLIC_KEY)) { diff --git a/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java b/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java index 18a2b9a81e8..e7a29a68261 100644 --- a/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java +++ b/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -49,7 +50,7 @@ public void clear() { } public Set getEntryNames(EntryTypes type) { - return registryMap.get(type).keySet(); + return registryMap.getOrDefault(type, Collections.emptyMap()).keySet(); } @Override diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 8e10e7a0cc2..7cdd1b9f85b 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -15,6 +15,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; import gregtech.common.covers.filter.ItemFilterContainer; +import gregtech.common.mui.widget.GTTextFieldWidget; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipe; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -53,11 +54,8 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.layout.Flow; -import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; @@ -498,11 +496,6 @@ public T getCapability(Capability capability, T defaultValue) { return defaultValue; } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { var panel = GTGuis.createPanel(this, 176, 192 + 18); @@ -514,7 +507,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .bindPlayerInventory(); } - protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + protected Flow createUI(GuiData data, PanelSyncManager guiSyncManager) { var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); @@ -526,16 +519,12 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncMana IntSyncValue throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - StringSyncValue formattedThroughput = new StringSyncValue(throughput::getStringValue, - throughput::setStringValue); - EnumSyncValue distributionMode = new EnumSyncValue<>(DistributionMode.class, this::getDistributionMode, this::setDistributionMode); guiSyncManager.syncValue("manual_io", manualIOmode); guiSyncManager.syncValue("conveyor_mode", conveyorMode); guiSyncManager.syncValue("distribution_mode", distributionMode); - guiSyncManager.syncValue("throughput", throughput); if (createThroughputRow()) column.child(Flow.row().coverChildrenHeight() @@ -548,11 +537,12 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncMana return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) - .child(new TextFieldWidget() + .child(new GTTextFieldWidget() .left(18).right(18) + .setPostFix(" items/s") .setTextColor(Color.WHITE.darker(1)) .setNumbers(1, maxItemTransferRate) - .value(formattedThroughput) + .value(throughput) .background(GTGuiTextures.DISPLAY)) .child(new ButtonWidget<>() .right(0).width(18) diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 0063a113faa..793e0eb50a3 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -7,24 +7,25 @@ import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; import gregtech.api.metatileentity.IFastRenderMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTLog; -import gregtech.api.util.Position; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; import gregtech.common.gui.widget.prospector.widget.WidgetOreList; import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; +import gregtech.common.mui.widget.GTTextFieldWidget; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -60,6 +61,20 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import codechicken.lib.vec.Rotation; +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -86,11 +101,27 @@ public enum MODE { MACHINE, PROXY; - public static MODE[] VALUES; + public static final MODE[] VALUES; static { VALUES = MODE.values(); } + + public IKey getLangKey(boolean selected) { + return IKey.lang( + "metaitem.cover.digital.mode." + name().toLowerCase() + "." + (selected ? "enabled" : "disabled")); + } + + public IDrawable getOverlay(boolean selected) { + final int i = selected ? 1 : 0; + return switch (this) { + case FLUID -> GTGuiTextures.BUTTON_FLUID[i]; + case ITEM -> GTGuiTextures.BUTTON_ITEM[i]; + case ENERGY -> GTGuiTextures.BUTTON_ENERGY[i]; + case MACHINE -> GTGuiTextures.BUTTON_MACHINE[i]; + case PROXY -> GTGuiTextures.BUTTON_INTERFACE[i]; + }; + } } // run-time data @@ -451,52 +482,87 @@ public boolean modeLeftClick(EntityPlayer entityPlayer, MODE mode, int slot) { } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(new Position(0, 10)); - primaryGroup.addWidget(new LabelWidget(10, 5, "metaitem.cover.digital.name", 0)); - ToggleButtonWidget[] buttons = new ToggleButtonWidget[5]; - buttons[0] = new ToggleButtonWidget(40, 20, 20, 20, GuiTextures.BUTTON_FLUID, () -> this.mode == MODE.FLUID, - (pressed) -> { - if (pressed) setMode(MODE.FLUID); - }).setTooltipText("metaitem.cover.digital.mode.fluid"); - buttons[1] = new ToggleButtonWidget(60, 20, 20, 20, GuiTextures.BUTTON_ITEM, () -> this.mode == MODE.ITEM, - (pressed) -> { - if (pressed) setMode(MODE.ITEM); - }).setTooltipText("metaitem.cover.digital.mode.item"); - buttons[2] = new ToggleButtonWidget(80, 20, 20, 20, GuiTextures.BUTTON_ENERGY, () -> this.mode == MODE.ENERGY, - (pressed) -> { - if (pressed) setMode(MODE.ENERGY); - }).setTooltipText("metaitem.cover.digital.mode.energy"); - buttons[3] = new ToggleButtonWidget(100, 20, 20, 20, GuiTextures.BUTTON_MACHINE, - () -> this.mode == MODE.MACHINE, (pressed) -> { - if (pressed) setMode(MODE.MACHINE); - }).setTooltipText("metaitem.cover.digital.mode.machine"); - buttons[4] = new ToggleButtonWidget(140, 20, 20, 20, GuiTextures.BUTTON_INTERFACE, - () -> this.mode == MODE.PROXY, (pressed) -> { - if (pressed) setMode(MODE.PROXY); - }).setTooltipText("metaitem.cover.digital.mode.proxy"); - primaryGroup.addWidget(new LabelWidget(10, 25, "metaitem.cover.digital.title.mode", 0)); - primaryGroup.addWidget(buttons[0]); - primaryGroup.addWidget(buttons[1]); - primaryGroup.addWidget(buttons[2]); - primaryGroup.addWidget(buttons[3]); - primaryGroup.addWidget(buttons[4]); - - primaryGroup.addWidget(new LabelWidget(10, 50, "monitor.gui.title.slot", 0)); - primaryGroup.addWidget( - new ClickButtonWidget(40, 45, 20, 20, "-1", (data) -> setMode(slot - (data.isShiftClick ? 10 : 1)))); - primaryGroup.addWidget( - new ClickButtonWidget(140, 45, 20, 20, "+1", (data) -> setMode(slot + (data.isShiftClick ? 10 : 1)))); - primaryGroup.addWidget(new ImageWidget(60, 45, 80, 20, GuiTextures.DISPLAY)); - primaryGroup.addWidget(new SimpleTextWidget(100, 55, "", 16777215, () -> Integer.toString(this.slot))); - - primaryGroup.addWidget(new LabelWidget(10, 75, "metaitem.cover.digital.title.spin", 0)); - primaryGroup.addWidget(new ClickButtonWidget(40, 70, 20, 20, "R", (data) -> setMode(this.spin.rotateY()))); - primaryGroup.addWidget(new ImageWidget(60, 70, 80, 20, GuiTextures.DISPLAY)); - primaryGroup.addWidget(new SimpleTextWidget(100, 80, "", 16777215, () -> this.spin.toString())); - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 202).widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 8, 120); - return builder.build(this, player); + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { + Flow row = Flow.row() + .pos(10, 20) + .coverChildren() + .child(IKey.lang("metaitem.cover.digital.title.mode").asWidget() + .size(30, 20)); + + IntSyncValue slotValue = new IntSyncValue(() -> this.slot, this::setMode); + EnumSyncValue modeValue = new EnumSyncValue<>(MODE.class, this::getMode, this::setMode); + EnumSyncValue spinValue = new EnumSyncValue<>(EnumFacing.class, () -> this.spin, this::setMode); + guiSyncManager.syncValue("mode", modeValue); + guiSyncManager.syncValue("spin", spinValue); + + for (MODE mode : MODE.VALUES) { + row.child(new ButtonWidget<>() + .size(20) + .onMousePressed(m -> { + modeValue.setValue(mode); + return true; + }) + .tooltipAutoUpdate(true) + .tooltipBuilder(tooltip -> tooltip.add(mode.getLangKey(getMode() == mode))) + .disableHoverBackground() + .background(new DynamicDrawable(() -> mode.getOverlay(getMode() == mode)))); + } + + return GTGuis.createPanel(this, 176, 202) + .child(CoverWithUI.createTitleRow(getPickItem()) + .pos(5, 5)) + .child(row) + .child(Flow.row() + .pos(10, 45) + .coverChildren() + .child(IKey.lang("monitor.gui.title.slot").asWidget() + .size(30, 20)) + .child(new ButtonWidget<>() + .size(20) + .overlay(IKey.str("-") + .color(Color.WHITE.main)) + .onMousePressed(m -> { + int s = slotValue.getIntValue(); + s -= Interactable.hasShiftDown() ? 10 : 1; + slotValue.setIntValue(s); + return true; + })) + .child(new GTTextFieldWidget() + .setNumbers(0, Integer.MAX_VALUE) + .value(slotValue) + .size(80, 20) + .setTextColor(Color.WHITE.main) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .size(20) + .overlay(IKey.str("+") + .color(Color.WHITE.main)) + .onMousePressed(m -> { + int s = slotValue.getIntValue(); + s += Interactable.hasShiftDown() ? 10 : 1; + slotValue.setIntValue(s); + return true; + }))) + .child(Flow.row() + .pos(10, 75) + .coverChildren() + .child(IKey.lang("metaitem.cover.digital.title.spin").asWidget() + .size(30, 20)) + .child(new ButtonWidget<>() + .size(20) + .overlay(IKey.str("R") + .color(Color.WHITE.main)) + .onMousePressed(m -> { + spinValue.setValue(spinValue.getValue().rotateY()); + return true; + })) + .child(IKey.dynamic(() -> spinValue.getValue().toString()).asWidget() + .alignment(Alignment.CenterLeft) + .paddingLeft(4) + .size(80, 20) + .color(Color.WHITE.main) + .background(GTGuiTextures.DISPLAY))) + .bindPlayerInventory(); } private void syncAllInfo() { @@ -914,14 +980,14 @@ public T getCapability(@NotNull Capability capability, T defaultValue) { @Override public void renderCover(CCRenderState ccRenderState, Matrix4 translation, IVertexOperation[] ops, Cuboid6 cuboid6, BlockRenderLayer blockRenderLayer) { - codechicken.lib.vec.Rotation rotation = new codechicken.lib.vec.Rotation(0, 0, 1, 0); + Rotation rotation = new Rotation(0, 0, 1, 0); if (this.getAttachedSide().getAxis().isVertical()) { if (this.spin == EnumFacing.WEST) { translation.translate(0, 0, 1); - rotation = new codechicken.lib.vec.Rotation(Math.PI / 2, 0, 1, 0); + rotation = new Rotation(Math.PI / 2, 0, 1, 0); } else if (this.spin == EnumFacing.EAST) { translation.translate(1, 0, 0); - rotation = new codechicken.lib.vec.Rotation(-Math.PI / 2, 0, 1, 0); + rotation = new Rotation(-Math.PI / 2, 0, 1, 0); } else if (this.spin == EnumFacing.SOUTH) { translation.translate(1, 0, 1); rotation = new Rotation(Math.PI, 0, 1, 0); @@ -961,7 +1027,7 @@ public void renderMetaTileEntityFast(CCRenderState renderState, Matrix4 translat public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { GlStateManager.pushMatrix(); /* hack the lightmap */ - net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + RenderHelper.disableStandardItemLighting(); float lastBrightnessX = OpenGlHelper.lastBrightnessX; float lastBrightnessY = OpenGlHelper.lastBrightnessY; OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240.0F, 240.0F); @@ -976,7 +1042,7 @@ public void renderMetaTileEntity(double x, double y, double z, float partialTick /* restore the lightmap */ OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY); - net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + RenderHelper.enableStandardItemLighting(); GlStateManager.popMatrix(); } diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index d5d7ae1086e..c0d9ff4c375 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -89,6 +89,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeBoolean(this.allowFlow); packetBuffer.writeBoolean(this.fluidFilterContainer.hasFilter()); if (this.fluidFilterContainer.hasFilter()) { packetBuffer.writeItemStack(this.fluidFilterContainer.getFilterStack()); @@ -98,6 +99,7 @@ public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { this.filterMode = FluidFilterMode.VALUES[packetBuffer.readByte()]; + this.allowFlow = packetBuffer.readBoolean(); if (!packetBuffer.readBoolean()) return; try { this.fluidFilterContainer.setFilterStack(packetBuffer.readItemStack()); @@ -139,11 +141,6 @@ public boolean canPipePassThrough() { return EnumActionResult.SUCCESS; } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { var filteringMode = new EnumSyncValue<>(FluidFilterMode.class, this::getFilterMode, this::setFilterMode); @@ -208,6 +205,7 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", this.filterMode.ordinal()); tagCompound.setTag("Filter", this.fluidFilterContainer.serializeNBT()); + tagCompound.setBoolean("allowFlow", this.allowFlow); } @Override @@ -221,6 +219,7 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { } else { this.fluidFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); } + this.allowFlow = tagCompound.getBoolean("allowFlow"); } private class FluidHandlerFiltered extends FluidHandlerDelegate { diff --git a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java index a3cf6bcbf96..f87ab8b9957 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java +++ b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java @@ -28,7 +28,7 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.apache.logging.log4j.message.FormattedMessage; @@ -249,7 +249,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { + protected Flow createUI(GuiData data, PanelSyncManager syncManager) { var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); transferMode.updateCacheFromSource(true); syncManager.syncValue("transfer_mode", transferMode); diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index a1374655bdf..b39ca770bf2 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -31,7 +31,6 @@ import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; @@ -77,7 +76,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { + protected Flow createUI(GuiData data, PanelSyncManager syncManager) { BooleanSyncValue isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); return super.createUI(data, syncManager) diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index 84f722c39c6..b8be41ff6d3 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -28,7 +28,7 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -107,7 +107,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { + protected Flow createUI(GuiData data, PanelSyncManager syncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); syncManager.syncValue("voiding_mode", voidingMode); diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 274afc462d3..b64c75a5ee1 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -81,17 +81,19 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeBoolean(this.allowFlow); packetBuffer.writeBoolean(itemFilterContainer.hasFilter()); if (itemFilterContainer.hasFilter()) { - packetBuffer.writeByte(this.filterMode.ordinal()); packetBuffer.writeItemStack(this.itemFilterContainer.getFilterStack()); } } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { - if (!packetBuffer.readBoolean()) return; this.filterMode = ItemFilterMode.VALUES[packetBuffer.readByte()]; + this.allowFlow = packetBuffer.readBoolean(); + if (!packetBuffer.readBoolean()) return; try { this.itemFilterContainer.setFilterStack(packetBuffer.readItemStack()); } catch (IOException e) { @@ -142,11 +144,6 @@ public boolean testItemStack(ItemStack stack) { return itemFilterContainer.test(stack); } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { var filteringMode = new EnumSyncValue<>(ItemFilterMode.class, this::getFilterMode, this::setFilterMode); @@ -196,6 +193,7 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", filterMode.ordinal()); tagCompound.setTag("Filter", this.itemFilterContainer.serializeNBT()); + tagCompound.setBoolean("allowFlow", this.allowFlow); } @Override @@ -209,6 +207,7 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { } else { this.itemFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); } + this.allowFlow = tagCompound.getBoolean("allowFlow"); } @Override diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index 95cfa8c8241..a69c9da98f8 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -28,7 +28,6 @@ import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; @@ -78,7 +77,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + protected Flow createUI(GuiData data, PanelSyncManager guiSyncManager) { BooleanSyncValue isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); return super.createUI(data, guiSyncManager) diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index 1a716509505..d66e93c1a69 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -25,7 +25,6 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -95,7 +94,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + protected Flow createUI(GuiData data, PanelSyncManager guiSyncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); guiSyncManager.syncValue("voiding_mode", voidingMode); diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 3a97582a9bc..8f076c37319 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -106,11 +106,6 @@ public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing s return EnumActionResult.SUCCESS; } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { EnumSyncValue controllerModeValue = new EnumSyncValue<>(ControllerMode.class, diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index 29bf0b2b52c..c595a56774a 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -14,6 +14,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; import gregtech.common.covers.filter.FluidFilterContainer; +import gregtech.common.mui.widget.GTTextFieldWidget; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.player.EntityPlayer; @@ -51,11 +52,8 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.layout.Flow; -import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -184,11 +182,6 @@ protected boolean checkInputFluid(FluidStack fluidStack) { return fluidFilterContainer.test(fluidStack); } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { var panel = GTGuis.createPanel(this, 176, 192); @@ -200,20 +193,16 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .bindPlayerInventory(); } - protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { + protected Flow createUI(GuiData data, PanelSyncManager syncManager) { var manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode); var throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - var throughputString = new StringSyncValue( - throughput::getStringValue, throughput::setStringValue); - var pumpMode = new EnumSyncValue<>(PumpMode.class, this::getPumpMode, this::setPumpMode); syncManager.syncValue("manual_io", manualIOmode); syncManager.syncValue("pump_mode", pumpMode); - syncManager.syncValue("throughput", throughput); var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); @@ -229,11 +218,12 @@ protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) - .child(new TextFieldWidget() + .child(new GTTextFieldWidget() .left(18).right(18) + .setPostFix(" L/s") .setTextColor(Color.WHITE.darker(1)) .setNumbers(1, maxFluidTransferRate) - .value(throughputString) + .value(throughput) .background(GTGuiTextures.DISPLAY)) .child(new ButtonWidget<>() .right(0).width(18) diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 31918dbcaac..159453207e7 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -27,7 +27,6 @@ import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; -import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -198,7 +197,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + protected Flow createUI(GuiData data, PanelSyncManager guiSyncManager) { EnumSyncValue transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); guiSyncManager.syncValue("transfer_mode", transferMode); diff --git a/src/main/java/gregtech/common/covers/CoverStorage.java b/src/main/java/gregtech/common/covers/CoverStorage.java index addf992cd3b..24dc4ac49d1 100644 --- a/src/main/java/gregtech/common/covers/CoverStorage.java +++ b/src/main/java/gregtech/common/covers/CoverStorage.java @@ -81,11 +81,6 @@ public void onRemoval() { return EnumActionResult.SUCCESS; } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { guiSyncManager.registerSlotGroup("item_inv", this.storageHandler.getSlots()); diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorBase.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorBase.java index b4df7c1822a..8e14f5fadb9 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorBase.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorBase.java @@ -3,6 +3,7 @@ import gregtech.api.cover.CoverBase; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.common.mui.widget.GTTextFieldWidget; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; @@ -10,15 +11,29 @@ import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextComponentTranslation; import codechicken.lib.raytracer.CuboidRayTraceResult; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.LongSyncValue; +import com.cleanroommc.modularui.widgets.layout.Flow; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; +import java.util.function.LongConsumer; +import java.util.function.LongSupplier; +import java.util.function.Supplier; import static gregtech.api.capability.GregtechDataCodes.UPDATE_INVERTED; public abstract class CoverDetectorBase extends CoverBase { + protected static final String MIN_KEY = "min"; + protected static final String MAX_KEY = "max"; protected static final String NBT_KEY_IS_INVERTED = "isInverted"; private boolean isInverted = false; @@ -48,6 +63,12 @@ private void toggleInvertedWithNotification() { } } + @Override + public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { + if (discriminator == UPDATE_INVERTED) + setInverted(buf.readBoolean()); + } + public final void setRedstoneSignalOutput(int redstoneSignalOutput) { this.redstoneSignalOutput = redstoneSignalOutput; getCoverableView().notifyBlockUpdate(); @@ -111,40 +132,58 @@ public boolean canConnectRedstone() { } /** - * Returns parsed result of {@code value} as long, or {@code fallbackValue} if the parse fails. + * Clamps {@code val} as int between {@code minValue} and {@code maxValue}. * - * @param value String to parse - * @param minValue Minimum value - * @param maxValue Maximum value - * @param fallbackValue Fallback value to be used in case of parse failure. + * @param val Current value + * @param minValue Minimum value + * @param maxValue Maximum value * @return Capped value of either parsed result or {@code fallbackValue} */ - protected static long parseCapped(String value, long minValue, long maxValue, long fallbackValue) { - long parsedValue; - try { - parsedValue = Long.parseLong(value); - } catch (NumberFormatException e) { - parsedValue = fallbackValue; - } - return Math.min(Math.max(parsedValue, minValue), maxValue); + protected final long clamp(long val, long minValue, long maxValue) { + return Math.min(Math.max(val, minValue), maxValue); } /** - * Returns parsed result of {@code value} as int, or {@code fallbackValue} if the parse fails. + * Clamps {@code val} as int between {@code minValue} and {@code maxValue}. * - * @param value String to parse - * @param minValue Minimum value - * @param maxValue Maximum value - * @param fallbackValue Fallback value to be used in case of parse failure. + * @param val Current value + * @param minValue Minimum value + * @param maxValue Maximum value * @return Capped value of either parsed result or {@code fallbackValue} */ - protected static int parseCapped(String value, int minValue, int maxValue, int fallbackValue) { - int parsedValue; - try { - parsedValue = Integer.parseInt(value); - } catch (NumberFormatException e) { - parsedValue = fallbackValue; - } - return Math.min(Math.max(parsedValue, minValue), maxValue); + protected final int clamp(int val, int minValue, int maxValue) { + return MathHelper.clamp(val, minValue, maxValue); + } + + protected static Flow createMinMaxRow(@NotNull String lang, @NotNull LongSupplier getter, + @Nullable LongConsumer setter) { + return createMinMaxRow(lang, getter, setter, null, null); + } + + protected static Flow createMinMaxRow(@NotNull String lang, @NotNull LongSupplier getter, + @Nullable LongConsumer setter, + @Nullable Supplier postFix, + @Nullable Consumer listener) { + return createMinMaxRow(lang, new LongSyncValue(getter, setter), postFix, listener); + } + + protected static Flow createMinMaxRow(@NotNull String lang, + @NotNull LongSyncValue syncValue, + @Nullable Supplier postFix, + @Nullable Consumer listener) { + return Flow.row() + .name("min/max row") + .coverChildrenHeight() + .marginBottom(5) + .child(IKey.lang(lang).asWidget()) + .child(new GTTextFieldWidget() + .name("min/max field") + .right(0) + .size(90, 18 - 4) + .setTextColor(Color.WHITE.main) + .setPattern(TextFieldWidget.WHOLE_NUMS) + .setPostFix(postFix) + .onUpdateListener(listener) + .value(syncValue)); } } diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java index 5363b7a48ca..286902aad32 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java @@ -7,6 +7,7 @@ import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; +import gregtech.common.metatileentities.storage.MetaTileEntityCreativeEnergy; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; @@ -27,7 +28,9 @@ public CoverDetectorEnergy(@NotNull CoverDefinition definition, @NotNull Coverab @Override public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { - return coverable.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, null) != null || + // do not attach for creative energy emitter + if (coverable instanceof MetaTileEntityCreativeEnergy) return false; + return coverable.hasCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, null) || coverable instanceof MetaTileEntityPowerSubstation; // todo check this } diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java index 95ebec138aa..d100e97289b 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java @@ -3,12 +3,10 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; +import gregtech.common.mui.widget.GTTextFieldWidget; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -24,20 +22,25 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverDetectorEnergyAdvanced extends CoverDetectorEnergy implements CoverWithUI { - private static final int PADDING = 5, SIZE = 18; - - private static final long DEFAULT_MIN_EU = 0, DEFAULT_MAX_EU = 2048; - private static final int DEFAULT_MIN_PERCENT = 33, DEFAULT_MAX_PERCENT = 66; + private static final long DEFAULT_MIN_EU = 0; + private static final long DEFAULT_MAX_EU = 2048; public long minValue = DEFAULT_MIN_EU; public long maxValue = DEFAULT_MAX_EU; private int outputAmount = 0; private boolean usePercent = false; - private WidgetGroup widgetsToUpdate; public CoverDetectorEnergyAdvanced(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide) { @@ -82,78 +85,76 @@ public void update() { } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup group = new WidgetGroup(); - group.addWidget(new LabelWidget(10, 8, "cover.advanced_energy_detector.label")); - - // get/set min EU - group.addWidget(new LabelWidget(10, 5 + (SIZE + PADDING), "cover.advanced_energy_detector.min")); - group.addWidget(new ImageWidget(72, (SIZE + PADDING), 8 * SIZE, SIZE, GuiTextures.DISPLAY)); - - // get/set max EU - group.addWidget(new LabelWidget(10, 5 + 2 * (SIZE + PADDING), "cover.advanced_energy_detector.max")); - group.addWidget(new ImageWidget(72, 2 * (SIZE + PADDING), 8 * SIZE, SIZE, GuiTextures.DISPLAY)); - - // surely this is a good idea :clueless: - // construct widgets that need to be updated - this.widgetsToUpdate = constructWidgetsToUpdate(); - - // change modes between percent and discrete EU - group.addWidget(new LabelWidget(10, 5 + 3 * (SIZE + PADDING), "cover.advanced_energy_detector.modes_label")); - group.addWidget( - new CycleButtonWidget(72, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isUsePercent, this::setUsePercent, - "cover.advanced_energy_detector.mode_eu", "cover.advanced_energy_detector.mode_percent") - .setTooltipHoverString("cover.advanced_energy_detector.modes_tooltip")); - - // invert logic button - group.addWidget(new LabelWidget(10, 5 + 4 * (SIZE + PADDING), "cover.generic.advanced_detector.invert_label")); - group.addWidget( - new CycleButtonWidget(72, 4 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") - .setTooltipHoverString("cover.advanced_energy_detector.invert_tooltip")); - - return ModularUI.builder(GuiTextures.BACKGROUND, 176 + (3 * SIZE), 108 + (SIZE)) - .widget(group) - .widget(widgetsToUpdate) // add synced widgets - .build(this, player); - } - - private WidgetGroup constructWidgetsToUpdate() { - WidgetGroup sync = new WidgetGroup(); - - sync.addWidget( - new TextFieldWidget2(76, 5 + (SIZE + PADDING), 8 * SIZE, SIZE, this::getMinValue, this::setMinValue) - .setAllowedChars(TextFieldWidget2.NATURAL_NUMS) - .setMaxLength(this.getLength()) - .setPostFix(this.getPostFix())); - sync.addWidget( - new TextFieldWidget2(76, 5 + 2 * (SIZE + PADDING), 8 * SIZE, SIZE, this::getMaxValue, this::setMaxValue) - .setAllowedChars(TextFieldWidget2.NATURAL_NUMS) - .setMaxLength(this.getLength()) - .setPostFix(this.getPostFix())); - return sync; - } - - private String getMinValue() { - return String.valueOf(minValue); - } - - private String getMaxValue() { - return String.valueOf(maxValue); - } - - private void setMinValue(String val) { - this.minValue = CoverDetectorBase.parseCapped(val, - 0, - this.maxValue - 1, - usePercent ? DEFAULT_MIN_PERCENT : DEFAULT_MIN_EU); - } - - private void setMaxValue(String val) { - this.maxValue = CoverDetectorBase.parseCapped(val, - this.minValue + 1, - usePercent ? 100 : Long.MAX_VALUE, - usePercent ? DEFAULT_MAX_PERCENT : DEFAULT_MAX_EU); + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager syncManager, UISettings settings) { + return GTGuis.defaultPanel(this) + .height(202) + .child(CoverWithUI.createTitleRow(getPickItem())) + .child(Flow.column() + .name("min/max parent column") + .top(28) + .margin(10, 0) + .coverChildrenHeight() + .child(createMinMaxRow("cover.advanced_energy_detector.min", + this::getMinValue, this::setMinValue, + this::getPostFix, this::updateWidget)) + .child(createMinMaxRow("cover.advanced_energy_detector.max", + this::getMaxValue, this::setMaxValue, + this::getPostFix, this::updateWidget)) + .child(Flow.row() + .name("mode row") + .coverChildrenHeight() + .marginBottom(5) + .child(IKey.lang("cover.advanced_energy_detector.modes_label").asWidget() + .size(72, 18)) + .child(new ToggleButton() + .name("mode button") + .right(0) + .size(72, 18) + .addTooltipLine(IKey.lang("cover.advanced_energy_detector.modes_tooltip")) + .value(new BooleanSyncValue(this::isUsePercent, this::setUsePercent)) + .overlay(true, IKey.lang("cover.advanced_energy_detector.mode_percent") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.advanced_energy_detector.mode_eu") + .style(IKey.WHITE)))) + .child(Flow.row() + .name("inverted row") + .coverChildrenHeight() + .child(IKey.lang("cover.generic.advanced_detector.invert_label").asWidget() + .size(72, 18)) + .child(new ToggleButton() + .name("inverted button") + .right(0) + .size(72, 18) + .addTooltipLine(IKey.lang("cover.advanced_energy_detector.invert_tooltip")) + .value(new BooleanSyncValue(this::isInverted, this::setInverted)) + .overlay(true, IKey.lang("cover.advanced_energy_detector.inverted") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.advanced_energy_detector.normal") + .style(IKey.WHITE))))) + .bindPlayerInventory(); + } + + private void updateWidget(GTTextFieldWidget w) { + w.setMaxLength(getLength()); + w.setNumbersLong(0, isUsePercent() ? 100 : Long.MAX_VALUE); + } + + private long getMinValue() { + return minValue; + } + + private long getMaxValue() { + return maxValue; + } + + private void setMinValue(long val) { + this.minValue = clamp(val, + 0, this.maxValue - 1); + } + + private void setMaxValue(long val) { + this.maxValue = clamp(val, + this.minValue + 1, usePercent ? 100 : Long.MAX_VALUE); } private boolean isUsePercent() { @@ -161,25 +162,30 @@ private boolean isUsePercent() { } private void setUsePercent(boolean b) { + if (isUsePercent() == b) return; this.usePercent = b; - if (this.usePercent) { // using percent - this.minValue = DEFAULT_MIN_PERCENT; - this.maxValue = DEFAULT_MAX_PERCENT; - } else { // using discrete EU + if (getCoverHolderCapacity() == 0) { + // can't use capacity, use default values this.minValue = DEFAULT_MIN_EU; - this.maxValue = DEFAULT_MAX_EU; + this.maxValue = isUsePercent() ? 100 : DEFAULT_MAX_EU; + return; } - // update widgets - updateSyncedWidgets(); - } - - private void updateSyncedWidgets() { - for (Widget widget : widgetsToUpdate.widgets) { - ((TextFieldWidget2) widget).setPostFix(getPostFix()); - ((TextFieldWidget2) widget).setMaxLength(getLength()); + // todo should precision be increased for percent? + // for large eu values switching modes starts to break down + long minValue, maxValue; + if (this.usePercent) { + // using percent + minValue = (long) Math.ceil(((double) this.minValue / getCoverHolderCapacity()) * 100d); + maxValue = (long) Math.ceil(((double) this.maxValue / getCoverHolderCapacity()) * 100d); + } else { + // using discrete EU + minValue = (long) Math.floor((this.minValue / 100d) * getCoverHolderCapacity()); + maxValue = (long) Math.floor((this.maxValue / 100d) * getCoverHolderCapacity()); } + this.minValue = clamp(minValue, 0, maxValue - 1); + this.maxValue = clamp(maxValue, minValue + 1, isUsePercent() ? 100 : Integer.MAX_VALUE); } private String getPostFix() { diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java index e3b0a26db68..f40fc28746f 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java @@ -4,6 +4,7 @@ import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; +import gregtech.common.metatileentities.storage.MetaTileEntityCreativeTank; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; @@ -28,7 +29,8 @@ public CoverDetectorFluid(@NotNull CoverDefinition definition, @NotNull Coverabl @Override public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { - return coverable.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null) != null; + if (coverable instanceof MetaTileEntityCreativeTank) return false; + return coverable.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null); } @Override diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java index 56d7eb246c9..0a05cb08ffb 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java @@ -3,9 +3,7 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.FluidFilterContainer; @@ -18,6 +16,7 @@ import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -28,17 +27,24 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverDetectorFluidAdvanced extends CoverDetectorFluid implements CoverWithUI { - private static final int PADDING = 3; - private static final int SIZE = 18; - private static final int DEFAULT_MIN = 1000; // 1 Bucket private static final int DEFAULT_MAX = 16000; // 16 Buckets - private int min = DEFAULT_MIN, max = DEFAULT_MAX, outputAmount; + private long min = DEFAULT_MIN; + private long max = DEFAULT_MAX; + private int outputAmount; private boolean isLatched = false; protected FluidFilterContainer fluidFilter; @@ -65,62 +71,66 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup group = new WidgetGroup(); - group.addWidget(new LabelWidget(10, 8, "cover.advanced_fluid_detector.label")); - - // set min fluid amount - group.addWidget(new LabelWidget(10, 5 + (SIZE + PADDING), "cover.advanced_fluid_detector.min")); - group.addWidget(new ImageWidget(98 - 4, (SIZE + PADDING), 4 * SIZE, SIZE, GuiTextures.DISPLAY)); - group.addWidget(new TextFieldWidget2(98, 5 + (SIZE + PADDING), 4 * SIZE, SIZE, - this::getMinValue, this::setMinValue) - .setMaxLength(10) - .setAllowedChars(TextFieldWidget2.WHOLE_NUMS) - .setPostFix("L")); - - // set max fluid amount - group.addWidget(new LabelWidget(10, 5 + 2 * (SIZE + PADDING), "cover.advanced_fluid_detector.max")); - group.addWidget(new ImageWidget(98 - 4, 2 * (SIZE + PADDING), 4 * SIZE, SIZE, GuiTextures.DISPLAY)); - group.addWidget(new TextFieldWidget2(98, 5 + 2 * (SIZE + PADDING), 4 * SIZE, SIZE, - this::getMaxValue, this::setMaxValue) - .setMaxLength(10) - .setAllowedChars(TextFieldWidget2.WHOLE_NUMS) - .setPostFix("L")); - - // invert logic button - // group.addWidget(new LabelWidget(10, 5 + 3 * (SIZE + PADDING), - // "cover.generic.advanced_detector.invert_label")); - group.addWidget( - new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") - .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); - group.addWidget( - new CycleButtonWidget(94, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isLatched, this::setLatched, - "cover.generic.advanced_detector.continuous", "cover.generic.advanced_detector.latched") - .setTooltipHoverString("cover.generic.advanced_detector.latch_tooltip")); - - this.fluidFilter.initUI(5 + 4 * (SIZE + PADDING), group::addWidget); + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { + return GTGuis.defaultPanel(this) + .height(202) + .child(CoverWithUI.createTitleRow(getPickItem())) + .child(Flow.column() + .name("min/max parent column") + .top(28) + .margin(5, 0) + .coverChildrenHeight() + .child(createMinMaxRow("cover.advanced_fluid_detector.min", + this::getMinValue, this::setMinValue, + this::getPostFix, w -> w.setMaxLength(10))) + .child(createMinMaxRow("cover.advanced_fluid_detector.max", + this::getMaxValue, this::setMaxValue, + this::getPostFix, w -> w.setMaxLength(10))) + .child(Flow.row() + .name("config row") + .coverChildrenHeight() + .marginBottom(5) + .child(new ToggleButton() + .name("inverted button") + .size(72, 18) + .value(new BooleanSyncValue(this::isInverted, this::setInverted)) + .addTooltipLine(IKey.lang("cover.generic.advanced_detector.invert_tooltip")) + .overlay(true, IKey.lang("cover.advanced_energy_detector.inverted") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.advanced_energy_detector.normal") + .style(IKey.WHITE))) + .child(new ToggleButton() + .name("latch button") + .size(72, 18) + .right(0) + .overlay(true, IKey.lang("cover.generic.advanced_detector.latched") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.generic.advanced_detector.continuous") + .style(IKey.WHITE)) + .addTooltipLine(IKey.lang("cover.generic.advanced_detector.latch_tooltip")) + .value(new BooleanSyncValue(this::isLatched, this::setLatched)))) + .child(this.fluidFilter.initUI(guiData, guiSyncManager))) + .bindPlayerInventory(); + } - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 164 + 4 * (SIZE + PADDING)) - .widget(group) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 164) - .build(this, player); + private @NotNull String getPostFix() { + return " mL"; } - private String getMinValue() { - return String.valueOf(min); + private long getMinValue() { + return min; } - private String getMaxValue() { - return String.valueOf(max); + private long getMaxValue() { + return max; } - private void setMinValue(String val) { - this.min = CoverDetectorBase.parseCapped(val, 0, max - 1, DEFAULT_MIN); + private void setMinValue(long val) { + this.min = clamp(val, 0, max - 1); } - private void setMaxValue(String val) { - this.max = CoverDetectorBase.parseCapped(val, min + 1, Integer.MAX_VALUE, DEFAULT_MAX); + private void setMaxValue(long val) { + this.max = clamp(val, min + 1, Long.MAX_VALUE); } private void setLatched(boolean isLatched) { @@ -162,8 +172,8 @@ public void update() { @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); - tagCompound.setInteger("min", this.min); - tagCompound.setInteger("max", this.max); + tagCompound.setLong(MIN_KEY, this.min); + tagCompound.setLong(MAX_KEY, this.max); tagCompound.setBoolean("isLatched", this.isLatched); tagCompound.setTag("filter", this.fluidFilter.serializeNBT()); } @@ -171,8 +181,14 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.min = tagCompound.getInteger("min"); - this.max = tagCompound.getInteger("max"); + if (tagCompound.hasKey(MIN_KEY, Constants.NBT.TAG_INT)) { + // if one of them is int, so is the other + this.min = tagCompound.getInteger(MIN_KEY); + this.max = tagCompound.getInteger(MAX_KEY); + } else { + this.min = tagCompound.getLong(MIN_KEY); + this.max = tagCompound.getLong(MAX_KEY); + } this.isLatched = tagCompound.getBoolean("isLatched"); this.fluidFilter.deserializeNBT(tagCompound.getCompoundTag("filter")); } @@ -180,16 +196,16 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeInt(this.min); - packetBuffer.writeInt(this.max); + packetBuffer.writeLong(this.min); + packetBuffer.writeLong(this.max); packetBuffer.writeBoolean(this.isLatched); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.min = packetBuffer.readInt(); - this.max = packetBuffer.readInt(); + this.min = packetBuffer.readLong(); + this.max = packetBuffer.readLong(); this.isLatched = packetBuffer.readBoolean(); } } diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java index 00df1e03792..c9cfeb43bc1 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java @@ -4,6 +4,7 @@ import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; +import gregtech.common.metatileentities.storage.MetaTileEntityCreativeChest; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; @@ -26,7 +27,8 @@ public CoverDetectorItem(@NotNull CoverDefinition definition, @NotNull Coverable @Override public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { - return coverable.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) != null; + if (coverable instanceof MetaTileEntityCreativeChest) return false; + return coverable.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); } @Override diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java index e2475756fd5..e3368e8ddd5 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java @@ -3,9 +3,7 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.ItemFilterContainer; @@ -18,6 +16,7 @@ import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraftforge.common.util.Constants; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -26,17 +25,24 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverDetectorItemAdvanced extends CoverDetectorItem implements CoverWithUI { - private static final int PADDING = 3; - private static final int SIZE = 18; - private static final int DEFAULT_MIN = 64; private static final int DEFAULT_MAX = 512; - private int min = DEFAULT_MIN, max = DEFAULT_MAX, outputAmount; + private long min = DEFAULT_MIN; + private long max = DEFAULT_MAX; + private int outputAmount; private boolean isLatched = false; protected ItemFilterContainer itemFilter; @@ -53,74 +59,60 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup group = new WidgetGroup(); - group.addWidget(new LabelWidget(10, 8, "cover.advanced_item_detector.label")); - - // set min fluid amount - group.addWidget(new LabelWidget(10, 5 + (SIZE + PADDING), "cover.advanced_item_detector.min")); - group.addWidget(new ImageWidget(98 - 4, (SIZE + PADDING), 4 * SIZE, SIZE, GuiTextures.DISPLAY)); - group.addWidget(new TextFieldWidget2(98, 5 + (SIZE + PADDING), 4 * SIZE, SIZE, - this::getMinValue, this::setMinValue) - .setMaxLength(10) - .setAllowedChars(TextFieldWidget2.WHOLE_NUMS)); - - // set max fluid amount - group.addWidget(new LabelWidget(10, 5 + 2 * (SIZE + PADDING), "cover.advanced_item_detector.max")); - group.addWidget(new ImageWidget(98 - 4, 2 * (SIZE + PADDING), 4 * SIZE, SIZE, GuiTextures.DISPLAY)); - group.addWidget(new TextFieldWidget2(98, 5 + 2 * (SIZE + PADDING), 4 * SIZE, SIZE, - this::getMaxValue, this::setMaxValue) - .setMaxLength(10) - .setAllowedChars(TextFieldWidget2.WHOLE_NUMS)); - - // invert logic button - // group.addWidget(new LabelWidget(10, 5 + 3 * (SIZE + PADDING), - // "cover.generic.advanced_detector.invert_label")); - group.addWidget( - new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") - .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); - // group.addWidget(new LabelWidget(10, 5 + 4 * (SIZE + PADDING), - // "cover.generic.advanced_detector.latch_label")); - group.addWidget( - new CycleButtonWidget(94, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isLatched, this::setLatched, - "cover.generic.advanced_detector.continuous", "cover.generic.advanced_detector.latched") - .setTooltipHoverString("cover.generic.advanced_detector.latch_tooltip")); - - this.itemFilter.initUI(5 + 4 * (SIZE + PADDING), group::addWidget); - - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 188 + 4 * (SIZE + PADDING)) - .widget(group) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 188) - .build(this, player); + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { + return GTGuis.defaultPanel(this) + .height(202) + .child(CoverWithUI.createTitleRow(getPickItem())) + .child(Flow.column() + .name("min/max parent column") + .top(28) + .margin(5, 0) + .coverChildrenHeight() + .child(createMinMaxRow("cover.advanced_item_detector.min", + this::getMinValue, this::setMinValue)) + .child(createMinMaxRow("cover.advanced_item_detector.max", + this::getMaxValue, this::setMaxValue)) + .child(Flow.row() + .name("config row") + .coverChildrenHeight() + .marginBottom(5) + .child(new ToggleButton() + .name("inverted button") + .size(72, 18) + .overlay(true, IKey.lang("cover.advanced_energy_detector.inverted") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.advanced_energy_detector.normal") + .style(IKey.WHITE)) + .addTooltipLine(IKey.lang("cover.generic.advanced_detector.invert_tooltip")) + .value(new BooleanSyncValue(this::isInverted, this::setInverted))) + .child(new ToggleButton() + .name("latch button") + .size(72, 18) + .right(0) + .overlay(true, IKey.lang("cover.generic.advanced_detector.latched") + .style(IKey.WHITE)) + .overlay(false, IKey.lang("cover.generic.advanced_detector.continuous") + .style(IKey.WHITE)) + .addTooltipLine(IKey.lang("cover.generic.advanced_detector.latch_tooltip")) + .value(new BooleanSyncValue(this::isLatched, this::setLatched)))) + .child(itemFilter.initUI(guiData, guiSyncManager))) + .bindPlayerInventory(); } - private String getMinValue() { - return String.valueOf(min); + private long getMinValue() { + return min; } - private String getMaxValue() { - return String.valueOf(max); + private long getMaxValue() { + return max; } - private void setMinValue(String val) { - int parsedValue; - try { - parsedValue = Integer.parseInt(val); - } catch (NumberFormatException e) { - parsedValue = DEFAULT_MIN; - } - this.min = Math.min(max - 1, Math.max(0, parsedValue)); + private void setMinValue(long val) { + this.min = clamp(val, 0, this.max - 1); } - private void setMaxValue(String val) { - int parsedValue; - try { - parsedValue = Integer.parseInt(val); - } catch (NumberFormatException e) { - parsedValue = DEFAULT_MAX; - } - max = Math.max(min + 1, parsedValue); + private void setMaxValue(long val) { + this.max = clamp(val, this.min + 1, Long.MAX_VALUE); } private void setLatched(boolean isLatched) { @@ -168,8 +160,8 @@ public void update() { @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); - tagCompound.setInteger("min", this.min); - tagCompound.setInteger("max", this.max); + tagCompound.setLong(MIN_KEY, this.min); + tagCompound.setLong(MAX_KEY, this.max); tagCompound.setBoolean("isLatched", this.isLatched); tagCompound.setTag("filter", this.itemFilter.serializeNBT()); } @@ -177,8 +169,14 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.min = tagCompound.getInteger("min"); - this.max = tagCompound.getInteger("max"); + if (tagCompound.hasKey(MIN_KEY, Constants.NBT.TAG_INT)) { + // if one of them is int, so is the other + this.min = tagCompound.getInteger(MIN_KEY); + this.max = tagCompound.getInteger(MAX_KEY); + } else { + this.min = tagCompound.getLong(MIN_KEY); + this.max = tagCompound.getLong(MAX_KEY); + } this.isLatched = tagCompound.getBoolean("isLatched"); this.itemFilter.deserializeNBT(tagCompound.getCompoundTag("filter")); } @@ -186,16 +184,16 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeInt(this.min); - packetBuffer.writeInt(this.max); + packetBuffer.writeLong(this.min); + packetBuffer.writeLong(this.max); packetBuffer.writeBoolean(this.isLatched); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.min = packetBuffer.readInt(); - this.max = packetBuffer.readInt(); + this.min = packetBuffer.readLong(); + this.max = packetBuffer.readLong(); this.isLatched = packetBuffer.readBoolean(); } } diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index f37a17d39fd..c200f506267 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -11,7 +11,9 @@ import gregtech.api.util.virtualregistry.EntryTypes; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.util.virtualregistry.VirtualEntry; +import gregtech.common.mui.widget.GTTextFieldWidget; import gregtech.common.mui.widget.InteractableText; +import gregtech.integration.ftb.utility.FTBTeamHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -24,6 +26,7 @@ import net.minecraft.util.ITickable; import codechicken.lib.raytracer.CuboidRayTraceResult; +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.DynamicDrawable; @@ -44,11 +47,9 @@ import com.cleanroommc.modularui.widgets.ListWidget; import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Flow; -import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.lwjgl.input.Keyboard; import java.util.ArrayList; import java.util.List; @@ -97,6 +98,11 @@ protected final UUID getOwner() { return isPrivate ? playerUUID : null; } + protected boolean canAccess(UUID other) { + return this.playerUUID == null || this.playerUUID.equals(other) || + FTBTeamHelper.isSameTeam(this.playerUUID, other); + } + @Override public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { super.readCustomData(discriminator, buf); @@ -131,36 +137,41 @@ public void updateColor(String str) { } } - @Override - public boolean usesMui2() { - return true; - } - @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { - var panel = GTGuis.createPanel(this, 176, 192); - - this.playerUUID = guiData.getPlayer().getUniqueID(); - - return panel.child(CoverWithUI.createTitleRow(getPickItem())) + if (!isPrivate()) { + // if we're public, we update the player uuid + // so when set to private, it'll use the latest player uuid + this.playerUUID = guiData.getPlayer().getUniqueID(); + } + return GTGuis.createPanel(this, 176, 192) + .child(CoverWithUI.createTitleRow(getPickItem())) .child(createWidgets(guiData, guiSyncManager)) .bindPlayerInventory(); } protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { - var name = new StringSyncValue(this::getColorStr, this::updateColor); + StringSyncValue name; + UUID uuid = data.getPlayer().getUniqueID(); - var entrySelectorSH = syncManager.panel("entry_selector", entrySelector(getType()), true); + if (canAccess(uuid)) { + name = new StringSyncValue(this::getColorStr, this::updateColor); + } else { + name = new StringSyncValue(this::getColorStr); + } + + IPanelHandler entrySelectorSH = syncManager.panel("entry_selector", entrySelector(getType(), uuid), true); return Flow.column().coverChildrenHeight().top(24) .margin(7, 0).widthRel(1f) - .child(new Row().marginBottom(2) + .child(Flow.row().marginBottom(2) .coverChildrenHeight() - .child(createPrivateButton()) + .child(createPrivateButton(uuid)) .child(createColorIcon()) .child(new TextFieldWidget() .height(18) .value(name) + .setTextColor(Color.WHITE.main) .setPattern(COLOR_INPUT_PATTERN) .widthRel(0.5f) .marginRight(2)) @@ -179,7 +190,7 @@ protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { } return true; }))) - .child(createIoRow()); + .child(createIoRow(uuid)); } protected abstract IWidget createEntrySlot(); @@ -194,29 +205,39 @@ protected IWidget createColorIcon() { .marginRight(2); } - protected IWidget createPrivateButton() { + protected IWidget createPrivateButton(UUID uniqueID) { + BooleanSyncValue syncValue; + if (canAccess(uniqueID)) + syncValue = new BooleanSyncValue(this::isPrivate, this::setPrivate); + else { + syncValue = new BooleanSyncValue(this::isPrivate); + } return new ToggleButton() - .value(new BooleanSyncValue(this::isPrivate, this::setPrivate)) - .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .value(syncValue) .background(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) .hoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) .selectedBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) .selectedHoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) - .tooltipBuilder(tooltip -> tooltip.addLine(IKey.lang(this.isPrivate ? - "cover.ender_fluid_link.private.tooltip.enabled" : - "cover.ender_fluid_link.private.tooltip.disabled"))) + .addTooltip(true, IKey.lang("cover.ender_fluid_link.private.tooltip.enabled")) + .addTooltip(false, IKey.lang("cover.ender_fluid_link.private.tooltip.disabled")) .marginRight(2); } - protected IWidget createIoRow() { + protected IWidget createIoRow(UUID uuid) { + BooleanSyncValue syncValue; + if (canAccess(uuid)) { + syncValue = new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled); + } else { + syncValue = new BooleanSyncValue(this::isIoEnabled); + } return Flow.row().marginBottom(2) .coverChildrenHeight() .child(new ToggleButton() - .value(new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled)) - .overlay(IKey.lang(() -> this.ioEnabled ? - "behaviour.soft_hammer.enabled" : - "behaviour.soft_hammer.disabled") - .color(Color.WHITE.darker(1))) + .value(syncValue) + .overlay(true, IKey.lang("behaviour.soft_hammer.enabled") + .color(Color.WHITE.main)) + .overlay(false, IKey.lang("behaviour.soft_hammer.disabled") + .color(Color.WHITE.main)) .widthRel(0.6f) .left(0)); } @@ -252,6 +273,7 @@ private void setPrivate(boolean isPrivate) { @Override public void writeInitialSyncData(PacketBuffer packetBuffer) { packetBuffer.writeString(this.playerUUID == null ? "null" : this.playerUUID.toString()); + packetBuffer.writeBoolean(this.isPrivate); } @Override @@ -259,6 +281,7 @@ public void readInitialSyncData(PacketBuffer packetBuffer) { // does client even need uuid info? just in case String uuidStr = packetBuffer.readString(36); this.playerUUID = uuidStr.equals("null") ? null : UUID.fromString(uuidStr); + this.isPrivate = packetBuffer.readBoolean(); } @Override @@ -283,11 +306,11 @@ public void writeToNBT(@NotNull NBTTagCompound nbt) { nbt.setInteger("Frequency", activeEntry.getColor()); } - protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { + protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type, UUID uuid) { return (syncManager, syncHandler) -> { List rows = new ArrayList<>(); for (String name : VirtualEnderRegistry.getEntryNames(getOwner(), type)) { - rows.add(createRow(name, syncManager, type)); + rows.add(createRow(name, syncManager, type, uuid)); } return GTGuis.createPopupPanel("entry_selector", 168, 112, true) .child(IKey.lang("cover.generic.ender.known_channels") @@ -297,7 +320,6 @@ protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { .left(4)) .child(new ListWidget<>() .children(rows) - // .builder(names, name -> createRow(name, syncManager, type)) .background(GTGuiTextures.DISPLAY.asIcon() .width(168 - 8) .height(112 - 20)) @@ -317,21 +339,13 @@ protected PanelSyncHandler.IPanelBuilder entryDescription(String key, T entry) { .asWidget() .left(4) .top(6)) - .child(new TextFieldWidget() { - - // todo move this to new class? - @Override - public @NotNull Result onKeyPressed(char character, int keyCode) { - var result = super.onKeyPressed(character, keyCode); - if (result == Result.SUCCESS && keyCode == Keyboard.KEY_RETURN) { - sync.setStringValue(getText()); + .child(new GTTextFieldWidget() + .onTextAccept(string -> { if (syncHandler.isPanelOpen()) { syncHandler.closePanel(); } - } - return result; - } - }.setTextColor(Color.WHITE.darker(1)) + }) + .setTextColor(Color.WHITE.darker(1)) .value(sync) .widthRel(0.95f) .height(18) @@ -340,13 +354,15 @@ protected PanelSyncHandler.IPanelBuilder entryDescription(String key, T entry) { }; } - protected IWidget createRow(final String name, final PanelSyncManager syncManager, final EntryTypes type) { - final T entry = VirtualEnderRegistry.getEntry(getOwner(), type, name); - var key = String.format("entry#%s_description", entry.getColorStr()); - var syncKey = PanelSyncManager.makeSyncKey(key, isPrivate ? 1 : 0); - final var panelHandler = (PanelSyncHandler) syncManager.panel(syncKey, + protected IWidget createRow(String name, PanelSyncManager syncManager, + EntryTypes type, UUID uuid) { + T entry = VirtualEnderRegistry.getEntry(getOwner(), type, name); + String key = String.format("entry#%s_description", entry.getColorStr()); + String syncKey = PanelSyncManager.makeSyncKey(key, isPrivate ? 1 : 0); + IPanelHandler panelHandler = syncManager.panel(syncKey, entryDescription(key, entry), true); - final var syncHandler = new EnderCoverSyncHandler(); + + EnderCoverSyncHandler syncHandler = new EnderCoverSyncHandler(); syncManager.syncValue(key + "_handler", syncHandler); return Flow.row() @@ -362,8 +378,13 @@ protected IWidget createRow(final String name, final PanelSyncManager syncManage .size(16) .background(GTGuiTextures.SLOT.asIcon().size(18)) .top(1)) - .child(new InteractableText<>(entry, this::updateColor) - .tooltipAutoUpdate(true) + .child(new InteractableText<>(entry, str -> { + if (canAccess(uuid)) { + updateColor(str); + return true; + } + return false; + }).tooltipAutoUpdate(true) .tooltipBuilder(tooltip -> { String desc = entry.getDescription(); if (!desc.isEmpty()) tooltip.add(desc); @@ -376,6 +397,8 @@ protected IWidget createRow(final String name, final PanelSyncManager syncManage .overlay(GuiTextures.GEAR) .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) .onMousePressed(i -> { + if (!canAccess(uuid)) return false; + // open entry settings if (panelHandler.isPanelOpen()) { panelHandler.closePanel(); @@ -390,6 +413,8 @@ protected IWidget createRow(final String name, final PanelSyncManager syncManage .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) .onMousePressed(i -> { + if (!canAccess(uuid)) return false; + // todo option to force delete, maybe as a popup? deleteEntry(getOwner(), name); syncHandler.syncToServer(1, buffer -> { diff --git a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java index 4c373dfd41c..0a3f14a990b 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java @@ -148,7 +148,6 @@ protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { var pumpMode = new EnumSyncValue<>(CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode); syncManager.syncValue("pump_mode", pumpMode); - pumpMode.updateCacheFromSource(true); return super.createWidgets(data, syncManager) .child(getFluidFilterContainer().initUI(data, syncManager)) diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilter.java b/src/main/java/gregtech/common/covers/filter/BaseFilter.java index 1bc6bc8f2d6..c5591a5021b 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilter.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilter.java @@ -34,8 +34,8 @@ public BaseFilterReader getFilterReader() { } @Override - public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("error", 100, 100) + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName) { + return GTGuis.createPopupPanel(panelName, 100, 100) .child(createWidgets(syncManager)); } diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java index b2a08d4f580..8c050a2e394 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -3,6 +3,7 @@ import gregtech.api.cover.CoverWithUI; import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.IDirtyNotifiable; +import gregtech.api.util.ItemStackHashStrategy; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -25,6 +26,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + public abstract class BaseFilterContainer extends ItemStackHandler { private int maxTransferSize = 1; @@ -81,11 +85,7 @@ public void setStackInSlot(int slot, @NotNull ItemStack stack) { if (ItemStack.areItemStacksEqual(stack, getFilterStack())) return; - if (stack.isEmpty()) { - setFilter(null); - } else if (isItemValid(stack)) { - setFilter(BaseFilter.getFilterFromStack(stack)); - } + setFilter(BaseFilter.getFilterFromStack(stack)); super.setStackInSlot(slot, stack); } @@ -140,7 +140,7 @@ public final boolean hasFilter() { } public final void setFilter(@Nullable BaseFilter newFilter) { - this.currentFilter = newFilter; + this.currentFilter = BaseFilter.ERROR_FILTER == newFilter ? null : newFilter; if (hasFilter()) { this.currentFilter.setDirtyNotifiable(this.dirtyNotifiable); this.currentFilter.setMaxTransferSize(this.maxTransferSize); @@ -212,12 +212,21 @@ public void handleLegacyNBT(NBTTagCompound nbt) { /** Uses Cleanroom MUI */ public IWidget initUI(GuiData data, PanelSyncManager manager) { - IPanelHandler panel = manager.panel("filter_panel", (syncManager, syncHandler) -> { + // i bet brachy is gonna really hate this, but it *does* work + // todo Find a better way to handle the filter popup panel than making + // a new panel handler every time it changes + // Could use a DynamicSyncedWidget or a client only panel in a future PR + AtomicReference filterPanel = new AtomicReference<>(); + AtomicReference oldStack = new AtomicReference<>(getFilterStack()); + AtomicInteger counter = new AtomicInteger(); + if (hasFilter()) filterPanel.set(getFilter().createPanelHandler(manager, counter.getAndIncrement())); + manager.registerSyncedAction("update_filter_panel", packet -> { if (hasFilter()) { - return getFilter().createPopupPanel(syncManager); + // make new panel handler only when we have a filter + filterPanel.set(getFilter().createPanelHandler(manager, counter.getAndIncrement())); } - return BaseFilter.ERROR_FILTER.createPopupPanel(syncManager); - }, true); + }); + ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingItemDamageCount(); return Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) @@ -226,9 +235,16 @@ public IWidget initUI(GuiData data, PanelSyncManager manager) { .filter(this::isItemValid) .singletonSlotGroup(101) .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!isItemValid(newItem) || (newItem.isEmpty() && panel.isPanelOpen())) { + if (strategy.equals(oldStack.get(), newItem)) return; + oldStack.set(newItem); + + IPanelHandler panel = filterPanel.get(); + if (panel != null && panel.isPanelOpen()) { panel.closePanel(); } + if (client) { + manager.callSyncedAction("update_filter_panel", packetBuffer -> {}); + } })) .size(18).marginRight(2) .background(GTGuiTextures.SLOT, GTGuiTextures.FILTER_SLOT_OVERLAY.asIcon().size(16))) @@ -238,6 +254,8 @@ public IWidget initUI(GuiData data, PanelSyncManager manager) { GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) .setEnabledIf(w -> hasFilter()) .onMousePressed(i -> { + IPanelHandler panel = filterPanel.get(); + if (panel == null) return false; if (!panel.isPanelOpen()) { setMaxTransferSize(getMaxTransferSize()); panel.openPanel(); diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java index 7dee10a1032..df2bc6d54de 100644 --- a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java @@ -5,51 +5,14 @@ import net.minecraft.item.ItemStack; import com.cleanroommc.modularui.api.drawable.IKey; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; - public class FluidFilterContainer extends BaseFilterContainer { public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable) { super(dirtyNotifiable); } - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new gregtech.api.gui.widgets.LabelWidget(10, y, "cover.pump.fluid_filter.title")); - widgetGroup.accept(new gregtech.api.gui.widgets.SlotWidget(this, 0, 10, y + 15) - .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, - gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); - - this.initFilterUI(y + 15, widgetGroup); - this.blacklistUI(y + 15, widgetGroup, () -> true); - } - - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupFluidFilter(y, this::getFilter, this::showGlobalTransferLimitSlider)); - } - - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - gregtech.api.gui.widgets.ServerWidgetGroup blacklistButton = new gregtech.api.gui.widgets.ServerWidgetGroup( - this::hasFilter); - blacklistButton.addWidget(new gregtech.api.gui.widgets.ToggleButtonWidget(144, y, 18, 18, - gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - @Override protected boolean isItemValid(ItemStack stack) { var filter = BaseFilter.getFilterFromStack(stack); diff --git a/src/main/java/gregtech/common/covers/filter/IFilter.java b/src/main/java/gregtech/common/covers/filter/IFilter.java index 05441442eb0..1bbde04af5d 100644 --- a/src/main/java/gregtech/common/covers/filter/IFilter.java +++ b/src/main/java/gregtech/common/covers/filter/IFilter.java @@ -6,22 +6,19 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.function.Consumer; - public interface IFilter { - @Deprecated - default void initUI(Consumer widgetGroup) {} - /** Uses Cleanroom MUI */ @NotNull - ModularPanel createPopupPanel(PanelSyncManager syncManager); + ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName); /** Uses Cleanroom MUI */ @NotNull @@ -32,6 +29,14 @@ default void initUI(Consumer widgetGroup) {} @NotNull Widget createWidgets(PanelSyncManager syncManager); + default IPanelHandler createPanelHandler(PanelSyncManager syncManager, int id) { + String translationKey = getContainerStack().getTranslationKey(); + return syncManager.getOrCreateSyncHandler(translationKey, id, PanelSyncHandler.class, () -> { + String key = PanelSyncManager.makeSyncKey(translationKey, id); + return (PanelSyncHandler) syncManager.panel(key, (psm, $) -> createPopupPanel(psm, key), true); + }); + } + ItemStack getContainerStack(); void setDirtyNotifiable(@Nullable IDirtyNotifiable dirtyNotifiable); diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java index 514d3d80e31..6d1705edf86 100644 --- a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java @@ -1,56 +1,18 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.ServerWidgetGroup; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.util.IDirtyNotifiable; import net.minecraft.item.ItemStack; import com.cleanroommc.modularui.api.drawable.IKey; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; - public class ItemFilterContainer extends BaseFilterContainer { public ItemFilterContainer(IDirtyNotifiable dirtyNotifiable) { super(dirtyNotifiable); } - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.conveyor.item_filter.title")); - widgetGroup.accept(new SlotWidget(this, 0, 10, y + 15) - .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, - gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); - - this.initFilterUI(y + 38, widgetGroup); - } - - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupItemFilter(y, this::getFilter)); - } - - /** @deprecated uses old builtin MUI */ - @Deprecated - @ApiStatus.ScheduledForRemoval(inVersion = "2.10") - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - ServerWidgetGroup blacklistButton = new ServerWidgetGroup(this::hasFilter); - blacklistButton.addWidget(new ToggleButtonWidget(144, y, 20, 20, gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - @Override protected boolean isItemValid(ItemStack stack) { var filter = BaseFilter.getFilterFromStack(stack); diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 1bfed239a08..75f2ed81afd 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -37,7 +37,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Consumer; public class OreDictionaryItemFilter extends BaseFilter { @@ -71,11 +70,8 @@ protected void clearCache() { } @Override - public void initUI(Consumer widgetGroup) {} - - @Override - public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("ore_dict_filter", 188, 76, false) + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName) { + return GTGuis.createPopupPanel(panelName, 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 25bbbf64362..f7b276a8f59 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -15,8 +15,6 @@ import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; - public class SimpleFluidFilter extends BaseFilter { private static final int MAX_FLUID_SLOTS = 9; @@ -38,8 +36,8 @@ public void configureFilterTanks(int amount) { } @Override - public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("simple_fluid_filter", 98, 81, false) + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName) { + return GTGuis.createPopupPanel(panelName, 98, 81, false) .padding(4) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22)); @@ -92,15 +90,6 @@ public boolean testFluid(FluidStack toTest) { return false; } - @Override - public void initUI(Consumer widgetGroup) { - for (int i = 0; i < 9; ++i) { - widgetGroup.accept((new gregtech.api.gui.widgets.PhantomFluidWidget(10 + 18 * (i % 3), 18 * (i / 3), 18, 18, - filterReader.getFluidTank(i))) - .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); - } - } - @Override public int getTransferLimit(FluidStack fluidStack, int transferSize) { int limit = 0; diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index abd858833a5..d4eb282053b 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -1,9 +1,6 @@ package gregtech.common.covers.filter; import gregtech.api.cover.CoverWithUI; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.widgets.PhantomSlotWidget; -import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.util.TextFormattingUtil; @@ -30,8 +27,6 @@ import com.cleanroommc.modularui.widgets.slot.SlotGroup; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; - public class SimpleItemFilter extends BaseFilter { private static final int MAX_MATCH_SLOTS = 9; @@ -80,21 +75,8 @@ public int getTransferLimit(ItemStack stack, int transferSize) { } @Override - public void initUI(Consumer widgetGroup) { - for (int i = 0; i < 9; i++) { - widgetGroup.accept(new PhantomSlotWidget(filterReader, i, 10 + 18 * (i % 3), 18 * (i / 3)) - .setBackgroundTexture(GuiTextures.SLOT)); - } - widgetGroup.accept(new ToggleButtonWidget(74, 0, 20, 20, GuiTextures.BUTTON_FILTER_DAMAGE, - filterReader::isIgnoreDamage, filterReader::setIgnoreDamage) - .setTooltipText("cover.item_filter.ignore_damage")); - widgetGroup.accept(new ToggleButtonWidget(99, 0, 20, 20, GuiTextures.BUTTON_FILTER_NBT, - filterReader::isIgnoreNBT, filterReader::setIgnoreNBT).setTooltipText("cover.item_filter.ignore_nbt")); - } - - @Override - public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("simple_item_filter", 98, 81, false) + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName) { + return GTGuis.createPopupPanel(panelName, 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 b86f37b0cde..f35becde25d 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -1,7 +1,6 @@ package gregtech.common.covers.filter; import gregtech.api.cover.CoverWithUI; -import gregtech.api.gui.widgets.CycleButtonWidget; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.recipes.Recipe; @@ -27,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import java.util.Collections; -import java.util.function.Consumer; public class SmartItemFilter extends BaseFilter { @@ -90,15 +88,8 @@ public FilterType getType() { } @Override - public void initUI(Consumer widgetGroup) { - widgetGroup.accept(new CycleButtonWidget(10, 0, 75, 20, - SmartFilteringMode.class, filterReader::getFilteringMode, filterReader::setFilteringMode) - .setTooltipHoverString("cover.smart_item_filter.filtering_mode.description")); - } - - @Override - public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { - return GTGuis.createPopupPanel("smart_item_filter", 98 + 27, 81, false) + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager, String panelName) { + return GTGuis.createPopupPanel(panelName, 98 + 27, 81, false) .child(CoverWithUI.createTitleRow(getContainerStack())) .child(createWidgets(syncManager).top(22).left(4)); } diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java deleted file mode 100644 index c43d7487467..00000000000 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java +++ /dev/null @@ -1,78 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; - -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; - -import org.jetbrains.annotations.ApiStatus; - -import java.io.IOException; -import java.util.function.Supplier; - -/** - * @deprecated in favor of new MUI - */ -@Deprecated -@ApiStatus.ScheduledForRemoval(inVersion = "2.10") -public class WidgetGroupFluidFilter extends AbstractWidgetGroup { - - private final Supplier fluidFilterSupplier; - private final Supplier showTipSupplier; - private BaseFilter fluidFilter; - - public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSupplier, - Supplier showTipSupplier) { - super(new Position(18 + 5, yPosition)); - this.fluidFilterSupplier = fluidFilterSupplier; - this.showTipSupplier = showTipSupplier; - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - BaseFilter newFluidFilter = fluidFilterSupplier.get(); - if (fluidFilter != newFluidFilter) { - clearAllWidgets(); - this.fluidFilter = newFluidFilter; - if (fluidFilter != null) { - this.fluidFilter.initUI(this::addWidget); - } - writeUpdateInfo(2, buffer -> { - if (fluidFilter != null) { - buffer.writeBoolean(true); - buffer.writeItemStack(fluidFilter.getContainerStack()); - } else { - buffer.writeBoolean(false); - } - }); - } - // if (fluidFilter != null && showTipSupplier != null && fluidFilter.showTip != showTipSupplier.get()) { - // fluidFilter.showTip = showTipSupplier.get(); - // writeUpdateInfo(3, buffer -> buffer.writeBoolean(fluidFilter.showTip)); - // } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 2) { - clearAllWidgets(); - if (buffer.readBoolean()) { - ItemStack stack; - try { - stack = buffer.readItemStack(); - } catch (IOException e) { - GTLog.logger.warn(e); - return; - } - this.fluidFilter = BaseFilter.getFilterFromStack(stack); - this.fluidFilter.initUI(this::addWidget); - } - } else if (id == 3) { - // fluidFilter.showTip = buffer.readBoolean(); - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java deleted file mode 100644 index 9f26302fb2f..00000000000 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java +++ /dev/null @@ -1,77 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.util.Position; - -import net.minecraft.network.PacketBuffer; - -import org.jetbrains.annotations.ApiStatus; - -import java.io.IOException; -import java.util.function.Supplier; - -/** - * @deprecated in favor of new MUI - */ -@Deprecated -@ApiStatus.ScheduledForRemoval(inVersion = "2.10") -public class WidgetGroupItemFilter extends AbstractWidgetGroup { - - private final Supplier itemFilterSupplier; - private BaseFilter itemFilter; - private int maxStackSize = 1; - - public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSupplier) { - super(new Position(0, yPosition)); - this.itemFilterSupplier = itemFilterSupplier; - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - BaseFilter newItemFilter = itemFilterSupplier.get(); - if (itemFilter != newItemFilter) { - clearAllWidgets(); - this.itemFilter = newItemFilter; - if (itemFilter != null) { - this.itemFilter.initUI(this::addWidget); - } - writeUpdateInfo(2, buffer -> { - if (itemFilter != null) { - buffer.writeBoolean(true); - buffer.writeItemStack(itemFilter.getContainerStack()); - } else { - buffer.writeBoolean(false); - } - }); - } - int newMaxStackSize = itemFilter == null ? 1 : itemFilter.getMaxTransferSize(); - if (maxStackSize != newMaxStackSize) { - this.maxStackSize = newMaxStackSize; - writeUpdateInfo(3, buffer -> buffer.writeVarInt(maxStackSize)); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 2) { - clearAllWidgets(); - if (buffer.readBoolean()) { - // int filterId = buffer.readVarInt(); - try { - this.itemFilter = BaseFilter.getFilterFromStack(buffer.readItemStack()); - this.itemFilter.initUI(this::addWidget); - this.itemFilter.setMaxTransferSize(maxStackSize); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } else if (id == 3) { - this.maxStackSize = buffer.readVarInt(); - if (itemFilter != null) { - itemFilter.setMaxTransferSize(maxStackSize); - } - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java index ea38dafd569..c9ea2a4032a 100644 --- a/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java +++ b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java @@ -5,7 +5,8 @@ import net.minecraft.nbt.NBTTagList; import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; import org.jetbrains.annotations.Nullable; @@ -19,10 +20,6 @@ public class SimpleFluidFilterReader extends BaseFilterReader { public SimpleFluidFilterReader(ItemStack container, int slots) { super(container, slots); fluidTanks = new WritableFluidTank[slots]; - for (int i = 0; i < fluidTanks.length; i++) { - fluidTanks[i] = new WritableFluidTank(this, getInventoryNbt().getCompoundTagAt(i)); - } - setCapacity(getStackTag().hasKey(CAPACITY) ? getCapacity() : 1000); } public final boolean shouldShowAmount() { @@ -40,10 +37,15 @@ public void setCapacity(int capacity) { } public int getCapacity() { + if (!getStackTag().hasKey(CAPACITY)) + getStackTag().setInteger(CAPACITY, 1000); return getStackTag().getInteger(CAPACITY); } public WritableFluidTank getFluidTank(int i) { + if (fluidTanks[i] == null) { + fluidTanks[i] = new WritableFluidTank(i); + } return fluidTanks[i]; } @@ -78,25 +80,27 @@ public void handleLegacyNBT(NBTTagCompound tag) { } } - public class WritableFluidTank extends FluidTank { + public class WritableFluidTank implements IFluidTank { - private final NBTTagCompound fluidTank; - private final SimpleFluidFilterReader filterReader; protected static final String FLUID_AMOUNT = "Amount"; protected static final String FLUID = "Fluid"; protected static final String EMPTY = "Empty"; - protected WritableFluidTank(SimpleFluidFilterReader filterReader, NBTTagCompound fluidTank) { - super(0); - this.filterReader = filterReader; - this.fluidTank = fluidTank; + private final int index; + + public WritableFluidTank(int index) { + this.index = index; + } + + private NBTTagCompound getTank() { + return getInventoryNbt().getCompoundTagAt(this.index); } public void setFluidAmount(int amount) { if (amount <= 0) { setFluid(null); - } else if (this.fluidTank.hasKey(FLUID)) { - this.fluidTank + } else if (this.getTank().hasKey(FLUID)) { + this.getTank() .getCompoundTag(FLUID) .setInteger(FLUID_AMOUNT, amount); markDirty(); @@ -104,7 +108,7 @@ public void setFluidAmount(int amount) { } public boolean isEmpty() { - return !this.fluidTank.hasKey(FLUID); + return !this.getTank().hasKey(FLUID); } protected @Nullable NBTTagCompound getFluidTag() { @@ -112,7 +116,7 @@ public boolean isEmpty() { return null; } - return this.fluidTank.getCompoundTag(FLUID); + return this.getTank().getCompoundTag(FLUID); } @Override @@ -121,40 +125,43 @@ public boolean isEmpty() { } @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + // @Override public void setFluid(@Nullable FluidStack stack) { if (stack == null) { - this.fluidTank.removeTag(FLUID); + this.getTank().removeTag(FLUID); } else { - this.fluidTank.setTag(FLUID, stack.writeToNBT(new NBTTagCompound())); + this.getTank().setTag(FLUID, stack.writeToNBT(new NBTTagCompound())); } markDirty(); } - public boolean showAmount() { - return this.filterReader.shouldShowAmount(); - } - @Override public int getFluidAmount() { - return this.fluidTank + return this.getTank() .getCompoundTag(FLUID) .getInteger(FLUID_AMOUNT); } @Override public int getCapacity() { - return this.filterReader.getCapacity(); + return SimpleFluidFilterReader.this.getCapacity(); } // getFluid() is checked for nullability, suppress @SuppressWarnings("DataFlowIssue") @Override public int fill(FluidStack resource, boolean doFill) { + // todo this class and filter readers really should not be handling show amount + // in a future pr if (isEmpty() || !getFluid().isFluidEqual(resource)) { setFluid(resource); - if (!showAmount()) setFluidAmount(1); + if (!shouldShowAmount()) setFluidAmount(1); return resource.amount; - } else if (showAmount()) { + } else if (shouldShowAmount()) { var fluid = getFluid(); int accepted = Math.min(resource.amount, getCapacity() - fluid.amount); fluid.amount += accepted; diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java index 1128819ff6d..f28489a4add 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java @@ -252,7 +252,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { } } - this.itemFilter.initUI(45 + rowSize * 18 + 5, builder::widget); + // this.itemFilter.initUI(45 + rowSize * 18 + 5, builder::widget); builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 45 + rowSize * 18 + 105); return builder.build(getHolder(), entityPlayer); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java index 29b350c41e9..469d5e3df4e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java @@ -19,6 +19,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -60,7 +61,7 @@ public MetaTileEntityCreativeChest(ResourceLocation metaTileEntityId) { protected void initializeInventory() { super.initializeInventory(); this.modifiableHandler = new ModifiableHandler(); - this.itemInventory = this.creativeHandler = new CreativeItemStackHandler(1); + this.creativeHandler = new CreativeItemStackHandler(1); } @Override @@ -194,6 +195,14 @@ public IItemHandler getTypeValue() { return this.creativeHandler; } + @Override + public T getCapability(Capability capability, EnumFacing side) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(this.creativeHandler); + } + return super.getCapability(capability, side); + } + // todo try to refactor this with mui2 rc6 protected class ModifiableHandler extends QuantumChestItemHandler implements IItemHandlerModifiable { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java index a6218aa7323..843e7387bdc 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java @@ -17,6 +17,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; @@ -157,6 +158,14 @@ public void addInformation(ItemStack stack, @Nullable World player, List // do not append the normal tooltips } + @Override + public T getCapability(Capability capability, EnumFacing side) { + if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { + return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(this.fluidTank); + } + return super.getCapability(capability, side); + } + private class CreativeFluidTank extends FluidTank { private final FluidTank internal; diff --git a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java index 23c14ab82ca..2de42778c68 100644 --- a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java +++ b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java @@ -117,9 +117,6 @@ public void draw(ModularGuiContext context, WidgetThemeEntry widgetTheme) { this.syncHandler.canFillSlot() || this.syncHandler.canDrainSlot()) { this.syncHandler.handleClick(data); - if (this.syncHandler.canLockFluid()) - this.syncHandler.toggleLockFluid(); - return Result.SUCCESS; } return Result.IGNORE; diff --git a/src/main/java/gregtech/common/mui/widget/GTTextFieldWidget.java b/src/main/java/gregtech/common/mui/widget/GTTextFieldWidget.java new file mode 100644 index 00000000000..485312f57db --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/GTTextFieldWidget.java @@ -0,0 +1,286 @@ +package gregtech.common.mui.widget; + +import gregtech.api.util.GTLog; + +import net.minecraft.util.math.MathHelper; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.value.IStringValue; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; +import com.cleanroommc.modularui.utils.MathUtils; +import com.cleanroommc.modularui.utils.ParseResult; +import com.cleanroommc.modularui.value.StringValue; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.value.sync.ValueSyncHandler; +import com.cleanroommc.modularui.widgets.textfield.BaseTextFieldWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldHandler; +import com.cleanroommc.modularui.widgets.textfield.TextFieldRenderer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.input.Keyboard; + +import java.text.ParsePosition; +import java.util.function.Consumer; +import java.util.function.DoubleUnaryOperator; +import java.util.function.Function; +import java.util.function.IntSupplier; +import java.util.function.IntUnaryOperator; +import java.util.function.LongSupplier; +import java.util.function.LongUnaryOperator; +import java.util.function.Supplier; +import java.util.regex.Pattern; + +public class GTTextFieldWidget extends BaseTextFieldWidget { + + private IStringValue stringValue; + private Function validator = val -> val; + private boolean numbers = false; + private double defaultNumber = 0; + private boolean tooltipOverride = false; + private final GTTextFieldRenderer renderer; + private Consumer onTextAccept = null; + + public GTTextFieldWidget() { + this.renderer = new GTTextFieldRenderer(this.handler); + super.renderer = this.renderer; + } + + public double parse(String num) { + ParseResult result = MathUtils.parseExpression(num, this.defaultNumber, true); + double value = result.getResult(); + if (result.isFailure()) { + String mathFailMessage = result.getError(); + GTLog.logger.error("Math expression error in {}: {}", this, mathFailMessage); + } + return value; + } + + @Override + public void onInit() { + super.onInit(); + if (this.stringValue == null) { + this.stringValue = new StringValue(""); + } + setText(this.stringValue.getStringValue()); + if (!hasTooltip() && !tooltipOverride) { + tooltipBuilder(tooltip -> tooltip.addLine(IKey.str(getText()))); + tooltipOverride = false; + } + } + + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + if (syncHandler instanceof IStringValueiStringValue && + syncHandler instanceof ValueSyncHandlervalueSyncHandler) { + this.stringValue = iStringValue; + valueSyncHandler.setChangeListener(() -> { + markTooltipDirty(); + setText(this.stringValue.getValue().toString()); + }); + return true; + } + return false; + } + + @Override + public void onUpdate() { + super.onUpdate(); + if (!isFocused()) { + String s = this.stringValue.getStringValue(); + if (!getText().equals(s)) { + setText(s); + } + } + } + + @Override + public @NotNull Result onKeyPressed(char character, int keyCode) { + Result result = super.onKeyPressed(character, keyCode); + if (result == Result.SUCCESS) switch (keyCode) { + case Keyboard.KEY_RETURN, Keyboard.KEY_NUMPADENTER -> { + if (this.onTextAccept != null) { + this.onTextAccept.accept(getText()); + } + } + } + return result; + } + + @Override + public void drawForeground(ModularGuiContext context) { + RichTooltip tooltip = getTooltip(); + if (tooltip != null && + (tooltipOverride || getScrollData().isScrollBarActive(getScrollArea())) && + isHoveringFor(tooltip.getShowUpTimer())) { + tooltip.draw(getContext()); + } + } + + public GTTextFieldWidget setPostFix(String postFix) { + return setPostFix(() -> postFix); + } + + public GTTextFieldWidget setPostFix(@Nullable Supplier postFix) { + if (postFix == null) return this; + return setPostFix(IKey.dynamic(postFix)); + } + + public GTTextFieldWidget setPostFix(IKey postFix) { + this.renderer.setPostFix(postFix); + return getThis(); + } + + /** + * @param onTextAccept Called when {@link Keyboard#KEY_RETURN} or {@link Keyboard#KEY_NUMPADENTER} is pressed. + */ + public GTTextFieldWidget onTextAccept(Consumer onTextAccept) { + this.onTextAccept = onTextAccept; + return this; + } + + @NotNull + public String getText() { + if (this.handler.getText().isEmpty()) { + return ""; + } + if (this.handler.getText().size() > 1) { + throw new IllegalStateException("GTTextFieldWidget can only have one line!"); + } + return this.handler.getText().get(0); + } + + public void setText(@NotNull String text) { + if (this.handler.getText().isEmpty()) { + this.handler.getText().add(text); + } else { + this.handler.getText().set(0, text); + } + } + + @Override + public void onRemoveFocus(ModularGuiContext context) { + super.onRemoveFocus(context); + this.setText(this.validator.apply(getText())); + this.stringValue + .setStringValue(this.numbers ? format.parse(getText(), new ParsePosition(0)).toString() : getText()); + } + + @Override + public boolean canHover() { + return true; + } + + public GTTextFieldWidget setMaxLength(int maxLength) { + this.handler.setMaxCharacters(maxLength); + return this; + } + + public GTTextFieldWidget setPattern(Pattern pattern) { + this.handler.setPattern(pattern); + return this; + } + + public GTTextFieldWidget setValidator(Function validator) { + this.validator = validator; + return this; + } + + public GTTextFieldWidget setNumbersLong(LongUnaryOperator validator) { + this.numbers = true; + setValidator(val -> { + long num; + if (val.isEmpty()) { + num = (long) this.defaultNumber; + } else { + num = (long) parse(val); + } + return format.format(validator.applyAsLong(num)); + }); + return this; + } + + public GTTextFieldWidget setNumbers(IntUnaryOperator validator) { + this.numbers = true; + return setValidator(val -> { + int num; + if (val.isEmpty()) { + num = (int) this.defaultNumber; + } else { + num = (int) parse(val); + } + return format.format(validator.applyAsInt(num)); + }); + } + + public GTTextFieldWidget setNumbersDouble(DoubleUnaryOperator validator) { + this.numbers = true; + return setValidator(val -> { + double num; + if (val.isEmpty()) { + num = this.defaultNumber; + } else { + num = parse(val); + } + return format.format(validator.applyAsDouble(num)); + }); + } + + public GTTextFieldWidget setNumbers(IntSupplier min, IntSupplier max) { + return setNumbers(val -> Math.min(max.getAsInt(), Math.max(min.getAsInt(), val))); + } + + public GTTextFieldWidget setNumbersLong(LongSupplier min, LongSupplier max) { + return setNumbersLong(val -> Math.min(max.getAsLong(), Math.max(min.getAsLong(), val))); + } + + public GTTextFieldWidget setNumbersLong(long min, long max) { + return setNumbersLong(val -> Math.min(Math.max(val, min), max)); + } + + public GTTextFieldWidget setNumbers(int min, int max) { + return setNumbers(val -> MathHelper.clamp(val, min, max)); + } + + public GTTextFieldWidget setNumbers() { + return setNumbers(Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + public GTTextFieldWidget setDefaultNumber(double defaultNumber) { + this.defaultNumber = defaultNumber; + return this; + } + + public GTTextFieldWidget value(IStringValue stringValue) { + this.stringValue = stringValue; + setValue(stringValue); + return this; + } + + @Override + public @NotNull RichTooltip tooltip() { + tooltipOverride = true; + return super.tooltip(); + } + + private static class GTTextFieldRenderer extends TextFieldRenderer { + + private @Nullable IKey postFix = null; + + public GTTextFieldRenderer(TextFieldHandler handler) { + super(handler); + } + + @Override + protected void draw(String text, float x, float y) { + if (postFix != null) { + text += postFix.getFormatted(); + } + super.draw(text, x, y); + } + + public void setPostFix(@NotNull IKey postFix) { + this.postFix = postFix; + } + } +} diff --git a/src/main/java/gregtech/common/mui/widget/InteractableText.java b/src/main/java/gregtech/common/mui/widget/InteractableText.java index 0ac02dd22e3..83141681f2d 100644 --- a/src/main/java/gregtech/common/mui/widget/InteractableText.java +++ b/src/main/java/gregtech/common/mui/widget/InteractableText.java @@ -13,14 +13,14 @@ import com.cleanroommc.modularui.widgets.TextWidget; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; +import java.util.function.Predicate; public class InteractableText extends TextWidget> implements Interactable { private final T entry; private final EntryColorSH syncHandler; - public InteractableText(T entry, Consumer setter) { + public InteractableText(T entry, Predicate setter) { super(IKey.str(entry.getColorStr()) .alignment(Alignment.CenterLeft) .color(Color.WHITE.darker(1))); @@ -32,9 +32,10 @@ public InteractableText(T entry, Consumer setter) { @NotNull @Override public Result onMousePressed(int mouseButton) { - Interactable.playButtonClickSound(); - this.syncHandler.setColor(this.entry.getColorStr()); - this.syncHandler.syncToServer(1, buf -> NetworkUtils.writeStringSafe(buf, this.entry.getColorStr())); + if (this.syncHandler.setColor(this.entry.getColorStr())) { + Interactable.playButtonClickSound(); + this.syncHandler.syncToServer(1, buf -> NetworkUtils.writeStringSafe(buf, this.entry.getColorStr())); + } return Result.SUCCESS; } @@ -45,14 +46,14 @@ public boolean isValidSyncHandler(SyncHandler syncHandler) { private static class EntryColorSH extends SyncHandler { - private final Consumer setter; + private final Predicate setter; - private EntryColorSH(Consumer setter) { + private EntryColorSH(Predicate setter) { this.setter = setter; } - public void setColor(String c) { - this.setter.accept(c); + public boolean setColor(String c) { + return this.setter.test(c); } @Override diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index f4121bb3ecb..9fa5c6c7edf 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -7,7 +7,6 @@ import gregtech.api.block.coil.CoilManager; import gregtech.api.capability.SimpleCapabilityManager; import gregtech.api.cover.CoverDefinition; -import gregtech.api.cover.CoverUIFactory; import gregtech.api.fluids.GTFluidRegistration; import gregtech.api.gui.UIFactory; import gregtech.api.items.gui.PlayerInventoryUIFactory; @@ -152,7 +151,6 @@ public void preInit(FMLPreInitializationEvent event) { logger.info("Registering GTCEu UI Factories"); MetaTileEntityUIFactory.INSTANCE.init(); PlayerInventoryUIFactory.INSTANCE.init(); - CoverUIFactory.INSTANCE.init(); logger.info("Registering addon UI Factories"); MinecraftForge.EVENT_BUS.post(new GregTechAPI.RegisterEvent<>(UI_FACTORY_REGISTRY, UIFactory.class)); UI_FACTORY_REGISTRY.freeze(); diff --git a/src/main/java/gregtech/integration/ftb/utility/FTBTeamHelper.java b/src/main/java/gregtech/integration/ftb/utility/FTBTeamHelper.java new file mode 100644 index 00000000000..6201b7d95c2 --- /dev/null +++ b/src/main/java/gregtech/integration/ftb/utility/FTBTeamHelper.java @@ -0,0 +1,14 @@ +package gregtech.integration.ftb.utility; + +import gregtech.api.util.Mods; + +import com.feed_the_beast.ftblib.lib.data.FTBLibAPI; + +import java.util.UUID; + +public class FTBTeamHelper { + + public static boolean isSameTeam(UUID first, UUID second) { + return Mods.FTB_UTILITIES.isModLoaded() && FTBLibAPI.arePlayersInSameTeam(first, second); + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index bdf8e329563..3429aad9618 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1424,7 +1424,7 @@ cover.generic.ender.delete_entry=Delete Entry cover.generic.advanced_detector.latched=Latched cover.generic.advanced_detector.continuous=Continuous -cover.generic.advanced_detector.latch_tooltip=Change the redstone behavior of this Cover. /n§eContinuous§7 - Default; values less than the minimum output 0; values higher than the maximum output 15; values between min and max output between 0 and 15 /n§eLatched§7 - output 15 until above max, then output 0 until below min +cover.generic.advanced_detector.latch_tooltip=Change the redstone behavior of this Cover. \n§eContinuous§7 - Default\n Values less than the minimum output §b0§7\n Values higher than the maximum output §b15§7\n Values between min and max output between §b0§7 and §b15§7 \n§eLatched§7\n Output §b15§7 until above max, then output §b0§7 until below min cover.generic.advanced_detector.invert_label=Redstone Output: cover.generic.advanced_detector.latch_label=Behavior: cover.generic.advanced_detector.invert_tooltip=Toggle to invert the redstone logic @@ -1432,7 +1432,7 @@ cover.generic.advanced_detector.invert_tooltip=Toggle to invert the redstone log cover.advanced_energy_detector.label=Advanced Energy Detector cover.advanced_energy_detector.min=Minimum: cover.advanced_energy_detector.max=Maximum: -cover.advanced_energy_detector.invert_tooltip=Toggle to invert the redstone logic/nBy default, redstone is emitted when less than the minimum EU, and stops emitting when greater than the max EU +cover.advanced_energy_detector.invert_tooltip=Toggle to invert the redstone logic\nBy default, redstone is emitted when less than the minimum EU, and stops emitting when greater than the max EU cover.advanced_energy_detector.normal=Normal cover.advanced_energy_detector.inverted=Inverted cover.advanced_energy_detector.modes_tooltip=Change between using discrete EU values or percentages for comparing min/max against an attached energy storage.