From d37a32cc1301a247dc2607a204bddf601a0d3c72 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Fri, 4 Oct 2024 17:23:42 +0200 Subject: [PATCH] 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) {