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 cbce82533..6f801a9a2 100644 Binary files a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png and b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/crafting_preview.png differ 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/crafting_preview/crafting_requests.png new file mode 100644 index 000000000..dce1ee2e3 Binary files /dev/null and b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/crafting_preview/crafting_requests.png differ