diff options
| author | querns <33518699+querns@users.noreply.github.com> | 2023-09-08 15:39:21 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-08 22:39:21 +0200 |
| commit | 7f837715a8377b24853bf0fea02f23c210b47cfc (patch) | |
| tree | ab75df3f15857a83ee653750cb5090225a7c089d /src/main | |
| parent | e4f17b7b40503fd34d9dae447802453480b9577c (diff) | |
| download | GT5-Unofficial-7f837715a8377b24853bf0fea02f23c210b47cfc.tar.gz GT5-Unofficial-7f837715a8377b24853bf0fea02f23c210b47cfc.tar.bz2 GT5-Unofficial-7f837715a8377b24853bf0fea02f23c210b47cfc.zip | |
Adds status messages, action buttons to UI of multiblock drills (#2270)
* Adds several UI elements to multiblock drills
* Spotless
* Adds formatNumbers calls in places where it'd been missed
* Eliminate wildcard import
* Add @NotNull annotations to new fields and methods
Diffstat (limited to 'src/main')
15 files changed, 808 insertions, 56 deletions
diff --git a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java index 83aeb1d029..19bf3ca3f4 100644 --- a/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java +++ b/src/main/java/gregtech/api/gui/modularui/GT_UITextures.java @@ -281,6 +281,8 @@ public class GT_UITextures { .fullImage(GregTech.ID, "gui/overlay_button/batch_mode_off_disabled"); public static final UITexture OVERLAY_BUTTON_FORBIDDEN = UITexture .fullImage(GregTech.ID, "gui/overlay_button/forbidden"); + public static final UITexture OVERLAY_BUTTON_LOCKED = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/lock_small"); public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_ON = UITexture .fullImage(GregTech.ID, "gui/overlay_button/down_tiering_on"); public static final UITexture OVERLAY_BUTTON_DOWN_TIERING_OFF = UITexture @@ -366,6 +368,17 @@ public class GT_UITextures { .fullImage(GregTech.ID, "gui/overlay_button/use_processing_state.png"); public static final UITexture OVERLAY_BUTTON_USE_INVERTED_PROCESSING_STATE = UITexture .fullImage(GregTech.ID, "gui/overlay_button/use_inverted_processing_state.png"); + public static final UITexture OVERLAY_CHUNK_LOADING = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/chunkloading"); + public static final UITexture OVERLAY_CHUNK_LOADING_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/chunkloading_off"); + public static final UITexture OVERLAY_WORK_AREA = UITexture.fullImage(GregTech.ID, "gui/overlay_button/work_area"); + public static final UITexture OVERLAY_REPLACE_COBBLE_ON = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_on"); + public static final UITexture OVERLAY_REPLACE_COBBLE_OFF = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/replace_cobble_off"); + public static final UITexture OVERLAY_RETRACT_PIPE = UITexture + .fullImage(GregTech.ID, "gui/overlay_button/retract_pipes"); /** * Can adjust size as needed. diff --git a/src/main/java/gregtech/api/gui/widgets/GT_DisabledWhileActiveButton.java b/src/main/java/gregtech/api/gui/widgets/GT_DisabledWhileActiveButton.java new file mode 100644 index 0000000000..e86589ac2a --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/GT_DisabledWhileActiveButton.java @@ -0,0 +1,104 @@ +package gregtech.api.gui.widgets; + +import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Supplier; + +import net.minecraft.util.StatCollector; + +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; + +import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.interfaces.tileentity.IMachineProgress; + +public class GT_DisabledWhileActiveButton extends ButtonWidget { + + @NotNull + private final WeakReference<IMachineProgress> machineRef; + + public GT_DisabledWhileActiveButton(@NotNull IMachineProgress machine, @NotNull ModularWindow.Builder builder) { + super(); + machineRef = new WeakReference<>(machine); + + super.attachSyncer( + new FakeSyncWidget.BooleanSyncer(() -> isMachineActive().orElse(true), a -> {}), + builder, + (widget, aBoolean) -> widget.notifyTooltipChange()); + + super.dynamicTooltip(this::generateTooltip); + } + + @NotNull + @Override + public ButtonWidget setOnClick(@NotNull BiConsumer<ClickData, Widget> clickAction) { + return super.setOnClick((clickData, widget) -> isMachineActive().ifPresent(isActive -> { + if (!isActive) { + clickAction.accept(clickData, widget); + } + })); + } + + @NotNull + @Override + public Widget setBackground(@NotNull IDrawable... drawables) { + return super.setBackground(() -> appendLockedOverlay(drawables)); + } + + @NotNull + @Override + public Widget setBackground(@NotNull Supplier<IDrawable[]> drawablesSupplier) { + return super.setBackground(() -> appendLockedOverlay(drawablesSupplier.get())); + } + + @NotNull + @Override + public Widget dynamicTooltip(@NotNull Supplier<List<String>> dynamicTooltip) { + return super.dynamicTooltip(() -> { + ImmutableList.Builder<String> tooltips = ImmutableList.<String>builder() + .addAll(dynamicTooltip.get()); + tooltips.addAll(generateTooltip()); + + return tooltips.build(); + }); + } + + @NotNull + private Optional<Boolean> isMachineActive() { + return Optional.ofNullable(machineRef.get()) + .map(IMachineProgress::isActive); + } + + @NotNull + private IDrawable[] appendLockedOverlay(@NotNull IDrawable[] drawables) { + return isMachineActive().map(isActive -> { + if (isActive) { + final IDrawable[] copy = Arrays.copyOf(drawables, drawables.length + 1); + copy[drawables.length] = GT_UITextures.OVERLAY_BUTTON_LOCKED; + return copy; + } + return drawables; + }) + .orElse(drawables); + } + + @NotNull + private List<String> generateTooltip() { + return isMachineActive().map(isActive -> { + if (isActive) { + return ImmutableList.of(StatCollector.translateToLocal("GT5U.gui.button.forbidden_while_running")); + } + return ImmutableList.<String>of(); + }) + .orElse(ImmutableList.of()); + } +} diff --git a/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java b/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java index aa129bab86..ad0d56708e 100644 --- a/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java +++ b/src/main/java/gregtech/api/recipe/check/CheckRecipeResultRegistry.java @@ -84,6 +84,13 @@ public final class CheckRecipeResultRegistry { * Machine had an internal error */ public static final CheckRecipeResult INTERNAL_ERROR = SimpleCheckRecipeResult.ofFailure("internal_error"); + /** Multiblock ore drill has no drilling fluid */ + public static final CheckRecipeResult NO_DRILLING_FLUID = SimpleCheckRecipeResult.ofFailure("no_drilling_fluid"); + /** Multiblock drill is missing mining pipe */ + public static final CheckRecipeResult MISSING_MINING_PIPE = SimpleCheckRecipeResult.ofFailure("no_mining_pipe"); + /** Concrete backfiller is out of concrete */ + public static final CheckRecipeResult BACKFILLER_NO_CONCRETE = SimpleCheckRecipeResult + .ofFailure("backfiller_no_concrete"); /** * Cannot process recipe because the machine cannot handle required EUt. diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_ConcreteBackfillerBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_ConcreteBackfillerBase.java index 1c7f802a38..3e9238003f 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_ConcreteBackfillerBase.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_ConcreteBackfillerBase.java @@ -9,13 +9,20 @@ import static gregtech.api.enums.GT_Values.VN; import java.util.List; import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; import gregtech.api.GregTech_API; import gregtech.api.enums.Materials; import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; @@ -23,12 +30,21 @@ public abstract class GT_MetaTileEntity_ConcreteBackfillerBase extends GT_MetaTi private int mLastXOff = 0, mLastZOff = 0; + /** Used to drive the readout in the GUI for the backfiller's current y-level. */ + private int clientYHead; + public GT_MetaTileEntity_ConcreteBackfillerBase(int aID, String aName, String aNameRegional) { super(aID, aName, aNameRegional); + initRecipeResults(); } public GT_MetaTileEntity_ConcreteBackfillerBase(String aName) { super(aName); + initRecipeResults(); + } + + private void initRecipeResults() { + addResultMessage(STATE_UPWARD, true, "backfiller_working"); } protected GT_Multiblock_Tooltip_Builder createTooltip(String aStructureName) { @@ -107,6 +123,7 @@ public abstract class GT_MetaTileEntity_ConcreteBackfillerBase extends GT_MetaTi } else { workState = STATE_DOWNWARD; stopMachine(); + setShutdownReason(StatCollector.translateToLocal("GT5U.gui.text.backfiller_finished")); return false; } } @@ -123,7 +140,10 @@ public abstract class GT_MetaTileEntity_ConcreteBackfillerBase extends GT_MetaTi } private boolean tryRefillBlock(int aX, int aY, int aZ) { - if (!tryConsumeFluid()) return false; + if (!tryConsumeFluid()) { + setRuntimeFailureReason(CheckRecipeResultRegistry.BACKFILLER_NO_CONCRETE); + return false; + } getBaseMetaTileEntity().getWorld() .setBlock(aX, aY, aZ, GregTech_API.sBlockConcretes, 8, 3); return true; @@ -136,4 +156,21 @@ public abstract class GT_MetaTileEntity_ConcreteBackfillerBase extends GT_MetaTi } return true; } + + @Override + protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { + super.drawTexts(screenElements, inventorySlot); + screenElements + .widget( + TextWidget + .dynamicString( + () -> StatCollector.translateToLocalFormatted( + "GT5U.gui.text.backfiller_current_area", + GT_Utility.formatNumbers(clientYHead))) + .setSynced(false) + .setTextAlignment(Alignment.CenterLeft) + .setEnabled(widget -> getBaseMetaTileEntity().isActive() && workState == STATE_UPWARD)) + .widget(new FakeSyncWidget.IntegerSyncer(this::getYHead, newInt -> clientYHead = newInt)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> workState, newInt -> workState = newInt)); + } } diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java index 77b5073c86..983e6c5998 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_DrillerBase.java @@ -16,12 +16,16 @@ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ORE_DRILL_ACT import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ORE_DRILL_ACTIVE_GLOW; import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_ORE_DRILL_GLOW; import static gregtech.api.enums.Textures.BlockIcons.getCasingTextureForId; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; import static gregtech.api.util.GT_StructureUtility.buildHatchAdder; import static gregtech.api.util.GT_StructureUtility.ofFrame; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; @@ -29,6 +33,7 @@ import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.StatCollector; import net.minecraft.world.ChunkCoordIntPair; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.ForgeDirection; @@ -41,10 +46,22 @@ import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructa import com.gtnewhorizon.structurelib.structure.IStructureDefinition; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import com.gtnewhorizon.structurelib.structure.StructureDefinition; +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; import gregtech.api.GregTech_API; import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; +import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.gui.widgets.GT_DisabledWhileActiveButton; import gregtech.api.interfaces.IChunkLoader; import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; @@ -56,6 +73,7 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_DataA import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy; import gregtech.api.objects.GT_ChunkManager; import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.recipe.check.SimpleCheckRecipeResult; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_ModHandler; @@ -127,13 +145,29 @@ public abstract class GT_MetaTileEntity_DrillerBase return zDrill; } + protected int getYHead() { + return yHead; + } + protected int workState; - protected static final int STATE_DOWNWARD = 0, STATE_AT_BOTTOM = 1, STATE_UPWARD = 2; + protected static final int STATE_DOWNWARD = 0, STATE_AT_BOTTOM = 1, STATE_UPWARD = 2, STATE_ABORT = 3; protected boolean mChunkLoadingEnabled = true; protected ChunkCoordIntPair mCurrentChunk = null; protected boolean mWorkChunkNeedsReload = true; + /** Stores default result messages for success/failures of each work state. */ + private final Map<ResultRegistryKey, CheckRecipeResult> resultRegistry = new HashMap<>(); + + /** Allows inheritors to supply custom runtime failure messages. */ + private CheckRecipeResult runtimeFailure = null; + + /** Allows inheritors to supply custom shutdown failure messages. */ + private @NotNull String shutdownReason = ""; + + /** Allows inheritors to suppress wiping the last error if the machine is forcibly turned off. */ + protected boolean suppressErrorWipe = false; + public GT_MetaTileEntity_DrillerBase(int aID, String aName, String aNameRegional) { super(aID, aName, aNameRegional); initFields(); @@ -154,6 +188,16 @@ public abstract class GT_MetaTileEntity_DrillerBase : W; casingTextureIndex = getCasingTextureIndex(); workState = STATE_DOWNWARD; + + // Inheritors can overwrite these to add custom operating messages. + addResultMessage(STATE_DOWNWARD, true, "deploying_pipe"); + addResultMessage(STATE_DOWNWARD, false, "extracting_pipe"); + addResultMessage(STATE_AT_BOTTOM, true, "drilling"); + addResultMessage(STATE_AT_BOTTOM, false, "no_mining_pipe"); + addResultMessage(STATE_UPWARD, true, "retracting_pipe"); + addResultMessage(STATE_UPWARD, false, "drill_generic_finished"); + addResultMessage(STATE_ABORT, true, "retracting_pipe"); + addResultMessage(STATE_ABORT, false, "drill_retract_pipes_finished"); } @Override @@ -380,6 +424,7 @@ public abstract class GT_MetaTileEntity_DrillerBase switch (tryLowerPipeState()) { case 2 -> { mMaxProgresstime = 0; + setRuntimeFailureReason(CheckRecipeResultRegistry.MISSING_MINING_PIPE); return false; } case 3 -> { @@ -417,6 +462,49 @@ public abstract class GT_MetaTileEntity_DrillerBase } } + /** Called once when the abort button is clicked. Use to perform any needed cleanup (e.g. unloading chunks.) */ + protected void onAbort() {} + + protected void abortDrilling() { + if (workState != STATE_ABORT) { + workState = STATE_ABORT; + onAbort(); + setShutdownReason(""); + + if (!isAllowedToWork()) { + enableWorking(); + } + } + } + + // This is a distinct state from workingUpward, because some inheritors (like concrete backfiller) operate + // exclusively on the workingUpward phase. It also allows for more distinct status messages. + protected boolean workingToAbortOperation(@NotNull ItemStack aStack, int xDrill, int yDrill, int zDrill, int xPipe, + int zPipe, int yHead, int oldYHead) { + if (tryPickPipe()) { + return true; + } else { + workState = STATE_DOWNWARD; + stopMachine(); + return false; + } + } + + @Override + public void enableWorking() { + super.enableWorking(); + shutdownReason = ""; + } + + @Override + public void onDisableWorking() { + if (suppressErrorWipe) { + suppressErrorWipe = false; + } else { + super.onDisableWorking(); + } + } + @Override @NotNull public CheckRecipeResult checkProcessing() { @@ -424,34 +512,88 @@ public abstract class GT_MetaTileEntity_DrillerBase // Public pipe actions setElectricityStats(); int oldYHead = yHead; - if (!checkPipesAndSetYHead() || !isEnergyEnough()) { + if (!checkPipesAndSetYHead()) { stopMachine(); return SimpleCheckRecipeResult.ofFailure("no_mining_pipe"); + } else if (!isEnergyEnough()) { + stopMachine(); + return SimpleCheckRecipeResult.ofFailure("not_enough_energy"); } putMiningPipesFromInputsInController(); + + final boolean wasSuccessful; switch (workState) { - case STATE_DOWNWARD -> { - return workingDownward(controllerStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead) - ? SimpleCheckRecipeResult.ofSuccess("drilling") - : SimpleCheckRecipeResult.ofFailure("extracting_pipe"); + case STATE_DOWNWARD -> wasSuccessful = workingDownward( + controllerStack, + xDrill, + yDrill, + zDrill, + xPipe, + zPipe, + yHead, + oldYHead); + case STATE_AT_BOTTOM -> wasSuccessful = workingAtBottom( + controllerStack, + xDrill, + yDrill, + zDrill, + xPipe, + zPipe, + yHead, + oldYHead); + case STATE_UPWARD -> wasSuccessful = workingUpward( + controllerStack, + xDrill, + yDrill, + zDrill, + xPipe, + zPipe, + yHead, + oldYHead); + case STATE_ABORT -> wasSuccessful = workingToAbortOperation( + controllerStack, + xDrill, + yDrill, + zDrill, + xPipe, + zPipe, + yHead, + oldYHead); + default -> wasSuccessful = false; + } - } - case STATE_AT_BOTTOM -> { - return workingAtBottom(controllerStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead) - ? SimpleCheckRecipeResult.ofSuccess("drilling") - : SimpleCheckRecipeResult.ofFailure("no_mining_pipe"); - } - case STATE_UPWARD -> { - return workingUpward(controllerStack, xDrill, yDrill, zDrill, xPipe, zPipe, yHead, oldYHead) - ? SimpleCheckRecipeResult.ofSuccess("retracting_pipe") - : SimpleCheckRecipeResult.ofFailure("no_mining_pipe"); - } - default -> { - return SimpleCheckRecipeResult.ofFailure("no_mining_pipe"); - } + if (runtimeFailure == null) { + return resultRegistry.getOrDefault( + new ResultRegistryKey(workState, wasSuccessful), + SimpleCheckRecipeResult.ofFailure("no_mining_pipe")); + } else { + final CheckRecipeResult result; + result = runtimeFailure; + runtimeFailure = null; + return result; } } + /** + * Allow drills to set a specific failure reason specific to their situation. E.g.: out of drilling fluid. + * Should be used when the machine doesn't turn off due to the failure. + * + * @param newFailureReason A new failure reason + */ + protected void setRuntimeFailureReason(@NotNull CheckRecipeResult newFailureReason) { + runtimeFailure = newFailureReason; + } + + /** + * Sets a line in the UI to explain why the drill shut down. E.g.: operation finished. + * Should be used when the machine has been turned off due to an operating issue or completion. + * + * @param newReason The reason for the machine shutdown + */ + protected void setShutdownReason(@NotNull String newReason) { + shutdownReason = newReason; + } + @Override protected IAlignmentLimits getInitialAlignmentLimits() { return (d, r, f) -> (d.flag & (ForgeDirection.UP.flag | ForgeDirection.DOWN.flag)) == 0 && r.isNotRotated() @@ -636,6 +778,89 @@ public abstract class GT_MetaTileEntity_DrillerBase return survivialBuildPiece(STRUCTURE_PIECE_MAIN, stackSize, 1, 6, 0, elementBudget, env, false, true); } + @Override + protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { + super.drawTexts(screenElements, inventorySlot); + screenElements.widget( + TextWidget.dynamicString(() -> shutdownReason) + .setSynced(false) + .setTextAlignment(Alignment.CenterLeft) + .setEnabled(widget -> !(getBaseMetaTileEntity().isActive() || shutdownReason.isEmpty()))) + .widget(new FakeSyncWidget.StringSyncer(() -> shutdownReason, newString -> shutdownReason = newString)); + } + + /** + * Adds additional buttons to the main button row. You do not need to set the position. + * + * @param builder Only use to attach SyncWidgets. + * @param buildContext Context for things like the player. + */ + protected List<ButtonWidget> getAdditionalButtons(ModularWindow.Builder builder, UIBuildContext buildContext) { + return ImmutableList.of(); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + super.addUIWidgets(builder, buildContext); + final int BUTTON_Y_LEVEL = 91; + + builder.widget( + new GT_DisabledWhileActiveButton(this.getBaseMetaTileEntity(), builder) + .setOnClick((clickData, widget) -> mChunkLoadingEnabled = !mChunkLoadingEnabled) + .setPlayClickSound(true) + .setBackground(() -> { + if (mChunkLoadingEnabled) { + return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED, + GT_UITextures.OVERLAY_CHUNK_LOADING }; + } + return new IDrawable[] { GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_CHUNK_LOADING_OFF }; + }) + .attachSyncer( + new FakeSyncWidget.BooleanSyncer( + () -> mChunkLoadingEnabled, + newBoolean -> mChunkLoadingEnabled = newBoolean), + builder, + (widget, val) -> widget.notifyTooltipChange()) + .dynamicTooltip( + () -> ImmutableList.of( + StatCollector.translateToLocal( + mChunkLoadingEnabled ? "GT5U.gui.button.chunk_loading_on" + : "GT5U.gui.button.chunk_loading_off"))) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(new Pos2d(80, BUTTON_Y_LEVEL)) + .setSize(16, 16)) + .widget( + new ButtonWidget().setOnClick((clickData, widget) -> abortDrilling()) + .setPlayClickSound(true) + .setBackground(() -> { + if (workState == STATE_ABORT) { + return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED, + GT_UITextures.OVERLAY_RETRACT_PIPE, GT_UITextures.OVERLAY_BUTTON_LOCKED }; + } + return new IDrawable[] { GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_RETRACT_PIPE }; + }) + .attachSyncer( + new FakeSyncWidget.IntegerSyncer(() -> workState, (newInt) -> workState = newInt), + builder, + (widget, integer) -> widget.notifyTooltipChange()) + .dynamicTooltip( + () -> ImmutableList.of( + StatCollector.translateToLocalFormatted( + workState == STATE_ABORT ? "GT5U.gui.button.drill_retract_pipes_active" + : "GT5U.gui.button.drill_retract_pipes"))) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .setPos(new Pos2d(174, 130)) + .setSize(16, 16)); + + int left = 98; + for (ButtonWidget button : getAdditionalButtons(builder, buildContext)) { + button.setPos(new Pos2d(left, BUTTON_Y_LEVEL)) + .setSize(16, 16); + builder.widget(button); + left += 18; + } + } + protected List<IHatchElement<? super GT_MetaTileEntity_DrillerBase>> getAllowedHatches() { return ImmutableList.of( InputHatch, @@ -667,4 +892,57 @@ public abstract class GT_MetaTileEntity_DrillerBase return t.mDataAccessHatches.size(); } } + + /** + * Sets or overrides the {@link CheckRecipeResult} for a given work state + * + * @param state A work state like {@link #STATE_DOWNWARD}. + * @param result A previously registered recipe result. + */ + protected void addResultMessage(final int state, @NotNull final CheckRecipeResult result) { + resultRegistry.put(new ResultRegistryKey(state, result.wasSuccessful()), result); + } + + /** + * Sets or overrides the {@link CheckRecipeResult} for a given work state and operation success type. + * + * @param state A work state like {@link #STATE_DOWNWARD}. + * @param wasSuccessful Whether the operation was successful. + * @param resultKey An I18N key for the message. + */ + protected void addResultMessage(final int state, final boolean wasSuccessful, @NotNull final String resultKey) { + addResultMessage( + state, + wasSuccessful ? SimpleCheckRecipeResult.ofSuccess(resultKey) + : SimpleCheckRecipeResult.ofFailure(resultKey)); + } + + @SuppressWarnings("ClassCanBeRecord") + private final static class ResultRegistryKey { + + private final int state; + private final boolean successful; + + public ResultRegistryKey(final int state, final boolean successful) { + this.state = state; + this.successful = successful; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ResultRegistryKey other)) { + return false; + } + + return (state == other.state && successful == other.successful); + } + + @Override + public int hashCode() { + return Objects.hash(state, successful); + } + } } diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java index 5031a664c7..9a6f2b5e80 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_OilDrillBase.java @@ -29,16 +29,25 @@ import net.minecraft.util.StatCollector; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.chunk.Chunk; import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.NotNull; + import com.google.common.collect.ImmutableList; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; import gregtech.api.enums.SoundResource; import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.objects.GT_ChunkManager; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Log; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; @@ -207,6 +216,7 @@ public abstract class GT_MetaTileEntity_OilDrillBase extends GT_MetaTileEntity_D if (pumpResult.getType() != ValidationType.VALID) { mEUt = 0; mMaxProgresstime = 0; + setRuntimeFailureReason(CheckRecipeResultRegistry.OUTPUT_FULL); return false; } FluidStack tFluid = pumpResult.getResult(); @@ -217,6 +227,7 @@ public abstract class GT_MetaTileEntity_OilDrillBase extends GT_MetaTileEntity_D } GT_ChunkManager.releaseTicket((TileEntity) getBaseMetaTileEntity()); workState = STATE_UPWARD; + setShutdownReason(StatCollector.translateToLocal("GT5U.gui.text.drill_exhausted")); return true; } @@ -359,24 +370,84 @@ public abstract class GT_MetaTileEntity_OilDrillBase extends GT_MetaTileEntity_D + EnumChatFormatting.RESET, StatCollector.translateToLocal("GT5U.machines.workarea") + ": " + EnumChatFormatting.GREEN - + (chunkRangeConfig) + + GT_Utility.formatNumbers(chunkRangeConfig) + " x " - + (chunkRangeConfig) + + GT_Utility.formatNumbers(chunkRangeConfig) + EnumChatFormatting.RESET + " " + StatCollector.translateToLocal("GT5U.machines.chunks"), - "Drilling fluid: " + EnumChatFormatting.GREEN - + (mOilId > 0 ? FluidRegistry.getFluid(mOilId) - .getName() : "None") - + EnumChatFormatting.RESET, + "Drilling fluid: " + EnumChatFormatting.GREEN + getFluidName() + EnumChatFormatting.RESET, "Drilling flow: " + EnumChatFormatting.GREEN - + GT_Utility.formatNumbers(this.mMaxProgresstime > 0 ? (mOilFlow / this.mMaxProgresstime) : 0) + + getFlowRatePerTick() + EnumChatFormatting.RESET + " L/t")); l.addAll(Arrays.asList(super.getInfoData())); return l.toArray(new String[0]); } + @NotNull + protected String getFlowRatePerTick() { + return GT_Utility.formatNumbers(this.mMaxProgresstime > 0 ? (mOilFlow / this.mMaxProgresstime) : |
