Skip to content

Commit b8e345d

Browse files
authored
[MUI2] Cleanroom (#4631)
1 parent 2e6af0c commit b8e345d

File tree

2 files changed

+174
-52
lines changed

2 files changed

+174
-52
lines changed

src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CleanroomMachine.java

Lines changed: 172 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,32 @@
1818
import com.gregtechceu.gtceu.api.machine.trait.CleanroomProviderTrait;
1919
import com.gregtechceu.gtceu.api.machine.trait.CleanroomReceiverTrait;
2020
import com.gregtechceu.gtceu.api.misc.EnergyContainerList;
21+
import com.gregtechceu.gtceu.api.mui.base.drawable.IKey;
22+
import com.gregtechceu.gtceu.api.mui.drawable.Icon;
23+
import com.gregtechceu.gtceu.api.mui.factory.PosGuiData;
24+
import com.gregtechceu.gtceu.api.mui.utils.Alignment;
25+
import com.gregtechceu.gtceu.api.mui.value.sync.BooleanSyncValue;
26+
import com.gregtechceu.gtceu.api.mui.value.sync.GenericSyncValue;
27+
import com.gregtechceu.gtceu.api.mui.value.sync.IntSyncValue;
28+
import com.gregtechceu.gtceu.api.mui.value.sync.LongSyncValue;
29+
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
30+
import com.gregtechceu.gtceu.api.mui.value.sync.StringSyncValue;
31+
import com.gregtechceu.gtceu.api.mui.widget.ParentWidget;
32+
import com.gregtechceu.gtceu.api.mui.widget.Widget;
33+
import com.gregtechceu.gtceu.api.mui.widgets.ListWidget;
34+
import com.gregtechceu.gtceu.api.mui.widgets.SlotGroupWidget;
35+
import com.gregtechceu.gtceu.api.mui.widgets.layout.Flow;
2136
import com.gregtechceu.gtceu.api.pattern.BlockPattern;
2237
import com.gregtechceu.gtceu.api.pattern.FactoryBlockPattern;
2338
import com.gregtechceu.gtceu.api.pattern.Predicates;
2439
import com.gregtechceu.gtceu.api.pattern.TraceabilityPredicate;
2540
import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField;
41+
import com.gregtechceu.gtceu.client.mui.screen.ModularPanel;
42+
import com.gregtechceu.gtceu.client.mui.screen.UISettings;
2643
import com.gregtechceu.gtceu.common.data.GTBlocks;
2744
import com.gregtechceu.gtceu.common.data.GTMachines;
45+
import com.gregtechceu.gtceu.common.data.mui.GTMuiWidgets;
46+
import com.gregtechceu.gtceu.common.data.mui.GTMultiblockTextUtil;
2847
import com.gregtechceu.gtceu.common.item.PortableScannerBehavior;
2948
import com.gregtechceu.gtceu.common.machine.electric.HullMachine;
3049
import com.gregtechceu.gtceu.common.machine.multiblock.generator.LargeCombustionEngineMachine;
@@ -34,16 +53,21 @@
3453
import com.gregtechceu.gtceu.common.machine.multiblock.primitive.PrimitiveBlastFurnaceMachine;
3554
import com.gregtechceu.gtceu.common.machine.multiblock.primitive.PrimitivePumpMachine;
3655
import com.gregtechceu.gtceu.common.machine.trait.CleanroomLogic;
56+
import com.gregtechceu.gtceu.common.mui.GTGuiTextures;
57+
import com.gregtechceu.gtceu.common.mui.GTGuis;
3758
import com.gregtechceu.gtceu.config.ConfigHolder;
3859
import com.gregtechceu.gtceu.data.recipe.CustomTags;
3960
import com.gregtechceu.gtceu.utils.GTUtil;
4061

4162
import com.lowdragmc.lowdraglib.utils.BlockInfo;
4263

64+
import net.minecraft.ChatFormatting;
4365
import net.minecraft.MethodsReturnNonnullByDefault;
4466
import net.minecraft.core.BlockPos;
4567
import net.minecraft.core.Direction;
4668
import net.minecraft.network.chat.Component;
69+
import net.minecraft.network.chat.HoverEvent;
70+
import net.minecraft.network.chat.Style;
4771
import net.minecraft.util.Mth;
4872
import net.minecraft.world.level.Level;
4973
import net.minecraft.world.level.block.Blocks;
@@ -66,6 +90,7 @@
6690

6791
import static com.gregtechceu.gtceu.api.pattern.Predicates.*;
6892
import static com.gregtechceu.gtceu.api.pattern.util.RelativeDirection.*;
93+
import static com.gregtechceu.gtceu.utils.serialization.network.ByteBufAdapters.COMPONENT;
6994

7095
@ParametersAreNonnullByDefault
7196
@MethodsReturnNonnullByDefault
@@ -451,58 +476,153 @@ protected boolean isMachineBanned(MetaMachine machine) {
451476
return machine instanceof PrimitivePumpMachine;
452477
}
453478

454-
/*
455-
* @Override
456-
* public void addDisplayText(List<Component> textList) {
457-
* if (isFormed()) {
458-
* var maxVoltage = getMaxVoltage();
459-
* if (maxVoltage > 0) {
460-
* String voltageName = GTValues.VNF[GTUtil.getFloorTierByVoltage(maxVoltage)];
461-
* textList.add(Component.translatable("gtceu.multiblock.max_energy_per_tick", maxVoltage, voltageName));
462-
* }
463-
*
464-
* if (cleanroomType != null) {
465-
* textList.add(Component.translatable(cleanroomType.getTranslationKey()));
466-
* }
467-
*
468-
* if (!isWorkingEnabled()) {
469-
* textList.add(Component.translatable("gtceu.multiblock.work_paused"));
470-
*
471-
* } else if (isActive()) {
472-
* textList.add(Component.translatable("gtceu.multiblock.running"));
473-
* int currentProgress = (int) (recipeLogic.getProgressPercent() * 100);
474-
* double maxInSec = (float) recipeLogic.getDuration() / 20.0f;
475-
* double currentInSec = (float) recipeLogic.getProgress() / 20.0f;
476-
* textList.add(
477-
* Component.translatable("gtceu.multiblock.progress", String.format("%.2f", (float) currentInSec),
478-
* String.format("%.2f", (float) maxInSec), currentProgress));
479-
* } else {
480-
* textList.add(Component.translatable("gtceu.multiblock.idling"));
481-
* }
482-
*
483-
* if (recipeLogic.isWaiting()) {
484-
* textList.add(Component.translatable("gtceu.multiblock.waiting")
485-
* .setStyle(Style.EMPTY.withColor(ChatFormatting.RED)));
486-
* }
487-
*
488-
* if (cleanroomProviderTrait.isActive()) {
489-
* textList.add(Component.translatable("gtceu.multiblock.cleanroom.clean_state"));
490-
* } else {
491-
* textList.add(Component.translatable("gtceu.multiblock.cleanroom.dirty_state"));
492-
* }
493-
* textList.add(Component.translatable("gtceu.multiblock.cleanroom.clean_amount", this.cleanAmount));
494-
* textList.add(Component.translatable("gtceu.multiblock.dimensions.0"));
495-
* textList.add(Component.translatable("gtceu.multiblock.dimensions.1", lDist + rDist + 1, hDist + 1,
496-
* fDist + bDist + 1));
497-
* } else {
498-
* Component tooltip = Component.translatable("gtceu.multiblock.invalid_structure.tooltip")
499-
* .withStyle(ChatFormatting.GRAY);
500-
* textList.add(Component.translatable("gtceu.multiblock.invalid_structure")
501-
* .withStyle(Style.EMPTY.withColor(ChatFormatting.RED)
502-
* .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tooltip))));
503-
* }
504-
* }
505-
*/
479+
@Override
480+
public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) {
481+
var panel = GTGuis.createPanel(this, 176, 176);
482+
483+
panel.child(GTMuiWidgets.createTitleBar(this.getDefinition(), 176))
484+
.child(new ParentWidget<>()
485+
.widthRel(0.95f)
486+
.heightRel(.45f)
487+
.margin(4, 0)
488+
.left(3).top(5)
489+
.child(Flow.row()
490+
.child(getMainTextPanel(syncManager, 170, 84))))
491+
.child(Flow.column()
492+
.coverChildren()
493+
.leftRel(1.0f)
494+
.reverseLayout(true)
495+
.bottom(16)
496+
.padding(0, 8, 4, 4)
497+
.childPadding(2)
498+
.background(GTGuiTextures.BACKGROUND.getSubArea(0.25f, 0f, 1.0f, 1.0f))
499+
.child(GTMuiWidgets.createPowerButton(this, syncManager))
500+
.child(GTMuiWidgets.createVoidingButton(this, syncManager))
501+
.excludeAreaInXei())
502+
.child(SlotGroupWidget.playerInventory(false).left(7).bottom(7));
503+
return panel;
504+
}
505+
506+
public Widget<?> getMainTextPanel(PanelSyncManager syncManager, int width, int height) {
507+
var parentWidget = new ParentWidget<>();
508+
var listWidget = new ListWidget<>();
509+
listWidget
510+
.width(width - 6)
511+
.height(height - 6)
512+
.childSeparator(Icon.EMPTY_2PX)
513+
.crossAxisAlignment(Alignment.CrossAxis.START)
514+
.alignX(Alignment.CenterLeft)
515+
.left(3)
516+
.top(3);
517+
parentWidget.size(width, height)
518+
.background(GTGuiTextures.MUI_DISPLAY);
519+
// Machine generic sync handlers
520+
BooleanSyncValue isFormed = syncManager.getOrCreateSyncHandler("isFormed", BooleanSyncValue.class,
521+
() -> new BooleanSyncValue(this::isFormed));
522+
BooleanSyncValue workingEnabled = syncManager.getOrCreateSyncHandler("workingEnabled", BooleanSyncValue.class,
523+
() -> new BooleanSyncValue(this.recipeLogic::isWorkingEnabled, this.recipeLogic::setWorkingEnabled));
524+
BooleanSyncValue active = syncManager.getOrCreateSyncHandler("isActive", BooleanSyncValue.class,
525+
() -> new BooleanSyncValue(this.recipeLogic::isActive));
526+
BooleanSyncValue waiting = syncManager.getOrCreateSyncHandler("isWaiting", BooleanSyncValue.class,
527+
() -> new BooleanSyncValue(this.recipeLogic::isWaiting));
528+
529+
// Energy bank specific sync handlers
530+
// These will not be called anywhere else, so we can create them directly instead of using
531+
// getOrCreateSyncHandler
532+
533+
LongSyncValue maxVoltage = new LongSyncValue(this::getMaxVoltage);
534+
syncManager.syncValue("maxVoltage", maxVoltage);
535+
536+
StringSyncValue cleanroomTranslationKey = new StringSyncValue(() -> {
537+
if (this.cleanroomType == null) return "";
538+
return this.cleanroomType.getTranslationKey();
539+
});
540+
syncManager.syncValue("cleanroomTranslationKey", cleanroomTranslationKey);
541+
542+
BooleanSyncValue cleanroomTypeIsNull = new BooleanSyncValue(() -> this.cleanroomType == null);
543+
syncManager.syncValue("cleanroomTypeIsNull", cleanroomTypeIsNull);
544+
545+
BooleanSyncValue cleanroomProviderTraitIsActive = new BooleanSyncValue(
546+
() -> this.cleanroomProviderTrait != null && this.cleanroomProviderTrait.isActive());
547+
syncManager.syncValue("cleanroomProviderTrait", cleanroomProviderTraitIsActive);
548+
549+
IntSyncValue cleanAmount = new IntSyncValue(() -> this.cleanAmount);
550+
syncManager.syncValue("cleanAmount", cleanAmount);
551+
552+
GenericSyncValue<Component> distComponent = new GenericSyncValue.Builder<>(Component.class)
553+
.adapter(COMPONENT)
554+
.getter(() -> Component.translatable("gtceu.multiblock.dimensions.1", lDist + rDist + 1, hDist + 1,
555+
fDist + bDist + 1))
556+
.build();
557+
syncManager.syncValue("distComponent", distComponent);
558+
559+
listWidget.child(IKey.dynamic(() -> {
560+
Component tooltip = Component.translatable("gtceu.multiblock.invalid_structure.tooltip")
561+
.withStyle(ChatFormatting.GRAY);
562+
return Component.translatable("gtceu.multiblock.invalid_structure")
563+
.withStyle(Style.EMPTY.withColor(ChatFormatting.RED)
564+
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tooltip)));
565+
})
566+
.asWidget()
567+
.setEnabledIf((widget) -> !isFormed.getBoolValue()));
568+
569+
listWidget.child(IKey.dynamic(() -> {
570+
String voltageName = GTValues.VNF[GTUtil.getFloorTierByVoltage(maxVoltage.getLongValue())];
571+
return Component.translatable("gtceu.multiblock.max_energy_per_tick", maxVoltage.getLongValue(),
572+
voltageName);
573+
})
574+
.asWidget()
575+
.setEnabledIf((widget) -> isFormed.getBoolValue() && maxVoltage.getLongValue() > 0));
576+
577+
listWidget.child(IKey.dynamic(() -> {
578+
if (cleanroomTypeIsNull.getBoolValue()) {
579+
return Component.empty();
580+
} else {
581+
return Component.translatable(cleanroomTranslationKey.getStringValue());
582+
}
583+
})
584+
.asWidget()
585+
.setEnabledIf((widget) -> isFormed.getBoolValue() && !cleanroomTypeIsNull.getBoolValue()));
586+
587+
listWidget.child(IKey.dynamic(() -> Component.translatable("gtceu.multiblock.work_paused"))
588+
.asWidget()
589+
.setEnabledIf((widget) -> isFormed.getBoolValue() && !workingEnabled.getBoolValue()));
590+
591+
listWidget.child(GTMultiblockTextUtil.addProgressLine(this, syncManager));
592+
593+
listWidget.child(IKey.lang(Component.translatable("gtceu.multiblock.idling"))
594+
.asWidget()
595+
.setEnabledIf((widget) -> isFormed.getBoolValue() && workingEnabled.getBoolValue() &&
596+
!active.getBoolValue()));
597+
598+
listWidget.child(IKey
599+
.lang(Component.translatable("gtceu.multiblock.waiting")
600+
.setStyle(Style.EMPTY.withColor(ChatFormatting.RED)))
601+
.asWidget()
602+
.setEnabledIf((widget) -> isFormed.getBoolValue() && waiting.getBoolValue()));
603+
604+
listWidget.child(IKey.lang(Component.translatable("gtceu.multiblock.cleanroom.clean_state"))
605+
.asWidget()
606+
.setEnabledIf((widget) -> isFormed.getBoolValue() && cleanroomProviderTraitIsActive.getBoolValue()));
607+
listWidget.child(IKey.lang(Component.translatable("gtceu.multiblock.cleanroom.dirty_state"))
608+
.asWidget()
609+
.setEnabledIf((widget) -> isFormed.getBoolValue() && !cleanroomProviderTraitIsActive.getBoolValue()));
610+
611+
listWidget.child(IKey.dynamic(
612+
() -> Component.translatable("gtceu.multiblock.cleanroom.clean_amount", cleanAmount.getIntValue()))
613+
.asWidget()
614+
.setEnabledIf((widget) -> isFormed.getBoolValue()));
615+
616+
listWidget.child(IKey.lang(Component.translatable("gtceu.multiblock.dimensions.0"))
617+
.asWidget()
618+
.setEnabledIf((widget) -> isFormed.getBoolValue()));
619+
listWidget.child(IKey.dynamic(() -> distComponent.getValue())
620+
.asWidget()
621+
.setEnabledIf((widget) -> isFormed.getBoolValue()));
622+
623+
parentWidget.child(listWidget);
624+
return parentWidget;
625+
}
506626

