From 457afca8a2a124fafda9dc7d0d0e905fe5c0536e Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Sun, 1 Sep 2024 19:40:24 +0200 Subject: [PATCH 1/5] feat: crafting preview screen --- .../api/autocrafting/CraftingPreview.java | 6 + .../common/api/RefinedStorageApi.java | 4 + .../common/api/RefinedStorageApiProxy.java | 7 + .../common/RefinedStorageApiImpl.java | 17 ++ .../AlternativeContainerMenu.java | 2 +- .../autocrafting/AlternativesScreen.java | 3 +- ...CraftingPatternClientTooltipComponent.java | 2 +- ...ocessingPatternClientTooltipComponent.java | 2 +- ...ingTablePatternClientTooltipComponent.java | 2 +- ...necutterPatternClientTooltipComponent.java | 2 +- .../autocrafting/preview/CraftingPreview.java | 6 + .../preview/CraftingPreviewContainerMenu.java | 45 +++ .../preview/CraftingPreviewItem.java | 6 + .../preview/CraftingPreviewScreen.java | 260 ++++++++++++++++++ .../autocrafting/preview/package-info.java | 7 + .../grid/screen/AbstractGridScreen.java | 15 +- .../grid/screen/GridSearchBoxWidget.java | 5 +- .../common/grid/view/FluidGridResource.java | 3 + .../common/grid/view/ItemGridResource.java | 2 +- .../common/support/ResourceSlotRendering.java | 2 +- .../support/amount/AbstractAmountScreen.java | 61 ++-- .../amount/AbstractSingleAmountScreen.java | 3 +- .../amount/AmountScreenConfiguration.java | 22 ++ .../common/support/amount/PriorityScreen.java | 3 +- .../support/amount/ResourceAmountScreen.java | 3 +- .../ResourceClientTooltipComponent.java | 5 +- .../common/support/tooltip/SmallText.java | 15 + ...radeDestinationClientTooltipComponent.java | 2 +- .../UpgradeItemClientTooltipComponent.java | 5 +- .../assets/refinedstorage/lang/en_us.json | 5 + .../textures/gui/crafting_preview.png | Bin 0 -> 662 bytes .../gui/sprites/crafting_preview/row.png | Bin 0 -> 171 bytes 32 files changed, 465 insertions(+), 57 deletions(-) create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/package-info.java create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/row.png diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java new file mode 100644 index 000000000..280f1377a --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java @@ -0,0 +1,6 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.list.ResourceList; + +public record CraftingPreview(ResourceList missing, ResourceList toTake, ResourceList toCraft) { +} diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java index a96e5fb72..d43da64b9 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java @@ -7,6 +7,7 @@ import com.refinedmods.refinedstorage.api.network.energy.EnergyStorage; import com.refinedmods.refinedstorage.api.network.node.NetworkNode; import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.constructordestructor.ConstructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.constructordestructor.DestructorStrategyFactory; @@ -46,6 +47,7 @@ import com.refinedmods.refinedstorage.common.api.wirelesstransmitter.WirelessTransmitterRangeModifier; import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; @@ -203,4 +205,6 @@ EnergyStorage asBlockItemEnergyStorage( boolean canPlaceNetworkNode(ServerPlayer player, Level level, BlockPos pos, BlockState state); Optional getPattern(ItemStack stack, Level level); + + void openCraftingPreview(List resources); } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java index 24c147598..c68bf1cd8 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java @@ -7,6 +7,7 @@ import com.refinedmods.refinedstorage.api.network.energy.EnergyStorage; import com.refinedmods.refinedstorage.api.network.node.NetworkNode; import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.constructordestructor.ConstructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.constructordestructor.DestructorStrategyFactory; @@ -46,6 +47,7 @@ import com.refinedmods.refinedstorage.common.api.wirelesstransmitter.WirelessTransmitterRangeModifier; import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; @@ -401,6 +403,11 @@ public Optional getPattern(final ItemStack stack, final Level level) { return ensureLoaded().getPattern(stack, level); } + @Override + public void openCraftingPreview(final List resources) { + ensureLoaded().openCraftingPreview(resources); + } + private RefinedStorageApi ensureLoaded() { if (delegate == null) { throw new IllegalStateException("API not loaded yet"); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index 41ccefd5e..83abe2af5 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -10,6 +10,7 @@ import com.refinedmods.refinedstorage.api.network.impl.NetworkFactory; import com.refinedmods.refinedstorage.api.network.node.NetworkNode; import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; @@ -49,6 +50,7 @@ import com.refinedmods.refinedstorage.common.api.support.slotreference.SlotReferenceProvider; import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeRegistry; import com.refinedmods.refinedstorage.common.api.wirelesstransmitter.WirelessTransmitterRangeModifier; +import com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen; import com.refinedmods.refinedstorage.common.grid.NoopGridSynchronizer; import com.refinedmods.refinedstorage.common.grid.screen.hint.GridInsertionHintsImpl; import com.refinedmods.refinedstorage.common.grid.screen.hint.ItemGridInsertionHint; @@ -99,12 +101,14 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.Item; @@ -595,4 +599,17 @@ public Optional getPattern(final ItemStack stack, final Level level) { i -> providerItem.getPattern(stack, level).orElse(null) )); } + + @Override + public void openCraftingPreview(final List resources) { + if (resources.isEmpty()) { + return; + } + final Minecraft minecraft = Minecraft.getInstance(); + if (minecraft.screen == null || minecraft.player == null) { + return; + } + final Inventory inventory = minecraft.player.getInventory(); + minecraft.setScreen(new CraftingPreviewScreen(minecraft.screen, inventory, resources.getFirst().resource())); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativeContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativeContainerMenu.java index 9af4991ba..b17189322 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativeContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativeContainerMenu.java @@ -22,7 +22,7 @@ import static com.refinedmods.refinedstorage.common.autocrafting.AlternativesScreen.ALTERNATIVE_ROW_HEIGHT; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.getTagTranslationKey; -public class AlternativeContainerMenu extends AbstractResourceContainerMenu { +class AlternativeContainerMenu extends AbstractResourceContainerMenu { private final List alternatives; private final ResourceSlot amountSlot; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativesScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativesScreen.java index e23aa3dcc..743e92a7d 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativesScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/AlternativesScreen.java @@ -493,7 +493,7 @@ protected ResourceLocation getTexture() { } @Override - protected void accept(final Double amount) { + protected boolean confirm(final Double amount) { slot.changeAmountOnClient(amount); final Set allowedAlternatives = new HashSet<>(); for (int i = 0; i < alternativeCheckboxes.size(); ++i) { @@ -502,6 +502,7 @@ protected void accept(final Double amount) { } } getMenu().sendAllowedAlternatives(allowedAlternatives); + return true; } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java index 9987552f7..f874917b5 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java @@ -78,7 +78,7 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap cycleStart = now; } if (outputText != null) { - graphics.drawString(font, outputText, x, y, requireNonNullElse(ChatFormatting.GRAY.getColor(), 15)); + graphics.drawString(font, outputText, x, y, 0xAAAAAA); } renderInputSlots(x, y + 9 + 2, graphics); renderArrow(x, y + 9 + 2, graphics); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java index 742cefdf6..e0309dec5 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java @@ -162,7 +162,7 @@ private void renderOutputText(final Font font, final int x, final int y, final G outputTexts.get(i), x, y + (i * 9), - requireNonNullElse(ChatFormatting.GRAY.getColor(), 15) + 0xAAAAAA ); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java index e9c4bc3cc..86fc09c17 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java @@ -29,7 +29,7 @@ class SmithingTablePatternClientTooltipComponent implements ClientTooltipCompone @Override public void renderImage(final Font font, final int x, final int y, final GuiGraphics graphics) { - graphics.drawString(font, outputText, x, y, requireNonNullElse(ChatFormatting.GRAY.getColor(), 15)); + graphics.drawString(font, outputText, x, y, 0xAAAAAA); final int slotsY = y + 9 + 2; graphics.blitSprite(Sprites.SLOT, x, slotsY, 18, 18); final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(ItemResource.class); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java index b749148dd..ddf5d2e39 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java @@ -32,7 +32,7 @@ class StonecutterPatternClientTooltipComponent implements ClientTooltipComponent @Override public void renderImage(final Font font, final int x, final int y, final GuiGraphics graphics) { - graphics.drawString(font, outputText, x, y, requireNonNullElse(ChatFormatting.GRAY.getColor(), 15)); + graphics.drawString(font, outputText, x, y, 0xAAAAAA); graphics.blitSprite(SLOT, x, y + 9 + 2, 18, 18); final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(ItemResource.class); rendering.render(input, graphics, x + 1, y + 9 + 2 + 1); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java new file mode 100644 index 000000000..bbb5a4794 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java @@ -0,0 +1,6 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import java.util.List; + +record CraftingPreview(boolean missing, List items) { +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java new file mode 100644 index 000000000..aca99a72c --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java @@ -0,0 +1,45 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; +import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; +import com.refinedmods.refinedstorage.common.support.containermenu.DisabledResourceSlot; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +import net.minecraft.network.chat.Component; + +class CraftingPreviewContainerMenu extends AbstractResourceContainerMenu { + @Nullable + private CraftingPreview preview; + + CraftingPreviewContainerMenu(final ResourceKey resource) { + super(null, 0); + final ResourceContainer resourceContainer = ResourceContainerImpl.createForFilter(1); + resourceContainer.set(0, new ResourceAmount(resource, 1)); + addSlot(new DisabledResourceSlot( + resourceContainer, + 0, + Component.empty(), + 157, + 48, + ResourceSlotType.FILTER + )); + + final List items = new ArrayList<>(); + for (int i = 0; i < 31; ++i) { + items.add(new CraftingPreviewItem(resource, i, i % 2 == 0 ? 999 : 0, i % 2 == 0 ? 0 : 1000)); + } + preview = new CraftingPreview(true, items); + } + + @Nullable + public CraftingPreview getPreview() { + return preview; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java new file mode 100644 index 000000000..84ec43f5b --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java @@ -0,0 +1,6 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +record CraftingPreviewItem(ResourceKey resource, long available, long missing, long toCraft) { +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java new file mode 100644 index 000000000..d592a0feb --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java @@ -0,0 +1,260 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; +import com.refinedmods.refinedstorage.common.support.amount.AbstractAmountScreen; +import com.refinedmods.refinedstorage.common.support.amount.AmountScreenConfiguration; +import com.refinedmods.refinedstorage.common.support.amount.DoubleAmountOperations; +import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; +import com.refinedmods.refinedstorage.common.support.widget.ScrollbarWidget; + +import java.util.List; +import javax.annotation.Nullable; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import org.joml.Vector3f; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; + +public class CraftingPreviewScreen extends AbstractAmountScreen { + private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/crafting_preview.png"); + private static final MutableComponent TITLE = Component.translatable("container.crafting"); + private static final MutableComponent START = createTranslation("gui", "crafting_preview.start"); + private static final MutableComponent MISSING_RESOURCES + = createTranslation("gui", "crafting_preview.start.missing_resources"); + private static final ResourceLocation ROW = createIdentifier("crafting_preview/row"); + + private static final int ROWS_VISIBLE = 4; + private static final int COLUMNS = 3; + private static final int PREVIEW_AREA_HEIGHT = 119; + + private static final int ROW_HEIGHT = 30; + private static final int ROW_WIDTH = 221; + + @Nullable + private ScrollbarWidget scrollbar; + + public CraftingPreviewScreen(final Screen parent, final Inventory playerInventory, final ResourceKey resource) { + super( + new CraftingPreviewContainerMenu(resource), + parent, + playerInventory, + TITLE, + AmountScreenConfiguration.AmountScreenConfigurationBuilder.create() + .withInitialAmount(1D) + .withIncrementsTop(1, 10, 64) + .withIncrementsTopStartPosition(new Vector3f(80, 20, 0)) + .withIncrementsBottom(-1, -10, -64) + .withIncrementsBottomStartPosition(new Vector3f(80, 71, 0)) + .withAmountFieldPosition(new Vector3f(77, 51, 0)) + .withActionButtonsStartPosition(new Vector3f(7, 222, 0)) + .withHorizontalActionButtons(true) + .withMinAmount(1D) + .withResetAmount(1D) + .withConfirmButtonText(START) + .build(), + DoubleAmountOperations.INSTANCE + ); + this.imageWidth = 254; + this.imageHeight = 249; + } + + @Override + protected void init() { + super.init(); + scrollbar = new ScrollbarWidget( + leftPos + 235, + topPos + 98, + ScrollbarWidget.Type.NORMAL, + PREVIEW_AREA_HEIGHT + ); + scrollbar.setEnabled(false); + if (confirmButton != null) { + confirmButton.active = false; + } + updatePreview(); + } + + private void updatePreview() { + if (scrollbar == null || confirmButton == null) { + return; + } + final CraftingPreview preview = getMenu().getPreview(); + if (preview == null) { + scrollbar.setEnabled(false); + scrollbar.setMaxOffset(0); + confirmButton.active = false; + return; + } + final int items = getMenu().getPreview().items().size(); + final int rows = Math.ceilDiv(items, COLUMNS) - ROWS_VISIBLE; + scrollbar.setMaxOffset(scrollbar.isSmoothScrolling() ? rows * ROW_HEIGHT : rows); + scrollbar.setEnabled(rows > 0); + confirmButton.active = !preview.missing(); + confirmButton.setTooltip(preview.missing() ? Tooltip.create(MISSING_RESOURCES) : null); + } + + @Override + public void render(final GuiGraphics graphics, final int mouseX, final int mouseY, final float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + if (scrollbar != null) { + scrollbar.render(graphics, mouseX, mouseY, partialTicks); + } + } + + @Override + protected void renderBg(final GuiGraphics graphics, final float delta, final int mouseX, final int mouseY) { + super.renderBg(graphics, delta, mouseX, mouseY); + final CraftingPreview preview = getMenu().getPreview(); + if (preview == null || scrollbar == null) { + return; + } + final int x = leftPos + 8; + final int y = topPos + 98; + graphics.enableScissor(x, y, x + 221, y + PREVIEW_AREA_HEIGHT); + final List items = getMenu().getPreview().items(); + final int rows = Math.ceilDiv(items.size(), COLUMNS); + for (int i = 0; i < rows; ++i) { + final int scrollOffset = scrollbar.isSmoothScrolling() + ? (int) scrollbar.getOffset() + : (int) scrollbar.getOffset() * ROW_HEIGHT; + final int yy = y + (i * ROW_HEIGHT) - scrollOffset; + renderRow(graphics, x, yy, i, items, mouseX, mouseY); + } + graphics.disableScissor(); + } + + private void renderRow(final GuiGraphics graphics, + final int x, + final int y, + final int i, + final List items, + final double mouseX, + final double mouseY) { + if (y <= topPos + 98 - ROW_HEIGHT || y > topPos + 98 + PREVIEW_AREA_HEIGHT) { + return; + } + graphics.blitSprite(ROW, x, y, ROW_WIDTH, ROW_HEIGHT); + for (int column = i * COLUMNS; column < Math.min(i * COLUMNS + COLUMNS, items.size()); ++column) { + final CraftingPreviewItem item = items.get(column); + final int xx = x + (column % COLUMNS) * 74; + renderCell(graphics, xx, y, item, mouseX, mouseY); + } + } + + private void renderCell(final GuiGraphics graphics, + final int x, + final int y, + final CraftingPreviewItem item, + final double mouseX, + final double mouseY) { + if (item.missing() > 0) { + graphics.fill(x, y, x + 73, y + 29, 0xFFF2DEDE); + } + int xx = x + 2; + final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(item.resource().getClass()); + int yy = y + 7; + rendering.render(item.resource(), graphics, xx, yy); + if (isHovering(xx - leftPos, yy - topPos, 16, 16, mouseX, mouseY) + && isHoveringOverPreviewArea(mouseX, mouseY)) { + setTooltipForNextRenderPass(rendering.getTooltip(item.resource()).stream() + .map(Component::getVisualOrderText) + .toList()); + } + if (!SmallText.isSmall()) { + yy -= 2; + } + xx += 16 + 3; + if (item.missing() > 0) { + renderCellText(graphics, "missing", rendering, xx, yy, item.missing()); + yy += 7; + } + if (item.available() > 0) { + renderCellText(graphics, "available", rendering, xx, yy, item.available()); + yy += 7; + } + if (item.toCraft() > 0) { + renderCellText(graphics, "to_craft", rendering, xx, yy, item.toCraft()); + } + } + + private void renderCellText(final GuiGraphics graphics, + final String type, + final ResourceRendering rendering, + final int x, + final int y, + final long amount) { + SmallText.render( + graphics, + font, + createTranslation("gui", "crafting_preview." + type, rendering.formatAmount(amount, true)) + .getVisualOrderText(), + x, + y, + 0x404040, + false + ); + } + + @Override + public boolean mouseClicked(final double mouseX, final double mouseY, final int clickedButton) { + if (scrollbar != null && scrollbar.mouseClicked(mouseX, mouseY, clickedButton)) { + return true; + } + return super.mouseClicked(mouseX, mouseY, clickedButton); + } + + @Override + public void mouseMoved(final double mx, final double my) { + if (scrollbar != null) { + scrollbar.mouseMoved(mx, my); + } + super.mouseMoved(mx, my); + } + + @Override + public boolean mouseReleased(final double mx, final double my, final int button) { + return (scrollbar != null && scrollbar.mouseReleased(mx, my, button)) + || super.mouseReleased(mx, my, button); + } + + @Override + public boolean mouseScrolled(final double x, final double y, final double z, final double delta) { + final boolean didScrollbar = scrollbar != null + && isHoveringOverPreviewArea(x, y) + && scrollbar.mouseScrolled(x, y, z, delta); + return didScrollbar || super.mouseScrolled(x, y, z, delta); + } + + private boolean isHoveringOverPreviewArea(final double x, final double y) { + return isHovering(7, 97, 241, 121, x, y); + } + + @Override + protected ResourceLocation getTexture() { + return TEXTURE; + } + + @Override + protected void onAmountFieldChanged() { + if (amountField == null || confirmButton == null) { + return; + } + confirmButton.active = false; + final boolean valid = getAndValidateAmount().isPresent(); + amountField.setTextColor(valid ? 0xFFFFFF : 0xFF5555); + } + + @Override + protected boolean confirm(final Double amount) { + return false; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/package-info.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/package-info.java new file mode 100644 index 000000000..b10fddc11 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 89ba11179..7877e55a2 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -4,6 +4,7 @@ import com.refinedmods.refinedstorage.api.grid.operations.GridInsertMode; import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.storage.tracked.TrackedResource; import com.refinedmods.refinedstorage.common.Platform; @@ -493,9 +494,17 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int final ItemStack carriedStack = getMenu().getCarried(); final PlatformGridResource resource = getCurrentGridResource(); - if (resource != null && resource.canExtract(carriedStack, getMenu().getView())) { - mouseClickedInGrid(clickedButton, resource); - return true; + if (resource != null) { + if (resource.canExtract(carriedStack, getMenu().getView()) && !hasControlDown()) { + mouseClickedInGrid(clickedButton, resource); + return true; + } else if (resource.isCraftable()) { + RefinedStorageApi.INSTANCE.openCraftingPreview(List.of(new ResourceAmount( + resource.getResourceForRecipeMods(), + 1 + ))); + return true; + } } if (isOverStorageArea((int) mouseX, (int) mouseY) diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java index 94f5ac1ac..ea0928725 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java @@ -85,9 +85,6 @@ public void addListener(final Consumer listener) { @Override public void setValid(final boolean valid) { this.valid = valid; - setTextColor(valid - ? Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15) - : Objects.requireNonNullElse(ChatFormatting.RED.getColor(), 15) - ); + setTextColor(valid ? 0xFFFFFF : 0xFF5555); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java index 0ffecdb6e..77834ef9a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java @@ -70,6 +70,9 @@ private Optional tryFillFluidContainer(final ItemStack car @Override public boolean canExtract(final ItemStack carriedStack, final GridView view) { + if (getAmount(view) == 0) { + return false; + } if (carriedStack.isEmpty()) { return true; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java index 0bc1a01d1..02d11ab59 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java @@ -80,7 +80,7 @@ public List getExtractionHints(final ItemStack carriedSt @Override public boolean canExtract(final ItemStack carriedStack, final GridView view) { - return carriedStack.isEmpty(); + return getAmount(view) > 0 && carriedStack.isEmpty(); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java index 4cd868c58..c0d29a830 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java @@ -58,7 +58,7 @@ public static void renderAmount(final GuiGraphics graphics, x, y, rendering.formatAmount(amount, true), - requireNonNullElse(ChatFormatting.WHITE.getColor(), 15), + 0xFFFFFF, true ); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java index e6a0e0a26..ae47bd290 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java @@ -3,11 +3,9 @@ import com.refinedmods.refinedstorage.common.autocrafting.AlternativesScreen; import com.refinedmods.refinedstorage.common.support.AbstractBaseScreen; -import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; -import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; @@ -26,7 +24,6 @@ public abstract class AbstractAmountScreen extends AbstractBaseScreen { - private static final MutableComponent SET_TEXT = createTranslation("gui", "configure_amount.set"); private static final MutableComponent RESET_TEXT = createTranslation("gui", "configure_amount.reset"); private static final MutableComponent CANCEL_TEXT = Component.translatable("gui.cancel"); @@ -34,16 +31,16 @@ public abstract class AbstractAmountScreen configuration; private final AmountOperations amountOperations; - @Nullable - private EditBox amountField; - @Nullable - private Button confirmButton; - protected AbstractAmountScreen(final T containerMenu, @Nullable final Screen parent, final Inventory playerInventory, @@ -89,10 +86,11 @@ private void addResetButton(final int x, final int y) { } private void addConfirmButton(final int x, final int y) { - confirmButton = addRenderableWidget(Button.builder(SET_TEXT, btn -> tryConfirmAndCloseToParent()) - .pos(leftPos + x, topPos + y) - .size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT) - .build()); + confirmButton = addRenderableWidget( + Button.builder(configuration.getConfirmButtonText(), btn -> tryConfirmAndCloseToParent()) + .pos(leftPos + x, topPos + y) + .size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT) + .build()); } private void addCancelButton(final int x, final int y) { @@ -119,24 +117,26 @@ private void addAmountField() { amountField.setVisible(true); amountField.setCanLoseFocus(this instanceof AlternativesScreen); amountField.setFocused(true); - amountField.setResponder(value -> { - final boolean valid = getAndValidateAmount().isPresent(); - if (confirmButton != null) { - confirmButton.active = valid; - } else { - tryConfirm(); - } - amountField.setTextColor(valid - ? Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15) - : Objects.requireNonNullElse(ChatFormatting.RED.getColor(), 15) - ); - }); - amountField.setTextColor(Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15)); + amountField.setResponder(value -> onAmountFieldChanged()); + amountField.setTextColor(0xFFFFFF); setFocused(amountField); addRenderableWidget(amountField); } + protected void onAmountFieldChanged() { + if (amountField == null) { + return; + } + final boolean valid = getAndValidateAmount().isPresent(); + if (confirmButton != null) { + confirmButton.active = valid; + } else { + tryConfirm(); + } + amountField.setTextColor(valid ? 0xFFFFFF : 0xFF5555); + } + private void addIncrementButtons() { final Vector3f incrementsTopPos = configuration.getIncrementsTopStartPosition(); addIncrementButtons( @@ -160,7 +160,7 @@ private void addIncrementButtons(final int[] increments, final int x, final int } } - protected abstract void accept(N amount); + protected abstract boolean confirm(N amount); private Button createIncrementButton(final int x, final int y, final int increment) { final Component text = Component.literal((increment > 0 ? "+" : "") + increment); @@ -252,13 +252,14 @@ protected void reset() { } private void tryConfirm() { - getAndValidateAmount().ifPresent(this::accept); + getAndValidateAmount().ifPresent(this::confirm); } private void tryConfirmAndCloseToParent() { getAndValidateAmount().ifPresent(value -> { - accept(value); - tryCloseToParent(); + if (confirm(value)) { + tryCloseToParent(); + } }); } @@ -270,7 +271,7 @@ private boolean tryCloseToParent() { return false; } - private Optional getAndValidateAmount() { + protected final Optional getAndValidateAmount() { if (amountField == null) { return Optional.empty(); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractSingleAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractSingleAmountScreen.java index 24b0c03a4..37b707b9c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractSingleAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractSingleAmountScreen.java @@ -38,8 +38,9 @@ protected AbstractSingleAmountScreen(final T containerMenu, } @Override - protected void accept(final Double amount) { + protected boolean confirm(final Double amount) { getMenu().changeAmountOnClient(amount); + return true; } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AmountScreenConfiguration.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AmountScreenConfiguration.java index 3f24f8552..b51cfa8c4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AmountScreenConfiguration.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AmountScreenConfiguration.java @@ -2,9 +2,15 @@ import javax.annotation.Nullable; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import org.joml.Vector3f; +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; + public final class AmountScreenConfiguration { + private static final MutableComponent SET_TEXT = createTranslation("gui", "configure_amount.set"); + @Nullable private final T initialAmount; private final int[] incrementsTop; @@ -16,6 +22,7 @@ public final class AmountScreenConfiguration { private final Vector3f actionButtonsStartPosition; private final boolean horizontalActionButtons; private final boolean actionButtonsEnabled; + private final Component confirmButtonText; @Nullable private final T minAmount; @Nullable @@ -33,6 +40,7 @@ private AmountScreenConfiguration(@Nullable final T initialAmount, final Vector3f actionButtonsStartPosition, final boolean horizontalActionButtons, final boolean actionButtonsEnabled, + final Component confirmButtonText, @Nullable final T minAmount, @Nullable final T maxAmount, @Nullable final T resetAmount) { @@ -46,6 +54,7 @@ private AmountScreenConfiguration(@Nullable final T initialAmount, this.actionButtonsStartPosition = actionButtonsStartPosition; this.horizontalActionButtons = horizontalActionButtons; this.actionButtonsEnabled = actionButtonsEnabled; + this.confirmButtonText = confirmButtonText; this.minAmount = minAmount; this.maxAmount = maxAmount; this.resetAmount = resetAmount; @@ -92,6 +101,10 @@ public boolean isActionButtonsEnabled() { return actionButtonsEnabled; } + public Component getConfirmButtonText() { + return confirmButtonText; + } + @Nullable public T getMinAmount() { return minAmount; @@ -118,6 +131,7 @@ public static final class AmountScreenConfigurationBuilder { private Vector3f amountFieldPosition = new Vector3f(0, 0, 0); private Vector3f actionButtonsStartPosition = new Vector3f(0, 0, 0); private boolean horizontalActionButtons = false; + private Component confirmButtonText = SET_TEXT; private boolean actionButtonsEnabled = true; @Nullable private T minAmount; @@ -182,6 +196,13 @@ public AmountScreenConfigurationBuilder withHorizontalActionButtons( return this; } + public AmountScreenConfigurationBuilder withConfirmButtonText( + final Component newConfirmButtonText + ) { + this.confirmButtonText = newConfirmButtonText; + return this; + } + public AmountScreenConfigurationBuilder withActionButtonsEnabled( final boolean newActionButtonsEnabled ) { @@ -216,6 +237,7 @@ public AmountScreenConfiguration build() { actionButtonsStartPosition, horizontalActionButtons, actionButtonsEnabled, + confirmButtonText, minAmount, maxAmount, resetAmount diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/PriorityScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/PriorityScreen.java index bf53e52dc..2e008372c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/PriorityScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/PriorityScreen.java @@ -43,8 +43,9 @@ public PriorityScreen(final ClientProperty property, } @Override - protected void accept(final Integer amount) { + protected boolean confirm(final Integer amount) { property.setValue(amount); + return true; } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ResourceAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ResourceAmountScreen.java index 3035986b6..104e9584a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ResourceAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ResourceAmountScreen.java @@ -46,8 +46,9 @@ public ResourceAmountScreen(final Screen parent, final Inventory playerInventory } @Override - protected void accept(final Double amount) { + protected boolean confirm(final Double amount) { slot.changeAmountOnClient(amount); + return true; } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/ResourceClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/ResourceClientTooltipComponent.java index ecff0219d..526fa8153 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/ResourceClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/ResourceClientTooltipComponent.java @@ -4,9 +4,6 @@ import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; -import java.util.Objects; - -import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -44,7 +41,7 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap name, x + 16 + 4, y + 4, - Objects.requireNonNullElse(ChatFormatting.GRAY.getColor(), 11184810) + 0xAAAAAA ); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java index a4756a8c2..d84fcc952 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java @@ -2,6 +2,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.util.FormattedCharSequence; import org.joml.Matrix4f; @@ -50,4 +51,18 @@ public static void render(final Font font, 15728880 ); } + + public static void render(final GuiGraphics graphics, + final Font font, + final FormattedCharSequence text, + final int x, + final int y, + final int color, + final boolean dropShadow) { + final float scale = getScale(); + graphics.pose().pushPose(); + graphics.pose().scale(scale, scale, 1); + graphics.drawString(font, text, (int) (x / scale), (int) (y / scale) + 1, color, dropShadow); + graphics.pose().popPose(); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java index 1895b2dac..633044702 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java @@ -45,7 +45,7 @@ private void renderMapping(final Font font, mapping.destinationDisplayName().copy().withStyle(ChatFormatting.GRAY), x + 16 + 4, y + 4, - Objects.requireNonNullElse(ChatFormatting.GRAY.getColor(), 7) + 0xAAAAAA ); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeItemClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeItemClientTooltipComponent.java index 737db9d77..be000cacc 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeItemClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeItemClientTooltipComponent.java @@ -3,9 +3,6 @@ import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeMapping; -import java.util.Objects; - -import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -36,7 +33,7 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap mapping.upgradeDisplayName(), x + 16 + 4, y + 4, - Objects.requireNonNullElse(ChatFormatting.WHITE.getColor(), 15) + 0xFFFFFF ); } } diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json index f278e5e54..2009ba76d 100644 --- a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json +++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json @@ -206,6 +206,11 @@ "gui.refinedstorage.crafter.chained.head_help": "This crafter is the head of the chain.", "gui.refinedstorage.crafter.not_chained": "Not chained", "gui.refinedstorage.crafter.not_chained.help": "If another crafter is facing this one, they'll form a chain, allowing you to have more patterns going into a single machine.", + "gui.refinedstorage.crafting_preview.start": "Start", + "gui.refinedstorage.crafting_preview.start.missing_resources": "There are missing resources.", + "gui.refinedstorage.crafting_preview.available": "Available: %s", + "gui.refinedstorage.crafting_preview.to_craft": "To craft: %s", + "gui.refinedstorage.crafting_preview.missing": "Missing: %s", "item.refinedstorage.controller.help": "Provides the storage network with energy. Multiple are allowed in a single storage network.", "item.refinedstorage.creative_controller.help": "Provides the storage network with an infinite source of energy.", "item.refinedstorage.disk_drive.help": "Accepts storage disks to provide the storage network with storage space.", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..cbce82533d29b98e1e0b66f77a60a17a2afc4ed3 GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5D>38$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBzC?geh%1o(|NsB7W5+^6L(R?2ySuw@-@XkL{BrrbA&}xI3GxdDDgXh7 zd(C?zfnuBm9+AZi41AkFn9%hAr*0NZ(sB}>>$u~ajoIAzxQvvd-lF{ z+9TJdCDzZKJ+||x7Ee&}xV3HTs@%QXwnkrVb6CCm|J%jfJPrM`bWi_a(%5YeG#&;l zr*p%Y3=Zd>GQl|$ig&`;;;cVvuFh(F94nJhd$DpmSi^EAo%An1Ce?d4+2|KCkYXl zaMvA02Fgh(IR{}iys<+B0z#$2;$k)kFXg)+LKwl4oNEl^{9)a2Z`r%bqxTs^q3!_+ zA_XOqPZ#JN5Nfy4uo@ZMpX^=|B8- S-SNn{1`*#dk*TyNjL-PqXJW#{(;D8gCb5n0T@z;_sg8IR|$NC67!dAc};cpQIw z){vKhf#ZNd0mHwuNsY|~rQatVTV^x6>G Date: Thu, 5 Sep 2024 19:12:06 +0200 Subject: [PATCH 2/5] feat: crafting requests on the side of the preview --- CHANGELOG.md | 3 + .../api/autocrafting/CraftingPreview.java | 6 - .../common/api/RefinedStorageApi.java | 2 +- .../common/api/RefinedStorageApiProxy.java | 4 +- .../api/grid/view/PlatformGridResource.java | 4 + .../common/RefinedStorageApiImpl.java | 11 +- .../autocrafting/CrafterBlockEntity.java | 1 + ...CraftingPatternClientTooltipComponent.java | 1 - ...ocessingPatternClientTooltipComponent.java | 1 - ...ingTablePatternClientTooltipComponent.java | 1 - ...necutterPatternClientTooltipComponent.java | 1 - .../preview/CraftingPreviewContainerMenu.java | 32 +-- .../preview/CraftingPreviewScreen.java | 204 +++++++++++++++--- .../autocrafting/preview/CraftingRequest.java | 46 ++++ .../preview/CraftingRequestButton.java | 73 +++++++ .../grid/screen/AbstractGridScreen.java | 24 ++- .../common/grid/screen/GridScreen.java | 2 +- .../grid/screen/GridSearchBoxWidget.java | 1 - .../common/grid/view/FluidGridResource.java | 7 + .../common/grid/view/ItemGridResource.java | 8 + .../common/support/ResourceSlotRendering.java | 3 - .../support/amount/AbstractAmountScreen.java | 13 +- .../common/support/widget/TextMarquee.java | 48 ++++- ...radeDestinationClientTooltipComponent.java | 1 - .../assets/refinedstorage/lang/en_us.json | 2 +- .../textures/gui/crafting_preview.png | Bin 662 -> 662 bytes .../crafting_preview/crafting_requests.png | Bin 0 -> 301 bytes 27 files changed, 418 insertions(+), 81 deletions(-) delete mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/crafting_requests.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b35d7e57..0adf911b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Resources in the Grid that are autocraftable now display an orange backdrop and tooltip to indicate whether the resource is autocraftable at a glance. - Slots used in the Pattern Grid for pattern encoding and Crafting Grid crafting matrix slots now display an orange backdrop and tooltip to indicate whether the item is autocraftable at a glance. This checks patterns from your network and from your inventory. - Added help tooltip for filtering based on recipe items in the Crafting Grid. +- The crafting amount and crafting preview screens have been merged. Changing the amount will update the live preview. +- The numbers on the crafting preview screen are now compacted with units. +- When requesting autocrafting multiple resources at once, which can happen via a recipe mod, all the crafting requests are now listed on the side of the GUI. ### Fixed diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java deleted file mode 100644 index 280f1377a..000000000 --- a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/CraftingPreview.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.refinedmods.refinedstorage.api.autocrafting; - -import com.refinedmods.refinedstorage.api.resource.list.ResourceList; - -public record CraftingPreview(ResourceList missing, ResourceList toTake, ResourceList toCraft) { -} diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java index d43da64b9..73afb28de 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java @@ -206,5 +206,5 @@ EnergyStorage asBlockItemEnergyStorage( Optional getPattern(ItemStack stack, Level level); - void openCraftingPreview(List resources); + void openCraftingPreview(List requests); } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java index c68bf1cd8..267910bd2 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java @@ -404,8 +404,8 @@ public Optional getPattern(final ItemStack stack, final Level level) { } @Override - public void openCraftingPreview(final List resources) { - ensureLoaded().openCraftingPreview(resources); + public void openCraftingPreview(final List requests) { + ensureLoaded().openCraftingPreview(requests); } private RefinedStorageApi ensureLoaded() { diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/PlatformGridResource.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/PlatformGridResource.java index 0b062d6fd..2b692f2fb 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/PlatformGridResource.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/PlatformGridResource.java @@ -3,6 +3,7 @@ import com.refinedmods.refinedstorage.api.grid.operations.GridExtractMode; import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.grid.GridScrollMode; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridExtractionStrategy; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridScrollingStrategy; @@ -47,6 +48,9 @@ void onScroll(GridScrollMode scrollMode, List getExtractionHints(ItemStack carriedStack, GridView view); + @Nullable + ResourceAmount getAutocraftingRequest(); + @Nullable @API(status = API.Status.INTERNAL) PlatformResourceKey getResourceForRecipeMods(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index 83abe2af5..39ab3bafb 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -51,6 +51,7 @@ import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeRegistry; import com.refinedmods.refinedstorage.common.api.wirelesstransmitter.WirelessTransmitterRangeModifier; import com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen; +import com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingRequest; import com.refinedmods.refinedstorage.common.grid.NoopGridSynchronizer; import com.refinedmods.refinedstorage.common.grid.screen.hint.GridInsertionHintsImpl; import com.refinedmods.refinedstorage.common.grid.screen.hint.ItemGridInsertionHint; @@ -601,8 +602,8 @@ public Optional getPattern(final ItemStack stack, final Level level) { } @Override - public void openCraftingPreview(final List resources) { - if (resources.isEmpty()) { + public void openCraftingPreview(final List requests) { + if (requests.isEmpty()) { return; } final Minecraft minecraft = Minecraft.getInstance(); @@ -610,6 +611,10 @@ public void openCraftingPreview(final List resources) { return; } final Inventory inventory = minecraft.player.getInventory(); - minecraft.setScreen(new CraftingPreviewScreen(minecraft.screen, inventory, resources.getFirst().resource())); + minecraft.setScreen(new CraftingPreviewScreen( + minecraft.screen, + inventory, + requests.stream().map(CraftingRequest::of).toList() + )); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java index 533cccb20..71d997548 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java @@ -40,6 +40,7 @@ import static com.refinedmods.refinedstorage.common.support.AbstractDirectionalBlock.tryExtractDirection; +// TODO: More energy usage for more patterns. public class CrafterBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity implements ExtendedMenuProvider, BlockEntityWithDrops, PatternInventory.Listener { static final int PATTERNS = 9; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java index f874917b5..b431f29ce 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternClientTooltipComponent.java @@ -20,7 +20,6 @@ import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_WIDTH; import static com.refinedmods.refinedstorage.common.support.Sprites.SLOT; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; -import static java.util.Objects.requireNonNullElse; class CraftingPatternClientTooltipComponent implements ClientTooltipComponent { private static final long CYCLE_MS = 1000; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java index e0309dec5..06afaf280 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java @@ -19,7 +19,6 @@ import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_HEIGHT; import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_WIDTH; import static com.refinedmods.refinedstorage.common.support.Sprites.SLOT; -import static java.util.Objects.requireNonNullElse; class ProcessingPatternClientTooltipComponent implements ClientTooltipComponent { private static final long CYCLE_MS = 1000; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java index 86fc09c17..71ad06504 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java @@ -14,7 +14,6 @@ import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW; import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_HEIGHT; import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_WIDTH; -import static java.util.Objects.requireNonNullElse; class SmithingTablePatternClientTooltipComponent implements ClientTooltipComponent { private static final int ARROW_SPACING = 8; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java index ddf5d2e39..5e32c883c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java @@ -15,7 +15,6 @@ import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_HEIGHT; import static com.refinedmods.refinedstorage.common.support.Sprites.LIGHT_ARROW_WIDTH; import static com.refinedmods.refinedstorage.common.support.Sprites.SLOT; -import static java.util.Objects.requireNonNullElse; class StonecutterPatternClientTooltipComponent implements ClientTooltipComponent { private static final int ARROW_SPACING = 8; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java index aca99a72c..1388b7ba8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java @@ -1,27 +1,26 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; import com.refinedmods.refinedstorage.common.support.containermenu.DisabledResourceSlot; import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import javax.annotation.Nullable; import net.minecraft.network.chat.Component; class CraftingPreviewContainerMenu extends AbstractResourceContainerMenu { - @Nullable - private CraftingPreview preview; + private final List requests; - CraftingPreviewContainerMenu(final ResourceKey resource) { + private CraftingRequest currentRequest; + + CraftingPreviewContainerMenu(final List requests) { super(null, 0); final ResourceContainer resourceContainer = ResourceContainerImpl.createForFilter(1); - resourceContainer.set(0, new ResourceAmount(resource, 1)); + resourceContainer.set(0, new ResourceAmount(requests.getFirst().getResource(), 1)); addSlot(new DisabledResourceSlot( resourceContainer, 0, @@ -30,16 +29,19 @@ class CraftingPreviewContainerMenu extends AbstractResourceContainerMenu { 48, ResourceSlotType.FILTER )); + this.requests = Collections.unmodifiableList(requests); + this.currentRequest = requests.getFirst(); + } + + List getRequests() { + return requests; + } - final List items = new ArrayList<>(); - for (int i = 0; i < 31; ++i) { - items.add(new CraftingPreviewItem(resource, i, i % 2 == 0 ? 999 : 0, i % 2 == 0 ? 0 : 1000)); - } - preview = new CraftingPreview(true, items); + CraftingRequest getCurrentRequest() { + return currentRequest; } - @Nullable - public CraftingPreview getPreview() { - return preview; + void setCurrentRequest(final CraftingRequest request) { + this.currentRequest = request; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java index d592a0feb..697b5b05a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java @@ -1,6 +1,5 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; -import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; import com.refinedmods.refinedstorage.common.support.amount.AbstractAmountScreen; @@ -9,12 +8,14 @@ import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; import com.refinedmods.refinedstorage.common.support.widget.ScrollbarWidget; +import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; @@ -25,12 +26,16 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; public class CraftingPreviewScreen extends AbstractAmountScreen { + static final int REQUEST_BUTTON_HEIGHT = 96 / 4; + static final int REQUEST_BUTTON_WIDTH = 64; + private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/crafting_preview.png"); private static final MutableComponent TITLE = Component.translatable("container.crafting"); private static final MutableComponent START = createTranslation("gui", "crafting_preview.start"); private static final MutableComponent MISSING_RESOURCES = createTranslation("gui", "crafting_preview.start.missing_resources"); private static final ResourceLocation ROW = createIdentifier("crafting_preview/row"); + private static final ResourceLocation CRAFTING_REQUESTS = createIdentifier("crafting_preview/crafting_requests"); private static final int ROWS_VISIBLE = 4; private static final int COLUMNS = 3; @@ -39,12 +44,25 @@ public class CraftingPreviewScreen extends AbstractAmountScreen requestButtons = new ArrayList<>(); + private final boolean requestsButtonsVisible; + + public CraftingPreviewScreen(final Screen parent, + final Inventory playerInventory, + final List requests) { super( - new CraftingPreviewContainerMenu(resource), + new CraftingPreviewContainerMenu(requests), parent, playerInventory, TITLE, @@ -65,39 +83,107 @@ public CraftingPreviewScreen(final Screen parent, final Inventory playerInventor ); this.imageWidth = 254; this.imageHeight = 249; + this.requestsButtonsVisible = getMenu().getRequests().size() > 1; } @Override protected void init() { super.init(); - scrollbar = new ScrollbarWidget( + previewItemsScrollbar = new ScrollbarWidget( leftPos + 235, topPos + 98, ScrollbarWidget.Type.NORMAL, PREVIEW_AREA_HEIGHT ); - scrollbar.setEnabled(false); + previewItemsScrollbar.setEnabled(false); + if (requestsButtonsVisible) { + initRequestButtons(); + } if (confirmButton != null) { confirmButton.active = false; } - updatePreview(); + updateCurrentRequest(); + getExclusionZones().add(new Rect2i( + leftPos - REQUESTS_WIDTH + 4, + topPos, + REQUESTS_WIDTH, + REQUESTS_HEIGHT + )); + } + + private void initRequestButtons() { + requestButtons.clear(); + requestButtonsScrollbar = new ScrollbarWidget( + leftPos - 17 + 4, + getRequestButtonsInnerY(), + ScrollbarWidget.Type.NORMAL, + 96 + ); + requestButtonsScrollbar.setListener(value -> { + final int scrollOffset = requestButtonsScrollbar.isSmoothScrolling() + ? (int) requestButtonsScrollbar.getOffset() + : (int) requestButtonsScrollbar.getOffset() * REQUEST_BUTTON_HEIGHT; + for (int i = 0; i < requestButtons.size(); i++) { + final CraftingRequestButton requestButton = requestButtons.get(i); + final int y = getCraftingRequestButtonY(i) - scrollOffset; + requestButton.setY(y); + requestButton.visible = isCraftingRequestButtonVisible(y); + } + }); + final int totalRequestButtons = getMenu().getRequests().size() - REQUESTS_VISIBLE; + final int maxOffset = requestButtonsScrollbar.isSmoothScrolling() + ? totalRequestButtons * REQUEST_BUTTON_HEIGHT + : totalRequestButtons; + requestButtonsScrollbar.setEnabled(maxOffset > 0); + requestButtonsScrollbar.setMaxOffset(maxOffset); + for (int i = 0; i < getMenu().getRequests().size(); ++i) { + final CraftingRequest request = getMenu().getRequests().get(i); + final int buttonY = getCraftingRequestButtonY(i); + final CraftingRequestButton button = new CraftingRequestButton( + getRequestButtonsInnerX(), + buttonY, + request, + this::changeCurrentRequest + ); + button.visible = isCraftingRequestButtonVisible(buttonY); + requestButtons.add(addWidget(button)); + } + } + + private boolean isCraftingRequestButtonVisible(final int y) { + final int innerY = getRequestButtonsInnerY(); + return y >= innerY - REQUEST_BUTTON_HEIGHT && y <= innerY + REQUESTS_INNER_HEIGHT; + } + + private int getCraftingRequestButtonY(final int i) { + return getRequestButtonsInnerY() + (i * REQUEST_BUTTON_HEIGHT); } - private void updatePreview() { - if (scrollbar == null || confirmButton == null) { + private void changeCurrentRequest(final CraftingRequest request) { + getMenu().setCurrentRequest(request); + updateCurrentRequest(); + } + + private void updateCurrentRequest() { + if (previewItemsScrollbar == null || confirmButton == null) { return; } - final CraftingPreview preview = getMenu().getPreview(); + final CraftingRequest currentRequest = getMenu().getCurrentRequest(); + for (final CraftingRequestButton requestButton : requestButtons) { + requestButton.active = requestButton.getRequest() != currentRequest; + } + updateAmount(currentRequest.getAmount()); + final CraftingPreview preview = currentRequest.getPreview(); if (preview == null) { - scrollbar.setEnabled(false); - scrollbar.setMaxOffset(0); + previewItemsScrollbar.setEnabled(false); + previewItemsScrollbar.setMaxOffset(0); confirmButton.active = false; return; } - final int items = getMenu().getPreview().items().size(); + final int items = preview.items().size(); final int rows = Math.ceilDiv(items, COLUMNS) - ROWS_VISIBLE; - scrollbar.setMaxOffset(scrollbar.isSmoothScrolling() ? rows * ROW_HEIGHT : rows); - scrollbar.setEnabled(rows > 0); + previewItemsScrollbar.setMaxOffset(previewItemsScrollbar.isSmoothScrolling() ? rows * ROW_HEIGHT : rows); + previewItemsScrollbar.setEnabled(rows > 0); confirmButton.active = !preview.missing(); confirmButton.setTooltip(preview.missing() ? Tooltip.create(MISSING_RESOURCES) : null); } @@ -105,27 +191,49 @@ private void updatePreview() { @Override public void render(final GuiGraphics graphics, final int mouseX, final int mouseY, final float partialTicks) { super.render(graphics, mouseX, mouseY, partialTicks); - if (scrollbar != null) { - scrollbar.render(graphics, mouseX, mouseY, partialTicks); + if (previewItemsScrollbar != null) { + previewItemsScrollbar.render(graphics, mouseX, mouseY, partialTicks); + } + if (requestButtonsScrollbar != null) { + requestButtonsScrollbar.render(graphics, mouseX, mouseY, partialTicks); + } + if (requestsButtonsVisible) { + final int requestsInnerX = getRequestButtonsInnerX(); + final int requestsInnerY = getRequestButtonsInnerY(); + graphics.enableScissor( + requestsInnerX, + requestsInnerY, + requestsInnerX + REQUESTS_INNER_WIDTH, + requestsInnerY + REQUESTS_INNER_HEIGHT + ); + for (final CraftingRequestButton requestButton : requestButtons) { + requestButton.render(graphics, mouseX, mouseY, partialTicks); + } + graphics.disableScissor(); } } @Override protected void renderBg(final GuiGraphics graphics, final float delta, final int mouseX, final int mouseY) { super.renderBg(graphics, delta, mouseX, mouseY); - final CraftingPreview preview = getMenu().getPreview(); - if (preview == null || scrollbar == null) { + if (requestsButtonsVisible) { + graphics.blitSprite(CRAFTING_REQUESTS, leftPos - REQUESTS_WIDTH + 4, topPos, REQUESTS_WIDTH, + REQUESTS_HEIGHT); + } + final CraftingRequest request = getMenu().getCurrentRequest(); + final CraftingPreview preview = request.getPreview(); + if (preview == null || previewItemsScrollbar == null) { return; } final int x = leftPos + 8; final int y = topPos + 98; graphics.enableScissor(x, y, x + 221, y + PREVIEW_AREA_HEIGHT); - final List items = getMenu().getPreview().items(); + final List items = preview.items(); final int rows = Math.ceilDiv(items.size(), COLUMNS); for (int i = 0; i < rows; ++i) { - final int scrollOffset = scrollbar.isSmoothScrolling() - ? (int) scrollbar.getOffset() - : (int) scrollbar.getOffset() * ROW_HEIGHT; + final int scrollOffset = previewItemsScrollbar.isSmoothScrolling() + ? (int) previewItemsScrollbar.getOffset() + : (int) previewItemsScrollbar.getOffset() * ROW_HEIGHT; final int yy = y + (i * ROW_HEIGHT) - scrollOffset; renderRow(graphics, x, yy, i, items, mouseX, mouseY); } @@ -206,7 +314,10 @@ private void renderCellText(final GuiGraphics graphics, @Override public boolean mouseClicked(final double mouseX, final double mouseY, final int clickedButton) { - if (scrollbar != null && scrollbar.mouseClicked(mouseX, mouseY, clickedButton)) { + if (previewItemsScrollbar != null && previewItemsScrollbar.mouseClicked(mouseX, mouseY, clickedButton)) { + return true; + } + if (requestButtonsScrollbar != null && requestButtonsScrollbar.mouseClicked(mouseX, mouseY, clickedButton)) { return true; } return super.mouseClicked(mouseX, mouseY, clickedButton); @@ -214,30 +325,56 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int @Override public void mouseMoved(final double mx, final double my) { - if (scrollbar != null) { - scrollbar.mouseMoved(mx, my); + if (previewItemsScrollbar != null) { + previewItemsScrollbar.mouseMoved(mx, my); + } + if (requestButtonsScrollbar != null) { + requestButtonsScrollbar.mouseMoved(mx, my); } super.mouseMoved(mx, my); } @Override public boolean mouseReleased(final double mx, final double my, final int button) { - return (scrollbar != null && scrollbar.mouseReleased(mx, my, button)) - || super.mouseReleased(mx, my, button); + if (previewItemsScrollbar != null && previewItemsScrollbar.mouseReleased(mx, my, button)) { + return true; + } + if (requestButtonsScrollbar != null && requestButtonsScrollbar.mouseReleased(mx, my, button)) { + return true; + } + return super.mouseReleased(mx, my, button); } @Override public boolean mouseScrolled(final double x, final double y, final double z, final double delta) { - final boolean didScrollbar = scrollbar != null + final boolean didPreviewItemsScrollbar = previewItemsScrollbar != null && isHoveringOverPreviewArea(x, y) - && scrollbar.mouseScrolled(x, y, z, delta); - return didScrollbar || super.mouseScrolled(x, y, z, delta); + && previewItemsScrollbar.mouseScrolled(x, y, z, delta); + final boolean didRequestButtonsScrollbar = !didPreviewItemsScrollbar + && requestButtonsScrollbar != null + && isHoveringOverRequestButtons(x, y) + && requestButtonsScrollbar.mouseScrolled(x, y, z, delta); + return didPreviewItemsScrollbar || didRequestButtonsScrollbar || super.mouseScrolled(x, y, z, delta); } private boolean isHoveringOverPreviewArea(final double x, final double y) { return isHovering(7, 97, 241, 121, x, y); } + private boolean isHoveringOverRequestButtons(final double x, final double y) { + final int requestsInnerX = getRequestButtonsInnerX() - 1; + final int requestsInnerY = getRequestButtonsInnerY() - 1; + return isHovering(requestsInnerX - leftPos, requestsInnerY - topPos, 80, 98, x, y); + } + + private int getRequestButtonsInnerY() { + return topPos + 8; + } + + private int getRequestButtonsInnerX() { + return leftPos - 83 + 4; + } + @Override protected ResourceLocation getTexture() { return TEXTURE; @@ -253,6 +390,11 @@ protected void onAmountFieldChanged() { amountField.setTextColor(valid ? 0xFFFFFF : 0xFF5555); } + @Override + protected void reset() { + updateAmount(getMenu().getCurrentRequest().getAmount()); + } + @Override protected boolean confirm(final Double amount) { return false; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java new file mode 100644 index 000000000..d8d19fa1c --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java @@ -0,0 +1,46 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; + +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +public class CraftingRequest { + private final ResourceKey resource; + private final double amount; + @Nullable + private CraftingPreview preview; + + private CraftingRequest(final ResourceKey resource, final double amount) { + this.resource = resource; + this.amount = amount; + final List items = new ArrayList<>(); + for (int i = 0; i < 31; ++i) { + items.add(new CraftingPreviewItem(resource, i, i % 2 == 0 ? 999 : 0, i % 2 == 0 ? 0 : 1000)); + } + this.preview = new CraftingPreview(true, items); + } + + public static CraftingRequest of(final ResourceAmount resourceAmount) { + final double displayAmount = resourceAmount.resource() instanceof PlatformResourceKey platformResourceKey + ? platformResourceKey.getResourceType().getDisplayAmount(resourceAmount.amount()) + : resourceAmount.amount(); + return new CraftingRequest(resourceAmount.resource(), displayAmount); + } + + ResourceKey getResource() { + return resource; + } + + double getAmount() { + return amount; + } + + @Nullable + CraftingPreview getPreview() { + return preview; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java new file mode 100644 index 000000000..fb8ede269 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java @@ -0,0 +1,73 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; +import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; +import com.refinedmods.refinedstorage.common.support.widget.TextMarquee; + +import java.util.function.Consumer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.network.chat.Component; + +import static com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen.REQUEST_BUTTON_HEIGHT; +import static com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen.REQUEST_BUTTON_WIDTH; + +class CraftingRequestButton extends AbstractButton { + private final CraftingRequest request; + private final TextMarquee text; + private final Consumer onPress; + + CraftingRequestButton(final int x, + final int y, + final CraftingRequest request, + final Consumer onPress) { + super(x, y, REQUEST_BUTTON_WIDTH, REQUEST_BUTTON_HEIGHT, Component.empty()); + this.request = request; + final ResourceKey resource = request.getResource(); + final long normalizedAmount = resource instanceof PlatformResourceKey platformResourceKey + ? platformResourceKey.getResourceType().normalizeAmount(request.getAmount()) + : 0; + final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(resource.getClass()); + this.text = new TextMarquee(Component.literal(rendering.formatAmount(normalizedAmount, true)) + .append(" ") + .append(rendering.getDisplayName(resource)), + REQUEST_BUTTON_WIDTH - 16 - 4 - 4 - 4, + 0xFFFFFF, + true, + true); + this.onPress = onPress; + } + + CraftingRequest getRequest() { + return request; + } + + @Override + protected void renderWidget(final GuiGraphics graphics, + final int mouseX, + final int mouseY, + final float partialTick) { + super.renderWidget(graphics, mouseX, mouseY, partialTick); + final ResourceKey resource = request.getResource(); + final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(resource.getClass()); + rendering.render(resource, graphics, getX() + 3, getY() + 4); + final int yOffset = SmallText.isSmall() ? 8 : 5; + text.render(graphics, getX() + 3 + 16 + 3, getY() + yOffset, Minecraft.getInstance().font, isHovered); + } + + @Override + public void onPress() { + onPress.accept(request); + } + + @Override + protected void updateWidgetNarration(final NarrationElementOutput narrationElementOutput) { + // no op + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 7877e55a2..b124ae275 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -498,11 +498,7 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int if (resource.canExtract(carriedStack, getMenu().getView()) && !hasControlDown()) { mouseClickedInGrid(clickedButton, resource); return true; - } else if (resource.isCraftable()) { - RefinedStorageApi.INSTANCE.openCraftingPreview(List.of(new ResourceAmount( - resource.getResourceForRecipeMods(), - 1 - ))); + } else if (resource.isCraftable() && tryStartAutocrafting(resource)) { return true; } } @@ -516,6 +512,24 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int return super.mouseClicked(mouseX, mouseY, clickedButton); } + private static boolean tryStartAutocrafting(final PlatformGridResource resource) { + final ResourceAmount request = resource.getAutocraftingRequest(); + if (request == null) { + return false; + } + final List requests = new ArrayList<>(); + requests.add(request); + // TODO: Remove - temporary code + if (hasShiftDown()) { + requests.add(new ResourceAmount(request.resource(), request.amount() * 2)); + requests.add(new ResourceAmount(request.resource(), request.amount() * 3)); + requests.add(new ResourceAmount(request.resource(), request.amount() * 4)); + requests.add(new ResourceAmount(request.resource(), request.amount() * 5)); + } + RefinedStorageApi.INSTANCE.openCraftingPreview(requests); + return true; + } + private void mouseClickedInGrid(final int clickedButton) { final GridInsertMode mode = clickedButton == 1 ? GridInsertMode.SINGLE_RESOURCE diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java index 58cb19f21..740c4d1e7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java @@ -9,7 +9,7 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; public class GridScreen extends AbstractGridScreen { - private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/grid.png"); + private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/grid2.png"); public GridScreen(final T menu, final Inventory inventory, final Component title) { super(menu, inventory, title, 99); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java index ea0928725..46f461841 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridSearchBoxWidget.java @@ -12,7 +12,6 @@ import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; import java.util.function.Consumer; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java index 77834ef9a..3b11cc868 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import javax.annotation.Nullable; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -61,6 +62,12 @@ public List getExtractionHints(final ItemStack carriedSt )).stream().toList(); } + @Nullable + @Override + public ResourceAmount getAutocraftingRequest() { + return new ResourceAmount(resource, Platform.INSTANCE.getBucketAmount()); + } + private Optional tryFillFluidContainer(final ItemStack carriedStack) { final ResourceAmount toFill = new ResourceAmount(resource, Platform.INSTANCE.getBucketAmount()); return carriedStack.isEmpty() diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java index 02d11ab59..dd56b2a55 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java @@ -3,6 +3,7 @@ import com.refinedmods.refinedstorage.api.grid.operations.GridExtractMode; import com.refinedmods.refinedstorage.api.grid.view.GridResourceAttributeKey; import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.grid.GridScrollMode; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridExtractionStrategy; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridScrollingStrategy; @@ -16,6 +17,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import javax.annotation.Nullable; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -78,6 +80,12 @@ public List getExtractionHints(final ItemStack carriedSt ); } + @Nullable + @Override + public ResourceAmount getAutocraftingRequest() { + return new ResourceAmount(itemResource, 1); + } + @Override public boolean canExtract(final ItemStack carriedStack, final GridView view) { return getAmount(view) > 0 && carriedStack.isEmpty(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java index c0d29a830..4c4d8d604 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java @@ -6,13 +6,10 @@ import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; -import static java.util.Objects.requireNonNullElse; - public final class ResourceSlotRendering { private ResourceSlotRendering() { } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java index ae47bd290..d6f8ef3a4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java @@ -112,7 +112,7 @@ private void addAmountField() { ); amountField.setBordered(false); if (configuration.getInitialAmount() != null) { - amountField.setValue(amountOperations.format(configuration.getInitialAmount())); + updateAmount(configuration.getInitialAmount()); } amountField.setVisible(true); amountField.setCanLoseFocus(this instanceof AlternativesScreen); @@ -124,6 +124,13 @@ private void addAmountField() { addRenderableWidget(amountField); } + protected final void updateAmount(final N amount) { + if (amountField == null) { + return; + } + amountField.setValue(amountOperations.format(amount)); + } + protected void onAmountFieldChanged() { if (amountField == null) { return; @@ -182,7 +189,7 @@ private void changeAmount(final int delta) { configuration.getMinAmount(), configuration.getMaxAmount() ); - amountField.setValue(amountOperations.format(newAmount)); + updateAmount(newAmount); }); } @@ -248,7 +255,7 @@ protected void reset() { if (amountField == null || configuration.getResetAmount() == null) { return; } - amountField.setValue(amountOperations.format(configuration.getResetAmount())); + updateAmount(configuration.getResetAmount()); } private void tryConfirm() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/TextMarquee.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/TextMarquee.java index dcf34b4b6..16532eab6 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/TextMarquee.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/TextMarquee.java @@ -1,20 +1,36 @@ package com.refinedmods.refinedstorage.common.support.widget; +import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; + import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; public class TextMarquee { private final int maxWidth; + private final int color; + private final boolean dropShadow; + private final boolean small; private Component text; private int offset; private int stateTicks; private State state = State.MOVING_LEFT; - public TextMarquee(final Component text, final int maxWidth) { + public TextMarquee(final Component text, + final int maxWidth, + final int color, + final boolean dropShadow, + final boolean small) { this.text = text; this.maxWidth = maxWidth; + this.color = color; + this.dropShadow = dropShadow; + this.small = small; + } + + public TextMarquee(final Component text, final int maxWidth) { + this(text, maxWidth, 4210752, false, false); } public int getEffectiveWidth(final Font font) { @@ -27,17 +43,41 @@ public void render(final GuiGraphics graphics, final int x, final int y, final F state = State.MOVING_LEFT; stateTicks = 0; } - final int width = font.width(text); + final int width = (int) (font.width(text) * (small ? SmallText.getScale() : 1F)); if (width > maxWidth) { final int overflow = width - maxWidth; if (hovering) { updateMarquee(overflow); } graphics.enableScissor(x, y, x + maxWidth, y + font.lineHeight); - graphics.drawString(font, text, x + offset, y, 4210752, false); + if (small) { + SmallText.render( + graphics, + font, + text.getVisualOrderText(), + x + offset, + y, + color, + dropShadow + ); + } else { + graphics.drawString(font, text, x + offset, y, color, dropShadow); + } graphics.disableScissor(); } else { - graphics.drawString(font, text, x, y, 4210752, false); + if (small) { + SmallText.render( + graphics, + font, + text.getVisualOrderText(), + x, + y, + color, + dropShadow + ); + } else { + graphics.drawString(font, text, x, y, color, dropShadow); + } } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java index 633044702..ae68aedf3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/upgrade/UpgradeDestinationClientTooltipComponent.java @@ -2,7 +2,6 @@ import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeMapping; -import java.util.Objects; import java.util.Set; import net.minecraft.ChatFormatting; diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json index 2009ba76d..f59b5e5d4 100644 --- a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json +++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json @@ -6,7 +6,7 @@ "block.refinedstorage.disk_drive": "Disk Drive", "block.refinedstorage.machine_casing": "Machine Casing", "block.refinedstorage.grid": "Grid", - "block.refinedstorage.pattern_grid": "Pattern Grid", + "block.refinedstorage.pattern_grid": "Pattern Fart Grid", "block.refinedstorage.crafting_grid": "Crafting Grid", "block.refinedstorage.controller": "Controller", "block.refinedstorage.creative_controller": "Creative Controller", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png index cbce82533d29b98e1e0b66f77a60a17a2afc4ed3..6f801a9a2cdbf9bf2088c37342589ba960396a6d 100644 GIT binary patch delta 21 dcmbQnI*oNgBiBX-2EL7qb9&@&ZS3Y|0su|n2Q2^q delta 21 dcmbQnI*oNgBiAMd2EI*{;n`WodQwy235%zn8}6>o2}ly8Bzk`sQUz@6PePz3rgcO|{!8vvVfr zZt~rBk|5_Y|LwK@-E218-^*BUi%5PBQ$Af*5&evB+rqgAT-s-E2D*yD)78&qol`;+ E0NdzyZU6uP literal 0 HcmV?d00001 From 673817fae9cf17a922dd4f2bd381d76ec9d9c481 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Fri, 4 Oct 2024 17:23:42 +0200 Subject: [PATCH 3/5] feat: crafting preview on the server --- .../common/RefinedStorageApiImpl.java | 8 +- .../preview/AutocraftingPreview.java | 18 +++ .../AutocraftingPreviewContainerMenu.java | 77 +++++++++++ .../preview/AutocraftingPreviewItem.java | 18 +++ .../preview/AutocraftingPreviewListener.java | 9 ++ .../preview/AutocraftingPreviewProvider.java | 8 ++ ...en.java => AutocraftingPreviewScreen.java} | 121 ++++++++++++------ .../preview/AutocraftingPreviewType.java | 7 + .../preview/AutocraftingRequest.java | 72 +++++++++++ ...on.java => AutocraftingRequestButton.java} | 20 +-- .../autocrafting/preview/CraftingPreview.java | 6 - .../preview/CraftingPreviewContainerMenu.java | 47 ------- .../preview/CraftingPreviewItem.java | 6 - .../autocrafting/preview/CraftingRequest.java | 46 ------- .../grid/AbstractGridContainerMenu.java | 26 +++- .../support/amount/AbstractAmountScreen.java | 56 +++++--- .../common/support/amount/ConfirmButton.java | 52 ++++++++ .../c2s/AutocraftingPreviewRequestPacket.java | 48 +++++++ .../common/support/packet/c2s/C2SPackets.java | 6 + .../AutocraftingPreviewResponsePacket.java | 37 ++++++ .../common/support/packet/s2c/S2CPackets.java | 7 + .../common/util/ClientPlatformUtil.java | 10 ++ .../assets/refinedstorage/lang/en_us.json | 14 +- ...g_preview.png => autocrafting_preview.png} | Bin .../requests.png} | Bin .../row.png | Bin .../textures/gui/sprites/error.png | Bin 0 -> 205 bytes .../fabric/ClientModInitializerImpl.java | 5 + .../fabric/ModInitializerImpl.java | 14 ++ .../neoforge/ModInitializer.java | 12 ++ 30 files changed, 566 insertions(+), 184 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java rename refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/{CraftingPreviewScreen.java => AutocraftingPreviewScreen.java} (78%) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java rename refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/{CraftingRequestButton.java => AutocraftingRequestButton.java} (83%) delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ConfirmButton.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java rename refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/{crafting_preview.png => autocrafting_preview.png} (100%) rename refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/{crafting_preview/crafting_requests.png => autocrafting_preview/requests.png} (100%) rename refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/{crafting_preview => autocrafting_preview}/row.png (100%) create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/error.png diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index 39ab3bafb..1daca02e8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -50,8 +50,8 @@ import com.refinedmods.refinedstorage.common.api.support.slotreference.SlotReferenceProvider; import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeRegistry; import com.refinedmods.refinedstorage.common.api.wirelesstransmitter.WirelessTransmitterRangeModifier; -import com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen; -import com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingRequest; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingRequest; import com.refinedmods.refinedstorage.common.grid.NoopGridSynchronizer; import com.refinedmods.refinedstorage.common.grid.screen.hint.GridInsertionHintsImpl; import com.refinedmods.refinedstorage.common.grid.screen.hint.ItemGridInsertionHint; @@ -611,10 +611,10 @@ public void openCraftingPreview(final List requests) { return; } final Inventory inventory = minecraft.player.getInventory(); - minecraft.setScreen(new CraftingPreviewScreen( + minecraft.setScreen(new AutocraftingPreviewScreen( minecraft.screen, inventory, - requests.stream().map(CraftingRequest::of).toList() + requests.stream().map(AutocraftingRequest::of).toList() )); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java new file mode 100644 index 000000000..afd1946f6 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java @@ -0,0 +1,18 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.common.util.PlatformUtil; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +public record AutocraftingPreview(AutocraftingPreviewType type, List items) { + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + PlatformUtil.enumStreamCodec(AutocraftingPreviewType.values()), AutocraftingPreview::type, + ByteBufCodecs.collection(ArrayList::new, AutocraftingPreviewItem.STREAM_CODEC), AutocraftingPreview::items, + AutocraftingPreview::new + ); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java new file mode 100644 index 000000000..a6d3da8ba --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java @@ -0,0 +1,77 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; +import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; +import com.refinedmods.refinedstorage.common.support.containermenu.DisabledResourceSlot; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import javax.annotation.Nullable; + +import net.minecraft.network.chat.Component; + +public class AutocraftingPreviewContainerMenu extends AbstractResourceContainerMenu { + private final List requests; + + private AutocraftingRequest currentRequest; + @Nullable + private AutocraftingPreviewListener listener; + + AutocraftingPreviewContainerMenu(final List requests) { + super(null, 0); + final ResourceContainer resourceContainer = ResourceContainerImpl.createForFilter(1); + resourceContainer.set(0, new ResourceAmount(requests.getFirst().getResource(), 1)); + addSlot(new DisabledResourceSlot( + resourceContainer, + 0, + Component.empty(), + 157, + 48, + ResourceSlotType.FILTER + )); + this.requests = Collections.unmodifiableList(requests); + this.currentRequest = requests.getFirst(); + } + + void setListener(final AutocraftingPreviewListener listener) { + this.listener = listener; + } + + List getRequests() { + return requests; + } + + AutocraftingRequest getCurrentRequest() { + return currentRequest; + } + + void setCurrentRequest(final AutocraftingRequest request) { + this.currentRequest = request; + if (listener != null) { + listener.requestChanged(request); + } + } + + void amountChanged(final double amount) { + if (currentRequest.trySendRequest(amount) && listener != null) { + listener.previewChanged(null); + } + } + + public void previewReceived(final UUID id, final AutocraftingPreview preview) { + if (currentRequest.previewReceived(id, preview) && listener != null) { + listener.previewChanged(preview); + } + } + + public void loadCurrentRequest() { + if (listener != null) { + currentRequest.clearPreview(); + listener.requestChanged(currentRequest); + } + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java new file mode 100644 index 000000000..c82b2e9f1 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java @@ -0,0 +1,18 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +public record AutocraftingPreviewItem(PlatformResourceKey resource, long available, long missing, long toCraft) { + static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ResourceCodecs.STREAM_CODEC, AutocraftingPreviewItem::resource, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::available, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::missing, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::toCraft, + AutocraftingPreviewItem::new + ); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java new file mode 100644 index 000000000..984f2c520 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java @@ -0,0 +1,9 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import javax.annotation.Nullable; + +interface AutocraftingPreviewListener { + void requestChanged(AutocraftingRequest request); + + void previewChanged(@Nullable AutocraftingPreview preview); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java new file mode 100644 index 000000000..1d42cb723 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java @@ -0,0 +1,8 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; + +@FunctionalInterface +public interface AutocraftingPreviewProvider { + AutocraftingPreview getPreview(PlatformResourceKey resource, long amount); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java similarity index 78% rename from refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java rename to refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java index 697b5b05a..03951eeed 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java @@ -12,6 +12,7 @@ import java.util.List; import javax.annotation.Nullable; +import com.google.common.util.concurrent.RateLimiter; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.screens.Screen; @@ -25,17 +26,21 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; -public class CraftingPreviewScreen extends AbstractAmountScreen { +public class AutocraftingPreviewScreen extends AbstractAmountScreen + implements AutocraftingPreviewListener { static final int REQUEST_BUTTON_HEIGHT = 96 / 4; static final int REQUEST_BUTTON_WIDTH = 64; - private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/crafting_preview.png"); - private static final MutableComponent TITLE = Component.translatable("container.crafting"); - private static final MutableComponent START = createTranslation("gui", "crafting_preview.start"); - private static final MutableComponent MISSING_RESOURCES - = createTranslation("gui", "crafting_preview.start.missing_resources"); - private static final ResourceLocation ROW = createIdentifier("crafting_preview/row"); - private static final ResourceLocation CRAFTING_REQUESTS = createIdentifier("crafting_preview/crafting_requests"); + private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/autocrafting_preview.png"); + private static final MutableComponent TITLE = createTranslation("gui", "autocrafting_preview.title"); + private static final MutableComponent START = createTranslation("gui", "autocrafting_preview.start"); + private static final MutableComponent PENDING = createTranslation("gui", "autocrafting_preview.pending"); + private static final MutableComponent MISSING_RESOURCES = createTranslation( + "gui", + "autocrafting_preview.start.missing_resources" + ); + private static final ResourceLocation ROW = createIdentifier("autocrafting_preview/row"); + private static final ResourceLocation CRAFTING_REQUESTS = createIdentifier("autocrafting_preview/requests"); private static final int ROWS_VISIBLE = 4; private static final int COLUMNS = 3; @@ -55,14 +60,19 @@ public class CraftingPreviewScreen extends AbstractAmountScreen requestButtons = new ArrayList<>(); + private final List requestButtons = new ArrayList<>(); private final boolean requestsButtonsVisible; - public CraftingPreviewScreen(final Screen parent, - final Inventory playerInventory, - final List requests) { + private final RateLimiter requestRateLimiter = RateLimiter.create(0.5); + + @Nullable + private Double changedAmount; + + public AutocraftingPreviewScreen(final Screen parent, + final Inventory playerInventory, + final List requests) { super( - new CraftingPreviewContainerMenu(requests), + new AutocraftingPreviewContainerMenu(requests), parent, playerInventory, TITLE, @@ -84,6 +94,7 @@ public CraftingPreviewScreen(final Screen parent, this.imageWidth = 254; this.imageHeight = 249; this.requestsButtonsVisible = getMenu().getRequests().size() > 1; + getMenu().setListener(this); } @Override @@ -101,8 +112,11 @@ protected void init() { } if (confirmButton != null) { confirmButton.active = false; + confirmButton.setMessage(START); + confirmButton.setTooltip(null); + confirmButton.setError(false); } - updateCurrentRequest(); + getMenu().loadCurrentRequest(); getExclusionZones().add(new Rect2i( leftPos - REQUESTS_WIDTH + 4, topPos, @@ -124,7 +138,7 @@ private void initRequestButtons() { ? (int) requestButtonsScrollbar.getOffset() : (int) requestButtonsScrollbar.getOffset() * REQUEST_BUTTON_HEIGHT; for (int i = 0; i < requestButtons.size(); i++) { - final CraftingRequestButton requestButton = requestButtons.get(i); + final AutocraftingRequestButton requestButton = requestButtons.get(i); final int y = getCraftingRequestButtonY(i) - scrollOffset; requestButton.setY(y); requestButton.visible = isCraftingRequestButtonVisible(y); @@ -137,9 +151,9 @@ private void initRequestButtons() { requestButtonsScrollbar.setEnabled(maxOffset > 0); requestButtonsScrollbar.setMaxOffset(maxOffset); for (int i = 0; i < getMenu().getRequests().size(); ++i) { - final CraftingRequest request = getMenu().getRequests().get(i); + final AutocraftingRequest request = getMenu().getRequests().get(i); final int buttonY = getCraftingRequestButtonY(i); - final CraftingRequestButton button = new CraftingRequestButton( + final AutocraftingRequestButton button = new AutocraftingRequestButton( getRequestButtonsInnerX(), buttonY, request, @@ -159,33 +173,40 @@ private int getCraftingRequestButtonY(final int i) { return getRequestButtonsInnerY() + (i * REQUEST_BUTTON_HEIGHT); } - private void changeCurrentRequest(final CraftingRequest request) { + private void changeCurrentRequest(final AutocraftingRequest request) { getMenu().setCurrentRequest(request); - updateCurrentRequest(); } - private void updateCurrentRequest() { + private void setRequest(final AutocraftingRequest request) { + for (final AutocraftingRequestButton requestButton : requestButtons) { + requestButton.active = requestButton.getRequest() != request; + } + updateAmount(request.getAmount()); + setPreview(request.getPreview()); + } + + private void setPreview(@Nullable final AutocraftingPreview preview) { if (previewItemsScrollbar == null || confirmButton == null) { return; } - final CraftingRequest currentRequest = getMenu().getCurrentRequest(); - for (final CraftingRequestButton requestButton : requestButtons) { - requestButton.active = requestButton.getRequest() != currentRequest; - } - updateAmount(currentRequest.getAmount()); - final CraftingPreview preview = currentRequest.getPreview(); + confirmButton.setMessage(START); if (preview == null) { previewItemsScrollbar.setEnabled(false); previewItemsScrollbar.setMaxOffset(0); confirmButton.active = false; + confirmButton.setError(false); + confirmButton.setTooltip(null); return; } final int items = preview.items().size(); final int rows = Math.ceilDiv(items, COLUMNS) - ROWS_VISIBLE; previewItemsScrollbar.setMaxOffset(previewItemsScrollbar.isSmoothScrolling() ? rows * ROW_HEIGHT : rows); previewItemsScrollbar.setEnabled(rows > 0); - confirmButton.active = !preview.missing(); - confirmButton.setTooltip(preview.missing() ? Tooltip.create(MISSING_RESOURCES) : null); + confirmButton.active = preview.type() == AutocraftingPreviewType.SUCCESS; + confirmButton.setError(preview.type() != AutocraftingPreviewType.SUCCESS); + confirmButton.setTooltip(preview.type() == AutocraftingPreviewType.MISSING_RESOURCES + ? Tooltip.create(MISSING_RESOURCES) + : null); } @Override @@ -206,7 +227,7 @@ public void render(final GuiGraphics graphics, final int mouseX, final int mouse requestsInnerX + REQUESTS_INNER_WIDTH, requestsInnerY + REQUESTS_INNER_HEIGHT ); - for (final CraftingRequestButton requestButton : requestButtons) { + for (final AutocraftingRequestButton requestButton : requestButtons) { requestButton.render(graphics, mouseX, mouseY, partialTicks); } graphics.disableScissor(); @@ -220,15 +241,15 @@ protected void renderBg(final GuiGraphics graphics, final float delta, final int graphics.blitSprite(CRAFTING_REQUESTS, leftPos - REQUESTS_WIDTH + 4, topPos, REQUESTS_WIDTH, REQUESTS_HEIGHT); } - final CraftingRequest request = getMenu().getCurrentRequest(); - final CraftingPreview preview = request.getPreview(); + final AutocraftingRequest request = getMenu().getCurrentRequest(); + final AutocraftingPreview preview = request.getPreview(); if (preview == null || previewItemsScrollbar == null) { return; } final int x = leftPos + 8; final int y = topPos + 98; graphics.enableScissor(x, y, x + 221, y + PREVIEW_AREA_HEIGHT); - final List items = preview.items(); + final List items = preview.items(); final int rows = Math.ceilDiv(items.size(), COLUMNS); for (int i = 0; i < rows; ++i) { final int scrollOffset = previewItemsScrollbar.isSmoothScrolling() @@ -244,7 +265,7 @@ private void renderRow(final GuiGraphics graphics, final int x, final int y, final int i, - final List items, + final List items, final double mouseX, final double mouseY) { if (y <= topPos + 98 - ROW_HEIGHT || y > topPos + 98 + PREVIEW_AREA_HEIGHT) { @@ -252,7 +273,7 @@ private void renderRow(final GuiGraphics graphics, } graphics.blitSprite(ROW, x, y, ROW_WIDTH, ROW_HEIGHT); for (int column = i * COLUMNS; column < Math.min(i * COLUMNS + COLUMNS, items.size()); ++column) { - final CraftingPreviewItem item = items.get(column); + final AutocraftingPreviewItem item = items.get(column); final int xx = x + (column % COLUMNS) * 74; renderCell(graphics, xx, y, item, mouseX, mouseY); } @@ -261,7 +282,7 @@ private void renderRow(final GuiGraphics graphics, private void renderCell(final GuiGraphics graphics, final int x, final int y, - final CraftingPreviewItem item, + final AutocraftingPreviewItem item, final double mouseX, final double mouseY) { if (item.missing() > 0) { @@ -303,7 +324,7 @@ private void renderCellText(final GuiGraphics graphics, SmallText.render( graphics, font, - createTranslation("gui", "crafting_preview." + type, rendering.formatAmount(amount, true)) + createTranslation("gui", "autocrafting_preview." + type, rendering.formatAmount(amount, true)) .getVisualOrderText(), x, y, @@ -386,8 +407,22 @@ protected void onAmountFieldChanged() { return; } confirmButton.active = false; - final boolean valid = getAndValidateAmount().isPresent(); - amountField.setTextColor(valid ? 0xFFFFFF : 0xFF5555); + confirmButton.setError(false); + confirmButton.setTooltip(null); + confirmButton.setMessage(PENDING); + getAndValidateAmount().ifPresentOrElse(amount -> { + changedAmount = amount; + amountField.setTextColor(0xFFFFFF); + }, () -> amountField.setTextColor(0xFF5555)); + } + + @Override + protected void containerTick() { + super.containerTick(); + if (changedAmount != null && requestRateLimiter.tryAcquire()) { + getMenu().amountChanged(changedAmount); + changedAmount = null; + } } @Override @@ -399,4 +434,14 @@ protected void reset() { protected boolean confirm(final Double amount) { return false; } + + @Override + public void requestChanged(final AutocraftingRequest request) { + setRequest(request); + } + + @Override + public void previewChanged(@Nullable final AutocraftingPreview preview) { + setPreview(preview); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java new file mode 100644 index 000000000..d53bef456 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java @@ -0,0 +1,7 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +public enum AutocraftingPreviewType { + SUCCESS, + MISSING_RESOURCES +} + diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java new file mode 100644 index 000000000..f3593d4ff --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java @@ -0,0 +1,72 @@ +package com.refinedmods.refinedstorage.common.autocrafting.preview; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.support.packet.c2s.C2SPackets; + +import java.util.UUID; +import javax.annotation.Nullable; + +public class AutocraftingRequest { + private final UUID id; + private final ResourceKey resource; + private final double amount; + @Nullable + private AutocraftingPreview preview; + private long pendingPreviewAmount; + + private AutocraftingRequest(final UUID id, final ResourceKey resource, final double amount) { + this.id = id; + this.resource = resource; + this.amount = amount; + } + + public static AutocraftingRequest of(final ResourceAmount resourceAmount) { + final double displayAmount = resourceAmount.resource() instanceof PlatformResourceKey platformResourceKey + ? platformResourceKey.getResourceType().getDisplayAmount(resourceAmount.amount()) + : resourceAmount.amount(); + return new AutocraftingRequest(UUID.randomUUID(), resourceAmount.resource(), displayAmount); + } + + boolean trySendRequest(final double amountRequested) { + if (!(resource instanceof PlatformResourceKey resourceKey)) { + return false; + } + final long normalizedAmount = resourceKey.getResourceType().normalizeAmount(amountRequested); + if (normalizedAmount == pendingPreviewAmount) { + return false; + } + this.preview = null; + this.pendingPreviewAmount = normalizedAmount; + C2SPackets.sendAutocraftingPreviewRequest(id, resourceKey, normalizedAmount); + return true; + } + + ResourceKey getResource() { + return resource; + } + + double getAmount() { + return amount; + } + + @Nullable + AutocraftingPreview getPreview() { + return preview; + } + + boolean previewReceived(final UUID idReceived, final AutocraftingPreview previewReceived) { + if (id.equals(idReceived)) { + pendingPreviewAmount = 0; + preview = previewReceived; + return true; + } + return false; + } + + void clearPreview() { + pendingPreviewAmount = 0; + preview = null; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequestButton.java similarity index 83% rename from refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java rename to refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequestButton.java index fb8ede269..050bdc89a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequestButton.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequestButton.java @@ -15,18 +15,18 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.network.chat.Component; -import static com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen.REQUEST_BUTTON_HEIGHT; -import static com.refinedmods.refinedstorage.common.autocrafting.preview.CraftingPreviewScreen.REQUEST_BUTTON_WIDTH; +import static com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen.REQUEST_BUTTON_HEIGHT; +import static com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen.REQUEST_BUTTON_WIDTH; -class CraftingRequestButton extends AbstractButton { - private final CraftingRequest request; +class AutocraftingRequestButton extends AbstractButton { + private final AutocraftingRequest request; private final TextMarquee text; - private final Consumer onPress; + private final Consumer onPress; - CraftingRequestButton(final int x, - final int y, - final CraftingRequest request, - final Consumer onPress) { + AutocraftingRequestButton(final int x, + final int y, + final AutocraftingRequest request, + final Consumer onPress) { super(x, y, REQUEST_BUTTON_WIDTH, REQUEST_BUTTON_HEIGHT, Component.empty()); this.request = request; final ResourceKey resource = request.getResource(); @@ -44,7 +44,7 @@ class CraftingRequestButton extends AbstractButton { this.onPress = onPress; } - CraftingRequest getRequest() { + AutocraftingRequest getRequest() { return request; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java deleted file mode 100644 index bbb5a4794..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreview.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import java.util.List; - -record CraftingPreview(boolean missing, List items) { -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java deleted file mode 100644 index 1388b7ba8..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewContainerMenu.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; -import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; -import com.refinedmods.refinedstorage.common.support.containermenu.DisabledResourceSlot; -import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; -import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; - -import java.util.Collections; -import java.util.List; - -import net.minecraft.network.chat.Component; - -class CraftingPreviewContainerMenu extends AbstractResourceContainerMenu { - private final List requests; - - private CraftingRequest currentRequest; - - CraftingPreviewContainerMenu(final List requests) { - super(null, 0); - final ResourceContainer resourceContainer = ResourceContainerImpl.createForFilter(1); - resourceContainer.set(0, new ResourceAmount(requests.getFirst().getResource(), 1)); - addSlot(new DisabledResourceSlot( - resourceContainer, - 0, - Component.empty(), - 157, - 48, - ResourceSlotType.FILTER - )); - this.requests = Collections.unmodifiableList(requests); - this.currentRequest = requests.getFirst(); - } - - List getRequests() { - return requests; - } - - CraftingRequest getCurrentRequest() { - return currentRequest; - } - - void setCurrentRequest(final CraftingRequest request) { - this.currentRequest = request; - } -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java deleted file mode 100644 index 84ec43f5b..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingPreviewItem.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.api.resource.ResourceKey; - -record CraftingPreviewItem(ResourceKey resource, long available, long missing, long toCraft) { -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java deleted file mode 100644 index d8d19fa1c..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/CraftingRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import com.refinedmods.refinedstorage.api.resource.ResourceKey; -import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; - -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nullable; - -public class CraftingRequest { - private final ResourceKey resource; - private final double amount; - @Nullable - private CraftingPreview preview; - - private CraftingRequest(final ResourceKey resource, final double amount) { - this.resource = resource; - this.amount = amount; - final List items = new ArrayList<>(); - for (int i = 0; i < 31; ++i) { - items.add(new CraftingPreviewItem(resource, i, i % 2 == 0 ? 999 : 0, i % 2 == 0 ? 0 : 1000)); - } - this.preview = new CraftingPreview(true, items); - } - - public static CraftingRequest of(final ResourceAmount resourceAmount) { - final double displayAmount = resourceAmount.resource() instanceof PlatformResourceKey platformResourceKey - ? platformResourceKey.getResourceType().getDisplayAmount(resourceAmount.amount()) - : resourceAmount.amount(); - return new CraftingRequest(resourceAmount.resource(), displayAmount); - } - - ResourceKey getResource() { - return resource; - } - - double getAmount() { - return amount; - } - - @Nullable - CraftingPreview getPreview() { - return preview; - } -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java index 8599226c3..f5ec39801 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java @@ -30,6 +30,10 @@ import com.refinedmods.refinedstorage.common.api.support.registry.PlatformRegistry; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewItem; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewType; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridExtractionStrategy; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridInsertionStrategy; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridScrollingStrategy; @@ -41,6 +45,8 @@ import com.refinedmods.refinedstorage.query.lexer.LexerTokenMappings; import com.refinedmods.refinedstorage.query.parser.ParserOperatorMappings; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiPredicate; @@ -58,7 +64,8 @@ import static java.util.Objects.requireNonNull; public abstract class AbstractGridContainerMenu extends AbstractResourceContainerMenu - implements GridWatcher, GridInsertionStrategy, GridExtractionStrategy, GridScrollingStrategy, ScreenSizeListener { + implements GridWatcher, GridInsertionStrategy, GridExtractionStrategy, GridScrollingStrategy, ScreenSizeListener, + AutocraftingPreviewProvider { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGridContainerMenu.class); private static final GridQueryParserImpl QUERY_PARSER = new GridQueryParserImpl( LexerTokenMappings.DEFAULT_MAPPINGS, @@ -483,6 +490,23 @@ protected ResourceKey getResourceForAutocraftableHint(final Slot slot) { return null; } + @Override + public AutocraftingPreview getPreview(final PlatformResourceKey resource, final long amount) { + final List items = new ArrayList<>(); + final boolean missing = amount == 404; + for (int i = 0; i < 31; ++i) { + items.add(new AutocraftingPreviewItem( + resource, + (i + 1), + (i % 2 == 0 && missing) ? amount : 0, + i % 2 == 0 ? 0 : amount + )); + } + return new AutocraftingPreview(missing + ? AutocraftingPreviewType.MISSING_RESOURCES + : AutocraftingPreviewType.SUCCESS, items); + } + public boolean isLargeSlot(final Slot slot) { return false; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java index d6f8ef3a4..f9cf67691 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java @@ -20,6 +20,7 @@ import org.joml.Vector3f; import org.lwjgl.glfw.GLFW; +import static com.refinedmods.refinedstorage.common.support.amount.ConfirmButton.ERROR_SIZE; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; public abstract class AbstractAmountScreen @@ -28,11 +29,12 @@ public abstract class AbstractAmountScreen reset()) + private Button addResetButton(final int x, final int y) { + final int width = configuration.isHorizontalActionButtons() + ? font.width(RESET_TEXT) + ACTION_BUTTON_SPACING + : ACTION_BUTTON_WIDTH; + return addRenderableWidget(Button.builder(RESET_TEXT, btn -> reset()) .pos(leftPos + x, topPos + y) - .size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT) + .size(width, ACTION_BUTTON_HEIGHT) .build()); } private void addConfirmButton(final int x, final int y) { - confirmButton = addRenderableWidget( - Button.builder(configuration.getConfirmButtonText(), btn -> tryConfirmAndCloseToParent()) - .pos(leftPos + x, topPos + y) - .size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT) - .build()); + final int width = configuration.isHorizontalActionButtons() + ? font.width(configuration.getConfirmButtonText()) + ACTION_BUTTON_SPACING + ERROR_SIZE + : ACTION_BUTTON_WIDTH; + confirmButton = addRenderableWidget(new ConfirmButton( + leftPos + x, + topPos + y, + width, + ACTION_BUTTON_HEIGHT, + configuration.getConfirmButtonText(), + btn -> tryConfirmAndCloseToParent() + )); } - private void addCancelButton(final int x, final int y) { - addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> tryCloseToParent()) + private Button addCancelButton(final int x, final int y) { + final int width = configuration.isHorizontalActionButtons() + ? font.width(CANCEL_TEXT) + ACTION_BUTTON_SPACING + : ACTION_BUTTON_WIDTH; + return addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> tryCloseToParent()) .pos(leftPos + x, topPos + y) - .size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT) + .size(width, ACTION_BUTTON_HEIGHT) .build()); } @@ -138,6 +153,7 @@ protected void onAmountFieldChanged() { final boolean valid = getAndValidateAmount().isPresent(); if (confirmButton != null) { confirmButton.active = valid; + confirmButton.setError(!valid); } else { tryConfirm(); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ConfirmButton.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ConfirmButton.java new file mode 100644 index 000000000..b4998c387 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/ConfirmButton.java @@ -0,0 +1,52 @@ +package com.refinedmods.refinedstorage.common.support.amount; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; + +public class ConfirmButton extends Button { + static final int ERROR_SIZE = 12; + + private static final ResourceLocation ERROR_ICON = createIdentifier("error"); + + private boolean error; + + public ConfirmButton(final int x, + final int y, + final int width, + final int height, + final Component message, + final OnPress onPress) { + super(x, y, width, height, message, onPress, DEFAULT_NARRATION); + } + + @Override + protected void renderWidget(final GuiGraphics graphics, + final int mouseX, + final int mouseY, + final float partialTick) { + super.renderWidget(graphics, mouseX, mouseY, partialTick); + if (error) { + graphics.blitSprite(ERROR_ICON, getX() + 4, getY() + 4, ERROR_SIZE, ERROR_SIZE); + } + } + + @Override + protected void renderScrollingString(final GuiGraphics graphics, + final Font font, + final int width, + final int color) { + final int offset = error ? (ERROR_SIZE - 6) : 0; + final int start = offset + getX() + width; + final int end = offset + getX() + getWidth() - width; + renderScrollingString(graphics, font, getMessage(), start, getY(), end, getY() + getHeight(), color); + } + + public void setError(final boolean error) { + this.error = error; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java new file mode 100644 index 000000000..3c5544aef --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java @@ -0,0 +1,48 @@ +package com.refinedmods.refinedstorage.common.support.packet.c2s; + +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; +import com.refinedmods.refinedstorage.common.support.packet.PacketContext; +import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; + +import java.util.UUID; + +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerPlayer; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; + +public record AutocraftingPreviewRequestPacket(UUID id, + PlatformResourceKey resource, + long amount) implements CustomPacketPayload { + public static final CustomPacketPayload.Type + PACKET_TYPE = new CustomPacketPayload.Type<>( + createIdentifier("autocrafting_preview_request") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec + .composite( + UUIDUtil.STREAM_CODEC, AutocraftingPreviewRequestPacket::id, + ResourceCodecs.STREAM_CODEC, AutocraftingPreviewRequestPacket::resource, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewRequestPacket::amount, + AutocraftingPreviewRequestPacket::new + ); + + public static void handle(final AutocraftingPreviewRequestPacket packet, final PacketContext ctx) { + if (ctx.getPlayer().containerMenu instanceof AutocraftingPreviewProvider provider) { + final AutocraftingPreview preview = provider.getPreview(packet.resource(), packet.amount()); + S2CPackets.sendAutocraftingPreviewResponse((ServerPlayer) ctx.getPlayer(), packet.id, preview); + } + } + + @Override + public CustomPacketPayload.Type type() { + return PACKET_TYPE; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java index 618e09aef..4aba50bee 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java @@ -131,4 +131,10 @@ public static void sendPatternGridSmithingTableRecipeTransfer(final List PACKET_TYPE = new Type<>( + createIdentifier("autocrafting_preview_response") + ); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + UUIDUtil.STREAM_CODEC, AutocraftingPreviewResponsePacket::id, + AutocraftingPreview.STREAM_CODEC, AutocraftingPreviewResponsePacket::preview, + AutocraftingPreviewResponsePacket::new + ); + + public static void handle(final AutocraftingPreviewResponsePacket packet) { + ClientPlatformUtil.craftingPreviewReceived(packet.id, packet.preview); + } + + @Override + public Type type() { + return PACKET_TYPE; + } +} + diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java index 2cc191708..ab1ef3796 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java @@ -5,6 +5,7 @@ import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.storage.StorageInfo; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; import com.refinedmods.refinedstorage.common.networking.NetworkTransmitterData; import java.util.Optional; @@ -85,4 +86,10 @@ public static void sendPatternGridAllowedAlternativesUpdate(final ServerPlayer p public static void sendCrafterNameUpdate(final ServerPlayer player, final Component name) { Platform.INSTANCE.sendPacketToClient(player, new CrafterNameUpdatePacket(name)); } + + public static void sendAutocraftingPreviewResponse(final ServerPlayer player, + final UUID id, + final AutocraftingPreview preview) { + Platform.INSTANCE.sendPacketToClient(player, new AutocraftingPreviewResponsePacket(id, preview)); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java index 72bf0d0dd..07ce08854 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java @@ -1,5 +1,9 @@ package com.refinedmods.refinedstorage.common.util; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen; + +import java.util.UUID; import javax.annotation.Nullable; import net.minecraft.client.Minecraft; @@ -30,4 +34,10 @@ public static void addNoPermissionToast(final Component message) { message ); } + + public static void craftingPreviewReceived(final UUID id, final AutocraftingPreview preview) { + if (Minecraft.getInstance().screen instanceof AutocraftingPreviewScreen screen) { + screen.getMenu().previewReceived(id, preview); + } + } } diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json index f59b5e5d4..23b21ddc2 100644 --- a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json +++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json @@ -6,7 +6,7 @@ "block.refinedstorage.disk_drive": "Disk Drive", "block.refinedstorage.machine_casing": "Machine Casing", "block.refinedstorage.grid": "Grid", - "block.refinedstorage.pattern_grid": "Pattern Fart Grid", + "block.refinedstorage.pattern_grid": "Pattern Grid", "block.refinedstorage.crafting_grid": "Crafting Grid", "block.refinedstorage.controller": "Controller", "block.refinedstorage.creative_controller": "Creative Controller", @@ -206,11 +206,13 @@ "gui.refinedstorage.crafter.chained.head_help": "This crafter is the head of the chain.", "gui.refinedstorage.crafter.not_chained": "Not chained", "gui.refinedstorage.crafter.not_chained.help": "If another crafter is facing this one, they'll form a chain, allowing you to have more patterns going into a single machine.", - "gui.refinedstorage.crafting_preview.start": "Start", - "gui.refinedstorage.crafting_preview.start.missing_resources": "There are missing resources.", - "gui.refinedstorage.crafting_preview.available": "Available: %s", - "gui.refinedstorage.crafting_preview.to_craft": "To craft: %s", - "gui.refinedstorage.crafting_preview.missing": "Missing: %s", + "gui.refinedstorage.autocrafting_preview.title": "Autocrafting", + "gui.refinedstorage.autocrafting_preview.start": "Start", + "gui.refinedstorage.autocrafting_preview.pending": "Pending", + "gui.refinedstorage.autocrafting_preview.start.missing_resources": "There are missing resources.", + "gui.refinedstorage.autocrafting_preview.available": "Available: %s", + "gui.refinedstorage.autocrafting_preview.to_craft": "To craft: %s", + "gui.refinedstorage.autocrafting_preview.missing": "Missing: %s", "item.refinedstorage.controller.help": "Provides the storage network with energy. Multiple are allowed in a single storage network.", "item.refinedstorage.creative_controller.help": "Provides the storage network with an infinite source of energy.", "item.refinedstorage.disk_drive.help": "Accepts storage disks to provide the storage network with storage space.", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/autocrafting_preview.png similarity index 100% rename from refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png rename to refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/autocrafting_preview.png diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/crafting_requests.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/autocrafting_preview/requests.png similarity index 100% rename from refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/crafting_requests.png rename to refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/autocrafting_preview/requests.png diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/row.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/autocrafting_preview/row.png similarity index 100% rename from refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/row.png rename to refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/autocrafting_preview/row.png diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/error.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/error.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee9da4ea1f73cf302fbfe1d1e938d49cc40d12f GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$3?vg*uel1O7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O=*!;1l9np{F<3!lKvI6ey6fHS;D&T}hB%@c;k+8631$egX113p^r=85sBu zgD~Uq{1qucK`T!e#}J9|+CEDm1_KTz&maHiZw|0X7Up8*4`E|EyO7=G)Gl+`B-idG qXG$6cK8drYNannjICrt~c%AW5hUGp|dtU=hVeoYIb6Mw<&;$VMB0LcQ literal 0 HcmV?d00001 diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java index fe960a80f..dd7ffd7ec 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java @@ -19,6 +19,7 @@ import com.refinedmods.refinedstorage.common.storagemonitor.StorageMonitorBlockEntityRenderer; import com.refinedmods.refinedstorage.common.support.network.item.NetworkItemPropertyFunction; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -290,6 +291,10 @@ private void registerPacketHandlers() { CrafterNameUpdatePacket.PACKET_TYPE, wrapHandler(CrafterNameUpdatePacket::handle) ); + ClientPlayNetworking.registerGlobalReceiver( + AutocraftingPreviewResponsePacket.PACKET_TYPE, + wrapHandler((packet, ctx) -> AutocraftingPreviewResponsePacket.handle(packet)) + ); } private static ClientPlayNetworking.PlayPayloadHandler wrapHandler( diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java index 92e3255ca..16747b7a0 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java @@ -29,6 +29,7 @@ import com.refinedmods.refinedstorage.common.storage.portablegrid.PortableGridType; import com.refinedmods.refinedstorage.common.support.AbstractBaseBlock; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; +import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingPreviewRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CrafterNameChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridClearPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridRecipeTransferPacket; @@ -53,6 +54,7 @@ import com.refinedmods.refinedstorage.common.support.packet.c2s.SingleAmountChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.StorageInfoRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.UseSlotReferencedItemPacket; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -443,6 +445,10 @@ private void registerServerToClientPackets() { CrafterNameUpdatePacket.PACKET_TYPE, CrafterNameUpdatePacket.STREAM_CODEC ); + PayloadTypeRegistry.playS2C().register( + AutocraftingPreviewResponsePacket.PACKET_TYPE, + AutocraftingPreviewResponsePacket.STREAM_CODEC + ); } private void registerClientToServerPackets() { @@ -530,6 +536,10 @@ private void registerClientToServerPackets() { CrafterNameChangePacket.PACKET_TYPE, CrafterNameChangePacket.STREAM_CODEC ); + PayloadTypeRegistry.playC2S().register( + AutocraftingPreviewRequestPacket.PACKET_TYPE, + AutocraftingPreviewRequestPacket.STREAM_CODEC + ); } private void registerPacketHandlers() { @@ -629,6 +639,10 @@ private void registerPacketHandlers() { CrafterNameChangePacket.PACKET_TYPE, wrapHandler(CrafterNameChangePacket::handle) ); + ServerPlayNetworking.registerGlobalReceiver( + AutocraftingPreviewRequestPacket.PACKET_TYPE, + wrapHandler(AutocraftingPreviewRequestPacket::handle) + ); } private static ServerPlayNetworking.PlayPayloadHandler wrapHandler( diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java index 537ae459f..79c413015 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java @@ -29,6 +29,7 @@ import com.refinedmods.refinedstorage.common.storage.portablegrid.PortableGridType; import com.refinedmods.refinedstorage.common.support.AbstractBaseBlock; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; +import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingPreviewRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CrafterNameChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridClearPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridRecipeTransferPacket; @@ -53,6 +54,7 @@ import com.refinedmods.refinedstorage.common.support.packet.c2s.SingleAmountChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.StorageInfoRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.UseSlotReferencedItemPacket; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -631,6 +633,11 @@ private static void registerServerToClientPackets(final PayloadRegistrar registr CrafterNameUpdatePacket.STREAM_CODEC, wrapHandler(CrafterNameUpdatePacket::handle) ); + registrar.playToClient( + AutocraftingPreviewResponsePacket.PACKET_TYPE, + AutocraftingPreviewResponsePacket.STREAM_CODEC, + wrapHandler((packet, ctx) -> AutocraftingPreviewResponsePacket.handle(packet)) + ); } private static void registerClientToServerPackets(final PayloadRegistrar registrar) { @@ -754,6 +761,11 @@ private static void registerClientToServerPackets(final PayloadRegistrar registr CrafterNameChangePacket.STREAM_CODEC, wrapHandler(CrafterNameChangePacket::handle) ); + registrar.playToServer( + AutocraftingPreviewRequestPacket.PACKET_TYPE, + AutocraftingPreviewRequestPacket.STREAM_CODEC, + wrapHandler(AutocraftingPreviewRequestPacket::handle) + ); } private static IPayloadHandler wrapHandler(final PacketHandler handler) { From 1b3a43e67e3306c5f9840a8c23acd3335a657dde Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Fri, 4 Oct 2024 20:40:09 +0200 Subject: [PATCH 4/5] feat: starting crafting tasks on the server Not autocrafting itself yet ;) --- .../common/RefinedStorageApiImpl.java | 2 +- .../AutocraftingPreviewContainerMenu.java | 26 ++++++- .../preview/AutocraftingPreviewListener.java | 2 + .../preview/AutocraftingPreviewProvider.java | 3 +- .../preview/AutocraftingPreviewScreen.java | 75 ++++++++++++++----- .../preview/AutocraftingRequest.java | 12 +++ .../grid/AbstractGridContainerMenu.java | 5 ++ .../grid/screen/AbstractGridScreen.java | 2 +- .../support/amount/AbstractAmountScreen.java | 2 +- .../packet/c2s/AutocraftingRequestPacket.java | 46 ++++++++++++ .../common/support/packet/c2s/C2SPackets.java | 6 ++ .../AutocraftingPreviewResponsePacket.java | 3 +- .../s2c/AutocraftingResponsePacket.java | 36 +++++++++ .../common/support/packet/s2c/S2CPackets.java | 6 ++ .../common/util/ClientPlatformUtil.java | 10 ++- .../fabric/ClientModInitializerImpl.java | 5 ++ .../fabric/ModInitializerImpl.java | 14 ++++ .../neoforge/ModInitializer.java | 12 +++ 18 files changed, 236 insertions(+), 31 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingResponsePacket.java diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index 1daca02e8..a7487641a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -614,7 +614,7 @@ public void openCraftingPreview(final List requests) { minecraft.setScreen(new AutocraftingPreviewScreen( minecraft.screen, inventory, - requests.stream().map(AutocraftingRequest::of).toList() + requests.stream().map(AutocraftingRequest::of).collect(Collectors.toList()) )); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java index a6d3da8ba..81054f343 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java @@ -7,7 +7,6 @@ import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; -import java.util.Collections; import java.util.List; import java.util.UUID; import javax.annotation.Nullable; @@ -33,7 +32,7 @@ public class AutocraftingPreviewContainerMenu extends AbstractResourceContainerM 48, ResourceSlotType.FILTER )); - this.requests = Collections.unmodifiableList(requests); + this.requests = requests; this.currentRequest = requests.getFirst(); } @@ -62,16 +61,35 @@ void amountChanged(final double amount) { } } - public void previewReceived(final UUID id, final AutocraftingPreview preview) { + public void previewResponseReceived(final UUID id, final AutocraftingPreview preview) { if (currentRequest.previewReceived(id, preview) && listener != null) { listener.previewChanged(preview); } } - public void loadCurrentRequest() { + void loadCurrentRequest() { if (listener != null) { currentRequest.clearPreview(); listener.requestChanged(currentRequest); } } + + void startRequest(final double amount) { + currentRequest.start(amount); + } + + boolean requestStarted(final UUID id) { + if (currentRequest.isStarted(id)) { + if (listener != null) { + listener.requestRemoved(currentRequest); + } + requests.remove(currentRequest); + if (!requests.isEmpty()) { + setCurrentRequest(requests.getFirst()); + return false; + } + return true; + } + return false; + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java index 984f2c520..eb6a0e3dd 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java @@ -6,4 +6,6 @@ interface AutocraftingPreviewListener { void requestChanged(AutocraftingRequest request); void previewChanged(@Nullable AutocraftingPreview preview); + + void requestRemoved(AutocraftingRequest request); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java index 1d42cb723..558056cb7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java @@ -2,7 +2,8 @@ import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -@FunctionalInterface public interface AutocraftingPreviewProvider { AutocraftingPreview getPreview(PlatformResourceKey resource, long amount); + + boolean start(PlatformResourceKey resource, long amount); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java index 03951eeed..4eef82282 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import javax.annotation.Nullable; import com.google.common.util.concurrent.RateLimiter; @@ -63,7 +64,7 @@ public class AutocraftingPreviewScreen extends AbstractAmountScreen requestButtons = new ArrayList<>(); private final boolean requestsButtonsVisible; - private final RateLimiter requestRateLimiter = RateLimiter.create(0.5); + private final RateLimiter requestRateLimiter = RateLimiter.create(1); @Nullable private Double changedAmount; @@ -111,10 +112,7 @@ protected void init() { initRequestButtons(); } if (confirmButton != null) { - confirmButton.active = false; - confirmButton.setMessage(START); - confirmButton.setTooltip(null); - confirmButton.setError(false); + setStartDisabled(); } getMenu().loadCurrentRequest(); getExclusionZones().add(new Rect2i( @@ -144,12 +142,7 @@ private void initRequestButtons() { requestButton.visible = isCraftingRequestButtonVisible(y); } }); - final int totalRequestButtons = getMenu().getRequests().size() - REQUESTS_VISIBLE; - final int maxOffset = requestButtonsScrollbar.isSmoothScrolling() - ? totalRequestButtons * REQUEST_BUTTON_HEIGHT - : totalRequestButtons; - requestButtonsScrollbar.setEnabled(maxOffset > 0); - requestButtonsScrollbar.setMaxOffset(maxOffset); + updateRequestsScrollbar(); for (int i = 0; i < getMenu().getRequests().size(); ++i) { final AutocraftingRequest request = getMenu().getRequests().get(i); final int buttonY = getCraftingRequestButtonY(i); @@ -189,19 +182,17 @@ private void setPreview(@Nullable final AutocraftingPreview preview) { if (previewItemsScrollbar == null || confirmButton == null) { return; } - confirmButton.setMessage(START); if (preview == null) { previewItemsScrollbar.setEnabled(false); previewItemsScrollbar.setMaxOffset(0); - confirmButton.active = false; - confirmButton.setError(false); - confirmButton.setTooltip(null); + setStartDisabled(); return; } final int items = preview.items().size(); final int rows = Math.ceilDiv(items, COLUMNS) - ROWS_VISIBLE; previewItemsScrollbar.setMaxOffset(previewItemsScrollbar.isSmoothScrolling() ? rows * ROW_HEIGHT : rows); previewItemsScrollbar.setEnabled(rows > 0); + confirmButton.setMessage(START); confirmButton.active = preview.type() == AutocraftingPreviewType.SUCCESS; confirmButton.setError(preview.type() != AutocraftingPreviewType.SUCCESS); confirmButton.setTooltip(preview.type() == AutocraftingPreviewType.MISSING_RESOURCES @@ -406,14 +397,28 @@ protected void onAmountFieldChanged() { if (amountField == null || confirmButton == null) { return; } + getAndValidateAmount().ifPresentOrElse(amount -> { + setPending(); + changedAmount = amount; + amountField.setTextColor(0xFFFFFF); + }, () -> { + setStartDisabled(); + amountField.setTextColor(0xFF5555); + }); + } + + private void setPending() { confirmButton.active = false; confirmButton.setError(false); confirmButton.setTooltip(null); confirmButton.setMessage(PENDING); - getAndValidateAmount().ifPresentOrElse(amount -> { - changedAmount = amount; - amountField.setTextColor(0xFFFFFF); - }, () -> amountField.setTextColor(0xFF5555)); + } + + private void setStartDisabled() { + confirmButton.active = false; + confirmButton.setError(false); + confirmButton.setTooltip(null); + confirmButton.setMessage(START); } @Override @@ -432,6 +437,8 @@ protected void reset() { @Override protected boolean confirm(final Double amount) { + setPending(); + getMenu().startRequest(amount); return false; } @@ -444,4 +451,34 @@ public void requestChanged(final AutocraftingRequest request) { public void previewChanged(@Nullable final AutocraftingPreview preview) { setPreview(preview); } + + @Override + public void requestRemoved(final AutocraftingRequest request) { + requestButtons.removeIf(requestButton -> requestButton.getRequest() == request); + updateRequestsScrollbar(); + for (int i = 0; i < requestButtons.size(); ++i) { + final AutocraftingRequestButton requestButton = requestButtons.get(i); + final int buttonY = getCraftingRequestButtonY(i); + requestButton.setY(buttonY); + requestButton.visible = isCraftingRequestButtonVisible(buttonY); + } + } + + private void updateRequestsScrollbar() { + if (requestButtonsScrollbar == null) { + return; + } + final int totalRequestButtons = getMenu().getRequests().size() - REQUESTS_VISIBLE; + final int maxOffset = requestButtonsScrollbar.isSmoothScrolling() + ? totalRequestButtons * REQUEST_BUTTON_HEIGHT + : totalRequestButtons; + requestButtonsScrollbar.setEnabled(maxOffset > 0); + requestButtonsScrollbar.setMaxOffset(maxOffset); + } + + public void responseReceived(final UUID id, final boolean started) { + if (started && getMenu().requestStarted(id)) { + tryCloseToParent(); + } + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java index f3593d4ff..714845084 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java @@ -43,6 +43,14 @@ boolean trySendRequest(final double amountRequested) { return true; } + void start(final double amountRequested) { + if (!(resource instanceof PlatformResourceKey resourceKey)) { + return; + } + final long normalizedAmount = resourceKey.getResourceType().normalizeAmount(amountRequested); + C2SPackets.sendAutocraftingRequest(id, resourceKey, normalizedAmount); + } + ResourceKey getResource() { return resource; } @@ -69,4 +77,8 @@ void clearPreview() { pendingPreviewAmount = 0; preview = null; } + + boolean isStarted(final UUID startedId) { + return id.equals(startedId); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java index f5ec39801..fcfe79c88 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java @@ -507,6 +507,11 @@ public AutocraftingPreview getPreview(final PlatformResourceKey resource, final : AutocraftingPreviewType.SUCCESS, items); } + @Override + public boolean start(final PlatformResourceKey resource, final long amount) { + return true; + } + public boolean isLargeSlot(final Slot slot) { return false; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index b124ae275..9747967b0 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -524,7 +524,7 @@ private static boolean tryStartAutocrafting(final PlatformGridResource resource) requests.add(new ResourceAmount(request.resource(), request.amount() * 2)); requests.add(new ResourceAmount(request.resource(), request.amount() * 3)); requests.add(new ResourceAmount(request.resource(), request.amount() * 4)); - requests.add(new ResourceAmount(request.resource(), request.amount() * 5)); + requests.add(new ResourceAmount(request.resource(), request.amount() * 4)); } RefinedStorageApi.INSTANCE.openCraftingPreview(requests); return true; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java index f9cf67691..e585d2fcf 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java @@ -286,7 +286,7 @@ private void tryConfirmAndCloseToParent() { }); } - private boolean tryCloseToParent() { + protected final boolean tryCloseToParent() { if (parent != null) { Minecraft.getInstance().setScreen(parent); return true; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java new file mode 100644 index 000000000..2b2ea00a0 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java @@ -0,0 +1,46 @@ +package com.refinedmods.refinedstorage.common.support.packet.c2s; + +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; +import com.refinedmods.refinedstorage.common.support.packet.PacketContext; +import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; + +import java.util.UUID; + +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerPlayer; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; + +public record AutocraftingRequestPacket(UUID id, + PlatformResourceKey resource, + long amount) implements CustomPacketPayload { + public static final Type PACKET_TYPE = new Type<>( + createIdentifier("autocrafting_request") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec + .composite( + UUIDUtil.STREAM_CODEC, AutocraftingRequestPacket::id, + ResourceCodecs.STREAM_CODEC, AutocraftingRequestPacket::resource, + ByteBufCodecs.VAR_LONG, AutocraftingRequestPacket::amount, + AutocraftingRequestPacket::new + ); + + public static void handle(final AutocraftingRequestPacket packet, final PacketContext ctx) { + if (ctx.getPlayer().containerMenu instanceof AutocraftingPreviewProvider provider) { + final boolean started = provider.start(packet.resource(), packet.amount()); + S2CPackets.sendAutocraftingResponse((ServerPlayer) ctx.getPlayer(), packet.id, started); + } + } + + @Override + public Type type() { + return PACKET_TYPE; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java index 4aba50bee..bc20c2224 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/C2SPackets.java @@ -137,4 +137,10 @@ public static void sendAutocraftingPreviewRequest(final UUID id, final long amount) { Platform.INSTANCE.sendPacketToServer(new AutocraftingPreviewRequestPacket(id, resource, amount)); } + + public static void sendAutocraftingRequest(final UUID id, + final PlatformResourceKey resource, + final long amount) { + Platform.INSTANCE.sendPacketToServer(new AutocraftingRequestPacket(id, resource, amount)); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java index e09b02d5b..bd9c8a1f1 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java @@ -1,7 +1,6 @@ package com.refinedmods.refinedstorage.common.support.packet.s2c; import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; -import com.refinedmods.refinedstorage.common.support.packet.PacketContext; import com.refinedmods.refinedstorage.common.util.ClientPlatformUtil; import java.util.UUID; @@ -26,7 +25,7 @@ public record AutocraftingPreviewResponsePacket(UUID id, AutocraftingPreview pre ); public static void handle(final AutocraftingPreviewResponsePacket packet) { - ClientPlatformUtil.craftingPreviewReceived(packet.id, packet.preview); + ClientPlatformUtil.autocraftingPreviewResponseReceived(packet.id, packet.preview); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingResponsePacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingResponsePacket.java new file mode 100644 index 000000000..1b1467d63 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingResponsePacket.java @@ -0,0 +1,36 @@ +package com.refinedmods.refinedstorage.common.support.packet.s2c; + +import com.refinedmods.refinedstorage.common.util.ClientPlatformUtil; + +import java.util.UUID; + +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; + +public record AutocraftingResponsePacket(UUID id, boolean started) implements CustomPacketPayload { + public static final Type PACKET_TYPE = new Type<>( + createIdentifier("autocrafting_response") + ); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + UUIDUtil.STREAM_CODEC, AutocraftingResponsePacket::id, + ByteBufCodecs.BOOL, AutocraftingResponsePacket::started, + AutocraftingResponsePacket::new + ); + + public static void handle(final AutocraftingResponsePacket packet) { + ClientPlatformUtil.autocraftingResponseReceived(packet.id, packet.started); + } + + @Override + public Type type() { + return PACKET_TYPE; + } +} + diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java index ab1ef3796..623a0bd79 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java @@ -92,4 +92,10 @@ public static void sendAutocraftingPreviewResponse(final ServerPlayer player, final AutocraftingPreview preview) { Platform.INSTANCE.sendPacketToClient(player, new AutocraftingPreviewResponsePacket(id, preview)); } + + public static void sendAutocraftingResponse(final ServerPlayer player, + final UUID id, + final boolean started) { + Platform.INSTANCE.sendPacketToClient(player, new AutocraftingResponsePacket(id, started)); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java index 07ce08854..065af4437 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java @@ -35,9 +35,15 @@ public static void addNoPermissionToast(final Component message) { ); } - public static void craftingPreviewReceived(final UUID id, final AutocraftingPreview preview) { + public static void autocraftingPreviewResponseReceived(final UUID id, final AutocraftingPreview preview) { if (Minecraft.getInstance().screen instanceof AutocraftingPreviewScreen screen) { - screen.getMenu().previewReceived(id, preview); + screen.getMenu().previewResponseReceived(id, preview); + } + } + + public static void autocraftingResponseReceived(final UUID id, final boolean started) { + if (Minecraft.getInstance().screen instanceof AutocraftingPreviewScreen screen) { + screen.responseReceived(id, started); } } } diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java index dd7ffd7ec..37e89fd79 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java @@ -20,6 +20,7 @@ import com.refinedmods.refinedstorage.common.support.network.item.NetworkItemPropertyFunction; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -295,6 +296,10 @@ private void registerPacketHandlers() { AutocraftingPreviewResponsePacket.PACKET_TYPE, wrapHandler((packet, ctx) -> AutocraftingPreviewResponsePacket.handle(packet)) ); + ClientPlayNetworking.registerGlobalReceiver( + AutocraftingResponsePacket.PACKET_TYPE, + wrapHandler((packet, ctx) -> AutocraftingResponsePacket.handle(packet)) + ); } private static ClientPlayNetworking.PlayPayloadHandler wrapHandler( diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java index 16747b7a0..dc3f23626 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java @@ -30,6 +30,7 @@ import com.refinedmods.refinedstorage.common.support.AbstractBaseBlock; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingPreviewRequestPacket; +import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CrafterNameChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridClearPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridRecipeTransferPacket; @@ -55,6 +56,7 @@ import com.refinedmods.refinedstorage.common.support.packet.c2s.StorageInfoRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.UseSlotReferencedItemPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -449,6 +451,10 @@ private void registerServerToClientPackets() { AutocraftingPreviewResponsePacket.PACKET_TYPE, AutocraftingPreviewResponsePacket.STREAM_CODEC ); + PayloadTypeRegistry.playS2C().register( + AutocraftingResponsePacket.PACKET_TYPE, + AutocraftingResponsePacket.STREAM_CODEC + ); } private void registerClientToServerPackets() { @@ -540,6 +546,10 @@ private void registerClientToServerPackets() { AutocraftingPreviewRequestPacket.PACKET_TYPE, AutocraftingPreviewRequestPacket.STREAM_CODEC ); + PayloadTypeRegistry.playC2S().register( + AutocraftingRequestPacket.PACKET_TYPE, + AutocraftingRequestPacket.STREAM_CODEC + ); } private void registerPacketHandlers() { @@ -643,6 +653,10 @@ private void registerPacketHandlers() { AutocraftingPreviewRequestPacket.PACKET_TYPE, wrapHandler(AutocraftingPreviewRequestPacket::handle) ); + ServerPlayNetworking.registerGlobalReceiver( + AutocraftingRequestPacket.PACKET_TYPE, + wrapHandler(AutocraftingRequestPacket::handle) + ); } private static ServerPlayNetworking.PlayPayloadHandler wrapHandler( diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java index 79c413015..a8b9ebd5a 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java @@ -30,6 +30,7 @@ import com.refinedmods.refinedstorage.common.support.AbstractBaseBlock; import com.refinedmods.refinedstorage.common.support.packet.PacketHandler; import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingPreviewRequestPacket; +import com.refinedmods.refinedstorage.common.support.packet.c2s.AutocraftingRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CrafterNameChangePacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridClearPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.CraftingGridRecipeTransferPacket; @@ -55,6 +56,7 @@ import com.refinedmods.refinedstorage.common.support.packet.c2s.StorageInfoRequestPacket; import com.refinedmods.refinedstorage.common.support.packet.c2s.UseSlotReferencedItemPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingPreviewResponsePacket; +import com.refinedmods.refinedstorage.common.support.packet.s2c.AutocraftingResponsePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.CrafterNameUpdatePacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.EnergyInfoPacket; import com.refinedmods.refinedstorage.common.support.packet.s2c.GridActivePacket; @@ -638,6 +640,11 @@ private static void registerServerToClientPackets(final PayloadRegistrar registr AutocraftingPreviewResponsePacket.STREAM_CODEC, wrapHandler((packet, ctx) -> AutocraftingPreviewResponsePacket.handle(packet)) ); + registrar.playToClient( + AutocraftingResponsePacket.PACKET_TYPE, + AutocraftingResponsePacket.STREAM_CODEC, + wrapHandler((packet, ctx) -> AutocraftingResponsePacket.handle(packet)) + ); } private static void registerClientToServerPackets(final PayloadRegistrar registrar) { @@ -766,6 +773,11 @@ private static void registerClientToServerPackets(final PayloadRegistrar registr AutocraftingPreviewRequestPacket.STREAM_CODEC, wrapHandler(AutocraftingPreviewRequestPacket::handle) ); + registrar.playToServer( + AutocraftingRequestPacket.PACKET_TYPE, + AutocraftingRequestPacket.STREAM_CODEC, + wrapHandler(AutocraftingRequestPacket::handle) + ); } private static IPayloadHandler wrapHandler(final PacketHandler handler) { From fb0c927c15c4e665f4895056c2582d0dd4c99e93 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Fri, 4 Oct 2024 22:47:51 +0200 Subject: [PATCH 5/5] feat: storage monitor autocrafting Only if the resource could no longer be extracted, try trigger autocrafting. I tried to reuse shift clicking for this to force autocrafting, but shift is already used to only extract one of a resource. You have to wait 250ms until the last extract to trigger autocrafting as attack method from block might be called very often, and we don't want open the autocrafting window when it's not needed (eg right after an extract). --- CHANGELOG.md | 1 + .../api/autocrafting/AutocraftingPreview.java | 6 ++ .../autocrafting/AutocraftingPreviewItem.java | 6 ++ .../AutocraftingPreviewProvider.java | 11 ++++ .../AutocraftingPreviewType.java | 2 +- .../refinedstorage/common/api/grid/Grid.java | 3 +- .../common/AbstractClientModInitializer.java | 11 ++++ .../common/AbstractModInitializer.java | 9 +++ .../common/RefinedStorageApiImpl.java | 2 +- .../preview/AutocraftingPreview.java | 18 ------ .../AutocraftingPreviewContainerMenu.java | 15 ++++- .../preview/AutocraftingPreviewItem.java | 18 ------ .../preview/AutocraftingPreviewListener.java | 2 + .../preview/AutocraftingPreviewProvider.java | 9 --- .../preview/AutocraftingPreviewScreen.java | 19 +++++- .../preview/AutocraftingRequest.java | 1 + .../refinedstorage/common/content/Menus.java | 13 +++++ .../common/grid/AbstractGridBlockEntity.java | 19 ++++++ .../grid/AbstractGridContainerMenu.java | 29 +++------- .../common/grid/WirelessGrid.java | 17 ++++++ .../common/grid/screen/GridScreen.java | 2 +- .../storage/portablegrid/PortableGrid.java | 13 +++++ ...tocraftingStorageMonitorContainerMenu.java | 50 ++++++++++++++++ ...ingStorageMonitorExtendedMenuProvider.java | 46 +++++++++++++++ .../storagemonitor/StorageMonitorBlock.java | 3 +- .../StorageMonitorBlockEntity.java | 58 ++++++++++++++++--- .../support/amount/AbstractAmountScreen.java | 14 +++-- .../c2s/AutocraftingPreviewRequestPacket.java | 9 +-- .../packet/c2s/AutocraftingRequestPacket.java | 2 +- .../AutocraftingPreviewResponsePacket.java | 26 ++++++++- .../common/support/packet/s2c/S2CPackets.java | 2 +- .../common/util/ClientPlatformUtil.java | 2 +- .../AutocraftingNetworkComponent.java | 3 +- .../AutocraftingNetworkComponentImpl.java | 28 +++++++++ .../AutocraftingNetworkComponentImplTest.java | 10 ++++ 35 files changed, 379 insertions(+), 100 deletions(-) create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreview.java create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewItem.java create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewProvider.java rename {refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview => refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting}/AutocraftingPreviewType.java (53%) delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java delete mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorContainerMenu.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorExtendedMenuProvider.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 0adf911b2..afca303c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - The crafting amount and crafting preview screens have been merged. Changing the amount will update the live preview. - The numbers on the crafting preview screen are now compacted with units. - When requesting autocrafting multiple resources at once, which can happen via a recipe mod, all the crafting requests are now listed on the side of the GUI. +- You can now request autocrafting from the Storage Monitor if the resource count reaches zero. ### Fixed diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreview.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreview.java new file mode 100644 index 000000000..e11e56a4f --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreview.java @@ -0,0 +1,6 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import java.util.List; + +public record AutocraftingPreview(AutocraftingPreviewType type, List items) { +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewItem.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewItem.java new file mode 100644 index 000000000..82919b373 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewItem.java @@ -0,0 +1,6 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +public record AutocraftingPreviewItem(ResourceKey resource, long available, long missing, long toCraft) { +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewProvider.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewProvider.java new file mode 100644 index 000000000..207a0d2fd --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewProvider.java @@ -0,0 +1,11 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Optional; + +public interface AutocraftingPreviewProvider { + Optional getPreview(ResourceKey resource, long amount); + + boolean start(ResourceKey resource, long amount); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewType.java similarity index 53% rename from refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java rename to refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewType.java index d53bef456..3d1832829 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewType.java +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AutocraftingPreviewType.java @@ -1,4 +1,4 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; +package com.refinedmods.refinedstorage.api.autocrafting; public enum AutocraftingPreviewType { SUCCESS, diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java index a493a55c0..e02e7412e 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.api.grid; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.api.grid.operations.GridOperations; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcher; import com.refinedmods.refinedstorage.api.storage.Actor; @@ -15,7 +16,7 @@ import org.apiguardian.api.API; @API(status = API.Status.STABLE, since = "2.0.0-milestone.3.0") -public interface Grid { +public interface Grid extends AutocraftingPreviewProvider { void addWatcher(GridWatcher watcher, Class actorType); void removeWatcher(GridWatcher watcher); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java index c1cc720b8..30fd6efb1 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java @@ -5,6 +5,8 @@ import com.refinedmods.refinedstorage.common.api.upgrade.UpgradeMapping; import com.refinedmods.refinedstorage.common.autocrafting.CrafterScreen; import com.refinedmods.refinedstorage.common.autocrafting.PatternGridScreen; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewContainerMenu; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen; import com.refinedmods.refinedstorage.common.constructordestructor.ConstructorScreen; import com.refinedmods.refinedstorage.common.constructordestructor.DestructorScreen; import com.refinedmods.refinedstorage.common.content.Items; @@ -93,6 +95,15 @@ protected static void registerScreens(final ScreenRegistration registration) { registration.register(Menus.INSTANCE.getRelay(), RelayScreen::new); registration.register(Menus.INSTANCE.getDiskInterface(), DiskInterfaceScreen::new); registration.register(Menus.INSTANCE.getCrafter(), CrafterScreen::new); + registration.register(Menus.INSTANCE.getAutocraftingStorageMonitor(), + new ScreenConstructor() { + @Override + public AutocraftingPreviewScreen create(final AutocraftingPreviewContainerMenu menu, + final Inventory inventory, + final Component title) { + return new AutocraftingPreviewScreen(menu, inventory, title); + } + }); } protected static void registerAlternativeGridHints() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java index 75373db79..b6b25841c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java @@ -121,6 +121,7 @@ import com.refinedmods.refinedstorage.common.storage.storageblock.StorageBlockLootItemFunction; import com.refinedmods.refinedstorage.common.storage.storagedisk.FluidStorageDiskItem; import com.refinedmods.refinedstorage.common.storage.storagedisk.ItemStorageDiskItem; +import com.refinedmods.refinedstorage.common.storagemonitor.AutocraftingStorageMonitorContainerMenu; import com.refinedmods.refinedstorage.common.storagemonitor.FluidStorageMonitorExtractionStrategy; import com.refinedmods.refinedstorage.common.storagemonitor.FluidStorageMonitorInsertionStrategy; import com.refinedmods.refinedstorage.common.storagemonitor.ItemStorageMonitorExtractionStrategy; @@ -136,6 +137,7 @@ import com.refinedmods.refinedstorage.common.support.network.component.PlatformStorageNetworkComponent; import com.refinedmods.refinedstorage.common.support.resource.FluidResourceContainerInsertStrategy; import com.refinedmods.refinedstorage.common.support.resource.FluidResourceFactory; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerData; import com.refinedmods.refinedstorage.common.support.resource.ResourceTypes; import com.refinedmods.refinedstorage.common.support.slotreference.InventorySlotReferenceFactory; @@ -745,6 +747,13 @@ protected final void registerMenus(final RegistryCallback> callback, ContentIds.STORAGE_MONITOR, () -> extendedMenuTypeFactory.create(StorageMonitorContainerMenu::new, ResourceContainerData.STREAM_CODEC) )); + Menus.INSTANCE.setAutocraftingStorageMonitor(callback.register( + createIdentifier("autocrafting_storage_monitor"), + () -> extendedMenuTypeFactory.create( + (syncId, playerInventory, data) -> new AutocraftingStorageMonitorContainerMenu(syncId, data), + ResourceCodecs.STREAM_CODEC + ) + )); Menus.INSTANCE.setNetworkTransmitter(callback.register( ContentIds.NETWORK_TRANSMITTER, () -> extendedMenuTypeFactory.create(NetworkTransmitterContainerMenu::new, diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index a7487641a..1daca02e8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -614,7 +614,7 @@ public void openCraftingPreview(final List requests) { minecraft.setScreen(new AutocraftingPreviewScreen( minecraft.screen, inventory, - requests.stream().map(AutocraftingRequest::of).collect(Collectors.toList()) + requests.stream().map(AutocraftingRequest::of).toList() )); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java deleted file mode 100644 index afd1946f6..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreview.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.common.util.PlatformUtil; - -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; - -public record AutocraftingPreview(AutocraftingPreviewType type, List items) { - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - PlatformUtil.enumStreamCodec(AutocraftingPreviewType.values()), AutocraftingPreview::type, - ByteBufCodecs.collection(ArrayList::new, AutocraftingPreviewItem.STREAM_CODEC), AutocraftingPreview::items, - AutocraftingPreview::new - ); -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java index 81054f343..2b9bc38d9 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewContainerMenu.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; @@ -7,11 +8,13 @@ import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.annotation.Nullable; import net.minecraft.network.chat.Component; +import net.minecraft.world.inventory.MenuType; public class AutocraftingPreviewContainerMenu extends AbstractResourceContainerMenu { private final List requests; @@ -21,7 +24,15 @@ public class AutocraftingPreviewContainerMenu extends AbstractResourceContainerM private AutocraftingPreviewListener listener; AutocraftingPreviewContainerMenu(final List requests) { - super(null, 0); + this(null, 0, requests); + } + + public AutocraftingPreviewContainerMenu(@Nullable final MenuType type, + final int syncId, + final List requests) { + super(type, syncId); + this.requests = new ArrayList<>(requests); + this.currentRequest = requests.getFirst(); final ResourceContainer resourceContainer = ResourceContainerImpl.createForFilter(1); resourceContainer.set(0, new ResourceAmount(requests.getFirst().getResource(), 1)); addSlot(new DisabledResourceSlot( @@ -32,8 +43,6 @@ public class AutocraftingPreviewContainerMenu extends AbstractResourceContainerM 48, ResourceSlotType.FILTER )); - this.requests = requests; - this.currentRequest = requests.getFirst(); } void setListener(final AutocraftingPreviewListener listener) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java deleted file mode 100644 index c82b2e9f1..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewItem.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; - -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; - -public record AutocraftingPreviewItem(PlatformResourceKey resource, long available, long missing, long toCraft) { - static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ResourceCodecs.STREAM_CODEC, AutocraftingPreviewItem::resource, - ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::available, - ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::missing, - ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::toCraft, - AutocraftingPreviewItem::new - ); -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java index eb6a0e3dd..5ba959f4e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewListener.java @@ -1,5 +1,7 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; + import javax.annotation.Nullable; interface AutocraftingPreviewListener { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java deleted file mode 100644 index 558056cb7..000000000 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewProvider.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.refinedmods.refinedstorage.common.autocrafting.preview; - -import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; - -public interface AutocraftingPreviewProvider { - AutocraftingPreview getPreview(PlatformResourceKey resource, long amount); - - boolean start(PlatformResourceKey resource, long amount); -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java index 4eef82282..fabe0d70a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingPreviewScreen.java @@ -1,5 +1,8 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewItem; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewType; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; import com.refinedmods.refinedstorage.common.support.amount.AbstractAmountScreen; @@ -72,8 +75,20 @@ public class AutocraftingPreviewScreen extends AbstractAmountScreen requests) { + this(new AutocraftingPreviewContainerMenu(requests), parent, playerInventory); + } + + public AutocraftingPreviewScreen(final AutocraftingPreviewContainerMenu menu, + final Inventory playerInventory, + final Component title) { + this(menu, null, playerInventory); + } + + public AutocraftingPreviewScreen(final AutocraftingPreviewContainerMenu menu, + @Nullable final Screen parent, + final Inventory playerInventory) { super( - new AutocraftingPreviewContainerMenu(requests), + menu, parent, playerInventory, TITLE, @@ -478,7 +493,7 @@ private void updateRequestsScrollbar() { public void responseReceived(final UUID id, final boolean started) { if (started && getMenu().requestStarted(id)) { - tryCloseToParent(); + close(); } } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java index 714845084..f93798dd7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/preview/AutocraftingRequest.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.autocrafting.preview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java index eba2dc15d..57d8771d3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java @@ -2,6 +2,7 @@ import com.refinedmods.refinedstorage.common.autocrafting.CrafterContainerMenu; import com.refinedmods.refinedstorage.common.autocrafting.PatternGridContainerMenu; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewContainerMenu; import com.refinedmods.refinedstorage.common.constructordestructor.ConstructorContainerMenu; import com.refinedmods.refinedstorage.common.constructordestructor.DestructorContainerMenu; import com.refinedmods.refinedstorage.common.controller.ControllerContainerMenu; @@ -75,6 +76,8 @@ public final class Menus { @Nullable private Supplier> storageMonitor; @Nullable + private Supplier> autocraftingStorageMonitor; + @Nullable private Supplier> networkTransmitter; @Nullable private Supplier> portableGridBlock; @@ -240,6 +243,16 @@ public void setStorageMonitor(final Supplier getAutocraftingStorageMonitor() { + return requireNonNull(autocraftingStorageMonitor).get(); + } + + public void setAutocraftingStorageMonitor( + final Supplier> supplier + ) { + this.autocraftingStorageMonitor = supplier; + } + public MenuType getNetworkTransmitter() { return requireNonNull(networkTransmitter).get(); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java index c29cc6df3..30988fee3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.grid; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.grid.operations.GridOperations; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcher; import com.refinedmods.refinedstorage.api.network.Network; @@ -7,6 +8,7 @@ import com.refinedmods.refinedstorage.api.network.impl.node.container.NetworkNodeContainerPriorities; import com.refinedmods.refinedstorage.api.network.impl.node.grid.GridNetworkNode; import com.refinedmods.refinedstorage.api.network.storage.StorageNetworkComponent; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.storage.Actor; import com.refinedmods.refinedstorage.api.storage.Storage; import com.refinedmods.refinedstorage.api.storage.TrackedResourceAmount; @@ -23,6 +25,7 @@ import com.refinedmods.refinedstorage.common.support.network.ColoredConnectionStrategy; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -97,6 +100,22 @@ public void removeWatcher(final GridWatcher watcher) { mainNetworkNode.removeWatcher(watcher); } + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + return Optional.ofNullable(mainNetworkNode.getNetwork()) + .map(network -> network.getComponent(AutocraftingNetworkComponent.class)) + .flatMap(component -> component.getPreview(resource, amount)); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + final Network network = mainNetworkNode.getNetwork(); + if (network == null) { + return false; + } + return network.getComponent(AutocraftingNetworkComponent.class).start(resource, amount); + } + @Override protected boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState oldBlockState, final BlockState newBlockState) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java index fcfe79c88..158af2302 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java @@ -1,5 +1,7 @@ package com.refinedmods.refinedstorage.common.grid; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl; @@ -30,10 +32,6 @@ import com.refinedmods.refinedstorage.common.api.support.registry.PlatformRegistry; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewItem; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewType; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridExtractionStrategy; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridInsertionStrategy; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridScrollingStrategy; @@ -45,9 +43,8 @@ import com.refinedmods.refinedstorage.query.lexer.LexerTokenMappings; import com.refinedmods.refinedstorage.query.parser.ParserOperatorMappings; -import java.util.ArrayList; -import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.BiPredicate; import javax.annotation.Nullable; @@ -491,25 +488,13 @@ protected ResourceKey getResourceForAutocraftableHint(final Slot slot) { } @Override - public AutocraftingPreview getPreview(final PlatformResourceKey resource, final long amount) { - final List items = new ArrayList<>(); - final boolean missing = amount == 404; - for (int i = 0; i < 31; ++i) { - items.add(new AutocraftingPreviewItem( - resource, - (i + 1), - (i % 2 == 0 && missing) ? amount : 0, - i % 2 == 0 ? 0 : amount - )); - } - return new AutocraftingPreview(missing - ? AutocraftingPreviewType.MISSING_RESOURCES - : AutocraftingPreviewType.SUCCESS, items); + public Optional getPreview(final ResourceKey resource, final long amount) { + return requireNonNull(grid).getPreview(resource, amount); } @Override - public boolean start(final PlatformResourceKey resource, final long amount) { - return true; + public boolean start(final ResourceKey resource, final long amount) { + return requireNonNull(grid).start(resource, amount); } public boolean isLargeSlot(final Slot slot) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java index e471c6e77..765b3a92e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java @@ -1,12 +1,15 @@ package com.refinedmods.refinedstorage.common.grid; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.grid.operations.GridOperations; import com.refinedmods.refinedstorage.api.grid.operations.NoopGridOperations; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcher; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcherManager; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcherManagerImpl; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent; import com.refinedmods.refinedstorage.api.network.storage.StorageNetworkComponent; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.storage.Actor; import com.refinedmods.refinedstorage.api.storage.NoopStorage; import com.refinedmods.refinedstorage.api.storage.Storage; @@ -100,4 +103,18 @@ private GridOperations createGridOperations(final ResourceType resourceType, final GridOperations operations = resourceType.createGridOperations(rootStorage, playerActor); return new SecuredGridOperations(player, securityNetworkComponent, operations); } + + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + return context.resolveNetwork() + .map(network -> network.getComponent(AutocraftingNetworkComponent.class)) + .flatMap(component -> component.getPreview(resource, amount)); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + return context.resolveNetwork() + .map(network -> network.getComponent(AutocraftingNetworkComponent.class).start(resource, amount)) + .orElse(false); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java index 740c4d1e7..58cb19f21 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/GridScreen.java @@ -9,7 +9,7 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; public class GridScreen extends AbstractGridScreen { - private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/grid2.png"); + private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/grid.png"); public GridScreen(final T menu, final Inventory inventory, final Component title) { super(menu, inventory, title, 99); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java index f7455d5fc..f38d75ae6 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.storage.portablegrid; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.core.Action; import com.refinedmods.refinedstorage.api.grid.operations.GridOperations; import com.refinedmods.refinedstorage.api.grid.operations.NoopGridOperations; @@ -7,6 +8,7 @@ import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcherManager; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcherManagerImpl; import com.refinedmods.refinedstorage.api.network.energy.EnergyStorage; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.storage.Actor; import com.refinedmods.refinedstorage.api.storage.NoopStorage; import com.refinedmods.refinedstorage.api.storage.StateTrackedStorage; @@ -23,6 +25,7 @@ import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; @@ -126,4 +129,14 @@ public GridOperations createOperations(final ResourceType resourceType, final Se final GridOperations operations = resourceType.createGridOperations(rootStorage, new PlayerActor(player)); return new PortableGridOperations(operations, energyStorage); } + + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + return Optional.empty(); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + return false; + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorContainerMenu.java new file mode 100644 index 000000000..5cb83aa86 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorContainerMenu.java @@ -0,0 +1,50 @@ +package com.refinedmods.refinedstorage.common.storagemonitor; + +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewContainerMenu; +import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingRequest; +import com.refinedmods.refinedstorage.common.content.Menus; + +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; + +import static java.util.Objects.requireNonNull; + +public class AutocraftingStorageMonitorContainerMenu extends AutocraftingPreviewContainerMenu + implements AutocraftingPreviewProvider { + @Nullable + private final StorageMonitorBlockEntity storageMonitor; + + public AutocraftingStorageMonitorContainerMenu(final int syncId, final PlatformResourceKey resource) { + super(Menus.INSTANCE.getAutocraftingStorageMonitor(), syncId, getRequests(resource)); + this.storageMonitor = null; + } + + AutocraftingStorageMonitorContainerMenu(final int syncId, + final PlatformResourceKey resource, + final StorageMonitorBlockEntity storageMonitor) { + super(Menus.INSTANCE.getAutocraftingStorageMonitor(), syncId, getRequests(resource)); + this.storageMonitor = storageMonitor; + } + + private static List getRequests(final PlatformResourceKey resource) { + return List.of(AutocraftingRequest.of( + new ResourceAmount(resource, resource.getResourceType().normalizeAmount(1.0D)) + )); + } + + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + return requireNonNull(storageMonitor).getPreview(resource, amount); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + return requireNonNull(storageMonitor).start(resource, amount); + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorExtendedMenuProvider.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorExtendedMenuProvider.java new file mode 100644 index 000000000..876db6b15 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/AutocraftingStorageMonitorExtendedMenuProvider.java @@ -0,0 +1,46 @@ +package com.refinedmods.refinedstorage.common.storagemonitor; + +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.content.ContentNames; +import com.refinedmods.refinedstorage.common.support.containermenu.ExtendedMenuProvider; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamEncoder; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; + +class AutocraftingStorageMonitorExtendedMenuProvider implements ExtendedMenuProvider { + private final PlatformResourceKey resource; + private final StorageMonitorBlockEntity blockEntity; + + AutocraftingStorageMonitorExtendedMenuProvider(final PlatformResourceKey resource, + final StorageMonitorBlockEntity blockEntity) { + this.resource = resource; + this.blockEntity = blockEntity; + } + + @Override + public AbstractContainerMenu createMenu(final int syncId, + final Inventory inventory, + final Player player) { + return new AutocraftingStorageMonitorContainerMenu(syncId, resource, blockEntity); + } + + @Override + public Component getDisplayName() { + return ContentNames.STORAGE_MONITOR; + } + + @Override + public PlatformResourceKey getMenuData() { + return resource; + } + + @Override + public StreamEncoder getMenuCodec() { + return ResourceCodecs.STREAM_CODEC; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlock.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlock.java index 6168adf7b..ddf44f1b0 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlock.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlock.java @@ -15,6 +15,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; @@ -96,7 +97,7 @@ public void attack(final BlockState state, final Level level, final BlockPos pos if (hitDirection != direction.asDirection()) { return; } - storageMonitor.extract(player); + storageMonitor.extract((ServerPlayer) player); } private Direction getHitDirection(final Level level, final Player player) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlockEntity.java index 8b8925d9c..ec255feac 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storagemonitor/StorageMonitorBlockEntity.java @@ -1,6 +1,9 @@ package com.refinedmods.refinedstorage.common.storagemonitor; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.api.network.Network; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.impl.node.SimpleNetworkNode; import com.refinedmods.refinedstorage.api.network.storage.StorageNetworkComponent; import com.refinedmods.refinedstorage.api.resource.ResourceKey; @@ -9,6 +12,7 @@ import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; import com.refinedmods.refinedstorage.common.api.storage.root.FuzzyRootStorage; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.content.BlockEntities; import com.refinedmods.refinedstorage.common.content.ContentNames; @@ -21,6 +25,7 @@ import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; import com.refinedmods.refinedstorage.common.util.PlatformUtil; +import java.util.Optional; import javax.annotation.Nullable; import com.google.common.util.concurrent.RateLimiter; @@ -31,6 +36,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.codec.StreamEncoder; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -44,7 +50,7 @@ import org.slf4j.LoggerFactory; public class StorageMonitorBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity - implements NetworkNodeExtendedMenuProvider { + implements NetworkNodeExtendedMenuProvider, AutocraftingPreviewProvider { private static final Logger LOGGER = LoggerFactory.getLogger(StorageMonitorBlockEntity.class); private static final String TAG_CLIENT_FILTER = "cf"; @@ -57,6 +63,7 @@ public class StorageMonitorBlockEntity extends AbstractBaseNetworkNodeContainerB private long currentAmount; private boolean currentlyActive; + private long lastExtractTime; public StorageMonitorBlockEntity(final BlockPos pos, final BlockState state) { super(BlockEntities.INSTANCE.getStorageMonitor(), pos, state, new SimpleNetworkNode( @@ -109,7 +116,7 @@ private long getAmount(final Network network, final ResourceKey configuredResour .sum(); } - public void extract(final Player player) { + public void extract(final ServerPlayer player) { if (level == null) { return; } @@ -117,14 +124,34 @@ public void extract(final Player player) { if (network == null) { return; } - final ResourceKey configuredResource = getConfiguredResource(); + final PlatformResourceKey configuredResource = getConfiguredResource(); if (configuredResource == null) { return; } - doExtract(level, player, configuredResource, network); + final boolean extracted = doExtract(level, player, configuredResource, network); + if (extracted) { + lastExtractTime = System.currentTimeMillis(); + } + if (!extracted && System.currentTimeMillis() - lastExtractTime > 250) { + tryAutocrafting(player, network, configuredResource); + } } - private void doExtract( + private void tryAutocrafting(final ServerPlayer player, + final Network network, + final PlatformResourceKey configuredResource) { + final boolean autocraftable = network.getComponent(AutocraftingNetworkComponent.class) + .getOutputs() + .contains(configuredResource); + if (autocraftable) { + Platform.INSTANCE.getMenuOpener().openMenu( + player, + new AutocraftingStorageMonitorExtendedMenuProvider(configuredResource, this) + ); + } + } + + private boolean doExtract( final Level level, final Player player, final ResourceKey configuredResource, @@ -138,7 +165,7 @@ private void doExtract( network ); if (!success) { - return; + return false; } sendDisplayUpdate(); level.playSound( @@ -149,6 +176,7 @@ private void doExtract( .2f, ((level.random.nextFloat() - level.random.nextFloat()) * .7f + 1) * 2 ); + return true; } public void insert(final Player player, final InteractionHand hand) { @@ -249,7 +277,7 @@ public void setFuzzyMode(final boolean fuzzyMode) { } @Nullable - public ResourceKey getConfiguredResource() { + public PlatformResourceKey getConfiguredResource() { return filter.getFilterContainer().getResource(0); } @@ -337,4 +365,20 @@ protected boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState final BlockState newBlockState) { return AbstractDirectionalBlock.didDirectionChange(oldBlockState, newBlockState); } + + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + return Optional.ofNullable(mainNetworkNode.getNetwork()) + .map(network -> network.getComponent(AutocraftingNetworkComponent.class)) + .flatMap(component -> component.getPreview(resource, amount)); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + final Network network = mainNetworkNode.getNetwork(); + if (network == null) { + return false; + } + return network.getComponent(AutocraftingNetworkComponent.class).start(resource, amount); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java index e585d2fcf..1743e4589 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/amount/AbstractAmountScreen.java @@ -109,7 +109,7 @@ private Button addCancelButton(final int x, final int y) { final int width = configuration.isHorizontalActionButtons() ? font.width(CANCEL_TEXT) + ACTION_BUTTON_SPACING : ACTION_BUTTON_WIDTH; - return addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> tryCloseToParent()) + return addRenderableWidget(Button.builder(CANCEL_TEXT, btn -> close()) .pos(leftPos + x, topPos + y) .size(width, ACTION_BUTTON_HEIGHT) .build()); @@ -259,9 +259,7 @@ public boolean keyPressed(final int key, final int scanCode, final int modifiers protected final boolean tryClose(final int key) { if (key == GLFW.GLFW_KEY_ESCAPE) { - if (!tryCloseToParent()) { - onClose(); - } + close(); return true; } return false; @@ -286,7 +284,7 @@ private void tryConfirmAndCloseToParent() { }); } - protected final boolean tryCloseToParent() { + private boolean tryCloseToParent() { if (parent != null) { Minecraft.getInstance().setScreen(parent); return true; @@ -294,6 +292,12 @@ protected final boolean tryCloseToParent() { return false; } + protected final void close() { + if (!tryCloseToParent()) { + onClose(); + } + } + protected final Optional getAndValidateAmount() { if (amountField == null) { return Optional.empty(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java index 3c5544aef..c7e7fb8d3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingPreviewRequestPacket.java @@ -1,8 +1,7 @@ package com.refinedmods.refinedstorage.common.support.packet.c2s; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.common.support.packet.PacketContext; import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets; import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; @@ -36,8 +35,10 @@ public record AutocraftingPreviewRequestPacket(UUID id, public static void handle(final AutocraftingPreviewRequestPacket packet, final PacketContext ctx) { if (ctx.getPlayer().containerMenu instanceof AutocraftingPreviewProvider provider) { - final AutocraftingPreview preview = provider.getPreview(packet.resource(), packet.amount()); - S2CPackets.sendAutocraftingPreviewResponse((ServerPlayer) ctx.getPlayer(), packet.id, preview); + final ServerPlayer player = (ServerPlayer) ctx.getPlayer(); + provider.getPreview(packet.resource(), packet.amount()).ifPresent( + preview -> S2CPackets.sendAutocraftingPreviewResponse(player, packet.id, preview) + ); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java index 2b2ea00a0..18ba3b302 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/c2s/AutocraftingRequestPacket.java @@ -1,7 +1,7 @@ package com.refinedmods.refinedstorage.common.support.packet.c2s; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.common.support.packet.PacketContext; import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets; import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java index bd9c8a1f1..94114242c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/AutocraftingPreviewResponsePacket.java @@ -1,26 +1,46 @@ package com.refinedmods.refinedstorage.common.support.packet.s2c; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewItem; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewType; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; import com.refinedmods.refinedstorage.common.util.ClientPlatformUtil; +import java.util.ArrayList; import java.util.UUID; import net.minecraft.core.UUIDUtil; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; +import static com.refinedmods.refinedstorage.common.util.PlatformUtil.enumStreamCodec; public record AutocraftingPreviewResponsePacket(UUID id, AutocraftingPreview preview) implements CustomPacketPayload { public static final Type PACKET_TYPE = new Type<>( createIdentifier("autocrafting_preview_response") ); - + private static final StreamCodec PREVIEW_ITEM_STREAM_CODEC = + StreamCodec.composite( + ResourceCodecs.STREAM_CODEC, item -> (PlatformResourceKey) item.resource(), + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::available, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::missing, + ByteBufCodecs.VAR_LONG, AutocraftingPreviewItem::toCraft, + AutocraftingPreviewItem::new + ); + private static final StreamCodec PREVIEW_STREAM_CODEC = + StreamCodec.composite( + enumStreamCodec(AutocraftingPreviewType.values()), AutocraftingPreview::type, + ByteBufCodecs.collection(ArrayList::new, PREVIEW_ITEM_STREAM_CODEC), AutocraftingPreview::items, + AutocraftingPreview::new + ); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( UUIDUtil.STREAM_CODEC, AutocraftingPreviewResponsePacket::id, - AutocraftingPreview.STREAM_CODEC, AutocraftingPreviewResponsePacket::preview, + PREVIEW_STREAM_CODEC, AutocraftingPreviewResponsePacket::preview, AutocraftingPreviewResponsePacket::new ); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java index 623a0bd79..08b365c36 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/packet/s2c/S2CPackets.java @@ -1,11 +1,11 @@ package com.refinedmods.refinedstorage.common.support.packet.s2c; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.storage.tracked.TrackedResource; import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.storage.StorageInfo; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; import com.refinedmods.refinedstorage.common.networking.NetworkTransmitterData; import java.util.Optional; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java index 065af4437..8d3f95629 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/util/ClientPlatformUtil.java @@ -1,6 +1,6 @@ package com.refinedmods.refinedstorage.common.util; -import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewScreen; import java.util.UUID; diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java index 392287596..8bca0a60a 100644 --- a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java +++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java @@ -1,10 +1,11 @@ package com.refinedmods.refinedstorage.api.network.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewProvider; import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; import com.refinedmods.refinedstorage.api.network.NetworkComponent; import org.apiguardian.api.API; @API(status = API.Status.STABLE, since = "2.0.0-milestone.4.8") -public interface AutocraftingNetworkComponent extends NetworkComponent, PatternRepository { +public interface AutocraftingNetworkComponent extends NetworkComponent, PatternRepository, AutocraftingPreviewProvider { } diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java index 6d3db761e..0e7fe1329 100644 --- a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java @@ -1,5 +1,8 @@ package com.refinedmods.refinedstorage.api.network.impl.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreview; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewItem; +import com.refinedmods.refinedstorage.api.autocrafting.AutocraftingPreviewType; import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; @@ -7,6 +10,9 @@ import com.refinedmods.refinedstorage.api.network.node.container.NetworkNodeContainer; import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import java.util.Set; public class AutocraftingNetworkComponentImpl implements AutocraftingNetworkComponent { @@ -44,4 +50,26 @@ public void remove(final Pattern pattern) { public Set getOutputs() { return patternRepository.getOutputs(); } + + @Override + public Optional getPreview(final ResourceKey resource, final long amount) { + final List items = new ArrayList<>(); + final boolean missing = amount == 404; + for (int i = 0; i < 31; ++i) { + items.add(new AutocraftingPreviewItem( + resource, + (i + 1), + (i % 2 == 0 && missing) ? amount : 0, + i % 2 == 0 ? 0 : amount + )); + } + return Optional.of(new AutocraftingPreview(missing + ? AutocraftingPreviewType.MISSING_RESOURCES + : AutocraftingPreviewType.SUCCESS, items)); + } + + @Override + public boolean start(final ResourceKey resource, final long amount) { + return true; + } } diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java index 2b4b0a7b8..791020b50 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java @@ -73,4 +73,14 @@ void shouldRemovePatternManually() { // Assert assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().isEmpty(); } + + @Test + void shouldStart() { + sut.start(FakeResources.A, 10); + } + + @Test + void shouldGetPreview() { + sut.getPreview(FakeResources.A, 10); + } }