diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java index 986fef65c54..1bacdd97fa4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java @@ -322,19 +322,32 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player ////////////////////////////////////// public boolean canConnectRedstone(BlockGetter level, BlockPos pos, Direction side) { - return MetaMachine.getMachine(level, pos).canConnectRedstone(side); + var machine = MetaMachine.getMachine(level, pos); + if (machine == null) return false; + return machine.canConnectRedstone(side); } @Override @SuppressWarnings("deprecation") // This is fine to override, just not to be called. public int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { - return MetaMachine.getMachine(level, pos).getOutputSignal(direction); + var machine = MetaMachine.getMachine(level, pos); + if (machine == null) return 0; + return machine.getOutputSignal(direction); + } + + @Override + public int getDirectSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { + var machine = MetaMachine.getMachine(level, pos); + if (machine == null) return 0; + return machine.getOutputDirectSignal(direction); } @Override @SuppressWarnings("deprecation") // This is fine to override, just not to be called. public int getAnalogOutputSignal(BlockState state, Level level, BlockPos pos) { - return MetaMachine.getMachine(level, pos).getAnalogOutputSignal(); + var machine = MetaMachine.getMachine(level, pos); + if (machine == null) return 0; + return machine.getAnalogOutputSignal(); } ///////// diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java b/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java deleted file mode 100644 index 42d7fc528bb..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gregtechceu.gtceu.api.capability; - -import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; - -import java.util.List; - -public interface ICentralMonitor { - - List getMonitorGroups(); -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java index 52d88b34306..2803528e134 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java @@ -4,8 +4,7 @@ import com.gregtechceu.gtceu.api.gui.fancy.FancyMachineUIWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.gui.widget.directional.IDirectionalConfigHandler; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.data.lang.LangHandler; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -40,12 +39,12 @@ public class AutoOutputFluidConfigHandler implements IDirectionalConfigHandler { GuiTextures.VANILLA_BUTTON, GuiTextures.IO_CONFIG_FLUID_MODES_BUTTON.getSubTexture(0, 2 / 3f, 1, 1 / 3f)); - private final IAutoOutputFluid machine; + private final AutoOutputTrait trait; private Direction side; private ButtonWidget ioModeButton; - public AutoOutputFluidConfigHandler(IAutoOutputFluid machine) { - this.machine = machine; + public AutoOutputFluidConfigHandler(AutoOutputTrait trait) { + this.trait = trait; } @Override @@ -61,8 +60,8 @@ public void updateScreen() { setButtonTexture(TEXTURE_OFF); setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.fluid_auto_output.unselected") .toArray(Component[]::new)); - } else if (machine.getOutputFacingFluids() == side) { - if (machine.isAutoOutputFluids()) { + } else if (trait.getFluidOutputDirection() == side) { + if (trait.isAutoOutputFluids()) { setButtonTexture(TEXTURE_AUTO); setHoverTooltips("gtceu.gui.fluid_auto_output.enabled"); } else { @@ -79,7 +78,7 @@ public void updateScreen() { group.addWidget(new ToggleButtonWidget( 19, 0, 18, 18, GuiTextures.BUTTON_FLUID_OUTPUT, - machine::isAllowInputFromOutputSideFluids, machine::setAllowInputFromOutputSideFluids) + trait::allowsFluidInputFromOutputSide, trait::setAllowFluidInputFromOutputSide) .setShouldUseBaseBackground().setTooltipText("gtceu.gui.fluid_auto_output.allow_input")); return group; @@ -89,11 +88,11 @@ private void onIOModePressed(ClickData cd) { if (this.side == null) return; - if (machine.getOutputFacingFluids() == this.side) { - machine.setAutoOutputFluids(!machine.isAutoOutputFluids()); + if (trait.getFluidOutputDirection() == this.side) { + trait.setAllowAutoOutputFluids(!trait.isAutoOutputFluids()); } else { - machine.setAutoOutputFluids(false); - machine.setOutputFacingFluids(this.side); + trait.setAllowAutoOutputFluids(false); + trait.setFluidOutputDirection(this.side); } } @@ -109,14 +108,14 @@ public ScreenSide getScreenSide() { @Override public void handleClick(ClickData cd, Direction direction) { - if (!canHandleClick(cd) || !machine.hasAutoOutputFluid()) + if (!canHandleClick(cd) || !trait.supportsAutoOutputFluids()) return; - if (machine.getOutputFacingFluids() != side) { - machine.setOutputFacingFluids(side); - machine.setAutoOutputFluids(false); + if (trait.getFluidOutputDirection() != side) { + trait.setFluidOutputDirection(side); + trait.setAllowAutoOutputFluids(false); } else { - machine.setAutoOutputFluids(!machine.isAutoOutputFluids()); + trait.setAllowAutoOutputFluids(!trait.isAutoOutputFluids()); } } @@ -125,20 +124,17 @@ private boolean canHandleClick(ClickData cd) { if (cd.button == 1) return true; - if (!(machine instanceof IAutoOutputItem) && cd.button == 0) - return true; - return false; } @Override @OnlyIn(Dist.CLIENT) public void renderOverlay(SceneWidget sceneWidget, BlockPosFace blockPosFace) { - if (machine.getOutputFacingFluids() != blockPosFace.facing) + if (trait.getFluidOutputDirection() != blockPosFace.facing) return; sceneWidget.drawFacingBorder(new PoseStack(), blockPosFace, - machine.isAutoOutputFluids() ? 0xff00b4ff : 0x8f00b4ff, 2); + trait.isAutoOutputFluids() ? 0xff00b4ff : 0x8f00b4ff, 2); } @Override @@ -147,7 +143,7 @@ public void addAdditionalUIElements(WidgetGroup parent) { @Override public boolean isVisible() { - return machine.isAutoOutputFluids() && machine.getOutputFacingFluids() != null; + return trait.isAutoOutputFluids() && trait.getFluidOutputDirection() != null; } }; diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java index fb474eca88d..d8a1d7911a6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java @@ -4,8 +4,7 @@ import com.gregtechceu.gtceu.api.gui.fancy.FancyMachineUIWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.gui.widget.directional.IDirectionalConfigHandler; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.data.lang.LangHandler; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -39,12 +38,12 @@ public class AutoOutputItemConfigHandler implements IDirectionalConfigHandler { GuiTextures.VANILLA_BUTTON, GuiTextures.IO_CONFIG_ITEM_MODES_BUTTON.getSubTexture(0, 2 / 3f, 1, 1 / 3f)); - private final IAutoOutputItem machine; + private final AutoOutputTrait trait; private Direction side; private ButtonWidget ioModeButton; - public AutoOutputItemConfigHandler(IAutoOutputItem machine) { - this.machine = machine; + public AutoOutputItemConfigHandler(AutoOutputTrait trait) { + this.trait = trait; } @Override @@ -61,8 +60,8 @@ public void updateScreen() { setButtonTexture(TEXTURE_OFF); setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.item_auto_output.unselected") .toArray(Component[]::new)); - } else if (machine.getOutputFacingItems() == side) { - if (machine.isAutoOutputItems()) { + } else if (trait.getItemOutputDirection() == side) { + if (trait.isAutoOutputItems()) { setButtonTexture(TEXTURE_AUTO); setHoverTooltips("gtceu.gui.item_auto_output.enabled"); } else { @@ -79,7 +78,7 @@ public void updateScreen() { group.addWidget(new ToggleButtonWidget( 19, 0, 18, 18, GuiTextures.BUTTON_ITEM_OUTPUT, - machine::isAllowInputFromOutputSideItems, machine::setAllowInputFromOutputSideItems) + trait::allowsItemInputFromOutputSide, trait::setAllowItemInputFromOutputSide) .setShouldUseBaseBackground().setTooltipText("gtceu.gui.item_auto_output.allow_input")); return group; @@ -89,11 +88,11 @@ private void onIOModePressed(ClickData cd) { if (this.side == null) return; - if (machine.getOutputFacingItems() == this.side) { - machine.setAutoOutputItems(!machine.isAutoOutputItems()); + if (trait.getItemOutputDirection() == this.side) { + trait.setAllowAutoOutputItems(!trait.isAutoOutputItems()); } else { - machine.setAutoOutputItems(false); - machine.setOutputFacingItems(this.side); + trait.setAllowAutoOutputItems(false); + trait.setItemOutputDirection(this.side); } } @@ -109,14 +108,14 @@ public ScreenSide getScreenSide() { @Override public void handleClick(ClickData cd, Direction direction) { - if (!canHandleClick(cd) || !machine.hasAutoOutputItem()) + if (!canHandleClick(cd) || !trait.supportsAutoOutputItems()) return; - if (machine.getOutputFacingItems() != side) { - machine.setOutputFacingItems(side); - machine.setAutoOutputItems(false); + if (trait.getItemOutputDirection() != side) { + trait.setItemOutputDirection(side); + trait.setAllowAutoOutputItems(false); } else { - machine.setAutoOutputItems(!machine.isAutoOutputItems()); + trait.setAllowAutoOutputItems(!trait.isAutoOutputItems()); } } @@ -125,20 +124,17 @@ private boolean canHandleClick(ClickData cd) { if (cd.button == 0) return true; - if (!(machine instanceof IAutoOutputFluid) && cd.button == 1) - return true; - return false; } @Override @OnlyIn(Dist.CLIENT) public void renderOverlay(SceneWidget sceneWidget, BlockPosFace blockPosFace) { - if (machine.getOutputFacingItems() != blockPosFace.facing) + if (trait.getItemOutputDirection() != blockPosFace.facing) return; sceneWidget.drawFacingBorder(new PoseStack(), blockPosFace, - machine.isAutoOutputItems() ? 0xffff6e0f : 0x8fff6e0f, 1); + trait.isAutoOutputItems() ? 0xffff6e0f : 0x8fff6e0f, 1); } @Override @@ -147,7 +143,7 @@ public void addAdditionalUIElements(WidgetGroup parent) { @Override public boolean isVisible() { - return machine.isAutoOutputItems() && machine.getOutputFacingItems() != null; + return trait.isAutoOutputItems() && trait.getItemOutputDirection() != null; } }; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java index 6b3b1c21f55..48cd480efab 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java @@ -21,6 +21,7 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTraitHolder; import com.gregtechceu.gtceu.api.machine.trait.feature.IFrontFacingTrait; @@ -40,10 +41,10 @@ import com.gregtechceu.gtceu.common.cover.FluidFilterCover; import com.gregtechceu.gtceu.common.cover.ItemFilterCover; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; -import com.gregtechceu.gtceu.common.item.tool.behavior.ToolModeSwitchBehavior; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.common.machine.owner.PlayerOwner; import com.gregtechceu.gtceu.utils.GTUtil; +import com.gregtechceu.gtceu.utils.data.TagCompatibilityFixer; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; @@ -101,8 +102,6 @@ import javax.annotation.ParametersAreNonnullByDefault; -import static com.gregtechceu.gtceu.api.item.tool.ToolHelper.getBehaviorsTag; - @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class MetaMachine extends ManagedSyncBlockEntity implements IGregtechBlockEntity, IToolable, IToolGridHighlight, @@ -178,6 +177,12 @@ public void onRemoved() { if (this instanceof IMachineLife l) l.onMachineRemoved(); } + @Override + public void load(CompoundTag tag) { + TagCompatibilityFixer.fixMachineAutoOutputTag(tag); + super.load(tag); + } + @MustBeInvokedByOverriders public void onLoad() { getTraitHolder().getAllTraits().forEach(MachineTrait::onMachineLoad); @@ -374,26 +379,9 @@ protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, return InteractionResult.FAIL; } setFrontFacing(gridSide); - } else { - var itemStack = playerIn.getItemInHand(hand); - var tagCompound = getBehaviorsTag(itemStack); - ToolModeSwitchBehavior.WrenchModeType type = ToolModeSwitchBehavior.WrenchModeType.values()[tagCompound - .getByte("Mode")]; - - if (type.isItem()) { - if (this instanceof IAutoOutputItem autoOutputItem && - (!hasFrontFacing() || gridSide != getFrontFacing())) { - autoOutputItem.setOutputFacingItems(gridSide); - } - } - if (type.isFluid()) { - if (this instanceof IAutoOutputFluid autoOutputFluid && - (!hasFrontFacing() || gridSide != getFrontFacing())) { - autoOutputFluid.setOutputFacingFluids(gridSide); - } - } + return InteractionResult.sidedSuccess(isRemote()); } - return InteractionResult.sidedSuccess(isRemote()); + return InteractionResult.PASS; } protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, Direction gridSide, @@ -411,51 +399,6 @@ protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand h protected InteractionResult onScrewdriverClick(Player playerIn, InteractionHand hand, Direction gridSide, BlockHitResult hitResult) { if (isRemote()) return InteractionResult.SUCCESS; - if (playerIn.isShiftKeyDown()) { - boolean changed = false; - if (this instanceof IAutoOutputItem autoOutputItem) { - if (autoOutputItem.getOutputFacingItems() == gridSide) { - autoOutputItem.setAllowInputFromOutputSideItems(!autoOutputItem.isAllowInputFromOutputSideItems()); - playerIn.displayClientMessage(Component - .translatable("gtceu.machine.basic.input_from_output_side." + - (autoOutputItem.isAllowInputFromOutputSideItems() ? "allow" : "disallow")) - .append(Component.translatable("gtceu.creative.chest.item")), true); - changed = true; - } - } - if (this instanceof IAutoOutputFluid autoOutputFluid) { - if (autoOutputFluid.getOutputFacingFluids() == gridSide) { - autoOutputFluid - .setAllowInputFromOutputSideFluids(!autoOutputFluid.isAllowInputFromOutputSideFluids()); - playerIn.displayClientMessage(Component - .translatable("gtceu.machine.basic.input_from_output_side." + - (autoOutputFluid.isAllowInputFromOutputSideFluids() ? "allow" : "disallow")) - .append(Component.translatable("gtceu.creative.tank.fluid")), true); - changed = true; - } - } - if (changed) { - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - } else { - boolean changed = false; - if (this instanceof IAutoOutputItem autoOutputItem) { - if (autoOutputItem.getOutputFacingItems() == gridSide) { - autoOutputItem.setAutoOutputItems(!autoOutputItem.isAutoOutputItems()); - changed = true; - } - } - if (this instanceof IAutoOutputFluid autoOutputFluid) { - if (autoOutputFluid.getOutputFacingFluids() == gridSide) { - autoOutputFluid.setAutoOutputFluids(!autoOutputFluid.isAutoOutputFluids()); - changed = true; - - } - } - if (changed) { - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - } return InteractionResult.PASS; } @@ -526,9 +469,6 @@ public void clearInventory(IItemHandlerModifiable inventory) { public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, ItemStack held, Set toolTypes) { if (toolTypes.contains(GTToolType.WRENCH)) return true; - if (toolTypes.contains(GTToolType.SCREWDRIVER) && - (this instanceof IAutoOutputItem || this instanceof IAutoOutputFluid)) - return true; for (CoverBehavior cover : coverContainer.getCovers()) { if (cover.shouldRenderGrid(player, pos, state, held, toolTypes)) return true; } @@ -536,7 +476,7 @@ public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, I for (var trait : getTraitHolder().getAllTraits()) { if (trait instanceof IRenderingTrait renderingTrait) { var result = renderingTrait.shouldRenderGridOverlay(player, pos, state, held, toolTypes); - if (result) return result; + if (result) return true; } } @@ -553,7 +493,7 @@ public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, I } if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { + if (player.isShiftKeyDown()) { if (isFacingValid(side) || (allowExtendedFacing() && hasFrontFacing() && side == getFrontFacing())) { return GuiTextures.TOOL_FRONT_FACING_ROTATION; } @@ -891,8 +831,9 @@ public IItemHandlerModifiable getItemHandlerCap(@Nullable Direction side, boolea if (list.isEmpty()) return null; var io = IO.BOTH; - if (side != null && this instanceof IAutoOutputItem autoOutput && autoOutput.getOutputFacingItems() == side && - !autoOutput.isAllowInputFromOutputSideItems()) { + var autoOutputTrait = getTraitHolder().getTrait(AutoOutputTrait.TYPE); + if (side != null && autoOutputTrait != null && autoOutputTrait.getItemOutputDirection() == side && + !autoOutputTrait.allowsItemInputFromOutputSide()) { io = IO.OUT; } @@ -915,8 +856,9 @@ public IFluidHandlerModifiable getFluidHandlerCap(@Nullable Direction side, bool if (list.isEmpty()) return null; var io = IO.BOTH; - if (side != null && this instanceof IAutoOutputFluid autoOutput && autoOutput.getOutputFacingFluids() == side && - !autoOutput.isAllowInputFromOutputSideFluids()) { + var autoOutputTrait = getTraitHolder().getTrait(AutoOutputTrait.TYPE); + if (side != null && autoOutputTrait != null && autoOutputTrait.getFluidOutputDirection() == side && + !autoOutputTrait.allowsFluidInputFromOutputSide()) { io = IO.OUT; } @@ -1062,7 +1004,7 @@ private static List getCapabilitiesFromTraits(List traits, public static class AE2CallWrapper { public static LazyOptional getGridNodeHostCapability(Capability cap, MetaMachine machine, - Direction side) { + @Nullable Direction side) { if (cap == Capabilities.IN_WORLD_GRID_NODE_HOST) { if (machine instanceof IInWorldGridNodeHost nodeHost) { return Capabilities.IN_WORLD_GRID_NODE_HOST.orEmpty(cap, LazyOptional.of(() -> nodeHost)); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java index 71a9d768080..ef966694592 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java @@ -12,22 +12,19 @@ import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfiguratorButton; import com.gregtechceu.gtceu.api.gui.widget.GhostCircuitSlotWidget; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.fancyconfigurator.CircuitFancyConfigurator; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputBoth; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IHasCircuitSlot; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.ui.GTRecipeTypeUI; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.common.item.IntCircuitBehaviour; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -38,22 +35,14 @@ import com.lowdragmc.lowdraglib.utils.Position; import net.minecraft.Util; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; import com.google.common.collect.Tables; import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import lombok.Getter; -import lombok.Setter; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -67,34 +56,8 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class SimpleTieredMachine extends WorkableTieredMachine - implements IAutoOutputBoth, IFancyUIMachine, IHasCircuitSlot { + implements IFancyUIMachine, IHasCircuitSlot { - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingItems; - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingFluids; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputFluids; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideItems; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideFluids; @Getter @SaveField protected final CustomItemStackHandler chargerInventory; @@ -102,14 +65,17 @@ public class SimpleTieredMachine extends WorkableTieredMachine @SaveField protected final NotifiableItemStackHandler circuitInventory; @Nullable - protected TickableSubscription autoOutputSubs, batterySubs; + protected TickableSubscription batterySubs; @Nullable - protected ISubscription exportItemSubs, exportFluidSubs, energySubs; + protected ISubscription energySubs; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; public SimpleTieredMachine(BlockEntityCreationInfo info, int tier, Int2IntFunction tankScalingFunction) { super(info, tier, tankScalingFunction); - this.outputFacingItems = hasFrontFacing() ? getFrontFacing().getOpposite() : Direction.UP; - this.outputFacingFluids = outputFacingItems; + + this.autoOutput = new AutoOutputTrait(this, List.of(exportItems), List.of(exportFluids)); this.chargerInventory = new CustomItemStackHandler() { @@ -133,12 +99,7 @@ public int getSlotLimit(int slot) { public void onLoad() { super.onLoad(); if (!isRemote()) { - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } updateBatterySubscription(); - exportItemSubs = exportItems.addChangedListener(this::updateAutoOutputSubscription); - exportFluidSubs = exportFluids.addChangedListener(this::updateAutoOutputSubscription); energySubs = energyContainer.addChangedListener(this::updateBatterySubscription); chargerInventory.setOnContentsChanged(this::updateBatterySubscription); } @@ -147,108 +108,12 @@ public void onLoad() { @Override public void onUnload() { super.onUnload(); - if (exportItemSubs != null) { - exportItemSubs.unsubscribe(); - exportItemSubs = null; - } - - if (exportFluidSubs != null) { - exportFluidSubs.unsubscribe(); - exportFluidSubs = null; - } - if (energySubs != null) { energySubs.unsubscribe(); energySubs = null; } } - ////////////////////////////////////// - // ******* Auto Output *******// - ////////////////////////////////////// - - @Override - public boolean hasAutoOutputFluid() { - return exportFluids.getTanks() > 0; - } - - @Override - public boolean hasAutoOutputItem() { - return exportItems.getSlots() > 0; - } - - @Override - public @Nullable Direction getOutputFacingFluids() { - if (hasAutoOutputFluid()) { - return outputFacingFluids; - } - return null; - } - - @Override - public @Nullable Direction getOutputFacingItems() { - if (hasAutoOutputItem()) { - return outputFacingItems; - } - return null; - } - - @Override - public void setAutoOutputItems(boolean allow) { - if (hasAutoOutputItem()) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - } - - @Override - public void setAutoOutputFluids(boolean allow) { - if (hasAutoOutputFluid()) { - this.autoOutputFluids = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); - updateAutoOutputSubscription(); - } - } - - @Override - public void setOutputFacingFluids(@Nullable Direction outputFacing) { - if (hasAutoOutputFluid()) { - this.outputFacingFluids = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingFluids"); - updateAutoOutputSubscription(); - } - } - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - if (hasAutoOutputItem()) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - - protected void updateAutoOutputSubscription() { - var outputFacingItems = getOutputFacingItems(); - var outputFacingFluids = getOutputFacingFluids(); - if ((isAutoOutputItems() && !exportItems.isEmpty() && outputFacingItems != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacingItems)) || - (isAutoOutputFluids() && !exportFluids.isEmpty() && outputFacingFluids != null && - GTTransferUtils.hasAdjacentFluidHandler(getLevel(), getBlockPos(), outputFacingFluids))) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::autoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - protected void updateBatterySubscription() { if (energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, true)) { batterySubs = subscribeServerTick(batterySubs, this::chargeBattery); @@ -264,26 +129,6 @@ protected void chargeBattery() { } } - protected void autoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputFluids() && getOutputFacingFluids() != null) { - exportFluids.exportToNearby(getOutputFacingFluids()); - } - if (isAutoOutputItems() && getOutputFacingItems() != null) { - exportItems.exportToNearby(getOutputFacingItems()); - } - } - updateAutoOutputSubscription(); - } - - @Override - public boolean isFacingValid(Direction facing) { - if (facing == getOutputFacingItems() || facing == getOutputFacingFluids()) { - return false; - } - return super.isFacingValid(facing); - } - ////////////////////////////////////// // ********** MISC ***********// ////////////////////////////////////// @@ -313,10 +158,10 @@ public long getDisplayRecipeVoltage() { public void attachConfigurators(ConfiguratorPanel configuratorPanel) { IFancyUIMachine.super.attachConfigurators(configuratorPanel); - if (hasAutoOutputFluid()) { + if (autoOutput.supportsAutoOutputFluids()) { configuratorPanel.attachConfigurators(createAutoOutputFluidConfigurator()); } - if (hasAutoOutputItem()) { + if (autoOutput.supportsAutoOutputItems()) { configuratorPanel.attachConfigurators(createAutoOutputItemConfigurator()); } @@ -329,16 +174,16 @@ private IFancyConfigurator createAutoOutputFluidConfigurator() { return createAutoOutputConfigurator( GuiTextures.IO_CONFIG_FLUID_MODES_BUTTON, "gtceu.gui.fluid_auto_output", - this::isAutoOutputFluids, - (cd, nextState) -> this.setAutoOutputFluids(nextState)); + this.autoOutput::isAutoOutputFluids, + (cd, nextState) -> this.autoOutput.setAllowAutoOutputFluids(nextState)); } private IFancyConfigurator createAutoOutputItemConfigurator() { return createAutoOutputConfigurator( GuiTextures.IO_CONFIG_ITEM_MODES_BUTTON, "gtceu.gui.item_auto_output", - this::isAutoOutputItems, - (cd, nextState) -> this.setAutoOutputItems(nextState)); + this.autoOutput::isAutoOutputItems, + (cd, nextState) -> this.autoOutput.setAllowAutoOutputItems(nextState)); } private IFancyConfigurator createAutoOutputConfigurator(ResourceTexture modesButtonTexture, @@ -443,25 +288,4 @@ protected static EditableUI createC protected IGuiTexture getCircuitSlotOverlay() { return GuiTextures.INT_CIRCUIT_OVERLAY; } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } - if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems() || side == getOutputFacingFluids()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } - return super.sideTips(player, pos, state, toolTypes, side); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 48dec4acd99..ac5eb261ff0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -192,8 +192,7 @@ public void clientTick() { if (previouslyMuffled != isMuffled) { previouslyMuffled = isMuffled; - if (recipeLogic != null) - recipeLogic.updateSound(); + recipeLogic.updateSound(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java index e2f392b7861..456fa6204ba 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java @@ -10,8 +10,7 @@ import com.gregtechceu.gtceu.api.gui.widget.directional.handlers.AutoOutputItemConfigHandler; import com.gregtechceu.gtceu.api.gui.widget.directional.handlers.CoverableConfigHandler; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.widget.Widget; @@ -76,11 +75,17 @@ public List getTabTooltips() { static { // Left side: CONFIG_HANDLERS.add( - machine -> machine instanceof IAutoOutputItem autoOutputItem && autoOutputItem.hasAutoOutputItem() ? - () -> new AutoOutputItemConfigHandler(autoOutputItem) : null); + machine -> { + var trait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE); + return trait != null && trait.supportsAutoOutputItems() ? + () -> new AutoOutputItemConfigHandler(trait) : null; + }); CONFIG_HANDLERS.add( - machine -> machine instanceof IAutoOutputFluid autoOutputFluid && autoOutputFluid.hasAutoOutputFluid() ? - () -> new AutoOutputFluidConfigHandler(autoOutputFluid) : null); + machine -> { + var trait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE); + return trait != null && trait.supportsAutoOutputFluids() ? + () -> new AutoOutputFluidConfigHandler(trait) : null; + }); // Right side: CONFIG_HANDLERS.add(machine -> () -> new CoverableConfigHandler(machine.getCoverContainer())); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputBoth.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputBoth.java deleted file mode 100644 index ce21d151ee7..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputBoth.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.gregtechceu.gtceu.api.machine.feature; - -public interface IAutoOutputBoth extends IAutoOutputItem, IAutoOutputFluid, IMachineFeature { - -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputFluid.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputFluid.java deleted file mode 100644 index 9a47c81243e..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputFluid.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gregtechceu.gtceu.api.machine.feature; - -import net.minecraft.core.Direction; - -import org.jetbrains.annotations.Nullable; - -public interface IAutoOutputFluid extends IMachineFeature { - - boolean isAutoOutputFluids(); - - void setAutoOutputFluids(boolean allow); - - boolean isAllowInputFromOutputSideFluids(); - - void setAllowInputFromOutputSideFluids(boolean allow); - - @Nullable - Direction getOutputFacingFluids(); - - void setOutputFacingFluids(@Nullable Direction outputFacing); - - default boolean hasAutoOutputFluid() { - return true; - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputItem.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputItem.java deleted file mode 100644 index fb8ad43fd47..00000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IAutoOutputItem.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gregtechceu.gtceu.api.machine.feature; - -import net.minecraft.core.Direction; - -import org.jetbrains.annotations.Nullable; - -public interface IAutoOutputItem extends IMachineFeature { - - boolean isAutoOutputItems(); - - void setAutoOutputItems(boolean allow); - - boolean isAllowInputFromOutputSideItems(); - - void setAllowInputFromOutputSideItems(boolean allow); - - @Nullable - Direction getOutputFacingItems(); - - void setOutputFacingItems(@Nullable Direction outputFacing); - - default boolean hasAutoOutputItem() { - return true; - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java index 64ec30a1ccf..6d001cc2ebc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java @@ -22,11 +22,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; import lombok.Getter; import org.jetbrains.annotations.NotNull; @@ -261,26 +257,6 @@ public void setUpwardsFacing(@NotNull Direction upwardsFacing) { } } - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (gridSide == getFrontFacing() && allowExtendedFacing()) { - setUpwardsFacing(playerIn.isShiftKeyDown() ? getUpwardsFacing().getCounterClockWise() : - getUpwardsFacing().getClockWise()); - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - if (playerIn.isShiftKeyDown()) { - if (gridSide == getFrontFacing() || !isFacingValid(gridSide)) { - return InteractionResult.FAIL; - } - if (!isRemote()) { - setFrontFacing(gridSide); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } - @Override public void setFrontFacing(Direction facing) { super.setFrontFacing(facing); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/AutoOutputTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/AutoOutputTrait.java new file mode 100644 index 00000000000..b11770867d6 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/AutoOutputTrait.java @@ -0,0 +1,400 @@ +package com.gregtechceu.gtceu.api.machine.trait; + +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; +import com.gregtechceu.gtceu.api.machine.trait.feature.IFrontFacingTrait; +import com.gregtechceu.gtceu.api.machine.trait.feature.IInteractionTrait; +import com.gregtechceu.gtceu.api.machine.trait.feature.IRenderingTrait; +import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; +import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; +import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; +import com.gregtechceu.gtceu.common.item.tool.behavior.ToolModeSwitchBehavior; +import com.gregtechceu.gtceu.utils.GTTransferUtils; +import com.gregtechceu.gtceu.utils.ISubscription; + +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.server.TickTask; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.IItemHandler; + +import com.mojang.datafixers.util.Pair; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import static com.gregtechceu.gtceu.api.item.tool.ToolHelper.getBehaviorsTag; + +public class AutoOutputTrait extends MachineTrait implements IRenderingTrait, IInteractionTrait, IFrontFacingTrait { + + public static final MachineTraitType TYPE = new MachineTraitType<>(AutoOutputTrait.class); + + @Getter + protected final List itemHandlers; + @Getter + protected final List fluidHandlers; + + @SaveField + @SyncToClient + @RerenderOnChanged + protected @Nullable Direction itemOutputDirection, fluidOutputDirection; + @Getter + @SaveField + @SyncToClient + @RerenderOnChanged + protected boolean autoOutputItems = false; + @Getter + @SaveField + @SyncToClient + @RerenderOnChanged + protected boolean autoOutputFluids = false; + @Setter + @SaveField + protected boolean allowItemInputFromOutputSide = false; + @Setter + @SaveField + protected boolean allowFluidInputFromOutputSide = false; + + @Setter + @Getter + protected int ticksPerCycle = 5; + @Setter + protected Predicate<@Nullable Direction> itemOutputDirectionValidator = $ -> true; + @Setter + protected Predicate<@Nullable Direction> fluidOutputDirectionValidator = $ -> true; + protected @Nullable TickableSubscription itemOutputSub, fluidOutputSub; + protected List itemSubs = new ArrayList<>(); + protected List fluidSubs = new ArrayList<>(); + private final boolean useDefaultToolHandlers; + + public AutoOutputTrait(MetaMachine machine, List itemHandlers, List fluidHandlers, + boolean useDefaultToolHandlers) { + super(machine); + + this.itemOutputDirection = machine.hasFrontFacing() ? machine.getFrontFacing().getOpposite() : Direction.UP; + this.fluidOutputDirection = itemOutputDirection; + + this.itemHandlers = itemHandlers.stream().filter(h -> { + if (h.getSlots() == 0) return false; + if (h instanceof ICapabilityTrait cap) return cap.canCapOutput(); + return true; + }).toList(); + this.fluidHandlers = fluidHandlers.stream().filter(h -> { + if (h.getTanks() == 0) return false; + if (h instanceof ICapabilityTrait cap) return cap.canCapOutput(); + return true; + }).toList(); + this.useDefaultToolHandlers = useDefaultToolHandlers; + } + + public AutoOutputTrait(MetaMachine machine, List itemHandlers, List fluidHandlers) { + this(machine, itemHandlers, fluidHandlers, true); + } + + @Override + public MachineTraitType getTraitType() { + return TYPE; + } + + public static AutoOutputTrait ofItems(MetaMachine machine, IItemHandler... itemHandlers) { + return new AutoOutputTrait(machine, Arrays.asList(itemHandlers), List.of()); + } + + public static AutoOutputTrait ofFluids(MetaMachine machine, IFluidHandler... fluidHandlers) { + return new AutoOutputTrait(machine, List.of(), Arrays.asList(fluidHandlers)); + } + + @Override + public void onMachineLoad() { + super.onMachineLoad(); + if (getLevel() instanceof ServerLevel serverLevel) { + serverLevel.getServer().tell(new TickTask(0, this::updateFluidOutputSubscription)); + serverLevel.getServer().tell(new TickTask(0, this::updateItemOutputSubscription)); + } + for (var handler : itemHandlers) { + if (handler instanceof NotifiableItemStackHandler notifiable) + itemSubs.add(notifiable.addChangedListener(this::updateItemOutputSubscription)); + } + + for (var handler : fluidHandlers) { + if (handler instanceof NotifiableFluidTank notifiable) + fluidSubs.add(notifiable.addChangedListener(this::updateFluidOutputSubscription)); + } + } + + @Override + public void onMachineUnload() { + if (itemOutputSub != null) { + itemOutputSub.unsubscribe(); + itemOutputSub = null; + } + if (fluidOutputSub != null) { + fluidOutputSub.unsubscribe(); + fluidOutputSub = null; + } + itemSubs.forEach(ISubscription::unsubscribe); + itemSubs.clear(); + fluidSubs.forEach(ISubscription::unsubscribe); + fluidSubs.clear(); + super.onMachineUnload(); + } + + @Override + public void onMachineNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { + updateItemOutputSubscription(); + updateFluidOutputSubscription(); + } + + public boolean supportsAutoOutputItems() { + return !itemHandlers.isEmpty(); + } + + public boolean supportsAutoOutputFluids() { + return !fluidHandlers.isEmpty(); + } + + public @Nullable Direction getItemOutputDirection() { + return supportsAutoOutputItems() ? itemOutputDirection : null; + } + + public @Nullable Direction getFluidOutputDirection() { + return supportsAutoOutputFluids() ? fluidOutputDirection : null; + } + + public boolean allowsItemInputFromOutputSide() { + return allowItemInputFromOutputSide; + } + + public boolean allowsFluidInputFromOutputSide() { + return allowFluidInputFromOutputSide; + } + + public void setAllowAutoOutputItems(boolean allow) { + if (supportsAutoOutputItems()) { + this.autoOutputItems = allow; + syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); + updateItemOutputSubscription(); + } + } + + public void setAllowAutoOutputFluids(boolean allow) { + if (supportsAutoOutputFluids()) { + this.autoOutputFluids = allow; + syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); + updateFluidOutputSubscription(); + } + } + + public void setFluidOutputDirection(@Nullable Direction outputFacing) { + if (supportsAutoOutputFluids()) { + if (!fluidOutputDirectionValidator.test(outputFacing) || + (machine.hasFrontFacing() && machine.getFrontFacing() == outputFacing)) + return; + this.fluidOutputDirection = outputFacing; + syncDataHolder.markClientSyncFieldDirty("outputFacingFluids"); + updateFluidOutputSubscription(); + } + } + + public void setItemOutputDirection(@Nullable Direction outputFacing) { + if (supportsAutoOutputItems()) { + if (!itemOutputDirectionValidator.test(outputFacing) || + (machine.hasFrontFacing() && machine.getFrontFacing() == outputFacing)) + return; + this.itemOutputDirection = outputFacing; + syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); + updateItemOutputSubscription(); + } + } + + private boolean shouldKeepItemSubscription() { + if (!supportsAutoOutputItems()) return false; + + if (!isAutoOutputItems() || getItemOutputDirection() == null || + !GTTransferUtils.hasAdjacentItemHandler(getLevel(), machine.getBlockPos(), getItemOutputDirection())) + return false; + return true; + } + + private boolean shouldKeepFluidSubscription() { + if (!supportsAutoOutputFluids()) return false; + if (!isAutoOutputFluids() || getFluidOutputDirection() == null || + !GTTransferUtils.hasAdjacentFluidHandler(getLevel(), machine.getBlockPos(), getFluidOutputDirection())) + return false; + return true; + } + + protected void updateItemOutputSubscription() { + if (shouldKeepItemSubscription()) { + itemOutputSub = machine.subscribeServerTick(itemOutputSub, this::autoOutputItems); + } else if (itemOutputSub != null) { + itemOutputSub.unsubscribe(); + itemOutputSub = null; + } + } + + protected void updateFluidOutputSubscription() { + if (shouldKeepFluidSubscription()) { + fluidOutputSub = machine.subscribeServerTick(fluidOutputSub, this::autoOutputFluids); + } else if (fluidOutputSub != null) { + fluidOutputSub.unsubscribe(); + fluidOutputSub = null; + } + } + + protected void autoOutputItems() { + if (machine.getOffsetTimer() % ticksPerCycle == 0 && getItemOutputDirection() != null) { + itemHandlers.forEach(this::exportItemToNearby); + } + updateItemOutputSubscription(); + } + + protected void autoOutputFluids() { + if (machine.getOffsetTimer() % ticksPerCycle == 0 && getFluidOutputDirection() != null) { + fluidHandlers.forEach(this::exportFluidToNearby); + } + updateFluidOutputSubscription(); + } + + private void exportFluidToNearby(IFluidHandler handler) { + var filter = getMachine().getFluidCapFilter(getFluidOutputDirection(), IO.OUT); + GTTransferUtils.getAdjacentFluidHandler(getLevel(), machine.getBlockPos(), getFluidOutputDirection()) + .ifPresent(adj -> GTTransferUtils.transferFluidsFiltered(handler, adj, filter)); + } + + private void exportItemToNearby(IItemHandler handler) { + var filter = getMachine().getItemCapFilter(getItemOutputDirection(), IO.OUT); + GTTransferUtils.getAdjacentItemHandler(getLevel(), machine.getBlockPos(), getItemOutputDirection()) + .ifPresent(adj -> GTTransferUtils.transferItemsFiltered(handler, adj, filter)); + } + + @Override + public boolean isValidFrontFace(Direction direction) { + return direction != getItemOutputDirection() && direction != getFluidOutputDirection(); + } + + @Override + public boolean shouldRenderGridOverlay(Player player, BlockPos pos, BlockState state, ItemStack held, + Set toolTypes) { + return toolTypes.contains(GTToolType.SCREWDRIVER) || toolTypes.contains(GTToolType.WRENCH); + } + + @Override + public @Nullable ResourceTexture getGridOverlayIcon(Player player, BlockPos pos, BlockState state, + Set toolTypes, Direction side) { + if (toolTypes.contains(GTToolType.WRENCH)) { + if (!player.isShiftKeyDown()) { + if (!machine.hasFrontFacing() || side != machine.getFrontFacing()) { + var canSwitchItemOutputToSide = supportsAutoOutputItems() && + itemOutputDirectionValidator.test(side) && side != getItemOutputDirection(); + var canSwitchFluidOutputToSide = supportsAutoOutputFluids() && + fluidOutputDirectionValidator.test(side) && side != getFluidOutputDirection(); + if (canSwitchItemOutputToSide || canSwitchFluidOutputToSide) + return GuiTextures.TOOL_IO_FACING_ROTATION; + } + } + } + if (toolTypes.contains(GTToolType.SCREWDRIVER)) { + if (side == getItemOutputDirection() || side == getFluidOutputDirection()) { + if (player.isShiftKeyDown()) return GuiTextures.TOOL_ALLOW_INPUT; + return GuiTextures.TOOL_AUTO_OUTPUT; + } + } + return null; + } + + @Override + public Pair onToolClick(Set toolType, Player player, + InteractionHand hand, Direction gridSide, + BlockHitResult hitResult) { + if (useDefaultToolHandlers) { + if (toolType.contains(GTToolType.WRENCH)) { + return Pair.of(GTToolType.WRENCH, onWrenchClick(player, hand, gridSide, hitResult)); + } + if (toolType.contains(GTToolType.SCREWDRIVER)) { + return Pair.of(GTToolType.SCREWDRIVER, onScrewdriverClick(player, hand, gridSide, hitResult)); + } + } + return IInteractionTrait.super.onToolClick(toolType, player, hand, gridSide, hitResult); + } + + private InteractionResult onWrenchClick(Player player, InteractionHand hand, Direction gridSide, + BlockHitResult hitResult) { + var itemStack = player.getItemInHand(hand); + var tagCompound = getBehaviorsTag(itemStack); + ToolModeSwitchBehavior.WrenchModeType type = ToolModeSwitchBehavior.WrenchModeType.VALUES[tagCompound + .getByte("Mode")]; + + boolean hasChanged = false; + if (type.isItem()) { + if ((!machine.hasFrontFacing() || gridSide != machine.getFrontFacing()) && + itemOutputDirectionValidator.test(gridSide)) { + setItemOutputDirection(gridSide); + hasChanged = true; + } + } + if (type.isFluid()) { + if ((!machine.hasFrontFacing() || gridSide != machine.getFrontFacing()) && + fluidOutputDirectionValidator.test(gridSide)) { + setFluidOutputDirection(gridSide); + hasChanged = true; + } + } + return hasChanged ? InteractionResult.sidedSuccess(machine.isRemote()) : InteractionResult.PASS; + } + + private InteractionResult onScrewdriverClick(Player player, InteractionHand hand, Direction gridSide, + BlockHitResult hitResult) { + boolean hasChanged = false; + if (player.isShiftKeyDown()) { + if (getItemOutputDirection() == gridSide) { + setAllowItemInputFromOutputSide(!allowsItemInputFromOutputSide()); + player.displayClientMessage(Component + .translatable("gtceu.machine.basic.input_from_output_side." + + (allowsItemInputFromOutputSide() ? "allow" : "disallow")) + .append(Component.translatable("gtceu.creative.chest.item")), true); + hasChanged = true; + } + + if (getFluidOutputDirection() == gridSide) { + setAllowFluidInputFromOutputSide(!allowsFluidInputFromOutputSide()); + player.displayClientMessage(Component + .translatable("gtceu.machine.basic.input_from_output_side." + + (allowsFluidInputFromOutputSide() ? "allow" : "disallow")) + .append(Component.translatable("gtceu.creative.tank.fluid")), true); + hasChanged = true; + } + + } else { + if (getItemOutputDirection() == gridSide) { + setAllowAutoOutputItems(!isAutoOutputItems()); + hasChanged = true; + } + if (getFluidOutputDirection() == gridSide) { + setAllowAutoOutputFluids(!isAutoOutputFluids()); + hasChanged = true; + } + } + return hasChanged ? InteractionResult.sidedSuccess(player.level().isClientSide) : InteractionResult.PASS; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidTankProxyTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidTankProxyTrait.java index 22d54ff1ef4..3cf525b8fa3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidTankProxyTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidTankProxyTrait.java @@ -12,6 +12,7 @@ import lombok.Setter; import lombok.experimental.Accessors; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; @Accessors(chain = true) public class FluidTankProxyTrait extends MachineTrait implements IFluidHandlerModifiable, ICapabilityTrait { @@ -27,7 +28,7 @@ public MachineTraitType getTraitType() { public final IO capabilityIO; @Setter @Getter - public IFluidHandlerModifiable proxy; + public @Nullable IFluidHandlerModifiable proxy; public FluidTankProxyTrait(MetaMachine machine, IO capabilityIO) { super(machine); diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/NBTSerializableTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/NBTSerializableTransformer.java index 31b2e54210b..20a03a83877 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/NBTSerializableTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/NBTSerializableTransformer.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.sync_system.data_transformers; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.utils.data.TagCompatibilityFixer; import net.minecraft.nbt.Tag; import net.minecraftforge.common.util.INBTSerializable; @@ -24,7 +25,7 @@ public Tag serializeNBT(INBTSerializable value, "Sync: Deserialization of INBTSerializable objects requires an existing object, they cannot be instantiated purely from saved data."); return null; } - currentVal.deserializeNBT(ValueTransformer.stripLdlibWrapper(tag)); + currentVal.deserializeNBT(TagCompatibilityFixer.stripLDLibPayloadWrapper(tag)); return currentVal; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformer.java index bf1506a9039..22a83bc1f86 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/ValueTransformer.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.api.sync_system.ISyncManaged; import com.gregtechceu.gtceu.api.sync_system.TypeDeclaration; -import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import org.jetbrains.annotations.NotNull; @@ -45,20 +44,6 @@ static TagType assertTagType(Class cls, Tag tag, } } - /** - * Extracts the actual data tag from an LDLib tag structure which is present in some serialized objects. - */ - static Tag stripLdlibWrapper(Tag t) { - if (!(t instanceof CompoundTag tag)) return t; - if (tag.contains("p") && tag.contains("t")) { - return tag.getCompound("p"); - } - if (tag.contains("t", Tag.TAG_COMPOUND)) { - return tag.getCompound("t").getCompound("p"); - } - return tag; - } - /** * A method which serializes this value into a tag, based on the current value and provided transformer context. */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ListTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ListTransformer.java index 9647d994ad6..aa217e318dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ListTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ListTransformer.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformers; +import com.gregtechceu.gtceu.utils.data.TagCompatibilityFixer; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; @@ -52,7 +53,7 @@ public Tag serializeNBT(List value, ValueTransformer.TransformerContext(); List finalCurrent = current; for (var t : listTag) { - T val = getElemTransformer(context).deserializeNBT(ValueTransformer.stripLdlibWrapper(t), + T val = getElemTransformer(context).deserializeNBT(TagCompatibilityFixer.stripLDLibPayloadWrapper(t), getInnerElemContext(null, context)); if (val != null) finalCurrent.add(val); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ObjectArrayTransformer.java b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ObjectArrayTransformer.java index 1ecd2e5f8f5..1f665105fe0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ObjectArrayTransformer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/sync_system/data_transformers/collections/ObjectArrayTransformer.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.sync_system.data_transformers.collections; import com.gregtechceu.gtceu.api.sync_system.data_transformers.ValueTransformer; +import com.gregtechceu.gtceu.utils.data.TagCompatibilityFixer; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; @@ -49,7 +50,7 @@ public Tag serializeNBT(T[] value, ValueTransformer.TransformerContext cont current = Arrays.copyOf(current, listTag.size()); } for (int i = 0; i < listTag.size(); i++) { - T result = elementTransformer.deserializeNBT(ValueTransformer.stripLdlibWrapper(listTag.get(i)), + T result = elementTransformer.deserializeNBT(TagCompatibilityFixer.stripLDLibPayloadWrapper(listTag.get(i)), getInnerElemContext(current[i], context)); if (result == null) return current; current[i] = result; diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java index e2a0c4b3c0d..13ff5a4e2b1 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java @@ -3,10 +3,9 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.client.model.BaseBakedModel; import com.gregtechceu.gtceu.client.model.IBlockEntityRendererBakedModel; import com.gregtechceu.gtceu.client.model.TextureOverrideModel; @@ -229,21 +228,22 @@ public List getMachineQuads(@Nullable BlockState blockState, @Nullabl } // render output overlays - if (machine instanceof IAutoOutputItem autoOutputItem) { - var itemFace = autoOutputItem.getOutputFacingItems(); + var outputTrait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE); + if (outputTrait != null && outputTrait.supportsAutoOutputItems()) { + var itemFace = outputTrait.getItemOutputDirection(); if (itemFace != null && side == itemFace) { quads.add(StaticFaceBakery.bakeFace(StaticFaceBakery.OUTPUT_OVERLAY, side, pipeOverlaySprite)); - if (autoOutputItem.isAutoOutputItems()) { + if (outputTrait.isAutoOutputItems()) { quads.add(StaticFaceBakery.bakeFace(StaticFaceBakery.AUTO_OUTPUT_OVERLAY, side, itemOutputOverlaySprite)); } } } - if (machine instanceof IAutoOutputFluid autoOutputFluid) { - var fluidFace = autoOutputFluid.getOutputFacingFluids(); + if (outputTrait != null && outputTrait.supportsAutoOutputFluids()) { + var fluidFace = outputTrait.getFluidOutputDirection(); if (fluidFace != null && side == fluidFace) { quads.add(StaticFaceBakery.bakeFace(StaticFaceBakery.OUTPUT_OVERLAY, side, pipeOverlaySprite)); - if (autoOutputFluid.isAutoOutputFluids()) { + if (outputTrait.isAutoOutputFluids()) { quads.add(StaticFaceBakery.bakeFace(StaticFaceBakery.AUTO_OUTPUT_OVERLAY, side, fluidOutputOverlaySprite)); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/MachineConfigCopyBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/MachineConfigCopyBehaviour.java index f7990a8dad6..88434f8236d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/MachineConfigCopyBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/MachineConfigCopyBehaviour.java @@ -5,6 +5,7 @@ import com.gregtechceu.gtceu.api.item.component.IInteractionItem; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.*; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.common.item.IntCircuitBehaviour; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.utils.GTTransferUtils; @@ -186,16 +187,19 @@ private static CompoundTag gatherMachineConfig(MetaMachine machine) { tag.putString(FACING_DIR, directionToString(machine.getFrontFacing())); - if (machine instanceof IAutoOutputItem autoOutputItem && autoOutputItem.getOutputFacingItems() != null) { - tag.putString(ITEM_OUTPUT_SIDE, directionToString(autoOutputItem.getOutputFacingItems())); - tag.putBoolean(ITEM_AUTO_OUTPUT, autoOutputItem.isAutoOutputItems()); - tag.putBoolean(ALLOW_ITEM_IN_FROM_OUT, autoOutputItem.isAllowInputFromOutputSideItems()); + var outputTrait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE); + if (outputTrait != null && outputTrait.supportsAutoOutputItems() && + outputTrait.getItemOutputDirection() != null) { + tag.putString(ITEM_OUTPUT_SIDE, directionToString(outputTrait.getItemOutputDirection())); + tag.putBoolean(ITEM_AUTO_OUTPUT, outputTrait.isAutoOutputItems()); + tag.putBoolean(ALLOW_ITEM_IN_FROM_OUT, outputTrait.allowsItemInputFromOutputSide()); } - if (machine instanceof IAutoOutputFluid autoOutputFluid && autoOutputFluid.getOutputFacingFluids() != null) { - tag.putString(FLUID_OUTPUT_SIDE, directionToString(autoOutputFluid.getOutputFacingFluids())); - tag.putBoolean(FLUID_AUTO_OUTPUT, autoOutputFluid.isAutoOutputFluids()); - tag.putBoolean(ALLOW_FLUID_IN_FROM_OUT, autoOutputFluid.isAllowInputFromOutputSideFluids()); + if (outputTrait != null && outputTrait.supportsAutoOutputFluids() && + outputTrait.getFluidOutputDirection() != null) { + tag.putString(FLUID_OUTPUT_SIDE, directionToString(outputTrait.getFluidOutputDirection())); + tag.putBoolean(FLUID_AUTO_OUTPUT, outputTrait.isAutoOutputFluids()); + tag.putBoolean(ALLOW_FLUID_IN_FROM_OUT, outputTrait.allowsFluidInputFromOutputSide()); } if (machine instanceof IMufflableMachine mufflableMachine) { @@ -218,20 +222,19 @@ private static CompoundTag gatherMachineConfig(MetaMachine machine) { } private static void pasteMachineConfig(ServerPlayer player, MetaMachine machine, CompoundTag tag) { - if (machine instanceof IAutoOutputItem autoOutputItem) { + var outputTrait = machine.getTraitHolder().getTrait(AutoOutputTrait.TYPE); + if (outputTrait != null) { if (tag.contains(ITEM_OUTPUT_SIDE)) - autoOutputItem.setOutputFacingItems(stringToDirection(tag.getString(ITEM_OUTPUT_SIDE))); - if (tag.contains(ITEM_AUTO_OUTPUT)) autoOutputItem.setAutoOutputItems(tag.getBoolean(ITEM_AUTO_OUTPUT)); + outputTrait.setItemOutputDirection(stringToDirection(tag.getString(ITEM_OUTPUT_SIDE))); + if (tag.contains(ITEM_AUTO_OUTPUT)) outputTrait.setAllowAutoOutputItems(tag.getBoolean(ITEM_AUTO_OUTPUT)); if (tag.contains(ALLOW_ITEM_IN_FROM_OUT)) - autoOutputItem.setAllowInputFromOutputSideItems(tag.getBoolean(ALLOW_ITEM_IN_FROM_OUT)); - } - - if (machine instanceof IAutoOutputFluid autoOutputFluid) { + outputTrait.setAllowItemInputFromOutputSide(tag.getBoolean(ALLOW_ITEM_IN_FROM_OUT)); if (tag.contains(FLUID_OUTPUT_SIDE)) - autoOutputFluid.setOutputFacingFluids(stringToDirection(tag.getString(FLUID_OUTPUT_SIDE))); - if (tag.contains(FLUID_AUTO_OUTPUT)) autoOutputFluid.setAutoOutputFluids(tag.getBoolean(FLUID_AUTO_OUTPUT)); + outputTrait.setFluidOutputDirection(stringToDirection(tag.getString(FLUID_OUTPUT_SIDE))); + if (tag.contains(FLUID_AUTO_OUTPUT)) + outputTrait.setAllowAutoOutputFluids(tag.getBoolean(FLUID_AUTO_OUTPUT)); if (tag.contains(ALLOW_FLUID_IN_FROM_OUT)) - autoOutputFluid.setAllowInputFromOutputSideFluids(tag.getBoolean(ALLOW_FLUID_IN_FROM_OUT)); + outputTrait.setAllowFluidInputFromOutputSide(tag.getBoolean(ALLOW_FLUID_IN_FROM_OUT)); } Direction facingDir = Direction.byName(tag.getString(FACING_DIR)); diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java index 692109b0de2..8a235fddcbc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java @@ -127,6 +127,8 @@ public enum WrenchModeType { FLUID(Component.translatable("gtceu.mode.fluid")), BOTH(Component.translatable("gtceu.mode.both")); + public static final WrenchModeType[] VALUES = values(); + private final Component name; WrenchModeType(Component name) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BlockBreakerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BlockBreakerMachine.java index e23dec41b32..5ae4bb47a6e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BlockBreakerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BlockBreakerMachine.java @@ -10,42 +10,31 @@ import com.gregtechceu.gtceu.api.gui.editor.EditableMachineUI; import com.gregtechceu.gtceu.api.gui.editor.EditableUI; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.utils.Position; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -53,7 +42,6 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Set; import java.util.function.BiFunction; import javax.annotation.ParametersAreNonnullByDefault; @@ -61,33 +49,26 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class BlockBreakerMachine extends TieredEnergyMachine - implements IAutoOutputItem, IFancyUIMachine, IMachineLife, IControllable { + implements IFancyUIMachine, IMachineLife, IControllable { - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; @SaveField protected final NotifiableItemStackHandler cache; @Getter @SaveField protected final CustomItemStackHandler chargerInventory; @Nullable - protected TickableSubscription autoOutputSubs, batterySubs, breakerSubs; + protected TickableSubscription batterySubs, breakerSubs; @Nullable - protected ISubscription exportItemSubs, energySubs; + protected ISubscription energySubs; private final int inventorySize; @SyncToClient private int blockBreakProgress = 0; private float currentHardness; private final long energyPerTick; public final float efficiencyMultiplier; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; @Getter @SaveField @@ -100,8 +81,9 @@ public BlockBreakerMachine(BlockEntityCreationInfo info, int tier) { this.cache = createCacheItemHandler(); this.chargerInventory = createChargerItemHandler(); this.energyPerTick = GTValues.V[tier - 1]; - setOutputFacingItems(getFrontFacing().getOpposite()); this.efficiencyMultiplier = 1.0f - getEfficiencyMultiplier(tier); + + this.autoOutput = AutoOutputTrait.ofItems(this, cache); } public static float getEfficiencyMultiplier(int tier) { @@ -136,10 +118,8 @@ public void onLoad() { super.onLoad(); if (!isRemote()) { if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); serverLevel.getServer().tell(new TickTask(0, this::updateBreakerSubscription)); } - exportItemSubs = cache.addChangedListener(this::updateAutoOutputSubscription); energySubs = energyContainer.addChangedListener(() -> { this.updateBatterySubscription(); this.updateBreakerSubscription(); @@ -155,10 +135,6 @@ public void onUnload() { energySubs.unsubscribe(); energySubs = null; } - if (exportItemSubs != null) { - exportItemSubs.unsubscribe(); - exportItemSubs = null; - } } @Override @@ -171,7 +147,6 @@ public void onMachineRemoved() { public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { super.onNeighborChanged(block, fromPos, isMoving); updateBreakerSubscription(); - updateAutoOutputSubscription(); } ////////////////////////////////////// @@ -203,10 +178,11 @@ public void breakerUpdate() { for (ItemStack drop : drops) { var remainder = tryFillCache(drop); if (!remainder.isEmpty()) { - if (getOutputFacingItems() == null) { + if (autoOutput.getItemOutputDirection() == null) { Block.popResource(getLevel(), getBlockPos(), remainder); } else { - Block.popResource(getLevel(), getBlockPos().relative(getOutputFacingItems()), + Block.popResource(getLevel(), + getBlockPos().relative(autoOutput.getItemOutputDirection()), remainder); } } @@ -273,46 +249,6 @@ public boolean drainEnergy(boolean simulate) { ////////////////////////////////////// // ******* Auto Output *******// ////////////////////////////////////// - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public boolean isAllowInputFromOutputSideItems() { - return false; - } - - @Override - public void setAllowInputFromOutputSideItems(boolean allow) {} - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingItems(); - if ((isAutoOutputItems() && !cache.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacing)) - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); - else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void checkAutoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) - cache.exportToNearby(getOutputFacingItems()); - updateAutoOutputSubscription(); - } - } protected void updateBatterySubscription() { if (energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, true)) @@ -333,14 +269,6 @@ public boolean shouldWeatherOrTerrainExplosion() { return false; } - @Override - public boolean isFacingValid(Direction facing) { - if (facing == getOutputFacingItems()) { - return false; - } - return super.isFacingValid(facing); - } - public void setWorkingEnabled(boolean workingEnabled) { isWorkingEnabled = workingEnabled; syncDataHolder.markClientSyncFieldDirty("isWorkingEnabled"); @@ -423,68 +351,4 @@ protected static EditableUI createTemplate(int }); }); } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } else if (toolTypes.contains(GTToolType.SOFT_MALLET)) { - return isWorkingEnabled ? GuiTextures.TOOL_PAUSE : GuiTextures.TOOL_START; - } else if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } - return super.sideTips(player, pos, state, toolTypes, side); - } - - ////////////////////////////////////// - // ******* Interactions ********// - ////////////////////////////////////// - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!playerIn.isShiftKeyDown() && !isRemote()) { - var tool = playerIn.getItemInHand(hand); - if (tool.getDamageValue() >= tool.getMaxDamage()) return InteractionResult.PASS; - if (hasFrontFacing() && gridSide == getFrontFacing()) return InteractionResult.PASS; - - // important not to use getters here, which have different logic - Direction itemFacing = this.outputFacingItems; - - if (gridSide != itemFacing) { - // if it is a new side, move it - setOutputFacingItems(gridSide); - } else { - // remove the output facing when wrenching the current one to disable it - setOutputFacingItems(null); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } - - @Override - protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - var controllable = GTCapabilityHelper.getControllable(getLevel(), getBlockPos(), gridSide); - if (controllable != null) { - if (!isRemote()) { - controllable.setWorkingEnabled(!controllable.isWorkingEnabled()); - playerIn.sendSystemMessage(Component.translatable(controllable.isWorkingEnabled() ? - "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled")); - } - return InteractionResult.CONSUME; - } - return InteractionResult.PASS; - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/FisherMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/FisherMachine.java index 3fed4ad7d57..a4cdfc0dd1f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/FisherMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/FisherMachine.java @@ -11,59 +11,46 @@ import com.gregtechceu.gtceu.api.gui.editor.EditableUI; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; import com.lowdragmc.lowdraglib.gui.texture.ItemStackTexture; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.utils.Position; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.storage.loot.BuiltInLootTables; import net.minecraft.world.level.storage.loot.LootParams; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.Nullable; -import java.util.Set; import java.util.function.BiFunction; import javax.annotation.ParametersAreNonnullByDefault; @@ -71,18 +58,8 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class FisherMachine extends TieredEnergyMachine - implements IAutoOutputItem, IFancyUIMachine, IMachineLife, IWorkable { + implements IFancyUIMachine, IMachineLife, IWorkable { - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; @SaveField protected final NotifiableItemStackHandler cache; @Getter @@ -96,9 +73,9 @@ public class FisherMachine extends TieredEnergyMachine @SaveField protected final CustomItemStackHandler chargerInventory; @Nullable - protected TickableSubscription autoOutputSubs, batterySubs, fishingSubs; + protected TickableSubscription batterySubs, fishingSubs; @Nullable - protected ISubscription exportItemSubs, energySubs, baitSubs; + protected ISubscription energySubs, baitSubs; private final long energyPerTick; private final int inventorySize; @@ -126,6 +103,9 @@ public class FisherMachine extends TieredEnergyMachine @SaveField @SyncToClient protected boolean junkEnabled = true; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; public FisherMachine(BlockEntityCreationInfo info, int tier) { super(info, tier); @@ -142,7 +122,7 @@ public FisherMachine(BlockEntityCreationInfo info, int tier) { (ConfigHolder.INSTANCE.compat.energy.nativeEUToFE && GTCapabilityHelper.getForgeEnergyItem(item) != null)); - setOutputFacingItems(getFrontFacing()); + autoOutput = AutoOutputTrait.ofItems(this, cache); } public void setWorkingEnabled(boolean enabled) { @@ -159,11 +139,6 @@ public void setJunkEnabled(boolean enabled) { public void onLoad() { super.onLoad(); if (isRemote()) return; - - if (getLevel() instanceof ServerLevel serverLevel) - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - - exportItemSubs = cache.addChangedListener(this::updateAutoOutputSubscription); energySubs = energyContainer.addChangedListener(() -> { this.updateBatterySubscription(); this.updateFishingUpdateSubscription(); @@ -180,10 +155,6 @@ public void onUnload() { energySubs.unsubscribe(); energySubs = null; } - if (exportItemSubs != null) { - exportItemSubs.unsubscribe(); - exportItemSubs = null; - } if (baitSubs != null) { baitSubs.unsubscribe(); baitSubs = null; @@ -299,23 +270,6 @@ public boolean drainEnergy(boolean simulate) { return false; } - ////////////////////////////////////// - // ******* Auto Output *******// - ////////////////////////////////////// - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - protected void updateBatterySubscription() { if (energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, true)) batterySubs = subscribeServerTick(batterySubs, this::chargeBattery); @@ -325,44 +279,11 @@ else if (batterySubs != null) { } } - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingItems(); - if ((isAutoOutputItems() && !cache.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacing)) - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); - else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void checkAutoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) - cache.exportToNearby(getOutputFacingItems()); - updateAutoOutputSubscription(); - } - } - protected void chargeBattery() { if (!energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, false)) updateBatterySubscription(); } - @Override - public boolean isFacingValid(Direction facing) { - if (facing == getOutputFacingItems()) { - return false; - } - return super.isFacingValid(facing); - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - ////////////////////////////////////// // ********** GUI ***********// ////////////////////////////////////// @@ -474,53 +395,4 @@ protected static EditableUI createTemplate(int inven }); }); } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } else if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } else if (toolTypes.contains(GTToolType.SOFT_MALLET)) { - return this.isWorkingEnabled ? GuiTextures.TOOL_PAUSE : GuiTextures.TOOL_START; - } - return super.sideTips(player, pos, state, toolTypes, side); - } - - ////////////////////////////////////// - // ******* Interactions ********// - ////////////////////////////////////// - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!playerIn.isShiftKeyDown() && !isRemote()) { - var tool = playerIn.getItemInHand(hand); - if (tool.getDamageValue() >= tool.getMaxDamage()) return InteractionResult.PASS; - if (hasFrontFacing() && gridSide == getFrontFacing()) return InteractionResult.PASS; - - // important not to use getters here, which have different logic - Direction itemFacing = this.outputFacingItems; - - if (gridSide != itemFacing) { - // if it is a new side, move it - setOutputFacingItems(gridSide); - } else { - // remove the output facing when wrenching the current one to disable it - setOutputFacingItems(null); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java index 08abbb811d7..22821876b65 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java @@ -12,13 +12,12 @@ import com.gregtechceu.gtceu.api.gui.editor.EditableUI; import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; @@ -27,40 +26,29 @@ import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.utils.Position; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import lombok.Getter; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Set; import java.util.function.BiFunction; import javax.annotation.ParametersAreNonnullByDefault; @@ -68,24 +56,13 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class ItemCollectorMachine extends TieredEnergyMachine - implements IAutoOutputItem, IFancyUIMachine, IMachineLife, IWorkable { + implements IFancyUIMachine, IMachineLife, IWorkable { @Getter private static final int[] INVENTORY_SIZES = { 4, 9, 16, 25, 25 }; private static final double MOTION_MULTIPLIER = 0.04; private static final int BASE_EU_CONSUMPTION = 6; - @Nullable - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; @SaveField protected final NotifiableItemStackHandler output; @@ -96,9 +73,9 @@ public class ItemCollectorMachine extends TieredEnergyMachine protected final CustomItemStackHandler filterInventory; @Nullable - protected TickableSubscription autoOutputSubs, batterySubs, collectionSubs; + protected TickableSubscription batterySubs, collectionSubs; @Nullable - protected ISubscription exportItemSubs, energySubs; + protected ISubscription energySubs; private final long energyPerTick; private final int inventorySize; @@ -125,6 +102,10 @@ public class ItemCollectorMachine extends TieredEnergyMachine @RerenderOnChanged private boolean active = false; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; + public ItemCollectorMachine(BlockEntityCreationInfo info, int tier) { super(info, tier); this.inventorySize = INVENTORY_SIZES[Mth.clamp(getTier(), 0, INVENTORY_SIZES.length - 1)]; @@ -132,10 +113,9 @@ public ItemCollectorMachine(BlockEntityCreationInfo info, int tier) { this.output = createOutputItemHandler(); this.chargerInventory = createChargerItemHandler(); this.filterInventory = createFilterItemHandler(); - + this.autoOutput = AutoOutputTrait.ofItems(this, output); maxRange = (int) Math.pow(2, tier + 2); range = maxRange; - setOutputFacingItems(getFrontFacing()); } ////////////////////////////////////// @@ -168,13 +148,9 @@ public void onLoad() { if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, () -> { - this.updateAutoOutputSubscription(); - this.updateCollectionSubscription(); - })); + serverLevel.getServer().tell(new TickTask(0, this::updateCollectionSubscription)); } - exportItemSubs = output.addChangedListener(this::updateAutoOutputSubscription); energySubs = energyContainer.addChangedListener(() -> { this.updateBatterySubscription(); this.updateCollectionSubscription(); @@ -189,10 +165,6 @@ public void onUnload() { energySubs.unsubscribe(); energySubs = null; } - if (exportItemSubs != null) { - exportItemSubs.unsubscribe(); - exportItemSubs = null; - } } @Override @@ -301,31 +273,6 @@ public boolean drainEnergy(boolean simulate) { return false; } - ////////////////////////////////////// - // ******* Auto Output *******// - ////////////////////////////////////// - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public boolean isAllowInputFromOutputSideItems() { - return false; - } - - @Override - public void setAllowInputFromOutputSideItems(boolean allow) {} - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - protected void updateBatterySubscription() { if (energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, true)) batterySubs = subscribeServerTick(batterySubs, this::chargeBattery); @@ -335,45 +282,12 @@ else if (batterySubs != null) { } } - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingItems(); - if ((isAutoOutputItems() && !output.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacing)) - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::autoOutput); - else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void autoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) - output.exportToNearby(getOutputFacingItems()); - updateAutoOutputSubscription(); - } - } - protected void chargeBattery() { if (!energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, false)) { updateBatterySubscription(); } } - @Override - public boolean isFacingValid(Direction facing) { - if (facing == getOutputFacingItems()) { - return false; - } - return super.isFacingValid(facing); - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - @Override public int getProgress() { return 0; @@ -496,69 +410,4 @@ protected static EditableUI createTemplate(in }); } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } else if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } else if (toolTypes.contains(GTToolType.SOFT_MALLET)) { - return isWorkingEnabled ? GuiTextures.TOOL_PAUSE : GuiTextures.TOOL_START; - } - - return super.sideTips(player, pos, state, toolTypes, side); - } - - ////////////////////////////////////// - // ******* Interactions ********// - ////////////////////////////////////// - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!playerIn.isShiftKeyDown() && !isRemote()) { - var tool = playerIn.getItemInHand(hand); - if (tool.getDamageValue() >= tool.getMaxDamage()) return InteractionResult.PASS; - if (hasFrontFacing() && gridSide == getFrontFacing()) return InteractionResult.PASS; - - // important not to use getters here, which have different logic - Direction itemFacing = this.outputFacingItems; - - if (gridSide != itemFacing) { - // if it is a new side, move it - setOutputFacingItems(gridSide); - } else { - // remove the output facing when wrenching the current one to disable it - setOutputFacingItems(null); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } - - @Override - protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - var controllable = GTCapabilityHelper.getControllable(getLevel(), getBlockPos(), gridSide); - if (controllable != null) { - if (!isRemote()) { - controllable.setWorkingEnabled(!controllable.isWorkingEnabled()); - playerIn.sendSystemMessage(Component.translatable(controllable.isWorkingEnabled() ? - "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled")); - } - return InteractionResult.CONSUME; - } - return InteractionResult.PASS; - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java index 6b278a6ebe8..a5276ee2fe9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java @@ -12,10 +12,9 @@ import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.WorkableTieredMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IDataInfoProvider; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; @@ -23,7 +22,6 @@ import com.gregtechceu.gtceu.common.machine.trait.miner.MinerLogic; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; import com.lowdragmc.lowdraglib.gui.widget.ComponentPanelWidget; @@ -34,23 +32,18 @@ import net.minecraft.ChatFormatting; import net.minecraft.Util; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.block.Block; import net.minecraft.world.phys.BlockHitResult; import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import lombok.Getter; -import lombok.Setter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,30 +57,20 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class MinerMachine extends WorkableTieredMachine - implements IMiner, IControllable, IFancyUIMachine, IDataInfoProvider, IAutoOutputItem { + implements IMiner, IControllable, IFancyUIMachine, IDataInfoProvider { - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideItems; @Getter @SaveField protected final CustomItemStackHandler chargerInventory; private final long energyPerTick; @Nullable - protected TickableSubscription autoOutputSubs, batterySubs; + protected TickableSubscription batterySubs; @Nullable - protected ISubscription exportItemSubs, energySubs; + protected ISubscription energySubs; + + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; public MinerMachine(BlockEntityCreationInfo info, int tier, int speed, int maximumRadius, int fortune) { super(info, tier, @@ -95,6 +78,8 @@ public MinerMachine(BlockEntityCreationInfo info, int tier, int speed, int maxim 0, (tier + 1) * (tier + 1), 0, 0, ($) -> 0); this.energyPerTick = GTValues.V[tier - 1]; this.chargerInventory = createChargerItemHandler(); + this.autoOutput = AutoOutputTrait.ofItems(this, exportItems); + autoOutput.setItemOutputDirectionValidator(d -> d != Direction.DOWN); } ////////////////////////////////////// @@ -122,21 +107,11 @@ public MinerLogic getRecipeLogic() { return (MinerLogic) super.getRecipeLogic(); } - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - @Override public void onLoad() { super.onLoad(); if (!isRemote()) { - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } updateBatterySubscription(); - exportItemSubs = exportItems.addChangedListener(this::updateAutoOutputSubscription); energySubs = energyContainer.addChangedListener(this::updateBatterySubscription); chargerInventory.setOnContentsChanged(this::updateBatterySubscription); } @@ -145,11 +120,6 @@ public void onLoad() { @Override public void onUnload() { super.onUnload(); - if (exportItemSubs != null) { - exportItemSubs.unsubscribe(); - exportItemSubs = null; - } - if (energySubs != null) { energySubs.unsubscribe(); energySubs = null; @@ -159,17 +129,6 @@ public void onUnload() { ////////////////////////////////////// // ********** LOGIC **********// ////////////////////////////////////// - protected void updateAutoOutputSubscription() { - var outputFace = getOutputFacingItems(); - if (isAutoOutputItems() && outputFace != null && !exportItems.isEmpty() && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFace)) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::autoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - protected void updateBatterySubscription() { if (energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, true)) { batterySubs = subscribeServerTick(batterySubs, this::chargeBattery); @@ -179,31 +138,6 @@ protected void updateBatterySubscription() { } } - protected void autoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) { - exportItems.exportToNearby(getOutputFacingItems()); - } - } - updateAutoOutputSubscription(); - } - - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - if (outputFacing != Direction.DOWN) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - } - protected void chargeBattery() { if (!energyContainer.dischargeOrRechargeEnergyContainers(chargerInventory, 0, false)) { updateBatterySubscription(); @@ -280,9 +214,8 @@ protected static EditableUI createTemplate(int invent slot.setCanPutItems(false); } }); - WidgetUtils.widgetByIdForEach(group, "^component_panel$", ComponentPanelWidget.class, panel -> { - panel.textSupplier(machine::addDisplayText); - }); + WidgetUtils.widgetByIdForEach(group, "^component_panel$", ComponentPanelWidget.class, + panel -> panel.textSupplier(machine::addDisplayText)); }); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/PumpMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/PumpMachine.java index a187bc42868..6a8668edc29 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/PumpMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/PumpMachine.java @@ -7,19 +7,16 @@ import com.gregtechceu.gtceu.api.gui.UITemplate; import com.gregtechceu.gtceu.api.gui.widget.TankWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.common.data.GTBlocks; import com.lowdragmc.lowdraglib.gui.modular.ModularUI; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.ImageWidget; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; @@ -57,7 +54,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class PumpMachine extends TieredEnergyMachine implements IAutoOutputFluid, IUIMachine, IMachineLife { +public class PumpMachine extends TieredEnergyMachine implements IUIMachine, IMachineLife { public static final int BASE_PUMP_RADIUS = 16; public static final int EXTRA_PUMP_RADIUS = 4; @@ -67,47 +64,24 @@ public class PumpMachine extends TieredEnergyMachine implements IAutoOutputFluid @Getter @SaveField private int pumpHeadY; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputFluids; @SaveField protected final NotifiableFluidTank cache; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; + public PumpMachine(BlockEntityCreationInfo info, int tier) { super(info, tier); this.cache = new NotifiableFluidTank(this, 1, 16 * FluidType.BUCKET_VOLUME * Math.max(1, getTier()), IO.NONE, IO.OUT); + this.autoOutput = AutoOutputTrait.ofFluids(this, cache); } ////////////////////////////////////// // ***** Initialization *****// ////////////////////////////////////// - @Override - public boolean isAllowInputFromOutputSideFluids() { - return false; - } - - @Override - public void setAllowInputFromOutputSideFluids(boolean allow) {} - - @Override - public Direction getOutputFacingFluids() { - return getFrontFacing(); - } - - public void setAutoOutputFluids(boolean autoOutputFluids) { - this.autoOutputFluids = autoOutputFluids; - syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); - } - - @Override - public void setOutputFacingFluids(@Nullable Direction outputFacing) { - setFrontFacing(outputFacing); - } - @Override public void onLoad() { super.onLoad(); @@ -507,8 +481,8 @@ private void pumpCycle() { } public void update() { - if (getOutputFacingFluids() != null) { - cache.exportToNearby(getOutputFacingFluids()); + if (autoOutput.getFluidOutputDirection() != null) { + cache.exportToNearby(autoOutput.getFluidOutputDirection()); } // do not do anything without enough energy supplied @@ -570,25 +544,10 @@ public ModularUI createUI(Player entityPlayer) { .widget(new TankWidget(cache.getStorages()[0], 90, 35, true, true) .setBackground(GuiTextures.FLUID_SLOT)) .widget(new ToggleButtonWidget(7, 53, 18, 18, - GuiTextures.BUTTON_FLUID_OUTPUT, this::isAutoOutputFluids, this::setAutoOutputFluids) + GuiTextures.BUTTON_FLUID_OUTPUT, this.autoOutput::isAutoOutputFluids, + this.autoOutput::setAllowAutoOutputFluids) .setShouldUseBaseBackground() .setTooltipText("gtceu.gui.fluid_auto_output.tooltip")) .widget(UITemplate.bindPlayerInventory(entityPlayer.getInventory(), GuiTextures.SLOT, 7, 84, true)); } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (player.isShiftKeyDown()) { - if (hasFrontFacing() && side != this.getFrontFacing() && isFacingValid(side)) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } - return super.sideTips(player, pos, state, toolTypes, side); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java index f8c36980058..4828888116c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java @@ -4,7 +4,6 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.blockentity.BlockEntityCreationInfo; import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; -import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IControllable; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.item.tool.GTToolType; @@ -232,20 +231,6 @@ public void setWorkingEnabled(boolean workingEnabled) { return super.sideTips(player, pos, state, toolTypes, side); } - protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - var controllable = GTCapabilityHelper.getControllable(getLevel(), getBlockPos(), gridSide); - if (controllable != null) { - if (!isRemote()) { - controllable.setWorkingEnabled(!controllable.isWorkingEnabled()); - playerIn.sendSystemMessage(Component.translatable(controllable.isWorkingEnabled() ? - "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled")); - } - return InteractionResult.CONSUME; - } - return InteractionResult.PASS; - } - @Override protected @NotNull InteractionResult onScrewdriverClick(Player playerIn, InteractionHand hand, Direction gridSide, BlockHitResult hitResult) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java index b0827e23796..13708588fbb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.blockentity.BlockEntityCreationInfo; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; -import com.gregtechceu.gtceu.api.capability.ICentralMonitor; import com.gregtechceu.gtceu.api.capability.IMonitorComponent; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -62,7 +61,7 @@ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class CentralMonitorMachine extends WorkableElectricMultiblockMachine - implements IMonitorComponent, IDataInfoProvider, IMachineLife, ICentralMonitor { + implements IMonitorComponent, IDataInfoProvider, IMachineLife { @SaveField @SyncToClient diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/BufferMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/BufferMachine.java index 710259ffa32..9fa3d889e57 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/BufferMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/BufferMachine.java @@ -5,76 +5,32 @@ import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.gui.widget.TankWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; -import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputBoth; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; -import com.gregtechceu.gtceu.utils.GTTransferUtils; -import com.gregtechceu.gtceu.utils.ISubscription; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; import lombok.Getter; -import lombok.Setter; -import org.jetbrains.annotations.Nullable; -import java.util.Set; +import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class BufferMachine extends TieredMachine implements IMachineLife, IAutoOutputBoth, IFancyUIMachine { +public class BufferMachine extends TieredMachine implements IMachineLife, IFancyUIMachine { public static final int TANK_SIZE = 64000; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected @Nullable Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected @Nullable Direction outputFacingFluids; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputFluids; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideItems; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideFluids; - @SaveField @Getter protected final NotifiableItemStackHandler inventory; @@ -82,17 +38,16 @@ public class BufferMachine extends TieredMachine implements IMachineLife, IAutoO @SaveField @Getter protected final NotifiableFluidTank tank; + @SaveField + @SyncToClient - @Nullable - protected TickableSubscription autoOutputSubs; - - @Nullable - protected ISubscription invSubs, tankSubs; + public final AutoOutputTrait autoOutput; public BufferMachine(BlockEntityCreationInfo info, int tier) { super(info, tier); this.inventory = createInventory(); this.tank = createTank(); + this.autoOutput = new AutoOutputTrait(this, List.of(inventory), List.of(tank)); } //////////////////////////////// @@ -115,94 +70,6 @@ protected NotifiableFluidTank createTank() { return new NotifiableFluidTank(this, getTankSize(tier), TANK_SIZE, IO.BOTH); } - @Override - public void onLoad() { - super.onLoad(); - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } - this.invSubs = inventory.addChangedListener(this::updateAutoOutputSubscription); - this.tankSubs = tank.addChangedListener(this::updateAutoOutputSubscription); - } - - @Override - public void onUnload() { - super.onUnload(); - if (invSubs != null) { - invSubs.unsubscribe(); - this.invSubs = null; - } - - if (tankSubs != null) { - tankSubs.unsubscribe(); - this.tankSubs = null; - } - } - - //////////////////////////////// - // ******* Auto Output *******// - //////////////////////////////// - - @Override - public void setAutoOutputFluids(boolean allow) { - this.autoOutputFluids = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingFluids(@Nullable Direction outputFacing) { - this.outputFacingFluids = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingFluids"); - updateAutoOutputSubscription(); - } - - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - - protected void updateAutoOutputSubscription() { - var outputFacingItems = getOutputFacingItems(); - var outputFacingFluids = getOutputFacingFluids(); - if ((isAutoOutputItems() && !inventory.isEmpty() && outputFacingItems != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacingItems)) || - (isAutoOutputFluids() && !tank.isEmpty() && outputFacingFluids != null && - GTTransferUtils.hasAdjacentFluidHandler(getLevel(), getBlockPos(), outputFacingFluids))) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::autoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void autoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputFluids() && getOutputFacingFluids() != null) { - tank.exportToNearby(getOutputFacingFluids()); - } - if (isAutoOutputItems() && getOutputFacingItems() != null) { - inventory.exportToNearby(getOutputFacingItems()); - } - } - updateAutoOutputSubscription(); - } - //////////////////////////////// // ********** GUI *********** // //////////////////////////////// @@ -234,20 +101,6 @@ public Widget createUIWidget() { return group; } - /////////////////////////////// - // ******* Rendering ********// - /////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems() || side == getOutputFacingFluids()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } - return super.sideTips(player, pos, state, toolTypes, side); - } - //////////////////////////////// // ********** Misc ***********// //////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java index daef71a5ae5..8a491110788 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java @@ -43,17 +43,14 @@ public CreativeChestMachine(BlockEntityCreationInfo info) { } @Override - protected ItemCache createCacheItemHandler() { - return new InfiniteCache(this); + public void onLoad() { + super.onLoad(); + if (!isRemote()) autoOutput.setTicksPerCycle(ticksPerCycle); } - protected void checkAutoOutput() { - if (getOffsetTimer() % ticksPerCycle == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) { - cache.exportToNearby(getOutputFacingItems()); - } - updateAutoOutputSubscription(); - } + @Override + protected ItemCache createCacheItemHandler() { + return new InfiniteCache(this); } private InteractionResult updateStored(ItemStack item) { @@ -65,6 +62,7 @@ private InteractionResult updateStored(ItemStack item) { private void setTicksPerCycle(String value) { if (value.isEmpty()) return; ticksPerCycle = Integer.parseInt(value); + autoOutput.setTicksPerCycle(ticksPerCycle); onItemChanged(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeTankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeTankMachine.java index 342762674c6..de4aa043e68 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeTankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeTankMachine.java @@ -51,13 +51,10 @@ protected FluidCache createCacheFluidHandler() { return new InfiniteCache(this); } - protected void checkAutoOutput() { - if (getOffsetTimer() % ticksPerCycle == 0) { - if (isAutoOutputFluids() && getOutputFacingFluids() != null) { - cache.exportToNearby(getOutputFacingFluids()); - } - updateAutoOutputSubscription(); - } + @Override + public void onLoad() { + super.onLoad(); + if (!isRemote()) autoOutput.setTicksPerCycle(ticksPerCycle); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java index 52053fbaed3..243d8aa7e4d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java @@ -4,35 +4,22 @@ import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.data.chemical.material.Material; import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey; -import com.gregtechceu.gtceu.api.gui.GuiTextures; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.TickableSubscription; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; import com.gregtechceu.gtceu.api.machine.feature.IDropSaveMachine; import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; -import com.gregtechceu.gtceu.config.ConfigHolder; -import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.ISubscription; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; - import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraftforge.fluids.FluidStack; @@ -42,28 +29,19 @@ import lombok.Getter; import org.jetbrains.annotations.Nullable; -import java.util.Set; +import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class DrumMachine extends MetaMachine implements IAutoOutputFluid, IDropSaveMachine, IInteractedMachine { +public class DrumMachine extends MetaMachine implements IDropSaveMachine, IInteractedMachine { - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputFluids; - @SaveField - protected boolean allowInputFromOutputSideFluids; @Getter private final int maxStoredFluids; @SaveField protected final NotifiableFluidTank cache; @Nullable - protected TickableSubscription autoOutputSubs; - @Nullable protected ISubscription exportFluidSubs; @SaveField(nbtKey = "Fluid") @SyncToClient @@ -72,11 +50,18 @@ public class DrumMachine extends MetaMachine implements IAutoOutputFluid, IDropS @Getter protected final Material material; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; + public DrumMachine(BlockEntityCreationInfo info, Material material, int maxStoredFluids) { super(info); this.material = material; this.maxStoredFluids = maxStoredFluids; this.cache = createCacheFluidHandler(); + this.autoOutput = new AutoOutputTrait(this, List.of(), List.of(cache), false); + autoOutput.setFluidOutputDirection(Direction.DOWN); + autoOutput.setFluidOutputDirectionValidator(d -> d == Direction.DOWN); } ////////////////////////////////////// @@ -92,9 +77,6 @@ protected NotifiableFluidTank createCacheFluidHandler() { public void onLoad() { super.onLoad(); updateStoredFluidFromCache(); - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } this.exportFluidSubs = cache.addChangedListener(this::onFluidChanged); } @@ -102,7 +84,6 @@ private void onFluidChanged() { if (!isRemote()) { syncDataHolder.markClientSyncFieldDirty("stored"); updateStoredFluidFromCache(); - updateAutoOutputSubscription(); } } @@ -143,64 +124,6 @@ public boolean savePickClone() { return false; } - @Override - public void setAutoOutputFluids(boolean allow) { - this.autoOutputFluids = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); - updateAutoOutputSubscription(); - } - - private static boolean canInputFluidsFromOutputSide() { - return ConfigHolder.INSTANCE.machines.allowDrumsInputFluidsFromOutputSide; - } - - @Override - public boolean isAllowInputFromOutputSideFluids() { - return canInputFluidsFromOutputSide() && this.allowInputFromOutputSideFluids; - } - - // always is facing down, and can never accept fluids from output side by default - @Override - public void setAllowInputFromOutputSideFluids(boolean allow) { - this.allowInputFromOutputSideFluids = allow; - } - - @Override - public void setOutputFacingFluids(@Nullable Direction outputFacing) { - updateAutoOutputSubscription(); - } - - @Override - public @Nullable Direction getOutputFacingFluids() { - return Direction.DOWN; - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingFluids(); - if ((isAutoOutputFluids() && !cache.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentFluidHandler(getLevel(), getBlockPos(), outputFacing)) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void checkAutoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputFluids() && getOutputFacingFluids() != null) { - cache.exportToNearby(getOutputFacingFluids()); - } - updateAutoOutputSubscription(); - } - } - @Override public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { @@ -213,73 +136,14 @@ public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Play } @Override - public boolean saveBreak() { - return !stored.isEmpty(); - } - - @Override - protected InteractionResult onScrewdriverClick(Player playerIn, InteractionHand hand, Direction gridSide, + protected InteractionResult onScrewdriverClick(Player player, InteractionHand hand, Direction gridSide, BlockHitResult hitResult) { - if (!isRemote()) { - if (canInputFluidsFromOutputSide()) { - setAllowInputFromOutputSideFluids(!isAllowInputFromOutputSideFluids()); - playerIn.sendSystemMessage( - Component - .translatable("gtceu.machine.basic.input_from_output_side." + - (isAllowInputFromOutputSideFluids() ? "allow" : "disallow")) - .append(Component.translatable("gtceu.creative.tank.fluid"))); - } else if (!playerIn.isShiftKeyDown()) { - setAutoOutputFluids(!isAutoOutputFluids()); - playerIn.sendSystemMessage(Component - .translatable("gtceu.machine.drum." + (autoOutputFluids ? "enable" : "disable") + "_output")); - return InteractionResult.SUCCESS; - } - return InteractionResult.SUCCESS; - } - return super.onScrewdriverClick(playerIn, hand, gridSide, hitResult); + autoOutput.setAllowAutoOutputItems(!autoOutput.isAutoOutputItems()); + return InteractionResult.SUCCESS; } @Override - protected InteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!isRemote()) { - if (!playerIn.isShiftKeyDown()) { - setAutoOutputFluids(!isAutoOutputFluids()); - playerIn.sendSystemMessage( - Component.translatable( - "gtceu.machine.drum." + (autoOutputFluids ? "enable" : "disable") + "_output")); - return InteractionResult.SUCCESS; - } - } - return super.onSoftMalletClick(playerIn, hand, gridSide, hitResult); - } - - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - - @Override - public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, ItemStack held, - Set toolTypes) { - return super.shouldRenderGrid(player, pos, state, held, toolTypes) || - toolTypes.contains(GTToolType.SOFT_MALLET) || toolTypes.contains(GTToolType.SCREWDRIVER); - } - - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.SOFT_MALLET) || - (!canInputFluidsFromOutputSide() && toolTypes.contains(GTToolType.SCREWDRIVER))) { - if (side == getOutputFacingFluids()) { - return isAutoOutputFluids() ? GuiTextures.TOOL_DISABLE_AUTO_OUTPUT : GuiTextures.TOOL_AUTO_OUTPUT; - } - } - if (canInputFluidsFromOutputSide() && toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingFluids()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } - - return super.sideTips(player, pos, state, toolTypes, side); + public boolean saveBreak() { + return !stored.isEmpty(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java index 1c1ebcbd898..4a0279a337f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java @@ -9,15 +9,13 @@ import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IDropSaveMachine; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTraitType; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; @@ -36,9 +34,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; @@ -51,22 +46,18 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; -import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import lombok.Getter; -import lombok.Setter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNullByDefault; import org.jetbrains.annotations.Nullable; import java.util.Set; import java.util.UUID; import java.util.function.Predicate; -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public class QuantumChestMachine extends TieredMachine implements IAutoOutputItem, IInteractedMachine, IControllable, +@NotNullByDefault +public class QuantumChestMachine extends TieredMachine implements IInteractedMachine, IControllable, IDropSaveMachine, IFancyUIMachine { /** @@ -77,20 +68,6 @@ public class QuantumChestMachine extends TieredMachine implements IAutoOutputIte */ public static final Object2LongOpenHashMap INTERACTION_LOGGER = new Object2LongOpenHashMap<>(); - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected @Nullable Direction outputFacingItems; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputItems; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideItems; @SaveField private boolean isVoiding; @@ -109,15 +86,16 @@ public class QuantumChestMachine extends TieredMachine implements IAutoOutputIte @SaveField protected long storedAmount = 0; - @Nullable - protected TickableSubscription autoOutputSubs; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; public QuantumChestMachine(BlockEntityCreationInfo info, int tier, long maxAmount) { super(info, tier); - this.outputFacingItems = getFrontFacing().getOpposite(); this.maxAmount = maxAmount; this.cache = createCacheItemHandler(); this.lockedItem = new CustomItemStackHandler(); + this.autoOutput = AutoOutputTrait.ofItems(this, cache); lockedItem.setOnContentsChanged(() -> syncDataHolder.markClientSyncFieldDirty("lockedItem")); } @@ -129,19 +107,10 @@ protected ItemCache createCacheItemHandler() { return new ItemCache(this); } - @Override - public void onLoad() { - super.onLoad(); - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } - } - protected void onItemChanged() { if (!isRemote()) { syncDataHolder.markClientSyncFieldDirty("storedAmount"); syncDataHolder.markClientSyncFieldDirty("stored"); - updateAutoOutputSubscription(); } } @@ -191,66 +160,20 @@ public void loadFromItem(CompoundTag tag) { // ******* Auto Output *******// ////////////////////////////////////// - @Override - public void setAutoOutputItems(boolean allow) { - this.autoOutputItems = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputItems"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingItems(@Nullable Direction outputFacing) { - this.outputFacingItems = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingItems"); - updateAutoOutputSubscription(); - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - @Override public boolean isWorkingEnabled() { - return isAutoOutputItems(); + return autoOutput.isAutoOutputItems(); } @Override public void setWorkingEnabled(boolean isWorkingAllowed) { - setAutoOutputItems(isWorkingAllowed); - } - - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingItems(); - if ((isAutoOutputItems() && !stored.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentItemHandler(getLevel(), getBlockPos(), outputFacing)) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void checkAutoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputItems() && getOutputFacingItems() != null) { - cache.exportToNearby(getOutputFacingItems()); - } - updateAutoOutputSubscription(); - } + autoOutput.setAllowAutoOutputItems(isWorkingAllowed); } ////////////////////////////////////// // ******* Interaction *******// ////////////////////////////////////// - @Override - public boolean isFacingValid(Direction facing) { - if (facing == outputFacingItems) return false; - return super.isFacingValid(facing); - } - @Override public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { @@ -298,46 +221,6 @@ public boolean onLeftClick(Player player, Level world, InteractionHand hand, Blo return IInteractedMachine.super.onLeftClick(player, world, hand, pos, direction); } - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!playerIn.isShiftKeyDown() && !isRemote()) { - var tool = playerIn.getItemInHand(hand); - if (tool.getDamageValue() >= tool.getMaxDamage()) return InteractionResult.PASS; - if (hasFrontFacing() && gridSide == getFrontFacing()) return InteractionResult.PASS; - if (gridSide != getOutputFacingItems()) { - setOutputFacingItems(gridSide); - } else { - setOutputFacingItems(null); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } - - @Override - protected InteractionResult onScrewdriverClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!isRemote()) { - if (gridSide == getOutputFacingItems()) { - if (isAllowInputFromOutputSideItems()) { - setAllowInputFromOutputSideItems(false); - playerIn.sendSystemMessage( - Component.translatable("gtceu.machine.basic.input_from_output_side.disallow") - .append(Component.translatable("gtceu.creative.chest.item"))); - } else { - setAllowInputFromOutputSideItems(true); - playerIn.sendSystemMessage( - Component.translatable("gtceu.machine.basic.input_from_output_side.allow") - .append(Component.translatable("gtceu.creative.chest.item"))); - } - } - return InteractionResult.SUCCESS; - } - return super.onScrewdriverClick(playerIn, hand, gridSide, hitResult); - } - public boolean isLocked() { return !lockedItem.getStackInSlot(0).isEmpty(); } @@ -389,7 +272,8 @@ public Widget createUIWidget() { stack -> stored.isEmpty() || GTUtil.isSameItemSameTags(stack, stored)) .setMaxStackSize(1)) .addWidget(new ToggleButtonWidget(4, 41, 18, 18, - GuiTextures.BUTTON_ITEM_OUTPUT, this::isAutoOutputItems, this::setAutoOutputItems) + GuiTextures.BUTTON_ITEM_OUTPUT, this.autoOutput::isAutoOutputItems, + this.autoOutput::setAllowAutoOutputItems) .setShouldUseBaseBackground() .setTooltipText("gtceu.gui.item_auto_output.tooltip")) .addWidget(new ToggleButtonWidget(22, 41, 18, 18, @@ -424,17 +308,7 @@ public Widget createUIWidget() { @Override public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } else if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingItems()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } else if (toolTypes.contains(GTToolType.SOFT_MALLET)) { + if (toolTypes.contains(GTToolType.SOFT_MALLET)) { if (side == getFrontFacing()) return null; } return super.sideTips(player, pos, state, toolTypes, side); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java index 4af4e9c4a34..3f267084a31 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java @@ -7,15 +7,13 @@ import com.gregtechceu.gtceu.api.gui.widget.PhantomFluidWidget; import com.gregtechceu.gtceu.api.gui.widget.TankWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; -import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.*; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; import com.gregtechceu.gtceu.api.machine.feature.IDropSaveMachine; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTraitType; -import com.gregtechceu.gtceu.api.sync_system.annotations.RerenderOnChanged; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.api.transfer.fluid.CustomFluidTank; @@ -25,7 +23,6 @@ import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.lowdragmc.lowdraglib.gui.editor.ColorPattern; -import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.ImageWidget; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; import com.lowdragmc.lowdraglib.gui.widget.Widget; @@ -34,14 +31,10 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraftforge.fluids.FluidStack; @@ -49,40 +42,21 @@ import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; -import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.objects.Object2LongArrayMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; import lombok.Getter; -import lombok.Setter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNullByDefault; import org.jetbrains.annotations.Nullable; -import java.util.Set; import java.util.function.Predicate; -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public class QuantumTankMachine extends TieredMachine implements IAutoOutputFluid, IInteractedMachine, IControllable, +@NotNullByDefault +public class QuantumTankMachine extends TieredMachine implements IInteractedMachine, IControllable, IDropSaveMachine, IFancyUIMachine { public static Object2LongMap TANK_CAPACITY = new Object2LongArrayMap<>(); - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected @Nullable Direction outputFacingFluids; - @Getter - @SaveField - @SyncToClient - @RerenderOnChanged - protected boolean autoOutputFluids; - @Getter - @Setter - @SaveField - protected boolean allowInputFromOutputSideFluids; @SaveField private boolean isVoiding; @@ -102,15 +76,16 @@ public class QuantumTankMachine extends TieredMachine implements IAutoOutputFlui @SaveField protected long storedAmount = 0; - @Nullable - protected TickableSubscription autoOutputSubs; + @SaveField + @SyncToClient + public final AutoOutputTrait autoOutput; public QuantumTankMachine(BlockEntityCreationInfo info, int tier, long maxAmount) { super(info, tier); - this.outputFacingFluids = getFrontFacing().getOpposite(); this.maxAmount = maxAmount; this.cache = createCacheFluidHandler(); this.lockedFluid = new CustomFluidTank(1000); + this.autoOutput = AutoOutputTrait.ofFluids(this, cache); } ////////////////////////////////////// @@ -124,16 +99,12 @@ protected FluidCache createCacheFluidHandler() { @Override public void onLoad() { super.onLoad(); - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription)); - } } protected void onFluidChanged() { if (!isRemote()) { syncDataHolder.markClientSyncFieldDirty("storedAmount"); syncDataHolder.markClientSyncFieldDirty("stored"); - updateAutoOutputSubscription(); } } @@ -167,70 +138,20 @@ public boolean saveBreak() { return super.getFluidHandlerCap(side, useCoverCapability); } - ////////////////////////////////////// - // ******* Auto Output *******// - ////////////////////////////////////// - - @Override - public void setAutoOutputFluids(boolean allow) { - this.autoOutputFluids = allow; - syncDataHolder.markClientSyncFieldDirty("autoOutputFluids"); - updateAutoOutputSubscription(); - } - - @Override - public void setOutputFacingFluids(@Nullable Direction outputFacing) { - this.outputFacingFluids = outputFacing; - syncDataHolder.markClientSyncFieldDirty("outputFacingFluids"); - updateAutoOutputSubscription(); - } - @Override public boolean isWorkingEnabled() { - return isAutoOutputFluids(); + return autoOutput.isAutoOutputFluids(); } @Override public void setWorkingEnabled(boolean isWorkingAllowed) { - setAutoOutputFluids(isWorkingAllowed); - } - - @Override - public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { - super.onNeighborChanged(block, fromPos, isMoving); - updateAutoOutputSubscription(); - } - - protected void updateAutoOutputSubscription() { - var outputFacing = getOutputFacingFluids(); - if ((isAutoOutputFluids() && !stored.isEmpty()) && outputFacing != null && - GTTransferUtils.hasAdjacentFluidHandler(getLevel(), getBlockPos(), outputFacing)) { - autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); - } else if (autoOutputSubs != null) { - autoOutputSubs.unsubscribe(); - autoOutputSubs = null; - } - } - - protected void checkAutoOutput() { - if (getOffsetTimer() % 5 == 0) { - if (isAutoOutputFluids() && getOutputFacingFluids() != null) { - cache.exportToNearby(getOutputFacingFluids()); - } - updateAutoOutputSubscription(); - } + autoOutput.setAllowAutoOutputFluids(isWorkingAllowed); } ////////////////////////////////////// // ******* Interaction *******// ////////////////////////////////////// - @Override - public boolean isFacingValid(Direction facing) { - if (facing == outputFacingFluids) return false; - return super.isFacingValid(facing); - } - @Override public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { @@ -242,46 +163,6 @@ public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Play return IInteractedMachine.super.onUse(state, world, pos, player, hand, hit); } - @Override - protected InteractionResult onWrenchClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!playerIn.isShiftKeyDown() && !isRemote()) { - var tool = playerIn.getItemInHand(hand); - if (tool.getDamageValue() >= tool.getMaxDamage()) return InteractionResult.PASS; - if (hasFrontFacing() && gridSide == getFrontFacing()) return InteractionResult.PASS; - if (gridSide != getOutputFacingFluids()) { - setOutputFacingFluids(gridSide); - } else { - setOutputFacingFluids(null); - } - return InteractionResult.sidedSuccess(playerIn.level().isClientSide); - } - - return super.onWrenchClick(playerIn, hand, gridSide, hitResult); - } - - @Override - protected InteractionResult onScrewdriverClick(Player playerIn, InteractionHand hand, Direction gridSide, - BlockHitResult hitResult) { - if (!isRemote()) { - if (gridSide == getOutputFacingFluids()) { - if (isAllowInputFromOutputSideFluids()) { - setAllowInputFromOutputSideFluids(false); - playerIn.sendSystemMessage( - Component.translatable("gtceu.machine.basic.input_from_output_side.disallow") - .append(Component.translatable("gtceu.creative.tank.fluid"))); - } else { - setAllowInputFromOutputSideFluids(true); - playerIn.sendSystemMessage( - Component.translatable("gtceu.machine.basic.input_from_output_side.allow") - .append(Component.translatable("gtceu.creative.tank.fluid"))); - } - } - return InteractionResult.SUCCESS; - } - return super.onScrewdriverClick(playerIn, hand, gridSide, hitResult); - } - public boolean isLocked() { return !lockedFluid.isEmpty(); } @@ -337,7 +218,8 @@ public Widget createUIWidget() { .setShowAmount(false) .setBackground(ColorPattern.T_GRAY.rectTexture())) .addWidget(new ToggleButtonWidget(4, 41, 18, 18, - GuiTextures.BUTTON_FLUID_OUTPUT, this::isAutoOutputFluids, this::setAutoOutputFluids) + GuiTextures.BUTTON_FLUID_OUTPUT, this.autoOutput::isAutoOutputFluids, + this.autoOutput::setAllowAutoOutputFluids) .setShouldUseBaseBackground() .setTooltipText("gtceu.gui.fluid_auto_output.tooltip")) .addWidget(new ToggleButtonWidget(22, 41, 18, 18, @@ -352,28 +234,6 @@ public Widget createUIWidget() { return group; } - ////////////////////////////////////// - // ******* Rendering ********// - ////////////////////////////////////// - @Override - public @Nullable ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, - Direction side) { - if (toolTypes.contains(GTToolType.WRENCH)) { - if (!player.isShiftKeyDown()) { - if (!hasFrontFacing() || side != getFrontFacing()) { - return GuiTextures.TOOL_IO_FACING_ROTATION; - } - } - } else if (toolTypes.contains(GTToolType.SCREWDRIVER)) { - if (side == getOutputFacingFluids()) { - return GuiTextures.TOOL_ALLOW_INPUT; - } - } else if (toolTypes.contains(GTToolType.SOFT_MALLET)) { - if (side == getFrontFacing()) return null; - } - return super.sideTips(player, pos, state, toolTypes, side); - } - protected class FluidCache extends MachineTrait implements IFluidHandler { public static final MachineTraitType TYPE = new MachineTraitType<>(FluidCache.class); diff --git a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java index 0956ffa83be..c15a4275e3f 100644 --- a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java @@ -581,10 +581,6 @@ public static class MachineConfigs { }) public int steamMultiParallelAmount = 8; - @Configurable - @Configurable.Comment("Whether the Drums can input fluids from the output side (bottom).") - public boolean allowDrumsInputFluidsFromOutputSide = false; - @Configurable @Configurable.Comment("Small Steam Boiler Options") public SmallBoilers smallBoilers = new SmallBoilers(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index eef0e3b0589..46c6131fd6d 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -41,8 +41,6 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -159,17 +157,15 @@ public MEPatternBufferPartMachine(BlockEntityCreationInfo info) { @Override public void onLoad() { super.onLoad(); - if (getLevel() instanceof ServerLevel serverLevel) { - serverLevel.getServer().tell(new TickTask(1, () -> { - for (int i = 0; i < patternInventory.getSlots(); i++) { - var pattern = patternInventory.getStackInSlot(i); - var patternDetails = PatternDetailsHelper.decodePattern(pattern, getLevel()); - if (patternDetails != null) { - this.detailsSlotMap.put(patternDetails, this.internalInventory[i]); - } + if (!isRemote()) { + for (int i = 0; i < patternInventory.getSlots(); i++) { + var pattern = patternInventory.getStackInSlot(i); + var patternDetails = PatternDetailsHelper.decodePattern(pattern, getLevel()); + if (patternDetails != null) { + this.detailsSlotMap.put(patternDetails, this.internalInventory[i]); } - needPatternSync = true; - })); + } + needPatternSync = true; } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java index 563a6738e1a..ebbc916d1fb 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java @@ -17,8 +17,6 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.nbt.Tag; -import net.minecraft.server.TickTask; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; @@ -56,9 +54,7 @@ public MEPatternBufferProxyPartMachine(BlockEntityCreationInfo info) { @Override public void onLoad() { super.onLoad(); - if (getLevel() instanceof ServerLevel level) { - level.getServer().tell(new TickTask(0, () -> this.setBuffer(bufferPos))); - } + if (!isRemote()) this.setBuffer(bufferPos); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/AutoOutputBlockProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/AutoOutputBlockProvider.java index 9704b4ab201..275d4d8a3e8 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/AutoOutputBlockProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/AutoOutputBlockProvider.java @@ -1,9 +1,7 @@ package com.gregtechceu.gtceu.integration.jade.provider; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; -import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.api.machine.trait.AutoOutputTrait; import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; @@ -11,59 +9,50 @@ import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.entity.BlockEntity; import org.apache.commons.lang3.StringUtils; import snownee.jade.api.BlockAccessor; -import snownee.jade.api.IBlockComponentProvider; -import snownee.jade.api.IServerDataProvider; import snownee.jade.api.ITooltip; import snownee.jade.api.config.IPluginConfig; -public class AutoOutputBlockProvider implements IBlockComponentProvider, IServerDataProvider { +public class AutoOutputBlockProvider extends MachineTraitProvider { + + public AutoOutputBlockProvider() { + super(GTCEu.id("auto_output_info"), AutoOutputTrait.TYPE); + } @Override - public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { - BlockEntity be = blockAccessor.getBlockEntity(); - if (be != null) { - CompoundTag data = blockAccessor.getServerData().getCompound(getUid().toString()); - if (data.contains("autoOutputItem", Tag.TAG_COMPOUND)) { - var tag = data.getCompound("autoOutputItem"); - addAutoOutputInfo(iTooltip, blockAccessor, tag, "gtceu.top.item_auto_output"); - } + protected void addTooltip(CompoundTag data, ITooltip tooltip, Player player, BlockAccessor block, + BlockEntity blockEntity, IPluginConfig config) { + if (data.contains("autoOutputItem", Tag.TAG_COMPOUND)) { + var tag = data.getCompound("autoOutputItem"); + addAutoOutputInfo(tooltip, block, tag, "gtceu.top.item_auto_output"); + } - if (data.contains("autoOutputFluid", Tag.TAG_COMPOUND)) { - var tag = data.getCompound("autoOutputFluid"); - addAutoOutputInfo(iTooltip, blockAccessor, tag, "gtceu.top.fluid_auto_output"); - } + if (data.contains("autoOutputFluid", Tag.TAG_COMPOUND)) { + var tag = data.getCompound("autoOutputFluid"); + addAutoOutputInfo(tooltip, block, tag, "gtceu.top.fluid_auto_output"); } } @Override - public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) { - CompoundTag data = compoundTag.getCompound(getUid().toString()); - var level = blockAccessor.getLevel(); - var pos = blockAccessor.getPosition(); - if (MetaMachine.getMachine(level, pos) instanceof IAutoOutputItem outputItem) { - var direction = outputItem.getOutputFacingItems(); + protected void write(CompoundTag data, BlockAccessor blockAccessor, AutoOutputTrait trait) { + if (trait.supportsAutoOutputItems()) { + var direction = trait.getItemOutputDirection(); if (direction != null) { data.put("autoOutputItem", writeData(new CompoundTag(), direction, blockAccessor, - outputItem.isAllowInputFromOutputSideItems(), outputItem.isAutoOutputItems())); + trait.allowsItemInputFromOutputSide(), trait.isAutoOutputItems())); } } - if (MetaMachine.getMachine(level, pos) instanceof IAutoOutputFluid outputFluid) { - var direction = outputFluid.getOutputFacingFluids(); + if (trait.supportsAutoOutputFluids()) { + var direction = trait.getFluidOutputDirection(); if (direction != null) { data.put("autoOutputFluid", writeData(new CompoundTag(), direction, blockAccessor, - outputFluid.isAllowInputFromOutputSideFluids(), outputFluid.isAutoOutputFluids())); + trait.allowsFluidInputFromOutputSide(), trait.isAutoOutputFluids())); } } - compoundTag.put(getUid().toString(), data); - } - - @Override - public ResourceLocation getUid() { - return GTCEu.id("auto_output_info"); } private CompoundTag writeData(CompoundTag compoundTag, Direction direction, BlockAccessor blockAccessor, diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MachineTraitProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MachineTraitProvider.java index 1ed9d65afc0..3d7c2edeeec 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MachineTraitProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MachineTraitProvider.java @@ -45,11 +45,11 @@ public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccesso var be = blockAccessor.getBlockEntity(); if (be instanceof MetaMachine machine) { T t = machine.getTraitHolder().getTrait(traitType); - if (t != null) write(compoundTag.getCompound(uid.toString()), t); + if (t != null) write(compoundTag.getCompound(uid.toString()), blockAccessor, t); } } - protected abstract void write(CompoundTag data, T trait); + protected abstract void write(CompoundTag data, BlockAccessor blockAccessor, T trait); protected abstract void addTooltip(CompoundTag data, ITooltip tooltip, Player player, BlockAccessor block, BlockEntity blockEntity, IPluginConfig config); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java index e39657b0d4b..5fd25ad6761 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java @@ -32,7 +32,7 @@ public RecipeLogicProvider() { } @Override - protected void write(CompoundTag data, RecipeLogic capability) { + protected void write(CompoundTag data, BlockAccessor blockAccessor, RecipeLogic capability) { data.putBoolean("Working", capability.isWorking()); var recipeInfo = new CompoundTag(); var recipe = capability.getLastRecipe(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java index 3d6baeada20..193e5d5f8ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java @@ -50,7 +50,7 @@ public RecipeOutputProvider() { } @Override - protected void write(CompoundTag data, RecipeLogic recipeLogic) { + protected void write(CompoundTag data, BlockAccessor blockAccessor, RecipeLogic recipeLogic) { if (recipeLogic.isWorking()) { data.putBoolean("Working", recipeLogic.isWorking()); var recipe = recipeLogic.getLastRecipe(); diff --git a/src/main/java/com/gregtechceu/gtceu/utils/data/TagCompatibilityFixer.java b/src/main/java/com/gregtechceu/gtceu/utils/data/TagCompatibilityFixer.java new file mode 100644 index 00000000000..f6ee9efc56f --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/utils/data/TagCompatibilityFixer.java @@ -0,0 +1,41 @@ +package com.gregtechceu.gtceu.utils.data; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TagCompatibilityFixer { + + public static void fixMachineAutoOutputTag(CompoundTag machineTag) { + if (!machineTag.contains("autoOutput")) { + var outputTag = new CompoundTag(); + Tag itemOutputDirection = machineTag.get("outputFacingItems"); + Tag fluidOutputDirection = machineTag.get("outputFacingFluids"); + Tag autoOutputItems = machineTag.get("autoOutputItems"); + Tag autoOutputFluids = machineTag.get("autoOutputFluids"); + Tag allowInputItems = machineTag.get("allowInputFromOutputSideItems"); + Tag allowInputFluids = machineTag.get("allowInputFromOutputSideFluids"); + if (itemOutputDirection != null) outputTag.put("itemOutputDirection", itemOutputDirection); + if (fluidOutputDirection != null) outputTag.put("fluidOutputDirection", fluidOutputDirection); + if (autoOutputItems != null) outputTag.put("autoOutputItems", autoOutputItems); + if (autoOutputFluids != null) outputTag.put("autoOutputFluids", autoOutputFluids); + if (allowInputItems != null) outputTag.put("allowItemInputFromOutputSide", allowInputItems); + if (allowInputFluids != null) outputTag.put("allowFluidInputFromOutputSide", allowInputFluids); + machineTag.put("autoOutput", outputTag); + } + } + + public static Tag stripLDLibPayloadWrapper(Tag t) { + if (!(t instanceof CompoundTag tag)) return t; + if (tag.contains("p") && tag.contains("t")) { + return tag.getCompound("p"); + } + if (tag.contains("t", Tag.TAG_COMPOUND)) { + return tag.getCompound("t").getCompound("p"); + } + return tag; + } +}