507627
/**
508628
* Adjust the cleanroom's clean amount

src/main/java/com/gregtechceu/gtceu/utils/serialization/network/ByteBufAdapters.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import net.minecraft.nbt.CompoundTag;
99
import net.minecraft.network.FriendlyByteBuf;
10+
import net.minecraft.network.chat.Component;
1011
import net.minecraft.resources.ResourceLocation;
1112
import net.minecraft.world.item.ItemStack;
1213
import net.minecraftforge.fluids.FluidStack;
@@ -28,6 +29,7 @@ public class ByteBufAdapters {
2829
public static final IByteBufAdapter<String> STRING = makeAdapter(NetworkUtils::readStringSafe, NetworkUtils::writeStringSafe, null);
2930
public static final IByteBufAdapter<ByteBuf> BYTE_BUF = makeAdapter(NetworkUtils::readByteBuf, NetworkUtils::writeByteBuf, null);
3031
public static final IByteBufAdapter<FriendlyByteBuf> FRIENDLY_BYTE_BUF = makeAdapter(NetworkUtils::readFriendlyByteBuf, NetworkUtils::writeByteBuf, null);
32+
public static final IByteBufAdapter<Component> COMPONENT = makeAdapter(FriendlyByteBuf::readComponent, FriendlyByteBuf::writeComponent, Objects::equals);
3133
// spotless:on
3234

3335
public static final IByteBufAdapter<byte[]> BYTE_ARR = new IByteBufAdapter<>() {

0 commit comments

Comments
 (0)