diff --git a/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java index e4443e15cd5..70fb8eab295 100644 --- a/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SimpleGeneratorMetaTileEntity.java @@ -10,6 +10,7 @@ import gregtech.api.gui.ModularUI; import gregtech.api.gui.widgets.LabelWidget; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.recipes.RecipeMap; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -28,10 +29,16 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Objects; import java.util.function.Function; public class SimpleGeneratorMetaTileEntity extends WorkableTieredMetaTileEntity implements IActiveOutputSide { @@ -128,6 +135,40 @@ protected void renderOverlays(CCRenderState renderState, Matrix4 translation, IV workable.isWorkingEnabled()); } + @Override + public boolean usesMui2() { + RecipeMap map = getRecipeMap(); + return map != null && map.getRecipeMapUI().usesMui2(); + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + RecipeMap workableRecipeMap = Objects.requireNonNull(workable.getRecipeMap(), "recipe map is null"); + int yOffset = 0; + if (workableRecipeMap.getMaxInputs() >= 6 || workableRecipeMap.getMaxFluidInputs() >= 6 || + workableRecipeMap.getMaxOutputs() >= 6 || workableRecipeMap.getMaxFluidOutputs() >= 6) { + yOffset = FONT_HEIGHT; + } + + ModularPanel panel = workableRecipeMap.getRecipeMapUI() + .setSize(176, 166 + yOffset) + .constructPanel(this, workable::getProgressPercent, + importItems, exportItems, + importFluids, exportFluids, + yOffset, guiSyncManager) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .bindPlayerInventory(); + + if (exportItems.getSlots() + exportFluids.getTanks() <= 9) { + panel.child(new Widget<>() + .size(17) + .right(7) + .top(45 + yOffset) + .background(GTGuiTextures.getLogo(getUITheme()))); + } + return panel; + } + @Override protected ModularUI createUI(EntityPlayer entityPlayer) { return createGuiTemplate(entityPlayer).build(getHolder(), entityPlayer); diff --git a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java index 5ecd01baa1a..597efe1eae3 100644 --- a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java @@ -14,13 +14,10 @@ import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.GhostCircuitSlotWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.widget.GhostCircuitSlotWidget; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -54,11 +51,23 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.function.Function; import static gregtech.api.capability.GregtechDataCodes.*; @@ -478,6 +487,92 @@ public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) clearInventory(itemBuffer, chargerInventory); } + @Override + public boolean usesMui2() { + RecipeMap map = getRecipeMap(); + return map != null && map.getRecipeMapUI().usesMui2(); + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + RecipeMap workableRecipeMap = Objects.requireNonNull(workable.getRecipeMap(), "recipe map is null"); + int yOffset = 0; + if (workableRecipeMap.getMaxInputs() >= 6 || workableRecipeMap.getMaxFluidInputs() >= 6 || + workableRecipeMap.getMaxOutputs() >= 6 || workableRecipeMap.getMaxFluidOutputs() >= 6) { + yOffset = FONT_HEIGHT; + } + + Flow col = Flow.column() + .debugName("col:special.buttons") + .right(7).bottom(7) + .height(18 * 4 + 4) + .width(18); + + BooleanSyncValue hasEnergy = new BooleanSyncValue(workable::isHasNotEnoughEnergy); + guiSyncManager.syncValue("has_energy", hasEnergy); + + ModularPanel panel = workableRecipeMap.getRecipeMapUI() + .setSize(176 + 20, 166 + yOffset) + .constructPanel(this, workable::getProgressPercent, + importItems, exportItems, + importFluids, exportFluids, + yOffset, guiSyncManager) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(GTGuiTextures.INDICATOR_NO_ENERGY.asWidget() + .debugName("energy.indicator") + .size(18) + .alignX(0.5f) + .top(42 + yOffset + 18) + .setEnabledIf($ -> hasEnergy.getBoolValue())) + .child(col) + .child(SlotGroupWidget.playerInventory().left(7)); + + if (exportItems.getSlots() > 0) { + col.child(new ToggleButton() + .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) + .value(new BooleanSyncValue(() -> autoOutputItems, val -> autoOutputItems = val)) + .addTooltip(true, IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled")) + .addTooltip(false, IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled"))); + } + + if (exportFluids.getTanks() > 0) { + col.child(new ToggleButton() + .overlay(GTGuiTextures.BUTTON_FLUID_OUTPUT) + .value(new BooleanSyncValue(() -> autoOutputFluids, val -> autoOutputFluids = val)) + .addTooltip(true, IKey.lang("gregtech.gui.fluid_auto_output.tooltip.enabled")) + .addTooltip(false, IKey.lang("gregtech.gui.fluid_auto_output.tooltip.disabled"))); + } + + col.child(new ItemSlot() + .debugName("charger.slot") + .slot(SyncHandlers.itemSlot(chargerInventory, 0)) + .background(GTGuiTextures.SLOT, GTGuiTextures.CHARGER_OVERLAY) + .bottom(18 + 4) + .addTooltipLine(IKey.lang("gregtech.gui.charger_slot.tooltip", + GTValues.VNF[getTier()], GTValues.VNF[getTier()]))); + + col.child(new Widget<>() + .size(17) + .marginTop(1) + .marginRight(1) + .top(-17 - 2) + .background(GTGuiTextures.getLogo(getUITheme()))); + + if (hasGhostCircuitInventory() && circuitInventory != null) { + col.child(new GhostCircuitSlotWidget() + .bottom(0) + .slot(SyncHandlers.itemSlot(circuitInventory, 0)) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)); + } + return panel; + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return createGuiTemplate(entityPlayer).build(getHolder(), entityPlayer); + } + + @Deprecated protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { RecipeMap workableRecipeMap = workable.getRecipeMap(); int yOffset = 0; @@ -489,38 +584,42 @@ protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { ModularUI.Builder builder = workableRecipeMap.getRecipeMapUI() .createUITemplate(workable::getProgressPercent, importItems, exportItems, importFluids, exportFluids, yOffset) - .widget(new LabelWidget(5, 5, getMetaFullName())) - .widget(new SlotWidget(chargerInventory, 0, 79, 62 + yOffset, true, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.CHARGER_OVERLAY) - .setTooltipText("gregtech.gui.charger_slot.tooltip", GTValues.VNF[getTier()], - GTValues.VNF[getTier()])) - .widget(new ImageWidget(79, 42 + yOffset, 18, 18, GuiTextures.INDICATOR_NO_ENERGY).setIgnoreColor(true) - .setPredicate(workable::isHasNotEnoughEnergy)) + .widget(new gregtech.api.gui.widgets.LabelWidget(5, 5, getMetaFullName())) + .widget(new gregtech.api.gui.widgets.SlotWidget(chargerInventory, 0, 79, 62 + yOffset, true, true, + false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.CHARGER_OVERLAY) + .setTooltipText("gregtech.gui.charger_slot.tooltip", GTValues.VNF[getTier()], + GTValues.VNF[getTier()])) + .widget(new gregtech.api.gui.widgets.ImageWidget(79, 42 + yOffset, 18, 18, + GuiTextures.INDICATOR_NO_ENERGY).setIgnoreColor(true) + .setPredicate(workable::isHasNotEnoughEnergy)) .bindPlayerInventory(player.inventory, GuiTextures.SLOT, yOffset); int leftButtonStartX = 7; if (exportItems.getSlots() > 0) { - builder.widget(new ToggleButtonWidget(leftButtonStartX, 62 + yOffset, 18, 18, + builder.widget(new gregtech.api.gui.widgets.ToggleButtonWidget(leftButtonStartX, 62 + yOffset, 18, 18, GuiTextures.BUTTON_ITEM_OUTPUT, this::isAutoOutputItems, this::setAutoOutputItems) .setTooltipText("gregtech.gui.item_auto_output.tooltip") .shouldUseBaseBackground()); leftButtonStartX += 18; } if (exportFluids.getTanks() > 0) { - builder.widget(new ToggleButtonWidget(leftButtonStartX, 62 + yOffset, 18, 18, + builder.widget(new gregtech.api.gui.widgets.ToggleButtonWidget(leftButtonStartX, 62 + yOffset, 18, 18, GuiTextures.BUTTON_FLUID_OUTPUT, this::isAutoOutputFluids, this::setAutoOutputFluids) .setTooltipText("gregtech.gui.fluid_auto_output.tooltip") .shouldUseBaseBackground()); } if (exportItems.getSlots() + exportFluids.getTanks() <= 9) { - ImageWidget logo = new ImageWidget(152, 63 + yOffset, 17, 17, + gregtech.api.gui.widgets.ImageWidget logo = new gregtech.api.gui.widgets.ImageWidget(152, 63 + yOffset, 17, + 17, GTValues.XMAS.get() ? getXmasLogo() : getLogo()).setIgnoreColor(true); if (this.circuitInventory != null) { - SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 124, 62 + yOffset) - .setBackgroundTexture(GuiTextures.SLOT, getCircuitSlotOverlay()); + gregtech.api.gui.widgets.SlotWidget circuitSlot = new gregtech.api.gui.widgets.GhostCircuitSlotWidget( + circuitInventory, 0, 124, 62 + yOffset) + .setBackgroundTexture(GuiTextures.SLOT, getCircuitSlotOverlay()); builder.widget(circuitSlot.setConsumer(this::getCircuitSlotTooltip)).widget(logo); } } @@ -546,7 +645,7 @@ protected TextureArea getCircuitSlotOverlay() { } // Method provided to override - protected void getCircuitSlotTooltip(SlotWidget widget) { + protected void getCircuitSlotTooltip(gregtech.api.gui.widgets.SlotWidget widget) { String configString; if (circuitInventory == null || circuitInventory.getCircuitValue() == GhostCircuitItemStackHandler.NO_CONFIG) { configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value").getFormattedText(); @@ -557,11 +656,6 @@ protected void getCircuitSlotTooltip(SlotWidget widget) { widget.setTooltipText("gregtech.gui.configurator_slot.tooltip", configString); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createGuiTemplate(entityPlayer).build(getHolder(), entityPlayer); - } - @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { super.addInformation(stack, player, tooltip, advanced); diff --git a/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java index ed904815d2d..8e43093ba3d 100644 --- a/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SteamMetaTileEntity.java @@ -8,6 +8,7 @@ import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.mui.GTGuiTheme; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTUtility; import gregtech.client.particle.VanillaParticleEffects; @@ -34,6 +35,10 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; @@ -43,6 +48,8 @@ public abstract class SteamMetaTileEntity extends MetaTileEntity { + // todo quick and dirty fix to not show input tank in ui, find better solution + protected static final FluidTankList EMPTY = new FluidTankList(false); protected static final int STEAM_CAPACITY = 16000; protected final boolean isHighPressure; @@ -127,6 +134,31 @@ public FluidTankList createImportFluidHandler() { return new FluidTankList(false, steamFluidTank); } + @Override + public boolean usesMui2() { + RecipeMap map = getRecipeMap(); + return map != null && map.getRecipeMapUI().usesMui2(); + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + RecipeMap map = Objects.requireNonNull(getRecipeMap()); + + // todo remove logo from background and use a widget + return map.getRecipeMapUI() + .constructPanel(this, workableHandler::getProgressPercent, + importItems, exportItems, + EMPTY, exportFluids, + 0, guiSyncManager) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .bindPlayerInventory(); + } + + @Override + public GTGuiTheme getUITheme() { + return isHighPressure ? GTGuiTheme.STEEL : GTGuiTheme.BRONZE; + } + public ModularUI.Builder createUITemplate(EntityPlayer player) { return ModularUI.builder(GuiTextures.BACKGROUND_STEAM.get(isHighPressure), 176, 166) .label(6, 6, getMetaFullName()).shouldColor(false) diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index aa7b579797f..0365700d779 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -1,5 +1,6 @@ package gregtech.api.mui; +import gregtech.api.GTValues; import gregtech.api.cover.CoverWithUI; import gregtech.common.ConfigHolder; @@ -56,6 +57,7 @@ private static String gregtech(String s) { .simpleToggleButton(IDs.STANDARD_BUTTON, IDs.STANDARD_SLOT, ConfigHolder.client.defaultUIColor) + .logo(() -> GTValues.XMAS.get() ? GTGuiTextures.GREGTECH_LOGO_XMAS : GTGuiTextures.GREGTECH_LOGO) .build(); public static final GTGuiTheme COVER = templateBuilder(Names.COVER) diff --git a/src/main/java/gregtech/api/mui/widget/RecipeProgressWidget.java b/src/main/java/gregtech/api/mui/widget/RecipeProgressWidget.java new file mode 100644 index 00000000000..688fd76a950 --- /dev/null +++ b/src/main/java/gregtech/api/mui/widget/RecipeProgressWidget.java @@ -0,0 +1,63 @@ +package gregtech.api.mui.widget; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.RecipeMaps; +import gregtech.integration.IntegrationModule; +import gregtech.integration.jei.JustEnoughItemsModule; +import gregtech.integration.jei.recipe.RecipeMapCategory; +import gregtech.modules.GregTechModules; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class RecipeProgressWidget extends ProgressWidget implements Interactable { + + private RecipeMap recipeMap; + + public RecipeProgressWidget recipeMap(RecipeMap recipeMap) { + this.recipeMap = recipeMap; + if (GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_JEI)) { + tooltip(t -> t.addLine(IKey.lang("gui.widget.recipeProgressWidget.default_tooltip"))); + } + return this; + } + + @Override + public @NotNull Result onMousePressed(int mouseButton) { + if (recipeMap == null) { + return Result.IGNORE; + } + if (mouseButton == 0 || mouseButton == 1) { + if (!GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_JEI)) { + return Result.ACCEPT; + } + + Collection categories = RecipeMapCategory.getCategoriesFor(recipeMap); + if (categories != null && !categories.isEmpty()) { + List categoryID = new ArrayList<>(); + if (recipeMap == RecipeMaps.FURNACE_RECIPES) { + categoryID.add("minecraft.smelting"); + } else { + for (RecipeMapCategory category : categories) { + categoryID.add(category.getUid()); + } + } + + if (JustEnoughItemsModule.jeiRuntime == null) { + IntegrationModule.logger.error("GTCEu JEI integration has crashed, this is not a good thing"); + return Result.ACCEPT; + } + JustEnoughItemsModule.jeiRuntime.getRecipesGui().showCategories(categoryID); + return Result.SUCCESS; + } + } + return Result.IGNORE; + } +} diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index 9b920a7239f..94018f05506 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -145,7 +145,6 @@ public RecipeMap(@NotNull String unlocalizedName, @NotNull R defaultRecipeBuilde @NotNull RecipeMapUIFunction recipeMapUI, int maxInputs, int maxOutputs, int maxFluidInputs, int maxFluidOutputs) { this.unlocalizedName = unlocalizedName; - this.recipeMapUI = recipeMapUI.apply(this); this.maxInputs = maxInputs; this.maxFluidInputs = maxFluidInputs; @@ -154,6 +153,8 @@ public RecipeMap(@NotNull String unlocalizedName, @NotNull R defaultRecipeBuilde this.primaryRecipeCategory = GTRecipeCategory.create(GTValues.MODID, unlocalizedName, getTranslationKey(), this); + this.recipeMapUI = recipeMapUI.apply(this); + defaultRecipeBuilder.setRecipeMap(this); defaultRecipeBuilder.category(primaryRecipeCategory); this.recipeBuilderSample = defaultRecipeBuilder; diff --git a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java index 2aa466d5f67..dcd0e62ee24 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java @@ -1,20 +1,24 @@ package gregtech.api.recipes; import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ProgressWidget; import gregtech.api.recipes.ui.RecipeMapUI; +import gregtech.api.recipes.ui.RecipeMapUIBuilder; import gregtech.api.recipes.ui.RecipeMapUIFunction; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; +import com.cleanroommc.modularui.drawable.UITexture; import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; import static gregtech.api.recipes.ui.RecipeMapUI.computeOverlayKey; @@ -23,8 +27,6 @@ public class RecipeMapBuilder> { private final String unlocalizedName; private final B defaultRecipeBuilder; - private final Byte2ObjectMap slotOverlays = new Byte2ObjectArrayMap<>(); - private int itemInputs; private boolean modifyItemInputs = true; private int itemOutputs; @@ -36,12 +38,6 @@ public class RecipeMapBuilder> { private boolean isGenerator; - private @Nullable TextureArea progressBar; - private @Nullable ProgressWidget.MoveType moveType; - - private @Nullable TextureArea specialTexture; - private int @Nullable [] specialTextureLocation; - private RecipeMapUIFunction recipeMapUIFunction = this::buildUI; private SoundEvent sound; @@ -51,6 +47,26 @@ public class RecipeMapBuilder> { private boolean sortToBack; + /* *********************** MUI 1 *********************** */ + + @Deprecated + private final Byte2ObjectMap slotOverlays = new Byte2ObjectArrayMap<>(); + @Deprecated + private @Nullable TextureArea progressBar; + @Deprecated + private @Nullable gregtech.api.gui.widgets.ProgressWidget.MoveType moveType; + @Deprecated + private @Nullable TextureArea specialTexture; + @Deprecated + private int @Nullable [] specialTextureLocation; + + /* *********************** MUI 2 *********************** */ + + @ApiStatus.Experimental + private boolean usesMui2 = false; + + private @Nullable Consumer mapUIBuilder; + /** * @param unlocalizedName the name of the recipemap * @param defaultRecipeBuilder the default recipe builder of the recipemap @@ -143,31 +159,40 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip } /** + * @deprecated in favor of the MUI2 method. * @param progressBar the progress bar texture to use * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder progressBar(@Nullable TextureArea progressBar) { this.progressBar = progressBar; return this; } /** + * @deprecated in favor of the MUI2 method. * @param progressBar the progress bar texture to use * @param moveType the progress bar move type to use * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder progressBar(@Nullable TextureArea progressBar, - @Nullable ProgressWidget.MoveType moveType) { + @Nullable gregtech.api.gui.widgets.ProgressWidget.MoveType moveType) { this.progressBar = progressBar; this.moveType = moveType; return this; } /** + * @deprecated in favor of the MUI2 method. * @param texture the texture to use * @param isOutput if the slot is an output slot * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder itemSlotOverlay(@NotNull TextureArea texture, boolean isOutput) { this.slotOverlays.put(computeOverlayKey(isOutput, false, false), texture); this.slotOverlays.put(computeOverlayKey(isOutput, false, true), texture); @@ -175,11 +200,14 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip } /** + * @deprecated in favor of the MUI2 method. * @param texture the texture to use * @param isOutput if the slot is an output slot * @param isLastSlot if the slot is the last slot * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder itemSlotOverlay(@NotNull TextureArea texture, boolean isOutput, boolean isLastSlot) { this.slotOverlays.put(computeOverlayKey(isOutput, false, isLastSlot), texture); @@ -187,10 +215,13 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip } /** + * @deprecated in favor of the MUI2 method. * @param texture the texture to use * @param isOutput if the slot is an output slot * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder fluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput) { this.slotOverlays.put(computeOverlayKey(isOutput, true, false), texture); this.slotOverlays.put(computeOverlayKey(isOutput, true, true), texture); @@ -198,17 +229,25 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip } /** + * @deprecated in favor of the MUI2 method. * @param texture the texture to use * @param isOutput if the slot is an output slot * @param isLastSlot if the slot is the last slot * @return this */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder fluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput, boolean isLastSlot) { this.slotOverlays.put(computeOverlayKey(isOutput, true, isLastSlot), texture); return this; } + /** + * @deprecated in favor of the MUI2 method. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull RecipeMapBuilder specialTexture(@NotNull TextureArea texture, int x, int y, int width, int height) { this.specialTexture = texture; @@ -216,6 +255,17 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + /** + * @apiNote Only needed if you do not set textures using MUI2 methods, i.e. the ones that accept{@link UITexture}. + *
+ * Marked experimental since this method will disappear once MUI2 is fully supported by all GTCEu UIs. + */ + @ApiStatus.Experimental + public @NotNull RecipeMapBuilder usesMui2() { + this.usesMui2 = true; + return this; + } + /** * @param recipeMapUIFunction the custom function for creating the RecipeMap's ui * @return this @@ -225,6 +275,12 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + public @NotNull RecipeMapBuilder uiBuilder(@NotNull Consumer mapUIBuilder) { + this.usesMui2 = true; + this.mapUIBuilder = Objects.requireNonNull(mapUIBuilder, "ui builder is null"); + return this; + } + /** * @param recipeMap the recipemap associated with the ui * @return the RecipeMap's ui @@ -232,17 +288,21 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip private @NotNull RecipeMapUI buildUI(@NotNull RecipeMap recipeMap) { RecipeMapUI ui = new RecipeMapUI<>(recipeMap, modifyItemInputs, modifyItemOutputs, modifyFluidInputs, modifyFluidOutputs, isGenerator); - if (progressBar != null) { - ui.setProgressBarTexture(progressBar); - } - if (moveType != null) { - ui.setProgressBarMoveType(moveType); - } - if (specialTexture != null && specialTextureLocation != null) { - ui.setSpecialTexture(specialTexture, specialTextureLocation); - } - for (var entry : slotOverlays.byte2ObjectEntrySet()) { - ui.setSlotOverlay(entry.getByteKey(), entry.getValue()); + if (usesMui2 && this.mapUIBuilder != null) { + ui.buildMui2(this.mapUIBuilder); + } else { + if (progressBar != null) { + ui.setProgressBarTexture(progressBar); + } + if (moveType != null) { + ui.setProgressBarMoveType(moveType); + } + if (specialTexture != null && specialTextureLocation != null) { + ui.setSpecialTexture(specialTexture, specialTextureLocation); + } + for (var entry : slotOverlays.byte2ObjectEntrySet()) { + ui.setSlotOverlay(entry.getByteKey(), entry.getValue()); + } } return ui; diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index 0f17d0609e3..3dcdd3b2f57 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -2,8 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.widgets.ProgressWidget; -import gregtech.api.gui.widgets.ProgressWidget.MoveType; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.recipes.builders.AssemblyLineRecipeBuilder; import gregtech.api.recipes.builders.BlastRecipeBuilder; import gregtech.api.recipes.builders.CircuitAssemblerRecipeBuilder; @@ -35,6 +34,9 @@ import net.minecraft.init.SoundEvents; +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.widgets.ProgressWidget.Direction; import crafttweaker.annotations.ZenRegister; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenProperty; @@ -77,8 +79,9 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(2) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.FURNACE_OVERLAY_1, false) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW) + .uiBuilder(builder -> builder + .itemSlotOverlay(GTGuiTextures.FURNACE_OVERLAY_1, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW)) .sound(GTSoundEvents.FURNACE) .build(); @@ -118,7 +121,7 @@ public final class RecipeMaps { .itemOutputs(9) .fluidInputs(1) .fluidOutputs(1) - .progressBar(GuiTextures.PROGRESS_BAR_ARC_FURNACE) + .uiBuilder(builder -> builder.progressBar(GTGuiTextures.PROGRESS_BAR_ARC_FURNACE)) .sound(GTSoundEvents.ARC) .onBuild(gregtechId("arc_furnace_oxygen"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { @@ -145,8 +148,9 @@ public final class RecipeMaps { .itemInputs(9) .itemOutputs(1) .fluidInputs(1) - .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT) + .uiBuilder(builder -> builder + .itemSlotOverlay(GTGuiTextures.CIRCUIT_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_CIRCUIT)) .sound(GTSoundEvents.ASSEMBLER) .onBuild(gregtechId("assembler_solder"), recipeBuilder -> { var fluidInputs = recipeBuilder.getFluidInputs(); @@ -206,9 +210,9 @@ public final class RecipeMaps { .itemOutputs(2) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, false) - .itemSlotOverlay(GuiTextures.CRYSTAL_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_CRYSTALLIZATION) + .uiBuilder(builder -> builder.itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.CRYSTAL_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_CRYSTALLIZATION)) .sound(GTSoundEvents.FURNACE) .build(); @@ -232,9 +236,10 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(2) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.BENDER_OVERLAY, false, false) - .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) - .progressBar(GuiTextures.PROGRESS_BAR_BENDING) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.BENDER_OVERLAY, false, false) + .itemSlotOverlay(GTGuiTextures.INT_CIRCUIT_OVERLAY, false, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_BENDING)) .sound(GTSoundEvents.MOTOR) .build(); @@ -292,8 +297,9 @@ public final class RecipeMaps { .itemInputs(1) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.BREWER_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.BREWER_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW_MULTIPLE)) .sound(GTSoundEvents.CHEMICAL_REACTOR) .build(); @@ -317,15 +323,14 @@ public final class RecipeMaps { @ZenProperty public static final RecipeMap CANNER_RECIPES = new RecipeMapFluidCanner("canner", new SimpleRecipeBuilder(), recipeMap -> { - RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); - ui.setItemSlotOverlay(GuiTextures.CANNER_OVERLAY, false, false); - ui.setItemSlotOverlay(GuiTextures.CANISTER_OVERLAY, false, true); - ui.setItemSlotOverlay(GuiTextures.CANISTER_OVERLAY, true); - ui.setFluidSlotOverlay(GuiTextures.DARK_CANISTER_OVERLAY, false); - ui.setFluidSlotOverlay(GuiTextures.DARK_CANISTER_OVERLAY, true); - ui.setProgressBar(GuiTextures.PROGRESS_BAR_CANNER, ProgressWidget.MoveType.HORIZONTAL); - return ui; + return ui.buildMui2(b -> b + .itemSlotOverlay(GTGuiTextures.CANNER_OVERLAY, false, false) + .itemSlotOverlay(GTGuiTextures.CANISTER_OVERLAY, false, true) + .itemSlotOverlay(GTGuiTextures.CANISTER_OVERLAY, true) + .fluidSlotOverlay(GTGuiTextures.DARK_CANISTER_OVERLAY, false) + .fluidSlotOverlay(GTGuiTextures.DARK_CANISTER_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_CANNER, Direction.RIGHT)); }); /** @@ -354,10 +359,11 @@ public final class RecipeMaps { .itemOutputs(6) .fluidInputs(1) .fluidOutputs(6) - .itemSlotOverlay(GuiTextures.EXTRACTOR_OVERLAY, false, false) - .itemSlotOverlay(GuiTextures.CANISTER_OVERLAY, false, true) - .fluidSlotOverlay(GuiTextures.CENTRIFUGE_OVERLAY, false, true) - .progressBar(GuiTextures.PROGRESS_BAR_EXTRACT) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.EXTRACTOR_OVERLAY, false, false) + .itemSlotOverlay(GTGuiTextures.CANISTER_OVERLAY, false, true) + .fluidSlotOverlay(GTGuiTextures.CENTRIFUGE_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_EXTRACT)) .sound(GTSoundEvents.CENTRIFUGE) .build(); @@ -380,9 +386,10 @@ public final class RecipeMaps { .itemOutputs(6) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.BREWER_OVERLAY, false, true) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MIXER, MoveType.CIRCULAR) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.BREWER_OVERLAY, false, true) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MIXER, Direction.CIRCULAR_CW)) .sound(GTSoundEvents.BATH) .build(); @@ -416,13 +423,14 @@ public final class RecipeMaps { .itemOutputs(2) .fluidInputs(3) .fluidOutputs(2) - .itemSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_1, false, false) - .itemSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_2, false, true) - .itemSlotOverlay(GuiTextures.VIAL_OVERLAY_1, true) - .fluidSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_3, false, false) - .fluidSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_4, false, true) - .fluidSlotOverlay(GuiTextures.VIAL_OVERLAY_2, true) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.MOLECULAR_OVERLAY_1, false, false) + .itemSlotOverlay(GTGuiTextures.MOLECULAR_OVERLAY_2, false, true) + .itemSlotOverlay(GTGuiTextures.VIAL_OVERLAY_1, true) + .fluidSlotOverlay(GTGuiTextures.MOLECULAR_OVERLAY_3, false) + .fluidSlotOverlay(GTGuiTextures.MOLECULAR_OVERLAY_4, false) + .fluidSlotOverlay(GTGuiTextures.VIAL_OVERLAY_2, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW_MULTIPLE)) .sound(GTValues.FOOLS.get() ? GTSoundEvents.SCIENCE : GTSoundEvents.CHEMICAL_REACTOR) .onBuild(gregtechId("lcr_copy"), recipeBuilder -> RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) @@ -470,8 +478,9 @@ public final class RecipeMaps { .itemInputs(6) .itemOutputs(1) .fluidInputs(1) - .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.CIRCUIT_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER)) .sound(GTSoundEvents.ASSEMBLER) .onBuild(gregtechId("circuit_assembler_solder"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { @@ -533,8 +542,9 @@ public final class RecipeMaps { new SimpleRecipeBuilder().duration(200).EUt(2)) .itemInputs(1) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.COMPRESSOR_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_COMPRESS) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.COMPRESSOR_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_COMPRESS)) .sound(GTSoundEvents.COMPRESSOR) .build(); @@ -590,10 +600,11 @@ public final class RecipeMaps { .itemInputs(1) .itemOutputs(2) .fluidInputs(1) - .itemSlotOverlay(GuiTextures.SAWBLADE_OVERLAY, false) - .itemSlotOverlay(GuiTextures.CUTTER_OVERLAY, true, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) - .progressBar(GuiTextures.PROGRESS_BAR_SLICE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.SAWBLADE_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.CUTTER_OVERLAY, true, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_SLICE)) .sound(GTSoundEvents.CUT) .onBuild(gregtechId("cutter_fluid"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { @@ -682,11 +693,12 @@ public final class RecipeMaps { .itemOutputs(1) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .fluidSlotOverlay(GuiTextures.BEAKER_OVERLAY_1, false) - .fluidSlotOverlay(GuiTextures.BEAKER_OVERLAY_4, true) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.INT_CIRCUIT_OVERLAY, false, true) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .fluidSlotOverlay(GTGuiTextures.BEAKER_OVERLAY_1, false) + .fluidSlotOverlay(GTGuiTextures.BEAKER_OVERLAY_4, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW_MULTIPLE)) .sound(GTSoundEvents.BOILER) .build(); @@ -711,10 +723,11 @@ public final class RecipeMaps { .itemOutputs(6) .fluidInputs(1) .fluidOutputs(6) - .itemSlotOverlay(GuiTextures.LIGHTNING_OVERLAY_1, false, false) - .itemSlotOverlay(GuiTextures.CANISTER_OVERLAY, false, true) - .fluidSlotOverlay(GuiTextures.LIGHTNING_OVERLAY_2, false) - .progressBar(GuiTextures.PROGRESS_BAR_EXTRACT) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.LIGHTNING_OVERLAY_1, false, false) + .itemSlotOverlay(GTGuiTextures.CANISTER_OVERLAY, false, true) + .fluidSlotOverlay(GTGuiTextures.LIGHTNING_OVERLAY_2, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_EXTRACT)) .sound(GTSoundEvents.ELECTROLYZER) .build(); @@ -737,9 +750,10 @@ public final class RecipeMaps { "electromagnetic_separator", new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(4) - .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MAGNET) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.CRUSHED_ORE_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MAGNET)) .sound(GTSoundEvents.ARC) .build(); @@ -763,8 +777,9 @@ public final class RecipeMaps { .itemInputs(1) .itemOutputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.EXTRACTOR_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_EXTRACT) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.EXTRACTOR_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_EXTRACT)) .sound(GTSoundEvents.COMPRESSOR) .build(); @@ -786,8 +801,9 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(2) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.MOLD_OVERLAY, false, true) - .progressBar(GuiTextures.PROGRESS_BAR_EXTRUDER) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.MOLD_OVERLAY, false, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_EXTRUDER)) .sound(GTSoundEvents.ARC) .build(); @@ -811,8 +827,9 @@ public final class RecipeMaps { .itemOutputs(1) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, false, true) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, false, true) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true, true)) .sound(GTSoundEvents.CHEMICAL_REACTOR) .build(); @@ -835,9 +852,10 @@ public final class RecipeMaps { .itemInputs(1) .fluidInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) - .fluidSlotOverlay(GuiTextures.HEATING_OVERLAY_1, false) - .fluidSlotOverlay(GuiTextures.HEATING_OVERLAY_2, true) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.INT_CIRCUIT_OVERLAY, false, true) + .fluidSlotOverlay(GTGuiTextures.HEATING_OVERLAY_1, false) + .fluidSlotOverlay(GTGuiTextures.HEATING_OVERLAY_2, true)) .sound(GTSoundEvents.BOILER) .build(); @@ -860,7 +878,8 @@ public final class RecipeMaps { .itemInputs(1) .itemOutputs(1) .fluidInputs(1) - .itemSlotOverlay(GuiTextures.SOLIDIFIER_OVERLAY, false) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.SOLIDIFIER_OVERLAY, false)) .sound(GTSoundEvents.COOLING) .build(); @@ -881,9 +900,13 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.HAMMER_OVERLAY, false) - .specialTexture(GuiTextures.PROGRESS_BAR_HAMMER_BASE, 78, 42, 20, 6) - .progressBar(GuiTextures.PROGRESS_BAR_HAMMER, MoveType.VERTICAL_DOWNWARDS) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.HAMMER_OVERLAY, false) + .specialTexture(widget -> widget.overlay(GTGuiTextures.PROGRESS_BAR_HAMMER_BASE.asIcon() + .size(20, 6) + .alignment(Alignment.BottomCenter) + .marginBottom(-5))) + .progressBar(GTGuiTextures.PROGRESS_BAR_HAMMER, Direction.DOWN)) .sound(GTSoundEvents.FORGE_HAMMER) .build(); @@ -901,7 +924,17 @@ public final class RecipeMaps { */ @ZenProperty public static final RecipeMap FORMING_PRESS_RECIPES = new RecipeMapFormingPress( - "forming_press", new SimpleRecipeBuilder(), FormingPressUI::new); + "forming_press", new SimpleRecipeBuilder(), recipeMap -> new FormingPressUI<>(recipeMap) + .buildMui2(b -> { + IDrawable[] overlays = { GTGuiTextures.PRESS_OVERLAY_2, GTGuiTextures.PRESS_OVERLAY_4, + GTGuiTextures.PRESS_OVERLAY_1 }; + for (int i = 0; i < 3; i++) { + b.itemSlotOverlay(overlays[i], i, false); + b.itemSlotOverlay(overlays[i], i + 3, false); + } + b.itemSlotOverlay(GTGuiTextures.PRESS_OVERLAY_3, true); + b.progressBar(GTGuiTextures.PROGRESS_BAR_COMPRESS, Direction.RIGHT); + })); /** * @@ -927,9 +960,9 @@ public final class RecipeMaps { public static final RecipeMap FURNACE_RECIPES = new RecipeMapFurnace("electric_furnace", new SimpleRecipeBuilder(), recipeMap -> { RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); - ui.setItemSlotOverlay(GuiTextures.FURNACE_OVERLAY_1, false); - ui.setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); - return ui; + return ui.buildMui2(b -> b + .itemSlotOverlay(GTGuiTextures.FURNACE_OVERLAY_1, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW, Direction.RIGHT)); }); /** @@ -959,6 +992,7 @@ public final class RecipeMaps { new FusionRecipeBuilder()) .fluidInputs(2) .fluidOutputs(1) + // todo figure out what to do here for mui2 .progressBar(GuiTextures.PROGRESS_BAR_FUSION) .sound(GTSoundEvents.ARC) .build(); @@ -968,9 +1002,10 @@ public final class RecipeMaps { "gas_collector", new SimpleRecipeBuilder()) .itemInputs(1) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) - .fluidSlotOverlay(GuiTextures.CENTRIFUGE_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.INT_CIRCUIT_OVERLAY, false, true) + .fluidSlotOverlay(GTGuiTextures.CENTRIFUGE_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_GAS_COLLECTOR)) .sound(GTSoundEvents.COOLING) .build(); @@ -1014,6 +1049,7 @@ public final class RecipeMaps { "implosion_compressor", new ImplosionRecipeBuilder().duration(20).EUt(VA[LV])) .itemInputs(3) .itemOutputs(2) + // todo figure out what to do here for mui2 .itemSlotOverlay(GuiTextures.IMPLOSION_OVERLAY_1, false, true) .itemSlotOverlay(GuiTextures.IMPLOSION_OVERLAY_2, false, false) .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) @@ -1047,6 +1083,7 @@ public final class RecipeMaps { .itemOutputs(3) .fluidInputs(5) .fluidOutputs(4) + // todo figure out what to do here for mui2 .itemSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_1, false, false) .itemSlotOverlay(GuiTextures.MOLECULAR_OVERLAY_2, false, true) .itemSlotOverlay(GuiTextures.VIAL_OVERLAY_1, true) @@ -1076,7 +1113,8 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(2) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.LENS_OVERLAY, false, true) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.LENS_OVERLAY, false, true)) .sound(GTSoundEvents.ELECTROLYZER) .build(); @@ -1097,11 +1135,15 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(2) - .itemSlotOverlay(GuiTextures.PIPE_OVERLAY_1, false) - .itemSlotOverlay(GuiTextures.PIPE_OVERLAY_2, true, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) - .specialTexture(GuiTextures.PROGRESS_BAR_LATHE_BASE, 98, 24, 5, 18) - .progressBar(GuiTextures.PROGRESS_BAR_LATHE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.PIPE_OVERLAY_1, false) + .itemSlotOverlay(GTGuiTextures.PIPE_OVERLAY_2, true, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true, true) + .specialTexture(widget -> widget.background(GTGuiTextures.PROGRESS_BAR_LATHE_BASE.asIcon() + .size(5, 18) + .marginRight(-3) + .alignment(Alignment.CenterRight))) + .progressBar(GTGuiTextures.PROGRESS_BAR_LATHE)) .sound(GTSoundEvents.CUT) .build(); @@ -1124,9 +1166,10 @@ public final class RecipeMaps { new SimpleRecipeBuilder().duration(150).EUt(2)) .itemInputs(1) .itemOutputs(4) - .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MACERATE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.CRUSHED_ORE_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MACERATE)) .sound(GTSoundEvents.MACERATOR) .build(); @@ -1140,11 +1183,12 @@ public final class RecipeMaps { .itemInputs(1) .fluidInputs(1) .fluidOutputs(2) - .itemSlotOverlay(GuiTextures.ATOMIC_OVERLAY_1, false) - .fluidSlotOverlay(GuiTextures.ATOMIC_OVERLAY_2, false) - .fluidSlotOverlay(GuiTextures.POSITIVE_MATTER_OVERLAY, true) - .fluidSlotOverlay(GuiTextures.NEUTRAL_MATTER_OVERLAY, true, true) - .progressBar(GuiTextures.PROGRESS_BAR_MASS_FAB) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.ATOMIC_OVERLAY_1, false) + .fluidSlotOverlay(GTGuiTextures.ATOMIC_OVERLAY_2, false) + .fluidSlotOverlay(GTGuiTextures.POSITIVE_MATTER_OVERLAY, true) + .fluidSlotOverlay(GTGuiTextures.NEUTRAL_MATTER_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MASS_FAB)) .sound(GTSoundEvents.REPLICATOR) .build(); @@ -1168,9 +1212,10 @@ public final class RecipeMaps { .itemOutputs(1) .fluidInputs(2) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MIXER, MoveType.CIRCULAR) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MIXER, Direction.CIRCULAR_CW)) .sound(GTSoundEvents.MIXER) .build(); @@ -1195,9 +1240,10 @@ public final class RecipeMaps { .itemInputs(2) .itemOutputs(3) .fluidInputs(1) - .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_BATH, MoveType.CIRCULAR) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.CRUSHED_ORE_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_BATH, Direction.CIRCULAR_CW)) .sound(GTSoundEvents.BATH) .build(); @@ -1221,9 +1267,10 @@ public final class RecipeMaps { new SimpleRecipeBuilder().EUt(12).duration(10)) .itemInputs(2) .itemOutputs(2) - .itemSlotOverlay(GuiTextures.BOX_OVERLAY, false, true) - .itemSlotOverlay(GuiTextures.BOXED_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_UNPACKER) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.BOX_OVERLAY, false, true) + .itemSlotOverlay(GTGuiTextures.BOXED_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_UNPACKER)) .sound(GTSoundEvents.ASSEMBLER) .build(); @@ -1244,7 +1291,8 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(1) - .progressBar(GuiTextures.PROGRESS_BAR_MAGNET) + .uiBuilder(b -> b + .progressBar(GTGuiTextures.PROGRESS_BAR_MAGNET)) .sound(GTSoundEvents.ARC) .build(); @@ -1312,12 +1360,13 @@ public final class RecipeMaps { .itemOutputs(1) .fluidInputs(2) .fluidOutputs(1) - .itemSlotOverlay(GuiTextures.DATA_ORB_OVERLAY, false) - .itemSlotOverlay(GuiTextures.ATOMIC_OVERLAY_1, true) - .fluidSlotOverlay(GuiTextures.NEUTRAL_MATTER_OVERLAY, false) - .fluidSlotOverlay(GuiTextures.POSITIVE_MATTER_OVERLAY, false, true) - .fluidSlotOverlay(GuiTextures.ATOMIC_OVERLAY_2, true) - .progressBar(GuiTextures.PROGRESS_BAR_REPLICATOR) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.DATA_ORB_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.ATOMIC_OVERLAY_1, true) + .fluidSlotOverlay(GTGuiTextures.NEUTRAL_MATTER_OVERLAY, false) + .fluidSlotOverlay(GTGuiTextures.POSITIVE_MATTER_OVERLAY, false) + .fluidSlotOverlay(GTGuiTextures.ATOMIC_OVERLAY_2, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_REPLICATOR)) .sound(GTSoundEvents.REPLICATOR) .build(); @@ -1330,9 +1379,10 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(4) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, false) - .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MACERATE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.CRUSHED_ORE_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MACERATE)) .sound(GTSoundEvents.FIRE) .build(); @@ -1353,10 +1403,10 @@ public final class RecipeMaps { public static final RecipeMap SCANNER_RECIPES = new RecipeMapScanner("scanner", new SimpleRecipeBuilder(), recipeMap -> { RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); - ui.setItemSlotOverlay(GuiTextures.DATA_ORB_OVERLAY, false, false); - ui.setItemSlotOverlay(GuiTextures.SCANNER_OVERLAY, false, true); - ui.setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); - return ui; + return ui.buildMui2(b -> b + .itemSlotOverlay(GTGuiTextures.DATA_ORB_OVERLAY, false, false) + .itemSlotOverlay(GTGuiTextures.SCANNER_OVERLAY, false, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW, Direction.RIGHT)); }); /** @@ -1380,7 +1430,8 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(1) .itemOutputs(6) - .progressBar(GuiTextures.PROGRESS_BAR_SIFT, MoveType.VERTICAL_DOWNWARDS) + .uiBuilder(b -> b + .progressBar(GTGuiTextures.PROGRESS_BAR_SIFT, Direction.DOWN)) .sound(SoundEvents.BLOCK_SAND_PLACE) .build(); @@ -1406,9 +1457,10 @@ public final class RecipeMaps { "thermal_centrifuge", new SimpleRecipeBuilder().duration(400).EUt(30)) .itemInputs(1) .itemOutputs(3) - .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, false) - .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) - .progressBar(GuiTextures.PROGRESS_BAR_MACERATE) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.CRUSHED_ORE_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.DUST_OVERLAY, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_MACERATE)) .sound(GTSoundEvents.CENTRIFUGE) .build(); @@ -1452,9 +1504,10 @@ public final class RecipeMaps { new SimpleRecipeBuilder()) .itemInputs(2) .itemOutputs(1) - .itemSlotOverlay(GuiTextures.WIREMILL_OVERLAY, false) - .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) - .progressBar(GuiTextures.PROGRESS_BAR_WIREMILL) + .uiBuilder(b -> b + .itemSlotOverlay(GTGuiTextures.WIREMILL_OVERLAY, false) + .itemSlotOverlay(GTGuiTextures.INT_CIRCUIT_OVERLAY, false, true) + .progressBar(GTGuiTextures.PROGRESS_BAR_WIREMILL)) .sound(GTSoundEvents.MOTOR) .build(); @@ -1466,8 +1519,9 @@ public final class RecipeMaps { public static final RecipeMap COMBUSTION_GENERATOR_FUELS = new RecipeMapBuilder<>( "combustion_generator", new FuelRecipeBuilder()) .fluidInputs(1) - .fluidSlotOverlay(GuiTextures.FURNACE_OVERLAY_2, false) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) + .uiBuilder(b -> b + .fluidSlotOverlay(GTGuiTextures.FURNACE_OVERLAY_2, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW_MULTIPLE)) .sound(GTSoundEvents.COMBUSTION) .allowEmptyOutputs() .generator() @@ -1477,8 +1531,9 @@ public final class RecipeMaps { public static final RecipeMap GAS_TURBINE_FUELS = new RecipeMapBuilder<>("gas_turbine", new FuelRecipeBuilder()) .fluidInputs(1) - .fluidSlotOverlay(GuiTextures.DARK_CANISTER_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) + .uiBuilder(b -> b + .fluidSlotOverlay(GTGuiTextures.DARK_CANISTER_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_GAS_COLLECTOR)) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() .generator() @@ -1489,8 +1544,9 @@ public final class RecipeMaps { new FuelRecipeBuilder()) .fluidInputs(1) .fluidOutputs(1) - .fluidSlotOverlay(GuiTextures.CENTRIFUGE_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) + .uiBuilder(b -> b + .fluidSlotOverlay(GTGuiTextures.CENTRIFUGE_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_GAS_COLLECTOR)) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() .generator() @@ -1500,8 +1556,9 @@ public final class RecipeMaps { public static final RecipeMap SEMI_FLUID_GENERATOR_FUELS = new RecipeMapBuilder<>( "semi_fluid_generator", new FuelRecipeBuilder()) .fluidInputs(1) - .fluidSlotOverlay(GuiTextures.FURNACE_OVERLAY_2, false) - .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) + .uiBuilder(b -> b + .fluidSlotOverlay(GTGuiTextures.FURNACE_OVERLAY_2, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_ARROW_MULTIPLE)) .sound(GTSoundEvents.COMBUSTION) .allowEmptyOutputs() .generator() @@ -1512,8 +1569,9 @@ public final class RecipeMaps { new FuelRecipeBuilder()) .fluidInputs(1) .fluidOutputs(1) - .fluidSlotOverlay(GuiTextures.CENTRIFUGE_OVERLAY, false) - .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) + .uiBuilder(b -> b + .fluidSlotOverlay(GTGuiTextures.CENTRIFUGE_OVERLAY, false) + .progressBar(GTGuiTextures.PROGRESS_BAR_GAS_COLLECTOR)) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() .generator() diff --git a/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java b/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java index a6d66d3e62e..9936800ed92 100644 --- a/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java +++ b/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java @@ -4,30 +4,47 @@ import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ProgressWidget; -import gregtech.api.gui.widgets.RecipeProgressWidget; import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.widget.RecipeProgressWidget; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.DoubleSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widget.sizer.Area; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import com.cleanroommc.modularui.widgets.layout.Flow; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; +import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnmodifiableView; +import java.util.function.Consumer; import java.util.function.DoubleSupplier; @ApiStatus.Experimental public class RecipeMapUI> { - private final Byte2ObjectMap slotOverlays = new Byte2ObjectOpenHashMap<>(); - private final R recipeMap; private final boolean modifyItemInputs; private final boolean modifyItemOutputs; @@ -36,12 +53,33 @@ public class RecipeMapUI> { private final boolean isGenerator; + private boolean isJEIVisible = true; + + /* *********************** MUI 1 *********************** */ + + @Deprecated + private final @NotNull Area specialTexturePosition = new Area(); + @Deprecated + private final Byte2ObjectMap slotOverlays = new Byte2ObjectOpenHashMap<>(); + + @Deprecated private TextureArea progressBarTexture = GuiTextures.PROGRESS_BAR_ARROW; - private ProgressWidget.MoveType moveType = ProgressWidget.MoveType.HORIZONTAL; + @Deprecated + private gregtech.api.gui.widgets.ProgressWidget.MoveType moveType = gregtech.api.gui.widgets.ProgressWidget.MoveType.HORIZONTAL; + @Deprecated private @Nullable TextureArea specialTexture; - private int @Nullable [] specialTexturePosition; - private boolean isJEIVisible = true; + /* *********************** MUI 2 *********************** */ + + private final Byte2ObjectMap> overlays = new Byte2ObjectArrayMap<>(4); + + @ApiStatus.Experimental + private boolean usesMui2 = false; + private UITexture progressTexture = GTGuiTextures.PROGRESS_BAR_ARROW; + private ProgressWidget.Direction progressDirection = ProgressWidget.Direction.RIGHT; + private Consumer> extraOverlays = null; + private int width = GTGuis.DEFAULT_WIDTH; + private int height = GTGuis.DEFAULT_HIEGHT; /** * @param recipeMap the recipemap corresponding to this ui @@ -106,6 +144,25 @@ public static byte computeOverlayKey(boolean isOutput, boolean isFluid, boolean return new int[] { itemSlotsToLeft, itemSlotsToDown }; } + /** + * Determines the slot grid sizes for the item and fluid counts + * + * @param itemInputsCount the amount of item slots + * @param fluidInputsCount the amount of fluid tanks + * @return [item grid width, item grid height, fluid grid width, fluid grid height] + */ + @Contract("_, _ -> new") + public static int @NotNull [] determineSlotsGrid(int itemInputsCount, int fluidInputsCount) { + int[] arr = determineSlotsGrid(itemInputsCount); + int[] sizes = { arr[0], arr[1], 0, 0 }; + arr = determineSlotsGrid(fluidInputsCount); + sizes[2] = arr[0]; + sizes[3] = arr[1]; + return sizes; + } + + /* *********************** MUI 1 *********************** */ + /** * Create a JEI UI Template * @@ -116,14 +173,16 @@ public static byte computeOverlayKey(boolean isOutput, boolean isFluid, boolean * @param yOffset the y offset for the gui * @return the populated builder */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public ModularUI.Builder createJeiUITemplate(IItemHandlerModifiable importItems, IItemHandlerModifiable exportItems, FluidTankList importFluids, FluidTankList exportFluids, int yOffset) { ModularUI.Builder builder = ModularUI.defaultBuilder(yOffset); - builder.widget(new RecipeProgressWidget(200, 78, 23 + yOffset, 20, 20, progressBarTexture, - moveType, recipeMap)); + builder.widget(new gregtech.api.gui.widgets.RecipeProgressWidget(200, 78, 23 + yOffset, 20, 20, + progressBarTexture, moveType, recipeMap)); addInventorySlotGroup(builder, importItems, importFluids, false, yOffset); addInventorySlotGroup(builder, exportItems, exportFluids, true, yOffset); - if (specialTexture != null && specialTexturePosition != null) { + if (specialTexture != null) { addSpecialTexture(builder); } return builder; @@ -140,16 +199,18 @@ public ModularUI.Builder createJeiUITemplate(IItemHandlerModifiable importItems, * @param yOffset the y offset for the gui * @return the populated builder */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public ModularUI.Builder createUITemplate(DoubleSupplier progressSupplier, IItemHandlerModifiable importItems, IItemHandlerModifiable exportItems, FluidTankList importFluids, FluidTankList exportFluids, int yOffset) { ModularUI.Builder builder = ModularUI.defaultBuilder(yOffset); builder.widget( - new RecipeProgressWidget(progressSupplier, 78, 23 + yOffset, 20, 20, progressBarTexture, - moveType, recipeMap)); + new gregtech.api.gui.widgets.RecipeProgressWidget(progressSupplier, 78, 23 + yOffset, 20, 20, + progressBarTexture, moveType, recipeMap)); addInventorySlotGroup(builder, importItems, importFluids, false, yOffset); addInventorySlotGroup(builder, exportItems, exportFluids, true, yOffset); - if (specialTexture != null && specialTexturePosition != null) { + if (specialTexture != null) { addSpecialTexture(builder); } return builder; @@ -166,16 +227,18 @@ public ModularUI.Builder createUITemplate(DoubleSupplier progressSupplier, IItem * @param yOffset the y offset for the gui * @return the populated builder */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public ModularUI.Builder createUITemplateNoOutputs(DoubleSupplier progressSupplier, IItemHandlerModifiable importItems, IItemHandlerModifiable exportItems, FluidTankList importFluids, FluidTankList exportFluids, int yOffset) { ModularUI.Builder builder = ModularUI.defaultBuilder(yOffset); builder.widget( - new RecipeProgressWidget(progressSupplier, 78, 23 + yOffset, 20, 20, progressBarTexture, - moveType, recipeMap)); + new gregtech.api.gui.widgets.RecipeProgressWidget(progressSupplier, 78, 23 + yOffset, 20, 20, + progressBarTexture, moveType, recipeMap)); addInventorySlotGroup(builder, importItems, importFluids, false, yOffset); - if (specialTexture != null && specialTexturePosition != null) { + if (specialTexture != null) { addSpecialTexture(builder); } return builder; @@ -188,6 +251,8 @@ public ModularUI.Builder createUITemplateNoOutputs(DoubleSupplier progressSuppli * @param isOutputs if slots should be output slots * @param yOffset the y offset for the gui */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") protected void addInventorySlotGroup(@NotNull ModularUI.Builder builder, @NotNull IItemHandlerModifiable itemHandler, @NotNull FluidTankList fluidHandler, boolean isOutputs, int yOffset) { @@ -223,7 +288,7 @@ protected void addInventorySlotGroup(@NotNull ModularUI.Builder builder, int startSpecX = isOutputs ? startInputsX + itemSlotsToLeft * 18 : startInputsX - 18; for (int i = 0; i < fluidInputsCount; i++) { int y = startInputsY + 18 * i; - addSlot(builder, startSpecX, y, i, itemHandler, fluidHandler, !invertFluids, isOutputs); + addSlot(builder, startSpecX, y, i, itemHandler, fluidHandler, true, isOutputs); } } else { int startSpecY = startInputsY + itemSlotsToDown * 18; @@ -231,7 +296,7 @@ protected void addInventorySlotGroup(@NotNull ModularUI.Builder builder, int x = isOutputs ? startInputsX + 18 * (i % 3) : startInputsX + itemSlotsToLeft * 18 - 18 - 18 * (i % 3); int y = startSpecY + (i / 3) * 18; - addSlot(builder, x, y, i, itemHandler, fluidHandler, !invertFluids, isOutputs); + addSlot(builder, x, y, i, itemHandler, fluidHandler, true, isOutputs); } } } @@ -249,6 +314,8 @@ protected void addInventorySlotGroup(@NotNull ModularUI.Builder builder, * @param isFluid if the slot is a fluid slot * @param isOutputs if slots should be output slots */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") protected void addSlot(ModularUI.Builder builder, int x, int y, int slotIndex, IItemHandlerModifiable itemHandler, FluidTankList fluidHandler, boolean isFluid, boolean isOutputs) { if (!isFluid) { @@ -261,24 +328,11 @@ protected void addSlot(ModularUI.Builder builder, int x, int y, int slotIndex, I } } - /** - * @param isOutput if the slot is an output slot - * @param isFluid if the slot is a fluid slot - * @param isLast if the slot is the last slot of its type - * @return the overlays for a slot - */ - protected TextureArea[] getOverlaysForSlot(boolean isOutput, boolean isFluid, boolean isLast) { - TextureArea base = isFluid ? GuiTextures.FLUID_SLOT : GuiTextures.SLOT; - byte overlayKey = computeOverlayKey(isOutput, isFluid, isLast); - if (slotOverlays.containsKey(overlayKey)) { - return new TextureArea[] { base, slotOverlays.get(overlayKey) }; - } - return new TextureArea[] { base }; - } - /** * @return the height used to determine size of background texture in JEI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public int getPropertyHeightShift() { int maxPropertyCount = 0; if (shouldShiftWidgets()) { @@ -295,28 +349,53 @@ public int getPropertyHeightShift() { /** * @return widgets should be shifted */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") private boolean shouldShiftWidgets() { return recipeMap.getMaxInputs() + recipeMap.getMaxOutputs() >= 6 || recipeMap.getMaxFluidInputs() + recipeMap.getMaxFluidOutputs() >= 6; } + /** + * @param isOutput if the slot is an output slot + * @param isFluid if the slot is a fluid slot + * @param isLast if the slot is the last slot of its type + * @return the overlays for a slot + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + protected TextureArea[] getOverlaysForSlot(boolean isOutput, boolean isFluid, boolean isLast) { + TextureArea base = isFluid ? GuiTextures.FLUID_SLOT : GuiTextures.SLOT; + byte overlayKey = computeOverlayKey(isOutput, isFluid, isLast); + if (slotOverlays.containsKey(overlayKey)) { + return new TextureArea[] { base, slotOverlays.get(overlayKey) }; + } + return new TextureArea[] { base }; + } + /** * @return the progress bar's move type */ - public @NotNull ProgressWidget.MoveType progressBarMoveType() { + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public @NotNull gregtech.api.gui.widgets.ProgressWidget.MoveType progressBarMoveType() { return moveType; } /** * @param moveType the new progress bar move type */ - public void setProgressBarMoveType(@NotNull ProgressWidget.MoveType moveType) { + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public void setProgressBarMoveType(@NotNull gregtech.api.gui.widgets.ProgressWidget.MoveType moveType) { this.moveType = moveType; } /** * @return the texture of the progress bar */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull TextureArea progressBarTexture() { return progressBarTexture; } @@ -324,6 +403,8 @@ public void setProgressBarMoveType(@NotNull ProgressWidget.MoveType moveType) { /** * @param progressBarTexture the new progress bar texture */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setProgressBarTexture(@NotNull TextureArea progressBarTexture) { this.progressBarTexture = progressBarTexture; } @@ -332,7 +413,10 @@ public void setProgressBarTexture(@NotNull TextureArea progressBarTexture) { * @param progressBarTexture the new progress bar texture * @param moveType the new progress bar move type */ - public void setProgressBar(@NotNull TextureArea progressBarTexture, @NotNull ProgressWidget.MoveType moveType) { + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public void setProgressBar(@NotNull TextureArea progressBarTexture, + @NotNull gregtech.api.gui.widgets.ProgressWidget.MoveType moveType) { this.progressBarTexture = progressBarTexture; this.moveType = moveType; } @@ -344,6 +428,8 @@ public void setProgressBar(@NotNull TextureArea progressBarTexture, @NotNull Pro * @param width the width of the texture * @param height the height of the texture */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setSpecialTexture(@NotNull TextureArea specialTexture, int x, int y, int width, int height) { setSpecialTexture(specialTexture, new int[] { x, y, width, height }); } @@ -352,14 +438,22 @@ public void setSpecialTexture(@NotNull TextureArea specialTexture, int x, int y, * @param specialTexture the special texture to set * @param position the position of the texture: [x, y, width, height] */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setSpecialTexture(@NotNull TextureArea specialTexture, int @NotNull [] position) { this.specialTexture = specialTexture; - this.specialTexturePosition = position; + this.specialTexturePosition.set( + position[0], + position[1], + position[2], + position[3]); } /** * @return the special texture */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @Nullable TextureArea specialTexture() { return this.specialTexture; } @@ -367,7 +461,7 @@ public void setSpecialTexture(@NotNull TextureArea specialTexture, int @NotNull /** * @return the special texture's position */ - public int @Nullable @UnmodifiableView [] specialTexturePosition() { + public Area specialTexturePosition() { return this.specialTexturePosition; } @@ -377,57 +471,15 @@ public void setSpecialTexture(@NotNull TextureArea specialTexture, int @NotNull * @param builder the builder to add to * @return the updated builder */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public @NotNull ModularUI.Builder addSpecialTexture(@NotNull ModularUI.Builder builder) { - if (specialTexturePosition != null) { - builder.image(specialTexturePosition[0], specialTexturePosition[1], - specialTexturePosition[2], - specialTexturePosition[3], specialTexture); - } + builder.image(specialTexturePosition.x(), specialTexturePosition.y(), + specialTexturePosition.w(), + specialTexturePosition.h(), specialTexture); return builder; } - /** - * @return if this ui should be visible in JEI - */ - public boolean isJEIVisible() { - return isJEIVisible; - } - - /** - * @param isJEIVisible if the ui should be visible in JEI - */ - public void setJEIVisible(boolean isJEIVisible) { - this.isJEIVisible = isJEIVisible; - } - - /** - * @return if item input slot amounts can be modified - */ - public boolean canModifyItemInputs() { - return modifyItemInputs; - } - - /** - * @return if item output slot amounts can be modified - */ - public boolean canModifyItemOutputs() { - return modifyItemOutputs; - } - - /** - * @return if fluid input slot amounts can be modified - */ - public boolean canModifyFluidInputs() { - return modifyFluidInputs; - } - - /** - * @return if fluid output slot amounts can be modified - */ - public boolean canModifyFluidOutputs() { - return modifyFluidOutputs; - } - /** * @return if this UI represents an energy generating recipemap */ @@ -439,6 +491,8 @@ public boolean isGenerator() { * @param texture the texture to set * @param isOutput if the slot is an output slot */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setItemSlotOverlay(@NotNull TextureArea texture, boolean isOutput) { this.slotOverlays.put(computeOverlayKey(isOutput, false, false), texture); this.slotOverlays.put(computeOverlayKey(isOutput, false, true), texture); @@ -449,6 +503,8 @@ public void setItemSlotOverlay(@NotNull TextureArea texture, boolean isOutput) { * @param isOutput if the slot is an output slot * @param isLastSlot if the slot is the last slot */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setItemSlotOverlay(@NotNull TextureArea texture, boolean isOutput, boolean isLastSlot) { this.slotOverlays.put(computeOverlayKey(isOutput, false, isLastSlot), texture); } @@ -457,6 +513,8 @@ public void setItemSlotOverlay(@NotNull TextureArea texture, boolean isOutput, b * @param texture the texture to set * @param isOutput if the slot is an output slot */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setFluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput) { this.slotOverlays.put(computeOverlayKey(isOutput, true, false), texture); this.slotOverlays.put(computeOverlayKey(isOutput, true, true), texture); @@ -467,6 +525,8 @@ public void setFluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput) * @param isOutput if the slot is an output slot * @param isLastSlot if the slot is the last slot */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public void setFluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput, boolean isLastSlot) { this.slotOverlays.put(computeOverlayKey(isOutput, true, isLastSlot), texture); } @@ -475,15 +535,380 @@ public void setFluidSlotOverlay(@NotNull TextureArea texture, boolean isOutput, * @param key the key to store the slot's texture with * @param texture the texture to store */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @ApiStatus.Internal public void setSlotOverlay(byte key, @NotNull TextureArea texture) { this.slotOverlays.put(key, texture); } + /* *********************** MUI 2 *********************** */ + + public RecipeMapUI setSize(int width, int height) { + this.width = width; + this.height = height; + return this; + } + + public ModularPanel constructPanel(MetaTileEntity mte, DoubleSupplier progressSupplier, + IItemHandlerModifiable importItems, IItemHandlerModifiable exportItems, + FluidTankList importFluids, FluidTankList exportFluids, + int yOffset, PanelSyncManager syncManager) { + CalculatedGrid inputGrid = CalculatedGrid.of(importItems, importFluids); + CalculatedGrid outputGrid = CalculatedGrid.of(exportItems, exportFluids); + + int inputHeight = inputGrid.getMaxHeight(); + int outputHeight = outputGrid.getMaxHeight(); + + ModularPanel panel = GTGuis.createPanel(mte, this.width, adjustHeight(inputHeight, outputHeight)); + + DoubleSyncValue progressValue = new DoubleSyncValue(progressSupplier); + + int h = 3 * 18; + if (Math.max(inputHeight, outputHeight) < 3) { + h -= 18; + } + + Flow row = Flow.row() + .height(h) + .debugName("row:recipemapui.parent") + .alignX(0.5f) + .crossAxisAlignment(Alignment.CrossAxis.CENTER) + .top(23 - 7); + + int progressSize = 20; + int margin = 6; + row.width(calculatePixelWidth(inputGrid, outputGrid, progressSize, margin)); + + if (inputGrid.getMaxWidth() < outputGrid.getMaxWidth()) { + row.mainAxisAlignment(Alignment.MainAxis.END); + } + + if (importItems.getSlots() > 0 || importFluids.getTanks() > 0) { + row.child(makeInventorySlotGroup(inputGrid, importItems, importFluids, false)); + } + RecipeProgressWidget progressWidget = new RecipeProgressWidget(); + if (this.extraOverlays != null) { + this.extraOverlays.accept(progressWidget); + } + row.child(progressWidget + .recipeMap(recipeMap) + .debugName("recipe.progress") + .size(progressSize) + .margin(margin, 0) + .value(progressValue) + .texture(progressTexture, 20) + .direction(progressDirection)); + if (exportItems.getSlots() > 0 || exportFluids.getTanks() > 0) { + row.child(makeInventorySlotGroup(outputGrid, exportItems, exportFluids, true)); + } + return panel.child(row); + } + + private static int calculatePixelWidth(CalculatedGrid inputGrid, CalculatedGrid outputGrid, + int progressSize, int margin) { + int leftWidth = inputGrid.getMaxWidth() * 18; + int rightWidth = outputGrid.getMaxWidth() * 18; + + return (Math.max(leftWidth, rightWidth) + margin) * 2 + progressSize; + } + + private int adjustHeight(int inputHeight, int outputHeight) { + if (Math.max(inputHeight, outputHeight) < 4) { + return this.height - 18; + } + return this.height; + } + + private Widget makeItemGroup(CalculatedGrid grid, IItemHandlerModifiable handler, boolean isOutputs) { + Flow col = Flow.column() + .mainAxisAlignment(Alignment.MainAxis.END) + .coverChildren() + .debugName("col:item_grid"); + int width = grid.getItemGridWidth(); + int height = grid.getItemGridHeight(); + + SlotGroup slotGroup = new SlotGroup(isOutputs ? "output_items" : "input_items", width, 1, !isOutputs); + for (int i = 0; i < height; i++) { + Flow row = Flow.row() + .mainAxisAlignment(isOutputs ? Alignment.MainAxis.START : Alignment.MainAxis.END) + .coverChildren() + .debugName("row:item_" + i); + for (int j = 0; j < width; j++) { + row.child(makeItemSlot(slotGroup, (i * height) + j, handler, isOutputs)); + } + col.child(row); + } + return col; + } + + private Widget makeFluidGroup(CalculatedGrid grid, FluidTankList handler, boolean isOutputs) { + Flow col = Flow.column() + .mainAxisAlignment(Alignment.MainAxis.START) + .coverChildren() + .debugName("col:fluid_grid"); + + int width = grid.getFluidGridWidth(); + int height = grid.getFluidGridHeight(); + + for (int i = 0; i < height; i++) { + Flow row = Flow.row() + .mainAxisAlignment(isOutputs ? Alignment.MainAxis.START : Alignment.MainAxis.END) + .coverChildren() + .debugName("row:fluid_" + i); + for (int j = 0; j < width; j++) { + row.child(makeFluidSlot((i * height) + j, handler, isOutputs)); + } + col.child(row); + } + return col; + } + + @NotNull + protected Widget makeInventorySlotGroup(CalculatedGrid grid, @NotNull IItemHandlerModifiable itemHandler, + @NotNull FluidTankList fluidHandler, boolean isOutputs) { + final int itemInputsCount = itemHandler.getSlots(); + boolean onlyFluids = itemInputsCount == 0; + final int fluidInputsCount = fluidHandler.getTanks(); + if (fluidInputsCount == 0 && onlyFluids) { + // nothing to do here + throw new IllegalArgumentException("item and fluid handlers are empty!"); + } + + int itemGridHeight = grid.getFluidGridHeight(); + int fluidGridHeight = grid.getFluidGridHeight(); + if (!onlyFluids) { + itemGridHeight = grid.getItemGridHeight(); + } + + boolean singleRow = grid.isSingleRow(); + + Flow flow = (singleRow ? Flow.row() : Flow.column()) + .coverChildren() + .debugName(singleRow ? "row:parent" : "col:parent"); + flow.crossAxisAlignment(isOutputs ? Alignment.CrossAxis.START : Alignment.CrossAxis.END); + + if (!onlyFluids && fluidGridHeight > 1) { + // 1 should be 18, 2 should be 0, 3 should be -18, 4 should be -36 + // this is to make the first item row align with progress widget + flow.top((2 - itemGridHeight) * 18); + } + + if (itemInputsCount > 6) { + flow.top(0); + } + + if (onlyFluids) { + flow.childIf(fluidInputsCount > 0, () -> makeFluidGroup(grid, fluidHandler, isOutputs)); + } else { + flow.childIf(!singleRow || isOutputs, () -> makeItemGroup(grid, itemHandler, isOutputs)); + flow.childIf(fluidInputsCount > 0, () -> makeFluidGroup(grid, fluidHandler, isOutputs)); + flow.childIf(singleRow && !isOutputs, () -> makeItemGroup(grid, itemHandler, isOutputs)); + } + + return flow; + } + + protected ItemSlot makeItemSlot(SlotGroup group, int slotIndex, IItemHandlerModifiable itemHandler, + boolean isOutputs) { + return new ItemSlot() + .debugName("item.slot." + slotIndex + ":" + group.getName()) + .slot(SyncHandlers.itemSlot(itemHandler, slotIndex) + .slotGroup(group) + .accessibility(!isOutputs, true)) + .background(getDrawableOverlaysForSlot(isOutputs, false, slotIndex)); + } + + protected GTFluidSlot makeFluidSlot(int slotIndex, FluidTankList fluidHandler, boolean isOutputs) { + return new GTFluidSlot() + .debugName("fluid.slot." + slotIndex) + .syncHandler(GTFluidSlot.sync(fluidHandler.getTankAt(slotIndex)) + .accessibility(true, !isOutputs) + .drawAlwaysFull(true)) + .background(getDrawableOverlaysForSlot(isOutputs, true, slotIndex)); + } + + @ApiStatus.Experimental + protected IDrawable getDrawableOverlaysForSlot(boolean isOutput, boolean isFluid, int index) { + UITexture base = isFluid ? GTGuiTextures.FLUID_SLOT : GTGuiTextures.SLOT; + Int2ObjectMap overlays = getOverlayMap(isOutput, isFluid); + if (overlays.containsKey(index)) { + return IDrawable.of(base, overlays.get(index)); + } + return IDrawable.of(base); + } + + protected Int2ObjectMap getOverlayMap(boolean isOutput, boolean isFluid) { + return this.overlays.computeIfAbsent(computeKey(isOutput, isFluid), k -> new Int2ObjectArrayMap<>()); + } + + protected static byte computeKey(boolean isOutput, boolean isFluid) { + byte k = 0b00; + if (isOutput) k |= 0b10; + if (isFluid) k |= 0b01; + return k; + } + + /** Marked experimental as this method will be removed when all GTCEu UIs are ported to MUI2. */ + @ApiStatus.Experimental + @ApiStatus.Internal + public void setUsesMui2() { + this.usesMui2 = true; + } + + /** Marked experimental as this method will be removed when all GTCEu UIs are ported to MUI2. */ + @ApiStatus.Experimental + public boolean usesMui2() { + return usesMui2; + } + + // todo this is a quick and dirty method, find a better way + /** Marked experimental as this method will be removed when all GTCEu UIs are ported to MUI2. */ + @ApiStatus.Experimental + public RecipeMapUI buildMui2(@NotNull Consumer builderConsumer) { + builderConsumer.accept(new RecipeMapUIBuilder(this)); + return this; + } + + /** + * @param progressTexture the new progress bar texture + */ + public void setProgressBarTexture(@NotNull UITexture progressTexture) { + this.progressTexture = progressTexture; + } + + /** + * @param direction the new progress bar move type + */ + public void setProgressBarDirection(@NotNull ProgressWidget.Direction direction) { + this.progressDirection = direction; + } + + /** + * @param extraOverlays Consumer for adding stuff to the progress widget + */ + public void setSpecialTexture(Consumer> extraOverlays) { + this.extraOverlays = extraOverlays; + } + + /** + * @param texture the texture to store + * @param index the key to store the slot's texture with + * @param isFluid if the slot is fluid + * @param isOutput if the slot is an output + */ + @ApiStatus.Internal + public void setSlotOverlay(@NotNull IDrawable texture, int index, boolean isFluid, boolean isOutput) { + getOverlayMap(isOutput, isFluid).put(index, texture); + } + + /** + * @return if this ui should be visible in JEI + */ + public boolean isJEIVisible() { + return isJEIVisible; + } + + /** + * @param isJEIVisible if the ui should be visible in JEI + */ + public void setJEIVisible(boolean isJEIVisible) { + this.isJEIVisible = isJEIVisible; + } + + /** + * @return if item input slot amounts can be modified + */ + public boolean canModifyItemInputs() { + return modifyItemInputs; + } + + /** + * @return if item output slot amounts can be modified + */ + public boolean canModifyItemOutputs() { + return modifyItemOutputs; + } + + /** + * @return if fluid input slot amounts can be modified + */ + public boolean canModifyFluidInputs() { + return modifyFluidInputs; + } + + /** + * @return if fluid output slot amounts can be modified + */ + public boolean canModifyFluidOutputs() { + return modifyFluidOutputs; + } + /** * @return the UI's recipemap */ public @NotNull R recipeMap() { return recipeMap; } + + protected static class CalculatedGrid { + + private final int itemCount; + private final int fluidCount; + private final int[] grid; + + protected static CalculatedGrid of(IItemHandlerModifiable itemHandler, FluidTankList fluidTankList) { + return new CalculatedGrid(itemHandler.getSlots(), fluidTankList.getTanks()); + } + + private CalculatedGrid(int itemCount, int fluidCount) { + this.itemCount = itemCount; + this.fluidCount = fluidCount; + this.grid = RecipeMapUI.determineSlotsGrid(this.itemCount, this.fluidCount); + } + + public int getItemCount() { + return this.itemCount; + } + + public int getItemGridWidth() { + return this.grid[0]; + } + + public int getItemGridHeight() { + return this.grid[1]; + } + + public int getFluidCount() { + return this.fluidCount; + } + + public int getFluidGridWidth() { + return this.grid[2]; + } + + public int getFluidGridHeight() { + return this.grid[3]; + } + + public int getMaxWidth() { + if (isSingleRow()) { + return getFluidGridWidth() + getItemGridWidth(); + } else { + return Math.max(getFluidGridWidth(), getItemGridWidth()); + } + } + + public int getMaxHeight() { + if (isSingleRow()) { + return Math.max(getFluidGridHeight(), getItemGridHeight()); + } else { + return getFluidGridHeight() + getItemGridHeight(); + } + } + + private boolean isSingleRow() { + return getItemGridHeight() >= getFluidCount() && getItemGridWidth() < 3; + } + } } diff --git a/src/main/java/gregtech/api/recipes/ui/RecipeMapUIBuilder.java b/src/main/java/gregtech/api/recipes/ui/RecipeMapUIBuilder.java new file mode 100644 index 00000000000..9c3c05bb59f --- /dev/null +++ b/src/main/java/gregtech/api/recipes/ui/RecipeMapUIBuilder.java @@ -0,0 +1,159 @@ +package gregtech.api.recipes.ui; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +@ApiStatus.Experimental +@SuppressWarnings({ "unused", "UnusedReturnValue" }) +public class RecipeMapUIBuilder { + + private final RecipeMapUI mapUI; + + public RecipeMapUIBuilder(RecipeMapUI mapUI) { + this.mapUI = mapUI; + this.mapUI.setUsesMui2(); + } + + /** + * @param progressBar the progress bar texture to use + * @return this + */ + public @NotNull RecipeMapUIBuilder progressBar(@NotNull UITexture progressBar) { + this.mapUI.setProgressBarTexture(progressBar); + return this; + } + + /** + * @param moveType the progress bar move type to use + * @return this + */ + public @NotNull RecipeMapUIBuilder progressDirection(@NotNull ProgressWidget.Direction moveType) { + this.mapUI.setProgressBarDirection(moveType); + return this; + } + + /** + * @param progressBar the progress bar texture to use + * @param moveType the progress bar move type to use + * @return this + */ + public @NotNull RecipeMapUIBuilder progressBar(@NotNull UITexture progressBar, + @NotNull ProgressWidget.Direction moveType) { + return progressBar(progressBar).progressDirection(moveType); + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @return this + */ + public @NotNull RecipeMapUIBuilder itemSlotOverlay(@NotNull IDrawable texture, boolean isOutput) { + int max = getMax(false, isOutput); + for (int i = 0; i < max; i++) { + slotOverlay(texture, i, false, isOutput); + } + return this; + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @return this + */ + public @NotNull RecipeMapUIBuilder itemSlotOverlay(@NotNull IDrawable texture, int index, boolean isOutput) { + return slotOverlay(texture, index, false, isOutput); + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @param isLastSlot if the slot is the last slot + * @return this + */ + public @NotNull RecipeMapUIBuilder itemSlotOverlay(@NotNull IDrawable texture, + boolean isOutput, + boolean isLastSlot) { + int max = getMax(false, isOutput); + if (isLastSlot) { + return slotOverlay(texture, max - 1, false, isOutput); + } else for (int i = 0; i < max - 1; i++) { + slotOverlay(texture, i, false, isOutput); + } + return this; + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @return this + */ + public @NotNull RecipeMapUIBuilder fluidSlotOverlay(@NotNull IDrawable texture, + boolean isOutput) { + int max = getMax(true, isOutput); + for (int i = 0; i < max; i++) { + slotOverlay(texture, i, true, isOutput); + } + return this; + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @return this + */ + public @NotNull RecipeMapUIBuilder fluidSlotOverlay(@NotNull IDrawable texture, + int index, + boolean isOutput) { + return slotOverlay(texture, index, true, isOutput); + } + + /** + * @param texture the texture to use + * @param isOutput if the slot is an output slot + * @return this + */ + public @NotNull RecipeMapUIBuilder fluidSlotOverlay(@NotNull IDrawable texture, + boolean isOutput, + boolean isLastSlot) { + int max = getMax(true, isOutput); + if (isLastSlot) { + return slotOverlay(texture, max - 1, true, isOutput); + } else for (int i = 0; i < max - 1; i++) { + slotOverlay(texture, i, true, isOutput); + } + return this; + } + + /** + * @param texture the texture to use + * @param index the slot index + * @param isFluid if this slot is fluid + * @param isOutput if this slot is an output + * @return this + */ + public @NotNull RecipeMapUIBuilder slotOverlay(@NotNull IDrawable texture, int index, boolean isFluid, + boolean isOutput) { + this.mapUI.setSlotOverlay(texture, index, isFluid, isOutput); + return this; + } + + /** + * @param extraOverlays Consumer for adding stuff to the progress widget + */ + public @NotNull RecipeMapUIBuilder specialTexture(Consumer> extraOverlays) { + this.mapUI.setSpecialTexture(extraOverlays); + return this; + } + + private int getMax(boolean isFluid, boolean isOutput) { + var map = mapUI.recipeMap(); + if (isOutput) return isFluid ? map.getMaxFluidOutputs() : map.getMaxOutputs(); + else return isFluid ? map.getMaxFluidInputs() : map.getMaxInputs(); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java index f322cfbc4b8..14aa0e0e9c1 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java @@ -4,16 +4,13 @@ import gregtech.api.capability.impl.CommonFluidFilters; import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.FluidContainerSlotWidget; -import gregtech.api.gui.widgets.ProgressWidget; -import gregtech.api.gui.widgets.ProgressWidget.MoveType; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuiTheme; +import gregtech.api.mui.GTGuis; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -23,11 +20,11 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.mui.widget.GTFluidSlot; import gregtech.core.sound.GTSoundEvents; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -47,6 +44,18 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.DoubleSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; @@ -153,12 +162,14 @@ public void readFromNBT(NBTTagCompound data) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(isBurning); + buf.writeVarInt(currentTemperature); } @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); this.isBurning = buf.readBoolean(); + this.currentTemperature = buf.readVarInt(); } @Override @@ -331,28 +342,80 @@ protected TextureArea getGuiTexture(String pathTemplate) { type, STRING_SUBSTITUTION_PATTERN.matcher(pathTemplate).replaceAll(Matcher.quoteReplacement(type)))); } - public ModularUI.Builder createUITemplate(EntityPlayer player) { - return ModularUI.builder(GuiTextures.BACKGROUND_STEAM.get(isHighPressure), 176, 166) - .label(6, 6, getMetaFullName()).shouldColor(false) - .widget(new ProgressWidget(this::getTemperaturePercent, 96, 26, 10, 54) - .setProgressBar(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(isHighPressure), - GuiTextures.PROGRESS_BAR_BOILER_HEAT, - MoveType.VERTICAL)) - - .widget(new TankWidget(waterFluidTank, 83, 26, 10, 54) - .setBackgroundTexture(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(isHighPressure))) - .widget(new TankWidget(steamFluidTank, 70, 26, 10, 54) - .setBackgroundTexture(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(isHighPressure))) - - .widget(new FluidContainerSlotWidget(containerInventory, 0, 43, 26, true) - .setBackgroundTexture(GuiTextures.SLOT_STEAM.get(isHighPressure), - GuiTextures.IN_SLOT_OVERLAY_STEAM.get(isHighPressure))) - .slot(containerInventory, 1, 43, 62, true, false, - GuiTextures.SLOT_STEAM.get(isHighPressure), - GuiTextures.OUT_SLOT_OVERLAY_STEAM.get(isHighPressure)) - .image(43, 44, 18, 18, GuiTextures.CANISTER_OVERLAY_STEAM.get(isHighPressure)) - - .bindPlayerInventory(player.inventory, GuiTextures.SLOT_STEAM.get(isHighPressure), 0); + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + IntSyncValue temp = new IntSyncValue(this::getCurrentTemperature); + guiSyncManager.syncValue("temperature", temp); + return GTGuis.defaultPanel(this) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(new ProgressWidget() + .texture(getEmptyBarDrawable(), GTGuiTextures.PROGRESS_BAR_BOILER_HEAT, -1) + .direction(ProgressWidget.Direction.UP) + .debugName("temp") + .tooltipBuilder( + tooltip -> tooltip.addLine(IKey.lang("gregtech.machine.steam_boiler.heat_tooltip", + temp.getIntValue(), getMaxTemperate()))) + .value(new DoubleSyncValue(this::getTemperaturePercent)) + .pos(96, 26) + .size(10, 54)) + .child(new GTFluidSlot() + .debugName("water") + .background(getEmptyBarDrawable()) + .syncHandler(GTFluidSlot.sync(waterFluidTank) + .showAmountOnSlot(false) + .accessibility(false, false)) + .pos(83, 26) + .size(10, 54)) + .child(new GTFluidSlot() + .debugName("steam") + .background(getEmptyBarDrawable()) + .syncHandler(GTFluidSlot.sync(steamFluidTank) + .showAmountOnSlot(false) + .accessibility(false, false)) + .pos(70, 26) + .size(10, 54)) + .child(new ItemSlot() + .debugName("fluid in") + .background(getSlotBackground(false)) + .slot(new ModularSlot(containerInventory, 0) + .singletonSlotGroup()) + .pos(43, 26)) + .child(new ItemSlot() + .debugName("fluid out") + .background(getSlotBackground(true)) + .slot(new ModularSlot(containerInventory, 1) + .accessibility(false, true)) + .pos(43, 62)) + .child(new Widget<>() + .pos(43, 44) + .size(18) + .background(isHighPressure ? GTGuiTextures.CANISTER_OVERLAY_STEEL : + GTGuiTextures.CANISTER_OVERLAY_BRONZE)) + .bindPlayerInventory(); + } + + @Override + public GTGuiTheme getUITheme() { + return isHighPressure ? GTGuiTheme.STEEL : GTGuiTheme.BRONZE; + } + + protected UITexture getEmptyBarDrawable() { + return isHighPressure ? GTGuiTextures.PROGRESS_BAR_BOILER_EMPTY_STEEL : + GTGuiTextures.PROGRESS_BAR_BOILER_EMPTY_BRONZE; + } + + protected IDrawable getSlotBackground(boolean output) { + UITexture base = isHighPressure ? GTGuiTextures.SLOT_STEEL : GTGuiTextures.SLOT_BRONZE; + UITexture overlay; + if (isHighPressure) + overlay = output ? GTGuiTextures.OUT_SLOT_OVERLAY_STEEL : GTGuiTextures.IN_SLOT_OVERLAY_STEEL; + else overlay = output ? GTGuiTextures.OUT_SLOT_OVERLAY_BRONZE : GTGuiTextures.IN_SLOT_OVERLAY_BRONZE; + return IDrawable.of(base, overlay); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java index 555595b007f..44d9915c4cf 100755 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java @@ -1,22 +1,26 @@ package gregtech.common.metatileentities.steam.boiler; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.ProgressWidget.MoveType; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.recipes.ModHandler; import gregtech.api.recipes.category.ICategoryOverride; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.DoubleSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import org.jetbrains.annotations.NotNull; public class SteamCoalBoiler extends SteamBoiler implements ICategoryOverride { @@ -83,15 +87,23 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate } @Override - public ModularUI createUI(EntityPlayer player) { - return createUITemplate(player) - .slot(this.importItems, 0, 115, 62, - GuiTextures.SLOT_STEAM.get(isHighPressure), GuiTextures.COAL_OVERLAY_STEAM.get(isHighPressure)) - .slot(this.exportItems, 0, 115, 26, true, false, - GuiTextures.SLOT_STEAM.get(isHighPressure), GuiTextures.DUST_OVERLAY_STEAM.get(isHighPressure)) - .progressBar(this::getFuelLeftPercent, 115, 44, 18, 18, - GuiTextures.PROGRESS_BAR_BOILER_FUEL.get(isHighPressure), MoveType.VERTICAL) - .build(getHolder(), player); + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager) + .child(new ItemSlot() + .slot(this.importItems, 0) + .pos(115, 62)) + .child(new ItemSlot() + .slot(new ModularSlot(this.exportItems, 0) + .accessibility(false, true)) + .pos(115, 26)) + .child(new ProgressWidget() + .value(new DoubleSyncValue(this::getFuelLeftPercent)) + .pos(115, 44) + .size(18) + .texture(isHighPressure ? + GTGuiTextures.PROGRESS_BAR_BOILER_FUEL_STEEL : + GTGuiTextures.PROGRESS_BAR_BOILER_FUEL_BRONZE, 18) + .direction(ProgressWidget.Direction.UP)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java index 1269bf30450..ce9acbe74af 100755 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamLavaBoiler.java @@ -5,17 +5,15 @@ import gregtech.api.capability.impl.CommonFluidFilters; import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.unification.material.Materials; import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; +import gregtech.common.mui.widget.GTFluidSlot; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; @@ -26,6 +24,9 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -121,11 +122,16 @@ protected int getCoolDownRate() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createUITemplate(entityPlayer) - .widget(new TankWidget(fuelFluidTank, 119, 26, 10, 54) - .setBackgroundTexture(GuiTextures.PROGRESS_BAR_BOILER_EMPTY.get(isHighPressure))) - .build(getHolder(), entityPlayer); + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager) + .child(new GTFluidSlot() + .syncHandler(GTFluidSlot.sync(fuelFluidTank) + .showAmountOnSlot(false)) + .pos(119, 26) + .size(10, 54) + .background(isHighPressure ? + GTGuiTextures.PROGRESS_BAR_BOILER_EMPTY_STEEL : + GTGuiTextures.PROGRESS_BAR_BOILER_EMPTY_BRONZE)); } @SideOnly(Side.CLIENT) diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamSolarBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamSolarBoiler.java index 970afae65d3..ecbc3d8b1e6 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamSolarBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamSolarBoiler.java @@ -1,18 +1,21 @@ package gregtech.common.metatileentities.steam.boiler; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.ProgressWidget.MoveType; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.DoubleSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ProgressWidget; + public class SteamSolarBoiler extends SteamBoiler { public SteamSolarBoiler(ResourceLocation metaTileEntityId, boolean isHighPressure) { @@ -47,11 +50,15 @@ protected int getCoolDownRate() { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createUITemplate(entityPlayer) - .progressBar(() -> GTUtility.canSeeSunClearly(getWorld(), getPos()) ? 1.0 : 0.0, 114, 44, 20, 20, - GuiTextures.PROGRESS_BAR_SOLAR_STEAM.get(isHighPressure), MoveType.HORIZONTAL) - .build(getHolder(), entityPlayer); + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager) + .child(new ProgressWidget() + .value(new DoubleSyncValue(() -> GTUtility.canSeeSunClearly(getWorld(), getPos()) ? 1.0 : 0.0)) + .pos(114, 44) + .size(20) + .texture(isHighPressure ? + GTGuiTextures.PROGRESS_BAR_SOLAR_STEEL : + GTGuiTextures.PROGRESS_BAR_SOLAR_BRONZE, -1)); } @SideOnly(Side.CLIENT) diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 79b97d5b382..bb01508bef7 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -3018,6 +3018,7 @@ gregtech.machine.steam_boiler_lava_steel.name=High Pressure Steam Liquid Boiler gregtech.machine.steam_boiler_lava_steel.tooltip=Faster than Small Steam Liquid Boiler gregtech.machine.steam_boiler.heat_amount=Heat Capacity: %s %% +gregtech.machine.steam_boiler.heat_tooltip=Heat: %,d°C / %,d°C gregtech.machine.steam_extractor_bronze.name=Steam Extractor gregtech.machine.steam_extractor_bronze.tooltip=Extracting your first Rubber