From ff8bdd981e1f150a4cb4d0a5fe867059d464853f Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Mon, 29 Jul 2024 22:45:40 +0200 Subject: [PATCH] feat: processing pattern encoding No alternatives selection yet. --- .../api/autocrafting/CraftingPattern.java | 5 - .../common/api/autocrafting/Pattern.java | 5 - .../api/autocrafting/ProcessingPattern.java | 7 +- .../support/resource/ResourceContainer.java | 11 + .../common/AbstractModInitializer.java | 7 + .../refinedstorage/common/Platform.java | 3 + .../refinedstorage/common/PlatformProxy.java | 6 + ...CraftingPatternClientTooltipComponent.java | 41 +- .../autocrafting/PatternGridBlockEntity.java | 127 ++++- .../PatternGridContainerMenu.java | 54 ++- .../common/autocrafting/PatternGridData.java | 8 +- .../autocrafting/PatternGridScreen.java | 441 +++++++++++++++--- .../common/autocrafting/PatternItem.java | 32 +- .../autocrafting/PatternItemOverrides.java | 18 +- .../common/autocrafting/PatternRendering.java | 22 +- .../autocrafting/PatternTooltipCache.java | 32 ++ .../ProcessingMatrixResourceSlot.java | 57 +++ ...ocessingPatternClientTooltipComponent.java | 137 ++++++ .../autocrafting/ProcessingPatternState.java | 47 ++ .../common/content/DataComponents.java | 13 + .../grid/AbstractGridContainerMenu.java | 6 +- .../common/grid/CraftingGridSourceImpl.java | 2 +- .../SnapshotCraftingGridRefillContext.java | 4 +- .../common/support/AbstractBaseScreen.java | 52 ++- .../common/support/TextureIds.java | 1 + .../support/containermenu/ResourceSlot.java | 2 +- .../PlatformStorageNetworkComponent.java | 2 +- .../support/resource/ResourceCodecs.java | 2 + .../resource/ResourceContainerImpl.java | 8 + .../stretching/AbstractStretchingScreen.java | 7 +- .../support/widget/ScrollbarWidget.java | 50 +- .../assets/refinedstorage/lang/en_us.json | 4 + .../models/item/pattern/processing.json | 6 + .../gui/sprites/pattern_grid/processing.png | Bin 0 -> 256 bytes .../pattern_grid/processing_matrix.png | Bin 0 -> 171 bytes .../gui/sprites/widget/small_scrollbar.png | Bin 0 -> 158 bytes .../widget/small_scrollbar_clicked.png | Bin 0 -> 158 bytes .../widget/small_scrollbar_disabled.png | Bin 0 -> 155 bytes .../textures/item/pattern/processing.png | Bin 0 -> 441 bytes .../refinedstorage/common/TestPlatform.java | 6 + .../list/FuzzyResourceListImplTest.java | 2 +- .../fabric/ClientModInitializerImpl.java | 18 +- .../refinedstorage/fabric/PlatformImpl.java | 6 + .../autocrafting/PatternBakedModel.java | 5 +- .../autocrafting/PatternUnbakedModel.java | 7 +- .../resources/refinedstorage.accesswidener | 1 + .../api/grid/view/GridViewBuilderImpl.java | 2 +- .../api/grid/view/GridViewImpl.java | 2 +- .../neoforge/ClientModInitializer.java | 18 +- .../refinedstorage/neoforge/PlatformImpl.java | 6 + .../autocrafting/PatternBakedModel.java | 7 +- .../autocrafting/PatternUnbakedGeometry.java | 5 +- .../resources/META-INF/accesstransformer.cfg | 1 + .../network/test/NetworkTestFixtures.java | 4 +- .../impl/node/storage/ExposedStorage.java | 2 +- .../StorageTransferNetworkNodeTest.java | 37 +- .../StorageNetworkComponentImplTest.java | 2 +- .../api/resource/ResourceAmount.java | 4 + .../api/resource/list/ResourceListImpl.java | 11 +- .../resource/list/ProxyResourceListTest.java | 2 +- .../resource/list/ResourceListImplTest.java | 2 +- .../ListenableResourceListTest.java | 2 +- .../api/storage/InMemoryStorageImpl.java | 2 +- .../api/storage/external/ExternalStorage.java | 4 +- .../api/storage/root/RootStorageImpl.java | 2 +- .../composite/CompositeStorageImplTest.java | 2 +- .../ExtractCompositeStorageImplTest.java | 2 +- .../InsertCompositeStorageImplTest.java | 2 +- .../SubCompositeCompositeStorageImplTest.java | 10 +- 69 files changed, 1142 insertions(+), 253 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternTooltipCache.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingMatrixResourceSlot.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternState.java create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/pattern/processing.json create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing_matrix.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/small_scrollbar.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/small_scrollbar_clicked.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/small_scrollbar_disabled.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/pattern/processing.png diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/CraftingPattern.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/CraftingPattern.java index 714a018fa..d047fb081 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/CraftingPattern.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/CraftingPattern.java @@ -3,7 +3,6 @@ import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; -import java.util.Collection; import java.util.List; import org.apiguardian.api.API; @@ -12,8 +11,4 @@ public record CraftingPattern(List> inputs, ResourceAmount output, List byproducts) implements Pattern { - @Override - public Collection getOutputs() { - return List.of(output); - } } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java index c055585f4..0bcbc0f31 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java @@ -1,12 +1,7 @@ package com.refinedmods.refinedstorage.common.api.autocrafting; -import com.refinedmods.refinedstorage.api.resource.ResourceAmount; - -import java.util.Collection; - import org.apiguardian.api.API; @API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6") public interface Pattern { - Collection getOutputs(); } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/ProcessingPattern.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/ProcessingPattern.java index ff9d33173..95dd7cf2f 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/ProcessingPattern.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/ProcessingPattern.java @@ -2,15 +2,10 @@ import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import java.util.Collection; import java.util.List; import org.apiguardian.api.API; @API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6") -public record ProcessingPattern(List> inputs, List outputs) implements Pattern { - @Override - public Collection getOutputs() { - return outputs; - } +public record ProcessingPattern(List inputs, List outputs) implements Pattern { } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceContainer.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceContainer.java index cdc582672..c6225cd24 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceContainer.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceContainer.java @@ -39,8 +39,19 @@ public interface ResourceContainer { void remove(int index); + void clear(); + int size(); + default boolean isEmpty() { + for (int i = 0; i < size(); i++) { + if (!isEmpty(i)) { + return false; + } + } + return true; + } + default boolean isEmpty(int index) { return get(index) == null; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java index 3a2ea3fe5..47989f300 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java @@ -18,6 +18,7 @@ import com.refinedmods.refinedstorage.common.autocrafting.PatternGridData; import com.refinedmods.refinedstorage.common.autocrafting.PatternItem; import com.refinedmods.refinedstorage.common.autocrafting.PatternState; +import com.refinedmods.refinedstorage.common.autocrafting.ProcessingPatternState; import com.refinedmods.refinedstorage.common.configurationcard.ConfigurationCardItem; import com.refinedmods.refinedstorage.common.configurationcard.ConfigurationCardState; import com.refinedmods.refinedstorage.common.constructordestructor.BlockBreakDestructorStrategyFactory; @@ -866,6 +867,12 @@ protected final void registerDataComponents(final RegistryCallback DataComponentType.builder() + .persistent(ProcessingPatternState.CODEC) + .networkSynchronized(ProcessingPatternState.STREAM_CODEC) + .build())); } protected final void registerInventorySlotReference() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Platform.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Platform.java index 00b0accf0..d7c8baaa7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Platform.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Platform.java @@ -37,6 +37,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; @@ -133,4 +134,6 @@ void saveSavedData(SavedData savedData, NetworkNodeContainerProvider getContainerProviderSafely(Level level, BlockPos pos, @Nullable Direction direction); int getItemColor(ItemStack stack, int tintIndex); + + void setSlotY(Slot slot, int y); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/PlatformProxy.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/PlatformProxy.java index 00ff22c91..51e7a2660 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/PlatformProxy.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/PlatformProxy.java @@ -37,6 +37,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; @@ -259,6 +260,11 @@ public int getItemColor(final ItemStack stack, final int tintIndex) { return ensureLoaded().getItemColor(stack, tintIndex); } + @Override + public void setSlotY(final Slot slot, final int y) { + ensureLoaded().setSlotY(slot, y); + } + private Platform ensureLoaded() { if (platform == null) { throw new IllegalStateException("Platform not loaded yet"); 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 be13f9548..e06c204a1 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 @@ -1,13 +1,12 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.autocrafting.CraftingPattern; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; import java.util.List; -import java.util.Objects; +import javax.annotation.Nullable; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; @@ -20,7 +19,9 @@ import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW; import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW_HEIGHT; import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW_WIDTH; +import static com.refinedmods.refinedstorage.common.support.TextureIds.SLOT; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; +import static java.util.Objects.requireNonNullElse; public class CraftingPatternClientTooltipComponent implements ClientTooltipComponent { private static final long CYCLE_MS = 1000; @@ -29,7 +30,6 @@ public class CraftingPatternClientTooltipComponent implements ClientTooltipCompo private static final int ARROW_SPACING = 8; - private static final ResourceLocation SLOT = createIdentifier("slot"); private static final ResourceLocation LARGE_SLOT = createIdentifier("large_slot"); private static final int LARGE_SLOT_WIDTH = 26; private static final int LARGE_SLOT_HEIGHT = 26; @@ -38,12 +38,27 @@ public class CraftingPatternClientTooltipComponent implements ClientTooltipCompo private final int height; private final CraftingPattern craftingPattern; + @Nullable + private final ItemStack outputStack; + @Nullable + private final Component outputText; + public CraftingPatternClientTooltipComponent(final int width, final int height, final CraftingPattern craftingPattern) { this.width = width; this.height = height; this.craftingPattern = craftingPattern; + final ItemResource outputResource = craftingPattern.output().getResource() instanceof ItemResource itemResource + ? itemResource + : null; + this.outputStack = outputResource != null + ? outputResource.toItemStack(craftingPattern.output().getAmount()) + : null; + this.outputText = outputResource != null + ? Component.literal(String.format("%dx ", craftingPattern.output().getAmount())) + .append(outputResource.toItemStack().getHoverName()) + .withStyle(ChatFormatting.GRAY) : null; } @Override @@ -66,16 +81,8 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap currentCycle++; cycleStart = now; } - if (craftingPattern.output().getResource() instanceof ItemResource itemResource) { - graphics.drawString( - font, - Component.literal(String.format("%dx ", craftingPattern.output().getAmount())) - .append(itemResource.toItemStack().getHoverName()) - .withStyle(ChatFormatting.GRAY), - x, - y, - Objects.requireNonNullElse(ChatFormatting.GRAY.getColor(), 15) - ); + if (outputText != null) { + graphics.drawString(font, outputText, x, y, requireNonNullElse(ChatFormatting.GRAY.getColor(), 15)); } renderInputSlots(x, y + 9 + 2, graphics); renderArrow(x, y + 9 + 2, graphics); @@ -120,13 +127,11 @@ private void renderResultSlot(final Font font, final int x, final int y, final G final int slotX = x + width * 18 + ARROW_SPACING + LIGHT_ARROW_WIDTH + ARROW_SPACING; final int slotY = y + ((height * 18) / 2) - (LARGE_SLOT_HEIGHT / 2); graphics.blitSprite(LARGE_SLOT, slotX, slotY, LARGE_SLOT_WIDTH, LARGE_SLOT_HEIGHT); - final ResourceAmount output = craftingPattern.output(); - if (output.getResource() instanceof ItemResource itemResource) { - final ItemStack resultItemStack = itemResource.toItemStack(output.getAmount()); + if (outputStack != null) { final int stackX = slotX + 5; final int stackY = slotY + 5; - graphics.renderItem(resultItemStack, stackX, stackY); - graphics.renderItemDecorations(font, resultItemStack, stackX, stackY); + graphics.renderItem(outputStack, stackX, stackY); + graphics.renderItemDecorations(font, outputStack, stackX, stackY); } } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridBlockEntity.java index a9b26747a..cf5e736fc 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridBlockEntity.java @@ -1,6 +1,8 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.Platform; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.content.BlockEntities; import com.refinedmods.refinedstorage.common.content.ContentNames; import com.refinedmods.refinedstorage.common.content.DataComponents; @@ -13,8 +15,13 @@ import com.refinedmods.refinedstorage.common.support.CraftingMatrix; import com.refinedmods.refinedstorage.common.support.FilteredContainer; import com.refinedmods.refinedstorage.common.support.containermenu.NetworkNodeExtendedMenuProvider; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerData; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; import com.refinedmods.refinedstorage.common.util.ContainerUtil; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import java.util.UUID; import javax.annotation.Nullable; @@ -37,10 +44,14 @@ public class PatternGridBlockEntity extends AbstractGridBlockEntity implements B NetworkNodeExtendedMenuProvider { private static final String TAG_PATTERN_INPUT = "pattern_input"; private static final String TAG_PATTERN_OUTPUT = "pattern_output"; + private static final String TAG_PROCESSING_INPUT = "processing_input"; + private static final String TAG_PROCESSING_OUTPUT = "processing_output"; private static final String TAG_FUZZY_MODE = "fuzzy_mode"; private static final String TAG_PATTERN_TYPE = "processing"; private final CraftingState craftingState = new CraftingState(this::setChanged, this::getLevel); + private final ResourceContainer processingInput = ResourceContainerImpl.createForFilter(81); + private final ResourceContainer processingOutput = ResourceContainerImpl.createForFilter(81); private final FilteredContainer patternInput = new FilteredContainer(1, PatternGridBlockEntity::isValidPattern); private final FilteredContainer patternOutput = new PatternOutputContainer(); private boolean fuzzyMode; @@ -55,6 +66,8 @@ public PatternGridBlockEntity(final BlockPos pos, final BlockState state) { ); patternInput.addListener(container -> setChanged()); patternOutput.addListener(container -> setChanged()); + processingInput.setListener(this::setChanged); + processingOutput.setListener(this::setChanged); } CraftingMatrix getCraftingMatrix() { @@ -65,6 +78,14 @@ ResultContainer getCraftingResult() { return craftingState.getCraftingResult(); } + ResourceContainer getProcessingInput() { + return processingInput; + } + + ResourceContainer getProcessingOutput() { + return processingOutput; + } + FilteredContainer getPatternInput() { return patternInput; } @@ -80,6 +101,8 @@ public void saveAdditional(final CompoundTag tag, final HolderLookup.Provider pr tag.put(TAG_PATTERN_OUTPUT, ContainerUtil.write(patternOutput, provider)); tag.putBoolean(TAG_FUZZY_MODE, fuzzyMode); tag.putInt(TAG_PATTERN_TYPE, PatternTypeSettings.getPatternType(patternType)); + tag.put(TAG_PROCESSING_INPUT, processingInput.toTag(provider)); + tag.put(TAG_PROCESSING_OUTPUT, processingOutput.toTag(provider)); craftingState.writeToTag(tag, provider); } @@ -94,6 +117,12 @@ public void loadAdditional(final CompoundTag tag, final HolderLookup.Provider pr } fuzzyMode = tag.getBoolean(TAG_FUZZY_MODE); patternType = PatternTypeSettings.getPatternType(tag.getInt(TAG_PATTERN_TYPE)); + if (tag.contains(TAG_PROCESSING_INPUT)) { + processingInput.fromTag(tag.getCompound(TAG_PROCESSING_INPUT), provider); + } + if (tag.contains(TAG_PROCESSING_OUTPUT)) { + processingOutput.fromTag(tag.getCompound(TAG_PROCESSING_OUTPUT), provider); + } craftingState.readFromTag(tag, provider); } @@ -134,7 +163,12 @@ public AbstractGridContainerMenu createMenu(final int syncId, final Inventory in @Override public PatternGridData getMenuData() { - return new PatternGridData(GridData.of(this), patternType); + return new PatternGridData( + GridData.of(this), + patternType, + ResourceContainerData.of(processingInput), + ResourceContainerData.of(processingOutput) + ); } @Override @@ -157,8 +191,17 @@ void clear() { if (level == null) { return; } - craftingState.getCraftingMatrix().clearContent(); - craftingState.updateResult(level); + switch (patternType) { + case CRAFTING -> { + craftingState.getCraftingMatrix().clearContent(); + craftingState.updateResult(level); + } + case PROCESSING -> { + processingInput.clear(); + processingOutput.clear(); + } + } + setChanged(); } void createPattern() { @@ -167,6 +210,7 @@ void createPattern() { } final ItemStack result = switch (patternType) { case CRAFTING -> createCraftingPattern(); + case PROCESSING -> createProcessingPattern(); default -> null; }; if (result != null) { @@ -178,6 +222,49 @@ void createPattern() { } } + @Nullable + private ItemStack createCraftingPattern() { + if (!craftingState.hasCraftingResult()) { + return null; + } + final ItemStack result = createPatternStack(PatternType.CRAFTING); + final CraftingPatternState state = new CraftingPatternState( + fuzzyMode, + getCraftingMatrix().asPositionedCraftInput() + ); + result.set(DataComponents.INSTANCE.getCraftingPatternState(), state); + return result; + } + + @Nullable + private ItemStack createProcessingPattern() { + if (processingInput.isEmpty() || processingOutput.isEmpty()) { + return null; + } + final ItemStack result = createPatternStack(PatternType.PROCESSING); + final List> inputs = new ArrayList<>(); + for (int i = 0; i < processingInput.size(); ++i) { + inputs.add(Optional.ofNullable(processingInput.get(i)).map(ResourceAmount::copy)); + } + final List> outputs = new ArrayList<>(); + for (int i = 0; i < processingOutput.size(); ++i) { + outputs.add(Optional.ofNullable(processingOutput.get(i)).map(ResourceAmount::copy)); + } + final ProcessingPatternState patternProcessingState = new ProcessingPatternState( + inputs, + outputs + ); + result.set(DataComponents.INSTANCE.getProcessingPatternState(), patternProcessingState); + return result; + } + + private static ItemStack createPatternStack(final PatternType patternType) { + final ItemStack result = new ItemStack(Items.INSTANCE.getPattern()); + final PatternState patternState = new PatternState(UUID.randomUUID(), patternType); + result.set(DataComponents.INSTANCE.getPatternState(), patternState); + return result; + } + void copyPattern(final ItemStack stack) { final PatternState state = stack.get(DataComponents.INSTANCE.getPatternState()); if (state == null) { @@ -194,6 +281,15 @@ void copyPattern(final ItemStack stack) { } copyCraftingPattern(patternCraftingState); } + case PROCESSING -> { + final ProcessingPatternState patternProcessingState = stack.get( + DataComponents.INSTANCE.getProcessingPatternState() + ); + if (patternProcessingState == null) { + return; + } + copyProcessingPattern(patternProcessingState); + } } setChanged(); } @@ -218,24 +314,17 @@ private void copyCraftingPattern(final CraftingPatternState state) { } } - @Nullable - private ItemStack createCraftingPattern() { - if (!craftingState.hasCraftingResult()) { - return null; + private void copyProcessingPattern(final ProcessingPatternState state) { + processingInput.clear(); + processingOutput.clear(); + for (int i = 0; i < state.inputs().size(); ++i) { + final int ii = i; + state.inputs().get(i).ifPresent(amount -> processingInput.set(ii, amount)); } - final boolean shouldExtractInputPattern = patternOutput.getItem(0).isEmpty(); - if (shouldExtractInputPattern) { - patternInput.removeItem(0, 1); + for (int i = 0; i < state.outputs().size(); ++i) { + final int ii = i; + state.outputs().get(i).ifPresent(amount -> processingOutput.set(ii, amount)); } - final ItemStack result = new ItemStack(Items.INSTANCE.getPattern()); - final PatternState patternState = new PatternState(UUID.randomUUID(), PatternType.CRAFTING); - result.set(DataComponents.INSTANCE.getPatternState(), patternState); - final CraftingPatternState patternCraftingState = new CraftingPatternState( - fuzzyMode, - getCraftingMatrix().asPositionedCraftInput() - ); - result.set(DataComponents.INSTANCE.getCraftingPatternState(), patternCraftingState); - return result; } private boolean isPatternAvailable() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridContainerMenu.java index bbde55ebc..b06323c5d 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridContainerMenu.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.content.Menus; import com.refinedmods.refinedstorage.common.grid.AbstractGridContainerMenu; import com.refinedmods.refinedstorage.common.support.CraftingMatrix; @@ -12,6 +13,7 @@ import com.refinedmods.refinedstorage.common.support.containermenu.ServerProperty; import com.refinedmods.refinedstorage.common.support.containermenu.ValidatedSlot; import com.refinedmods.refinedstorage.common.support.packet.c2s.C2SPackets; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerImpl; import javax.annotation.Nullable; @@ -23,12 +25,16 @@ public class PatternGridContainerMenu extends AbstractGridContainerMenu { private static final int Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_PATTERN_INPUT_SLOT = 81; private static final int SPACING_BETWEEN_PATTERN_INPUT_AND_PATTERN_OUTPUT_SLOTS = 36; - private static final int Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT = 86; + private static final int Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT = 85; + private static final int Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_PROCESSING_MATRIX_SLOT = 76; + private static final int INDIVIDUAL_PROCESSING_MATRIX_SIZE = 54; private final Container patternInput; private final Container patternOutput; private final Container craftingMatrix; private final Container craftingResult; + private final ResourceContainer processingInput; + private final ResourceContainer processingOutput; @Nullable private PatternGridListener listener; @@ -41,6 +47,8 @@ public PatternGridContainerMenu(final int syncId, super(Menus.INSTANCE.getPatternGrid(), syncId, playerInventory, patternGridData.gridData()); this.patternInput = new FilteredContainer(1, PatternGridBlockEntity::isValidPattern); this.patternOutput = new PatternOutputContainer(); + this.processingInput = ResourceContainerImpl.createForFilter(patternGridData.processingInputData()); + this.processingOutput = ResourceContainerImpl.createForFilter(patternGridData.processingOutputData()); this.craftingMatrix = new CraftingMatrix(null, 3, 3); this.craftingResult = new ResultContainer(); onScreenReady(0); @@ -73,6 +81,8 @@ protected void onChangedOnClient(final Boolean newValue) { this.patternOutput = grid.getPatternOutput(); this.craftingMatrix = grid.getCraftingMatrix(); this.craftingResult = grid.getCraftingResult(); + this.processingInput = grid.getProcessingInput(); + this.processingOutput = grid.getProcessingOutput(); this.patternGrid = grid; onScreenReady(0); registerProperty(new ServerProperty<>( @@ -118,6 +128,7 @@ boolean canCreatePattern() { } return switch (getPatternType()) { case CRAFTING -> !craftingResult.getItem(0).isEmpty(); + case PROCESSING -> !processingInput.isEmpty() && !processingOutput.isEmpty(); default -> false; }; } @@ -128,6 +139,7 @@ public void onScreenReady(final int playerInventoryY) { transferManager.clear(); addPatternSlots(playerInventoryY); addCraftingMatrixSlots(playerInventoryY); + addProcessingMatrixSlots(playerInventoryY); } private void addPatternSlots(final int playerInventoryY) { @@ -167,7 +179,7 @@ public void set(final ItemStack stack) { private void addCraftingMatrixSlots(final int playerInventoryY) { for (int y = 0; y < 3; ++y) { for (int x = 0; x < 3; ++x) { - final int slotX = 12 + ((x % 3) * 18); + final int slotX = 13 + ((x % 3) * 18); final int slotY = playerInventoryY - Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT + ((y % 3) * 18); @@ -182,7 +194,7 @@ public boolean isActive() { addSlot(new DisabledSlot( craftingResult, 0, - 116 + 4, + 117 + 4, playerInventoryY - Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT + 18 ) { @Override @@ -192,6 +204,42 @@ public boolean isActive() { }); } + private void addProcessingMatrixSlots(final int playerInventoryY) { + final int y = playerInventoryY - Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_PROCESSING_MATRIX_SLOT; + final int startY = y - 18; + final int endY = y + INDIVIDUAL_PROCESSING_MATRIX_SIZE; + addProcessingMatrixSlots(13, y, startY, endY, processingInput, true); + addProcessingMatrixSlots(13 + INDIVIDUAL_PROCESSING_MATRIX_SIZE + 2, y, startY, endY, processingOutput, false); + } + + private void addProcessingMatrixSlots(final int x, + final int y, + final int startY, + final int endY, + final ResourceContainer resourceContainer, + final boolean input) { + int slotX = x; + int slotY = y; + for (int i = 0; i < resourceContainer.size(); ++i) { + addSlot(new ProcessingMatrixResourceSlot( + resourceContainer, + i, + slotX, + slotY, + input, + this::getPatternType, + startY, + endY + )); + if ((i + 1) % 3 == 0) { + slotX = x; + slotY += 18; + } else { + slotX += 18; + } + } + } + public void clear() { if (patternGrid != null) { patternGrid.clear(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridData.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridData.java index a04c8c6e7..47f22df67 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridData.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridData.java @@ -1,15 +1,21 @@ package com.refinedmods.refinedstorage.common.autocrafting; import com.refinedmods.refinedstorage.common.grid.GridData; +import com.refinedmods.refinedstorage.common.support.resource.ResourceContainerData; import com.refinedmods.refinedstorage.common.util.PacketUtil; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; -public record PatternGridData(GridData gridData, PatternType patternType) { +public record PatternGridData(GridData gridData, + PatternType patternType, + ResourceContainerData processingInputData, + ResourceContainerData processingOutputData) { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( GridData.STREAM_CODEC, PatternGridData::gridData, PacketUtil.enumStreamCodec(PatternType.values()), PatternGridData::patternType, + ResourceContainerData.STREAM_CODEC, PatternGridData::processingInputData, + ResourceContainerData.STREAM_CODEC, PatternGridData::processingOutputData, PatternGridData::new ); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridScreen.java index e3ee37662..30589cd96 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternGridScreen.java @@ -1,8 +1,11 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.grid.screen.AbstractGridScreen; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; import com.refinedmods.refinedstorage.common.support.widget.CustomCheckboxWidget; import com.refinedmods.refinedstorage.common.support.widget.HoveredImageButton; +import com.refinedmods.refinedstorage.common.support.widget.ScrollbarWidget; import java.util.EnumMap; import java.util.Map; @@ -20,8 +23,10 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; +import static java.util.Objects.requireNonNull; -public class PatternGridScreen extends AbstractGridScreen { +public class PatternGridScreen extends AbstractGridScreen implements + PatternGridContainerMenu.PatternGridListener { private static final ResourceLocation TEXTURE = createIdentifier("textures/gui/pattern_grid.png"); private static final MutableComponent CREATE_PATTERN = createTranslation("gui", "pattern_grid.create_pattern"); private static final MutableComponent CLEAR = createTranslation("gui", "pattern_grid.clear"); @@ -30,8 +35,15 @@ public class PatternGridScreen extends AbstractGridScreen patternTypeButtons = new EnumMap<>(PatternType.class); @@ -55,34 +77,38 @@ public PatternGridScreen(final PatternGridContainerMenu menu, final Inventory in super(menu, inventory, title, 177); this.inventoryLabelY = 153; this.imageWidth = 193; - this.imageHeight = 250; + this.imageHeight = 249; } @Override protected void init() { super.init(); - createPatternButton = createCreatePatternButton(leftPos + 152, topPos + imageHeight - bottomHeight + 32); + this.createPatternButton = createCreatePatternButton(leftPos + 152, topPos + imageHeight - bottomHeight + 32); addRenderableWidget(createPatternButton); - final ImageButton clearButton = createClearButton(leftPos + 68, topPos + imageHeight - bottomHeight + 8); - addRenderableWidget(clearButton); addPatternTypeButtons(getMenu().getPatternType()); - final CustomCheckboxWidget fuzzyMode = createFuzzyModeCheckbox(); - addRenderableWidget(fuzzyMode); - menu.setListener(new PatternGridContainerMenu.PatternGridListener() { - @Override - public void patternTypeChanged(final PatternType value) { - patternTypeButtons.values().forEach(button -> button.setSelected(false)); - patternTypeButtons.get(value).setSelected(true); - fuzzyMode.visible = value == PatternType.CRAFTING; - clearButton.visible = value == PatternType.CRAFTING; - } + this.clearButton = createClearButton(getMenu().getPatternType()); + addRenderableWidget(clearButton); + this.fuzzyModeCheckbox = createFuzzyModeCheckbox(); + addRenderableWidget(fuzzyModeCheckbox); + this.processingScrollbar = createProcessingScrollbar(); + updateMaxProcessingScrollbarOffset(); + addWidget(processingScrollbar); + menu.setListener(this); + } - @Override - public void fuzzyModeChanged(final boolean value) { - fuzzyMode.setSelected(value); - fuzzyMode.setTooltip(getFuzzyModeTooltip(value)); - } - }); + private ImageButton createCreatePatternButton(final int x, final int y) { + final HoveredImageButton button = new HoveredImageButton( + x, + y, + CREATE_PATTERN_BUTTON_SIZE, + CREATE_PATTERN_BUTTON_SIZE, + CREATE_PATTERN_BUTTON_SPRITES, + b -> getMenu().sendCreatePattern(), + CREATE_PATTERN + ); + button.setTooltip(Tooltip.create(CREATE_PATTERN)); + button.active = getMenu().canCreatePattern(); + return button; } private void addPatternTypeButtons(final PatternType currentPatternType) { @@ -101,74 +127,369 @@ private void addPatternTypeButtons(final PatternType currentPatternType) { } } - @Override - protected void containerTick() { - super.containerTick(); - if (createPatternButton != null) { - createPatternButton.active = getMenu().canCreatePattern(); - } + private ImageButton createClearButton(final PatternType patternType) { + final HoveredImageButton button = new HoveredImageButton( + getClearButtonX(patternType), + getClearButtonY(patternType), + CLEAR_BUTTON_SIZE, + CLEAR_BUTTON_SIZE, + CLEAR_BUTTON_SPRITES, + b -> getMenu().sendClear(), + CLEAR + ); + button.setTooltip(Tooltip.create(CLEAR)); + button.visible = isClearButtonVisible(); + return button; } private CustomCheckboxWidget createFuzzyModeCheckbox() { - final CustomCheckboxWidget fuzzyMode = new CustomCheckboxWidget( - leftPos + 11, + final CustomCheckboxWidget checkbox = new CustomCheckboxWidget( + getInsetContentX(), topPos + imageHeight - bottomHeight + 65, FUZZY_MODE, font, getMenu().isFuzzyMode(), CustomCheckboxWidget.Size.SMALL ); - fuzzyMode.setOnPressed((checkbox, selected) -> getMenu().setFuzzyMode(selected)); - fuzzyMode.setTooltip(getFuzzyModeTooltip(getMenu().isFuzzyMode())); - fuzzyMode.visible = getMenu().getPatternType() == PatternType.CRAFTING; - return fuzzyMode; + checkbox.setOnPressed((c, selected) -> getMenu().setFuzzyMode(selected)); + checkbox.setTooltip(getFuzzyModeTooltip(getMenu().isFuzzyMode())); + checkbox.visible = isFuzzyModeCheckboxVisible(); + return checkbox; } private static Tooltip getFuzzyModeTooltip(final boolean fuzzyMode) { return fuzzyMode ? Tooltip.create(FUZZY_MODE_ON_HELP) : Tooltip.create(FUZZY_MODE_OFF_HELP); } - private ImageButton createCreatePatternButton(final int x, final int y) { - final HoveredImageButton button = new HoveredImageButton( - x, - y, - CREATE_PATTERN_BUTTON_SIZE, - CREATE_PATTERN_BUTTON_SIZE, - CREATE_PATTERN_BUTTON_SPRITES, - b -> getMenu().sendCreatePattern(), - CREATE_PATTERN + private ScrollbarWidget createProcessingScrollbar() { + final ScrollbarWidget scrollbar = new ScrollbarWidget( + getInsetX() + 126, + getInsetY() + 14, + ScrollbarWidget.Type.SMALL, + 52 ); - button.setTooltip(Tooltip.create(CREATE_PATTERN)); - button.active = getMenu().canCreatePattern(); - return button; + scrollbar.visible = isProcessingScrollbarVisible(); + scrollbar.setListener(offset -> onScrollbarChanged((int) offset)); + return scrollbar; } - private ImageButton createClearButton(final int x, final int y) { - final HoveredImageButton button = new HoveredImageButton( - x, - y, - CLEAR_BUTTON_SIZE, - CLEAR_BUTTON_SIZE, - CLEAR_BUTTON_SPRITES, - b -> getMenu().sendClear(), - CLEAR - ); - button.setTooltip(Tooltip.create(CLEAR)); - button.visible = getMenu().getPatternType() == PatternType.CRAFTING; - return button; + private void onScrollbarChanged(final int offset) { + int inputRow = 0; + int outputRow = 0; + final int scrollbarOffset = (processingScrollbar != null && processingScrollbar.isSmoothScrolling()) + ? offset + : offset * PROCESSING_MATRIX_SLOT_SIZE; + for (int i = 0; i < getMenu().getResourceSlots().size(); ++i) { + final ResourceSlot slot = getMenu().getResourceSlots().get(i); + if (!(slot instanceof ProcessingMatrixResourceSlot matrixSlot)) { + continue; + } + final int row = matrixSlot.isInput() ? inputRow : outputRow; + final int slotY = getInsetContentY() + + PROCESSING_INSET_Y_PADDING + 1 + + (row * PROCESSING_MATRIX_SLOT_SIZE) + - scrollbarOffset + - topPos; + Platform.INSTANCE.setSlotY(getMenu().getResourceSlots().get(i), slotY); + if ((i + 1) % 3 == 0) { + if (matrixSlot.isInput()) { + inputRow++; + } else { + outputRow++; + } + } + } + } + + @Override + protected void containerTick() { + super.containerTick(); + if (createPatternButton != null) { + createPatternButton.active = getMenu().canCreatePattern(); + } + updateMaxProcessingScrollbarOffset(); + } + + private void updateMaxProcessingScrollbarOffset() { + if (processingScrollbar == null || getMenu().getPatternType() != PatternType.PROCESSING) { + return; + } + + int filledInputSlots = 0; + int filledOutputSlots = 0; + int lastFilledInputSlot = 0; + int lastFilledOutputSlot = 0; + + for (int i = 0; i < getMenu().getResourceSlots().size(); ++i) { + final ResourceSlot resourceSlot = getMenu().getResourceSlots().get(i); + if (resourceSlot.isEmpty() || !(resourceSlot instanceof ProcessingMatrixResourceSlot matrixSlot)) { + continue; + } + if (matrixSlot.isInput()) { + filledInputSlots++; + lastFilledInputSlot = i; + } else { + filledOutputSlots++; + lastFilledOutputSlot = i - 81; + } + } + + final int maxFilledSlots = Math.max(filledInputSlots, filledOutputSlots); + final int maxFilledRows = Math.floorDiv(maxFilledSlots - 1, 3); + + final int maxLastFilledSlot = Math.max(lastFilledInputSlot, lastFilledOutputSlot); + final int maxLastFilledRow = Math.floorDiv(maxLastFilledSlot, 3) - 2; + + final int maxOffset = Math.max(maxFilledRows, maxLastFilledRow); + final int maxOffsetCorrected = processingScrollbar.isSmoothScrolling() + ? maxOffset * PROCESSING_MATRIX_SLOT_SIZE + : maxOffset; + processingScrollbar.setMaxOffset(maxOffsetCorrected); + processingScrollbar.setEnabled(maxOffsetCorrected > 0); + } + + @Override + public void render(final GuiGraphics graphics, final int mouseX, final int mouseY, final float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + if (processingScrollbar != null) { + processingScrollbar.render(graphics, mouseX, mouseY, partialTicks); + } } @Override protected void renderBg(final GuiGraphics graphics, final float delta, final int mouseX, final int mouseY) { super.renderBg(graphics, delta, mouseX, mouseY); + final int insetContentX = getInsetContentX(); + final int insetContentY = getInsetContentY(); switch (getMenu().getPatternType()) { - case CRAFTING -> - graphics.blitSprite(CRAFTING, leftPos + 7 + 4, topPos + imageHeight - bottomHeight + 4 + 4, 130, 54); + case CRAFTING -> graphics.blitSprite(CRAFTING, insetContentX, insetContentY, 130, 54); + case PROCESSING -> renderProcessingBackground(graphics, mouseX, mouseY, insetContentX, insetContentY); + } + } + + private void renderProcessingBackground(final GuiGraphics graphics, + final int mouseX, + final int mouseY, + final int insetContentX, + final int insetContentY) { + graphics.blitSprite(PROCESSING, insetContentX, insetContentY + PROCESSING_INSET_Y_PADDING, 130, 54); + renderProcessingMatrix( + graphics, + getInsetContentX() + 1, + getInsetY() + 14, + getInsetContentX() + 1 + 52 + 1, // include the edge so we get the item counts properly + getInsetY() + 14 + 52 + 1, // include the edge so we get the item counts properly + mouseX, + mouseY, + true + ); + renderProcessingMatrix( + graphics, + getInsetContentX() + INDIVIDUAL_PROCESSING_MATRIX_SIZE + 2 + 1, + getInsetY() + 14, + getInsetContentX() + INDIVIDUAL_PROCESSING_MATRIX_SIZE + 2 + 1 + 52 + 1, + getInsetY() + 14 + 52 + 1, + mouseX, + mouseY, + false + ); + } + + private void renderProcessingMatrix(final GuiGraphics graphics, + final int startX, + final int startY, + final int endX, + final int endY, + final int mouseX, + final int mouseY, + final boolean input) { + graphics.enableScissor(startX, startY, endX, endY); + renderProcessingMatrixSlotBackground(graphics, input); + renderProcessingMatrixSlots(graphics, mouseX, mouseY, input); + graphics.disableScissor(); + } + + private void renderProcessingMatrixSlotBackground(final GuiGraphics graphics, final boolean input) { + final int x = getInsetContentX() + (!input ? INDIVIDUAL_PROCESSING_MATRIX_SIZE + 2 : 0); + final int startY = getInsetY() + PROCESSING_INSET_Y_PADDING - INDIVIDUAL_PROCESSING_MATRIX_SIZE; + final int endY = getInsetY() + PROCESSING_INSET_Y_PADDING + INDIVIDUAL_PROCESSING_MATRIX_SIZE; + final int scrollbarOffset = processingScrollbar != null ? (int) processingScrollbar.getOffset() : 0; + final int scrollbarOffsetCorrected = processingScrollbar != null && processingScrollbar.isSmoothScrolling() + ? scrollbarOffset + : scrollbarOffset * PROCESSING_MATRIX_SLOT_SIZE; + for (int i = 0; i < 9; ++i) { + final int y = (getInsetY() + 13) + + (i * INDIVIDUAL_PROCESSING_MATRIX_SIZE) + - scrollbarOffsetCorrected; + if (y < startY || y > endY) { + continue; + } + graphics.blitSprite( + PROCESSING_MATRIX, + x, + y, + INDIVIDUAL_PROCESSING_MATRIX_SIZE, + INDIVIDUAL_PROCESSING_MATRIX_SIZE + ); } } + private void renderProcessingMatrixSlots(final GuiGraphics graphics, + final int mouseX, + final int mouseY, + final boolean input) { + for (final ResourceSlot resourceSlot : getMenu().getResourceSlots()) { + if (resourceSlot.isActive() + && resourceSlot instanceof ProcessingMatrixResourceSlot matrixSlot + && matrixSlot.isInput() == input) { + tryRenderResourceSlot(graphics, resourceSlot); + if (isHovering(resourceSlot.x, resourceSlot.y, 16, 16, mouseX, mouseY) + && canInteractWithResourceSlot(resourceSlot, mouseX, mouseY)) { + renderSlotHighlight(graphics, leftPos + resourceSlot.x, topPos + resourceSlot.y, 0); + } + } + } + } + + @Override + protected void renderResourceSlots(final GuiGraphics graphics) { + // no op, we render them in the scissor rendering + } + + @Override + protected boolean canInteractWithResourceSlot(final ResourceSlot resourceSlot, + final double mouseX, + final double mouseY) { + // Ensure that we can't interact with the resource slot, when the resource slot is on the + // edge of the scissoring area and still technically visible and active, + // but we're no longer hovering over the processing matrix. + final int insetContentX = getInsetContentX() + ( + resourceSlot instanceof ProcessingMatrixResourceSlot matrixSlot && !matrixSlot.isInput() + ? INDIVIDUAL_PROCESSING_MATRIX_SIZE + 2 + : 0); + final int insetContentY = getInsetContentY(); + return mouseX >= insetContentX + && mouseX < insetContentX + INDIVIDUAL_PROCESSING_MATRIX_SIZE + && mouseY >= insetContentY + PROCESSING_INSET_Y_PADDING + && mouseY < insetContentY + PROCESSING_INSET_Y_PADDING + INDIVIDUAL_PROCESSING_MATRIX_SIZE; + } + + @Override + protected void renderLabels(final GuiGraphics graphics, final int mouseX, final int mouseY) { + super.renderLabels(graphics, mouseX, mouseY); + if (getMenu().getPatternType() == PatternType.PROCESSING) { + final int x = getInsetContentX() - leftPos; + final int y = getInsetContentY() - topPos; + graphics.drawString(font, INPUTS, x, y, 4210752, false); + graphics.drawString(font, OUTPUTS, x + 56, y, 4210752, false); + } + } + + @Override + public boolean mouseClicked(final double mouseX, final double mouseY, final int clickedButton) { + if (processingScrollbar != null && processingScrollbar.mouseClicked(mouseX, mouseY, clickedButton)) { + return true; + } + return super.mouseClicked(mouseX, mouseY, clickedButton); + } + + @Override + public void mouseMoved(final double mx, final double my) { + if (processingScrollbar != null) { + processingScrollbar.mouseMoved(mx, my); + } + super.mouseMoved(mx, my); + } + + @Override + public boolean mouseReleased(final double mx, final double my, final int button) { + return (processingScrollbar != null && processingScrollbar.mouseReleased(mx, my, button)) + || super.mouseReleased(mx, my, button); + } + + @Override + public boolean mouseScrolled(final double x, final double y, final double z, final double delta) { + final boolean isOverProcessingArea = x >= getInsetX() + && (x < getInsetX() + INSET_WIDTH) + && y > getInsetY() + && (y < getInsetY() + INSET_HEIGHT); + final boolean didScrollbar = processingScrollbar != null + && processingScrollbar.isActive() + && isOverProcessingArea + && processingScrollbar.mouseScrolled(x, y, z, delta); + return didScrollbar || super.mouseScrolled(x, y, z, delta); + } + @Override protected ResourceLocation getTexture() { return TEXTURE; } + + @Override + public void patternTypeChanged(final PatternType value) { + patternTypeButtons.values().forEach(button -> button.setSelected(false)); + patternTypeButtons.get(value).setSelected(true); + if (fuzzyModeCheckbox != null) { + fuzzyModeCheckbox.visible = isFuzzyModeCheckboxVisible(); + } + if (clearButton != null) { + clearButton.visible = isClearButtonVisible(); + if (clearButton.visible) { + clearButton.setX(getClearButtonX(value)); + requireNonNull(clearButton).setY(getClearButtonY(value)); + } + } + if (processingScrollbar != null) { + processingScrollbar.visible = isProcessingScrollbarVisible(); + } + } + + @Override + public void fuzzyModeChanged(final boolean value) { + if (fuzzyModeCheckbox == null) { + return; + } + fuzzyModeCheckbox.setSelected(value); + fuzzyModeCheckbox.setTooltip(getFuzzyModeTooltip(value)); + } + + private int getClearButtonX(final PatternType patternType) { + return patternType == PatternType.CRAFTING ? leftPos + 69 : leftPos + 124; + } + + private int getClearButtonY(final PatternType patternType) { + if (patternType == PatternType.PROCESSING) { + return getInsetContentY() + PROCESSING_INSET_Y_PADDING; + } + return getInsetContentY(); + } + + private boolean isClearButtonVisible() { + return getMenu().getPatternType() == PatternType.CRAFTING + || getMenu().getPatternType() == PatternType.PROCESSING; + } + + private boolean isFuzzyModeCheckboxVisible() { + return getMenu().getPatternType() == PatternType.CRAFTING; + } + + private boolean isProcessingScrollbarVisible() { + return getMenu().getPatternType() == PatternType.PROCESSING; + } + + private int getInsetX() { + return leftPos + 8; + } + + private int getInsetY() { + return topPos + imageHeight - bottomHeight + 5; + } + + private int getInsetContentX() { + return getInsetX() + INSET_PADDING; + } + + private int getInsetContentY() { + return getInsetY() + INSET_PADDING; + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItem.java index 1f5faab19..72faa2e61 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItem.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItem.java @@ -5,6 +5,7 @@ import com.refinedmods.refinedstorage.common.api.autocrafting.CraftingPattern; import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; +import com.refinedmods.refinedstorage.common.api.autocrafting.ProcessingPattern; import com.refinedmods.refinedstorage.common.api.support.HelpTooltipComponent; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.content.DataComponents; @@ -96,12 +97,21 @@ public Optional getTooltipImage(final ItemStack stack) { .filter(CraftingPattern.class::isInstance) .map(CraftingPattern.class::cast) .map(craftingPattern -> new CraftingPatternTooltipComponent( - HELP, + state.id(), craftingPattern, craftingState.input().input().width(), craftingState.input().input().height() )); } + case PROCESSING -> { + final ProcessingPatternState processingState = stack.get( + DataComponents.INSTANCE.getProcessingPatternState() + ); + if (processingState == null) { + yield Optional.empty(); + } + yield Optional.of(new ProcessingPatternTooltipComponent(state.id(), processingState)); + } default -> Optional.empty(); }; } @@ -124,6 +134,7 @@ public Optional getPattern(final ItemStack stack, final Level level) { } return switch (state.type()) { case CRAFTING -> getCraftingPattern(stack, level); + case PROCESSING -> getProcessingPattern(stack); default -> Optional.empty(); }; } @@ -199,6 +210,16 @@ private List getByproducts(final CraftingRecipe recipe, final Cr .toList(); } + private Optional getProcessingPattern(final ItemStack stack) { + final ProcessingPatternState state = stack.get( + DataComponents.INSTANCE.getProcessingPatternState() + ); + if (state == null) { + return Optional.empty(); + } + return Optional.of(new ProcessingPattern(state.getFlatInputs(), state.getFlatOutputs())); + } + @Override public InteractionResultHolder use(final Level level, final Player player, final InteractionHand hand) { final ItemStack stack = player.getItemInHand(hand); @@ -211,10 +232,11 @@ public InteractionResultHolder use(final Level level, final Player pl return new InteractionResultHolder<>(InteractionResult.PASS, stack); } - public record CraftingPatternTooltipComponent(Component helpText, - CraftingPattern craftingPattern, - int width, - int height) + public record CraftingPatternTooltipComponent(UUID id, CraftingPattern craftingPattern, int width, int height) + implements TooltipComponent { + } + + public record ProcessingPatternTooltipComponent(UUID id, ProcessingPatternState state) implements TooltipComponent { } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItemOverrides.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItemOverrides.java index faf433d82..3a6aa09fb 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItemOverrides.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternItemOverrides.java @@ -17,14 +17,17 @@ public class PatternItemOverrides extends ItemOverrides { private final BakedModel emptyModel; private final BakedModel craftingModel; + private final BakedModel processingModel; @SuppressWarnings({"DataFlowIssue"}) // null is allowed as long as we don't pass overrides public PatternItemOverrides(final ModelBaker modelBaker, final BakedModel emptyModel, - final BakedModel craftingModel) { + final BakedModel craftingModel, + final BakedModel processingModel) { super(modelBaker, null, List.of()); this.emptyModel = emptyModel; this.craftingModel = craftingModel; + this.processingModel = processingModel; } @Override @@ -38,15 +41,18 @@ public BakedModel resolve(final BakedModel model, return emptyModel; } if (state.type() == PatternType.CRAFTING) { - return getCraftingOutputModel(stack, level, entity, seed).orElse(craftingModel); + return getOutputModel(stack, level, entity, seed).orElse(craftingModel); + } + if (state.type() == PatternType.PROCESSING) { + return getOutputModel(stack, level, entity, seed).orElse(processingModel); } return emptyModel; } - private Optional getCraftingOutputModel(final ItemStack stack, - @Nullable final ClientLevel level, - @Nullable final LivingEntity entity, - final int seed) { + private Optional getOutputModel(final ItemStack stack, + @Nullable final ClientLevel level, + @Nullable final LivingEntity entity, + final int seed) { if (PatternRendering.canDisplayOutput(stack)) { return PatternRendering.getOutput(stack).map( output -> Minecraft.getInstance().getItemRenderer().getModel(output, level, entity, seed) diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternRendering.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternRendering.java index 16db1edf6..165abc671 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternRendering.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternRendering.java @@ -1,9 +1,9 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.autocrafting.CraftingPattern; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; +import com.refinedmods.refinedstorage.common.api.autocrafting.ProcessingPattern; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; import com.refinedmods.refinedstorage.common.util.PlatformUtil; @@ -26,13 +26,17 @@ public static Optional getOutput(final ItemStack stack) { if (level == null) { return Optional.empty(); } - return RefinedStorageApi.INSTANCE.getPattern(stack, level) - .filter(CraftingPattern.class::isInstance) - .map(CraftingPattern.class::cast) - .map(CraftingPattern::output) - .map(ResourceAmount::getResource) - .filter(ItemResource.class::isInstance) - .map(ItemResource.class::cast) - .map(ItemResource::toItemStack); + return RefinedStorageApi.INSTANCE.getPattern(stack, level).map(pattern -> { + if (pattern instanceof CraftingPattern craftingPattern + && craftingPattern.output().getResource() instanceof ItemResource itemResource) { + return itemResource.toItemStack(); + } + if (pattern instanceof ProcessingPattern processingPattern + && processingPattern.outputs().size() == 1 + && processingPattern.outputs().getFirst().getResource() instanceof ItemResource itemResource) { + return itemResource.toItemStack(); + } + return null; + }); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternTooltipCache.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternTooltipCache.java new file mode 100644 index 000000000..cd7b91269 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternTooltipCache.java @@ -0,0 +1,32 @@ +package com.refinedmods.refinedstorage.common.autocrafting; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; + +public final class PatternTooltipCache { + private static final Map CACHE = new HashMap<>(); + + private PatternTooltipCache() { + } + + public static ClientTooltipComponent getComponent(final PatternItem.CraftingPatternTooltipComponent key) { + if (CACHE.size() > 1000) { + CACHE.clear(); + } + return CACHE.computeIfAbsent(key.id(), id -> new CraftingPatternClientTooltipComponent( + key.width(), + key.height(), + key.craftingPattern() + )); + } + + public static ClientTooltipComponent getComponent(final PatternItem.ProcessingPatternTooltipComponent key) { + if (CACHE.size() > 1000) { + CACHE.clear(); + } + return CACHE.computeIfAbsent(key.id(), id -> new ProcessingPatternClientTooltipComponent(key.state())); + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingMatrixResourceSlot.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingMatrixResourceSlot.java new file mode 100644 index 000000000..a397e7baf --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingMatrixResourceSlot.java @@ -0,0 +1,57 @@ +package com.refinedmods.refinedstorage.common.autocrafting; + +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlotType; + +import java.util.function.Supplier; + +import net.minecraft.network.chat.MutableComponent; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; + +class ProcessingMatrixResourceSlot extends ResourceSlot { + private static final MutableComponent INPUT_HELP = createTranslation( + "gui", + "pattern_grid.processing.input_slots_help" + ); + private static final MutableComponent OUTPUT_HELP = createTranslation( + "gui", + "pattern_grid.processing.output_slots_help" + ); + + private final Supplier patternTypeSupplier; + private final boolean input; + private final int startY; + private final int endY; + + ProcessingMatrixResourceSlot(final ResourceContainer resourceContainer, + final int index, + final int x, + final int y, + final boolean input, + final Supplier patternTypeSupplier, + final int startY, + final int endY) { + super(resourceContainer, index, input ? INPUT_HELP : OUTPUT_HELP, x, y, ResourceSlotType.FILTER_WITH_AMOUNT); + this.patternTypeSupplier = patternTypeSupplier; + this.input = input; + this.startY = startY; + this.endY = endY; + } + + boolean isInput() { + return input; + } + + @Override + public boolean isActive() { + final PatternType patternType = patternTypeSupplier.get(); + return patternType == PatternType.PROCESSING && y >= startY && y < endY; + } + + @Override + public boolean isHighlightable() { + return false; // we render the highlight in the scissor render + } +} 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 new file mode 100644 index 000000000..5131a51a2 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternClientTooltipComponent.java @@ -0,0 +1,137 @@ +package com.refinedmods.refinedstorage.common.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; +import com.refinedmods.refinedstorage.common.api.support.resource.ResourceRendering; +import com.refinedmods.refinedstorage.common.support.AbstractBaseScreen; + +import java.util.List; +import java.util.Optional; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; + +import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW; +import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW_HEIGHT; +import static com.refinedmods.refinedstorage.common.support.TextureIds.LIGHT_ARROW_WIDTH; +import static com.refinedmods.refinedstorage.common.support.TextureIds.SLOT; +import static java.util.Objects.requireNonNullElse; + +public class ProcessingPatternClientTooltipComponent implements ClientTooltipComponent { + private static final int ARROW_SPACING = 8; + + private final ProcessingPatternState state; + private final int rows; + private final List outputs; + + public ProcessingPatternClientTooltipComponent(final ProcessingPatternState state) { + this.state = state; + this.rows = calculateMaxRows(state); + this.outputs = getOutputText(state); + } + + private static int calculateMaxRows(final ProcessingPatternState state) { + int lastFilledInputIndex = 0; + for (int i = 0; i < state.inputs().size(); i++) { + if (state.inputs().get(i).isPresent()) { + lastFilledInputIndex = i; + } + } + int lastFilledOutputIndex = 0; + for (int i = 0; i < state.outputs().size(); i++) { + if (state.outputs().get(i).isPresent()) { + lastFilledOutputIndex = i; + } + } + final int lastFilledInputRow = Math.ceilDiv(lastFilledInputIndex + 1, 3); + final int lastFilledOutputRow = Math.ceilDiv(lastFilledOutputIndex + 1, 3); + return Math.max(lastFilledInputRow, lastFilledOutputRow); + } + + private static List getOutputText(final ProcessingPatternState state) { + return state.getFlatOutputs() + .stream() + .map(ProcessingPatternClientTooltipComponent::getOutputText) + .toList(); + } + + private static Component getOutputText(final ResourceAmount resourceAmount) { + final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering( + resourceAmount.getResource() + ); + final String displayAmount = rendering.getDisplayedAmount( + resourceAmount.getAmount(), + false + ); + return Component.literal(String.format("%sx ", displayAmount)) + .append(rendering.getDisplayName(resourceAmount.getResource())) + .withStyle(ChatFormatting.GRAY); + } + + @Override + public int getHeight() { + return (outputs.size() * 9) + 2 + (rows * 18) + 3; + } + + @Override + public int getWidth(final Font font) { + return (18 * 3) + ARROW_SPACING + LIGHT_ARROW_WIDTH + ARROW_SPACING + (18 * 3); + } + + @Override + public void renderImage(final Font font, final int x, final int y, final GuiGraphics graphics) { + renderOutputText(font, x, y, graphics); + final int matrixSlotsY = y + (outputs.size() * 9) + 2; + renderMatrixSlots(x, matrixSlotsY, true, graphics); + graphics.blitSprite( + LIGHT_ARROW, + x + (18 * 3) + ARROW_SPACING, + y + (outputs.size() * 9) + 2 + ((rows * 18) / 2) - (LIGHT_ARROW_HEIGHT / 2), + LIGHT_ARROW_WIDTH, + LIGHT_ARROW_HEIGHT + ); + renderMatrixSlots(x, matrixSlotsY, false, graphics); + } + + private void renderMatrixSlots(final int x, + final int y, + final boolean input, + final GuiGraphics graphics) { + final List> slots = input ? state.inputs() : state.outputs(); + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < 3; ++column) { + final int slotXOffset = !input ? ((18 * 3) + ARROW_SPACING + LIGHT_ARROW_WIDTH + ARROW_SPACING) : 0; + final int slotX = x + slotXOffset + column * 18; + final int slotY = y + row * 18; + final int idx = row * 3 + column; + if (idx >= slots.size()) { + break; + } + graphics.blitSprite(SLOT, slotX, slotY, 18, 18); + slots.get(idx).ifPresent(resourceAmount -> { + final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering( + resourceAmount.getResource() + ); + rendering.render(resourceAmount.getResource(), graphics, slotX + 1, slotY + 1); + AbstractBaseScreen.renderResourceAmount(graphics, slotX + 1, slotY + 1, resourceAmount.getAmount(), + rendering); + }); + } + } + } + + private void renderOutputText(final Font font, final int x, final int y, final GuiGraphics graphics) { + for (int i = 0; i < outputs.size(); ++i) { + graphics.drawString( + font, + outputs.get(i), + x, + y + (i * 9), + requireNonNullElse(ChatFormatting.GRAY.getColor(), 15) + ); + } + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternState.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternState.java new file mode 100644 index 000000000..afa7d0f76 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternState.java @@ -0,0 +1,47 @@ +package com.refinedmods.refinedstorage.common.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.list.ResourceList; +import com.refinedmods.refinedstorage.api.resource.list.ResourceListImpl; +import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +public record ProcessingPatternState( + List> inputs, + List> outputs +) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.list(ResourceCodecs.AMOUNT_OPTIONAL_CODEC).fieldOf("inputs").forGetter(ProcessingPatternState::inputs), + Codec.list(ResourceCodecs.AMOUNT_OPTIONAL_CODEC).fieldOf("outputs").forGetter(ProcessingPatternState::outputs) + ).apply(instance, ProcessingPatternState::new)); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + ByteBufCodecs.collection(ArrayList::new, ResourceCodecs.AMOUNT_STREAM_OPTIONAL_CODEC), + ProcessingPatternState::inputs, + ByteBufCodecs.collection(ArrayList::new, ResourceCodecs.AMOUNT_STREAM_OPTIONAL_CODEC), + ProcessingPatternState::outputs, + ProcessingPatternState::new + ); + + List getFlatInputs() { + final ResourceList list = ResourceListImpl.orderPreserving(); + inputs.forEach(input -> input.ifPresent(list::add)); + return new ArrayList<>(list.getAll()); + } + + List getFlatOutputs() { + final ResourceList list = ResourceListImpl.orderPreserving(); + outputs.forEach(output -> output.ifPresent(list::add)); + return new ArrayList<>(list.getAll()); + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DataComponents.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DataComponents.java index 47dfd40fd..4b9d7ad45 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DataComponents.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DataComponents.java @@ -2,6 +2,7 @@ import com.refinedmods.refinedstorage.common.autocrafting.CraftingPatternState; import com.refinedmods.refinedstorage.common.autocrafting.PatternState; +import com.refinedmods.refinedstorage.common.autocrafting.ProcessingPatternState; import com.refinedmods.refinedstorage.common.configurationcard.ConfigurationCardState; import com.refinedmods.refinedstorage.common.security.SecurityCardBoundPlayer; import com.refinedmods.refinedstorage.common.security.SecurityCardPermissions; @@ -37,6 +38,8 @@ public final class DataComponents { private Supplier> patternState; @Nullable private Supplier> craftingPatternState; + @Nullable + private Supplier> processingPatternState; private DataComponents() { } @@ -122,4 +125,14 @@ public void setCraftingPatternState( ) { this.craftingPatternState = supplier; } + + public DataComponentType getProcessingPatternState() { + return requireNonNull(processingPatternState).get(); + } + + public void setProcessingPatternState( + @Nullable final Supplier> supplier + ) { + this.processingPatternState = supplier; + } } 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 065c4f96e..51d45f07c 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,7 +30,7 @@ import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridInsertionStrategy; import com.refinedmods.refinedstorage.common.grid.strategy.ClientGridScrollingStrategy; import com.refinedmods.refinedstorage.common.grid.view.CompositeGridResourceFactory; -import com.refinedmods.refinedstorage.common.support.AbstractBaseContainerMenu; +import com.refinedmods.refinedstorage.common.support.containermenu.AbstractResourceContainerMenu; import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets; import com.refinedmods.refinedstorage.common.support.resource.ResourceTypes; import com.refinedmods.refinedstorage.common.support.stretching.ScreenSizeListener; @@ -53,7 +53,7 @@ import static java.util.Objects.requireNonNull; -public abstract class AbstractGridContainerMenu extends AbstractBaseContainerMenu +public abstract class AbstractGridContainerMenu extends AbstractResourceContainerMenu implements GridWatcher, GridInsertionStrategy, GridExtractionStrategy, GridScrollingStrategy, ScreenSizeListener { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGridContainerMenu.class); private static final GridQueryParserImpl QUERY_PARSER = new GridQueryParserImpl( @@ -125,7 +125,7 @@ protected AbstractGridContainerMenu( final Inventory playerInventory, final Grid grid ) { - super(menuType, syncId); + super(menuType, syncId, playerInventory.player); this.view = createViewBuilder().build(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridSourceImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridSourceImpl.java index 60411e3ca..08f3ade93 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridSourceImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridSourceImpl.java @@ -128,7 +128,7 @@ private boolean extractFromPlayerInventory(final Player player, final ItemResour } private ResourceList createCombinedPlayerInventoryAndNetworkList(final Player player) { - final ResourceList list = new ResourceListImpl(); + final ResourceList list = ResourceListImpl.create(); addNetworkItemsIntoList(list); addPlayerInventoryItemsIntoList(player, list); return list; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/SnapshotCraftingGridRefillContext.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/SnapshotCraftingGridRefillContext.java index 5dbf3da73..2aae5c9e4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/SnapshotCraftingGridRefillContext.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/SnapshotCraftingGridRefillContext.java @@ -14,8 +14,8 @@ class SnapshotCraftingGridRefillContext implements CraftingGridRefillContext { private final PlayerActor playerActor; private final CraftingGridBlockEntity blockEntity; - private final ResourceList available = new ResourceListImpl(); - private final ResourceList used = new ResourceListImpl(); + private final ResourceList available = ResourceListImpl.create(); + private final ResourceList used = ResourceListImpl.create(); SnapshotCraftingGridRefillContext( final Player player, diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseScreen.java index 6c642ed05..713e825c2 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseScreen.java @@ -25,6 +25,8 @@ 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 net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -95,7 +97,7 @@ public void render(final GuiGraphics graphics, final int mouseX, final int mouse renderTooltip(graphics, mouseX, mouseY); } - protected final void renderResourceSlots(final GuiGraphics graphics) { + protected void renderResourceSlots(final GuiGraphics graphics) { if (!(menu instanceof AbstractResourceContainerMenu resourceContainerMenu)) { return; } @@ -104,7 +106,7 @@ protected final void renderResourceSlots(final GuiGraphics graphics) { } } - private void tryRenderResourceSlot(final GuiGraphics graphics, final ResourceSlot slot) { + protected final void tryRenderResourceSlot(final GuiGraphics graphics, final ResourceSlot slot) { final ResourceKey resource = slot.getResource(); if (resource == null) { return; @@ -128,15 +130,15 @@ private void renderResourceSlot(final GuiGraphics graphics, final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(resource); rendering.render(resource, graphics, x, y); if (renderAmount) { - renderResourceSlotAmount(graphics, x, y, amount, rendering); + renderResourceAmount(graphics, x, y, amount, rendering); } } - private void renderResourceSlotAmount(final GuiGraphics graphics, - final int x, - final int y, - final long amount, - final ResourceRendering rendering) { + public static void renderResourceAmount(final GuiGraphics graphics, + final int x, + final int y, + final long amount, + final ResourceRendering rendering) { renderAmount( graphics, x, @@ -147,12 +149,13 @@ private void renderResourceSlotAmount(final GuiGraphics graphics, ); } - protected void renderAmount(final GuiGraphics graphics, - final int x, - final int y, - final String amount, - final int color, - final boolean large) { + protected static void renderAmount(final GuiGraphics graphics, + final int x, + final int y, + final String amount, + final int color, + final boolean large) { + final Font font = Minecraft.getInstance().font; final PoseStack poseStack = graphics.pose(); poseStack.pushPose(); // Large amounts overlap with the slot lines (see Minecraft behavior) @@ -186,7 +189,7 @@ protected void renderTooltip(final GuiGraphics graphics, final int x, final int return; } } - if (hoveredSlot instanceof ResourceSlot resourceSlot) { + if (hoveredSlot instanceof ResourceSlot resourceSlot && canInteractWithResourceSlot(resourceSlot, x, y)) { final List tooltip = getResourceTooltip(menu.getCarried(), resourceSlot); if (!tooltip.isEmpty()) { Platform.INSTANCE.renderTooltip(graphics, tooltip, x, y); @@ -294,9 +297,10 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int if (hoveredSlot instanceof ResourceSlot resourceSlot && !resourceSlot.supportsItemSlotInteractions() && !resourceSlot.isDisabled() - && getMenu() instanceof AbstractResourceContainerMenu containerMenu) { - if (!tryOpenResourceAmountScreen(resourceSlot)) { - containerMenu.sendResourceSlotChange(hoveredSlot.index, clickedButton == 1); + && canInteractWithResourceSlot(resourceSlot, mouseX, mouseY)) { + if (!tryOpenResourceAmountScreen(resourceSlot) + && getMenu() instanceof AbstractResourceContainerMenu resourceMenu) { + resourceMenu.sendResourceSlotChange(hoveredSlot.index, clickedButton == 1); } return true; } @@ -308,14 +312,22 @@ private boolean tryOpenResourceAmountScreen(final ResourceSlot slot) { final boolean canModifyAmount = isFilterSlot && slot.canModifyAmount(); final boolean isNotTryingToRemoveFilter = !hasShiftDown(); final boolean isNotCarryingItem = getMenu().getCarried().isEmpty(); - final boolean canOpen = - isFilterSlot && canModifyAmount && isNotTryingToRemoveFilter && isNotCarryingItem; + final boolean canOpen = isFilterSlot + && canModifyAmount + && isNotTryingToRemoveFilter + && isNotCarryingItem; if (canOpen && minecraft != null) { minecraft.setScreen(new ResourceAmountScreen(this, playerInventory, slot)); } return canOpen; } + protected boolean canInteractWithResourceSlot(final ResourceSlot resourceSlot, + final double mouseX, + final double mouseY) { + return true; + } + @Nullable @API(status = API.Status.INTERNAL) public PlatformResourceKey getHoveredResource() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/TextureIds.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/TextureIds.java index 7604a0fb7..57e62faf0 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/TextureIds.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/TextureIds.java @@ -7,6 +7,7 @@ public final class TextureIds { public static final ResourceLocation SIDE_BUTTON_ICONS = createIdentifier("textures/side_button_icons.png"); public static final ResourceLocation LIGHT_ARROW = createIdentifier("light_arrow"); + public static final ResourceLocation SLOT = createIdentifier("slot"); public static final int LIGHT_ARROW_WIDTH = 22; public static final int LIGHT_ARROW_HEIGHT = 15; public static final ResourceLocation WARNING = createIdentifier("warning"); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/containermenu/ResourceSlot.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/containermenu/ResourceSlot.java index 41ca7769d..b7d4e4b8b 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/containermenu/ResourceSlot.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/containermenu/ResourceSlot.java @@ -56,7 +56,7 @@ public ResourceSlot(final ResourceContainer resourceContainer, } public ResourceSlot forAmountScreen(final int newX, final int newY) { - return new ResourceSlot(resourceContainer, container, index, helpText, newX, newY, type) { + return new ResourceSlot(resourceContainer, container, getContainerSlot(), helpText, newX, newY, type) { @Override public boolean canModifyAmount() { return false; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/network/component/PlatformStorageNetworkComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/network/component/PlatformStorageNetworkComponent.java index 0302c6dad..0ed1f5fd8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/network/component/PlatformStorageNetworkComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/network/component/PlatformStorageNetworkComponent.java @@ -14,7 +14,7 @@ public class PlatformStorageNetworkComponent extends StorageNetworkComponentImpl private final FuzzyResourceList fuzzyResourceList; public PlatformStorageNetworkComponent() { - this(new FuzzyResourceListImpl(new ResourceListImpl())); + this(new FuzzyResourceListImpl(ResourceListImpl.create())); } private PlatformStorageNetworkComponent(final FuzzyResourceList fuzzyResourceList) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceCodecs.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceCodecs.java index 9f44cb67b..2c1e07eaa 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceCodecs.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceCodecs.java @@ -40,6 +40,8 @@ public final class ResourceCodecs { CODEC.fieldOf("resource").forGetter(resourceAmount -> (PlatformResourceKey) resourceAmount.getResource()), Codec.LONG.fieldOf("amount").forGetter(ResourceAmount::getAmount) ).apply(instance, ResourceAmount::new)); + public static final Codec> AMOUNT_OPTIONAL_CODEC = AMOUNT_CODEC.optionalFieldOf("resource") + .codec(); public static final StreamCodec STREAM_CODEC = new StreamCodec<>() { @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceContainerImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceContainerImpl.java index f41dcc314..8e62a7724 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceContainerImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ResourceContainerImpl.java @@ -136,6 +136,14 @@ public void remove(final int index) { changed(); } + @Override + public void clear() { + for (int i = 0; i < size(); ++i) { + removeSilently(i); + } + changed(); + } + private void removeSilently(final int index) { slots[index] = null; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/stretching/AbstractStretchingScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/stretching/AbstractStretchingScreen.java index d1a71632a..ecf213992 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/stretching/AbstractStretchingScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/stretching/AbstractStretchingScreen.java @@ -41,7 +41,12 @@ protected void init() { super.init(); - this.scrollbar = new ScrollbarWidget(leftPos + 174, topPos + 20, 12, (visibleRows * ROW_SIZE) - 2); + this.scrollbar = new ScrollbarWidget( + leftPos + 174, + topPos + 20, + ScrollbarWidget.Type.NORMAL, + (visibleRows * ROW_SIZE) - 2 + ); this.scrollbar.setListener(offset -> scrollbarChanged(visibleRows)); addWidget(scrollbar); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/ScrollbarWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/ScrollbarWidget.java index 6073e437d..2b167e2c3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/ScrollbarWidget.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/ScrollbarWidget.java @@ -14,17 +14,13 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; public class ScrollbarWidget extends AbstractWidget { - private static final ResourceLocation TEXTURE = createIdentifier("widget/scrollbar"); - private static final ResourceLocation CLICKED_TEXTURE = createIdentifier("widget/scrollbar_clicked"); - private static final ResourceLocation DISABLED_TEXTURE = createIdentifier("widget/scrollbar_disabled"); - - private static final int SCROLLER_WIDTH = 12; private static final int SCROLLER_HEIGHT = 15; private static final int ANIMATION_SCROLL_DURATION_IN_TICKS = 10; private static final double ANIMATION_SCROLL_HEIGHT_IN_PIXELS = 30; private final boolean smoothScrolling; + private final Type type; private double offset; private double maxOffset; @@ -38,9 +34,10 @@ public class ScrollbarWidget extends AbstractWidget { @Nullable private DoubleConsumer listener; - public ScrollbarWidget(final int x, final int y, final int width, final int height) { - super(x, y, width, height, Component.empty()); + public ScrollbarWidget(final int x, final int y, final Type type, final int height) { + super(x, y, type.width, height, Component.empty()); this.smoothScrolling = Platform.INSTANCE.getConfig().isSmoothScrolling(); + this.type = type; } public void setListener(@Nullable final DoubleConsumer listener) { @@ -57,9 +54,9 @@ public void setEnabled(final boolean enabled) { private ResourceLocation getTexture() { if (!enabled) { - return DISABLED_TEXTURE; + return type.disabledTexture; } - return clicked ? CLICKED_TEXTURE : TEXTURE; + return clicked ? type.clickedTexture : type.texture; } @Override @@ -71,7 +68,7 @@ public void renderWidget(final GuiGraphics graphics, final int mouseX, final int getTexture(), getX(), getY() + (int) ((float) offset / (float) maxOffset * (height - SCROLLER_HEIGHT)), - SCROLLER_WIDTH, + type.width, SCROLLER_HEIGHT ); } @@ -166,6 +163,9 @@ public void setMaxOffset(final double maxOffset) { this.maxOffset = Math.max(0, maxOffset); if (this.offset > this.maxOffset) { this.offset = this.maxOffset; + if (listener != null) { + listener.accept(this.offset); + } } } @@ -188,4 +188,34 @@ private void updateOffset(final double mouseY) { protected void updateWidgetNarration(final NarrationElementOutput narrationElementOutput) { // intentionally empty } + + public enum Type { + NORMAL( + createIdentifier("widget/scrollbar"), + createIdentifier("widget/scrollbar_clicked"), + createIdentifier("widget/scrollbar_disabled"), + 12 + ), + SMALL( + createIdentifier("widget/small_scrollbar"), + createIdentifier("widget/small_scrollbar_clicked"), + createIdentifier("widget/small_scrollbar_disabled"), + 7 + ); + + private final ResourceLocation texture; + private final ResourceLocation clickedTexture; + private final ResourceLocation disabledTexture; + private final int width; + + Type(final ResourceLocation texture, + final ResourceLocation clickedTexture, + final ResourceLocation disabledTexture, + final int width) { + this.texture = texture; + this.clickedTexture = clickedTexture; + this.disabledTexture = disabledTexture; + this.width = width; + } + } } 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 e4522ab58..486c24929 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 @@ -67,6 +67,10 @@ "gui.refinedstorage.pattern_grid.fuzzy_mode": "Fuzzy mode", "gui.refinedstorage.pattern_grid.fuzzy_mode.on.help": "Match the pattern inputs, ignoring components.", "gui.refinedstorage.pattern_grid.fuzzy_mode.off.help": "Match the pattern inputs exactly.", + "gui.refinedstorage.pattern_grid.processing.inputs": "Inputs", + "gui.refinedstorage.pattern_grid.processing.outputs": "Outputs", + "gui.refinedstorage.pattern_grid.processing.input_slots_help": "The resources that will be extracted from the storage network and will be inserted into the target inventory.", + "gui.refinedstorage.pattern_grid.processing.output_slots_help": "The resources that are expected to be returned to the storage network to deem the crafting task successful.", "gui.refinedstorage.screen_size": "Screen size", "gui.refinedstorage.screen_size.stretch": "Stretch", "gui.refinedstorage.screen_size.small": "Small", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/pattern/processing.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/pattern/processing.json new file mode 100644 index 000000000..0a09e5b10 --- /dev/null +++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/pattern/processing.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "refinedstorage:item/pattern/processing" + } +} diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing.png new file mode 100644 index 0000000000000000000000000000000000000000..07750be3c6d516a702fe8307b4c02f8523ea8669 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^O+akM!3-pA+BU8MQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1``2&1HT+PkRySuw@-@g6-|9_xZa<9J{kYX(f@(Tuv{Ac*RjV~A|z**oC zS`O%y!e8YQ1*v+3Qo6aF(3nmD^T4H(r9u*_f(PGItBz|Q%wx@C>@-RmdKI;Vst0ESOh@Bjb+ literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing_matrix.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/pattern_grid/processing_matrix.png new file mode 100644 index 0000000000000000000000000000000000000000..6bcd16977f63859f2f8d79eacc392d3b8c6b87b0 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SM3?%Ea%ijSh#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>0X`wF=H}+z-QEBH|6d&O{W3_fz$3Dlfr0NZ2s0kfUy%Y7)b@0746!(! z+`#Cj!{g@2A#f_E)V!VDyD>7VEYQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`c>;VwT>t<7-`(AP?AWo;(9kanMprEv; yi(`ny_E)V!VDyD>7VEYQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`c>;VwT>t<7-`(B4b?es9(9mhW9wY$8ISV`@iy0XB4ude`@%$AjKtX9w y7sn8Z%gGE(jBIMEs?2O^j*84hk%x{QV`Dg$#`;OgQ_2OXjKR~@&t;ucLK6UClq%!^ literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/small_scrollbar_disabled.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/small_scrollbar_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..c28213ac9befe0ef07d07c1e2567320e5723da0f GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)V!VDyD>7VEYQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`IRkt`T>t<7-`(9E8XD^GN%kB_u)rg-n1O-sFbFdq&tH)O6qNRKaSV~T toXo()$mZtg$jauX>dIOa>Ez|b#jt>zWy^-C1^z%~44$rjF6*2UngBWPCz=2N literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/pattern/processing.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/pattern/processing.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6f13658cb8a53aabdf11bd65de8e18357e2fd1 GIT binary patch literal 441 zcmV;q0Y?6bP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ZvIoK~y+TwUIw- zgJ2NGAG-+oMBOq6lBkd=d$%r~qUaVO-8y#28YsyUaLy3hrA|hTA3*3JbaN0ggtzZq zqO{~sn?N5p&eMB--n}pWRl2SVihX&R$e5<7$g=E8$g^N$k|ZLI;|n3uj8_>?J4g@& z9KS-ify}0immMUF-fGBvK0ghi59{@M*C78)fRFT@Yg%DCoeIZs4ko$TXEYiOsHzIt z1l>3Ad7I+ie#BrfK%VDVtybuCI(2WQ8lWf&Ow+`6yM<+0xO;Fg91c+w1(wStO~`$t z(TH=U8nD@HVB2=xK#(vDu~;miX&S$CT^G$}6J=R)eIVLRjw%ep-~+36uJ#^}$D-YC zpT7w*M^VIv%G~XC+5G+RDk=N?Lj-BHTJU|JYkHo|X7D`kX#Y_WgsycmnTTGmcYf?s j>i7FXUfp%(zX|vPQ~ls*8%1sR00000NkvXXu0mjf*LA%| literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/TestPlatform.java b/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/TestPlatform.java index ac3bdd729..e15c86a2f 100644 --- a/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/TestPlatform.java +++ b/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/TestPlatform.java @@ -37,6 +37,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingInput; @@ -232,4 +233,9 @@ public NetworkNodeContainerProvider getContainerProviderSafely(final Level level public int getItemColor(final ItemStack stack, final int tintIndex) { throw new UnsupportedOperationException(); } + + @Override + public void setSlotY(final Slot slot, final int y) { + throw new UnsupportedOperationException(); + } } diff --git a/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/support/resource/list/FuzzyResourceListImplTest.java b/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/support/resource/list/FuzzyResourceListImplTest.java index dfc5dfcc3..d067faa78 100644 --- a/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/support/resource/list/FuzzyResourceListImplTest.java +++ b/refinedstorage-common/src/test/java/com/refinedmods/refinedstorage/common/support/resource/list/FuzzyResourceListImplTest.java @@ -33,7 +33,7 @@ class FuzzyResourceListImplTest { @BeforeEach void setUp() { - sut = new FuzzyResourceListImpl(new ResourceListImpl()); + sut = new FuzzyResourceListImpl(ResourceListImpl.create()); } @Test 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 e8a6a0a07..b175fd745 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 @@ -4,9 +4,9 @@ import com.refinedmods.refinedstorage.common.AbstractClientModInitializer; import com.refinedmods.refinedstorage.common.api.support.HelpTooltipComponent; import com.refinedmods.refinedstorage.common.api.upgrade.AbstractUpgradeItem; -import com.refinedmods.refinedstorage.common.autocrafting.CraftingPatternClientTooltipComponent; import com.refinedmods.refinedstorage.common.autocrafting.PatternItem; import com.refinedmods.refinedstorage.common.autocrafting.PatternItemColor; +import com.refinedmods.refinedstorage.common.autocrafting.PatternTooltipCache; import com.refinedmods.refinedstorage.common.configurationcard.ConfigurationCardItemPropertyFunction; import com.refinedmods.refinedstorage.common.content.BlockColorMap; import com.refinedmods.refinedstorage.common.content.BlockEntities; @@ -405,15 +405,13 @@ private void registerCustomTooltips() { }); TooltipComponentCallback.EVENT.register(data -> { if (data instanceof PatternItem.CraftingPatternTooltipComponent component) { - final ClientTooltipComponent help = HelpClientTooltipComponent.create(component.helpText()); - return new CompositeClientTooltipComponent(List.of( - new CraftingPatternClientTooltipComponent( - component.width(), - component.height(), - component.craftingPattern() - ), - help - )); + return PatternTooltipCache.getComponent(component); + } + return null; + }); + TooltipComponentCallback.EVENT.register(data -> { + if (data instanceof PatternItem.ProcessingPatternTooltipComponent component) { + return PatternTooltipCache.getComponent(component); } return null; }); diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/PlatformImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/PlatformImpl.java index 8f5e05b2e..6cdaf7999 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/PlatformImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/PlatformImpl.java @@ -82,6 +82,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; @@ -485,6 +486,11 @@ public int getItemColor(final ItemStack stack, final int tintIndex) { return itemColor.getColor(stack, tintIndex); } + @Override + public void setSlotY(final Slot slot, final int y) { + slot.y = y; + } + private void doSave(final CompoundTag compoundTag, final Path tempFile, final Path targetPath) throws IOException { // Write to temp file first. NbtIo.writeCompressed(compoundTag, tempFile); diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternBakedModel.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternBakedModel.java index fc7f3ed44..afe70ec19 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternBakedModel.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternBakedModel.java @@ -12,9 +12,10 @@ class PatternBakedModel extends ForwardingBakedModel { PatternBakedModel(final ModelBaker modelBaker, final BakedModel emptyModel, - final BakedModel craftingModel) { + final BakedModel craftingModel, + final BakedModel processingModel) { this.wrapped = emptyModel; - this.itemOverrides = new PatternItemOverrides(modelBaker, emptyModel, craftingModel); + this.itemOverrides = new PatternItemOverrides(modelBaker, emptyModel, craftingModel, processingModel); } @Override diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternUnbakedModel.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternUnbakedModel.java index 08b2f3c8b..a81382ba8 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternUnbakedModel.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/autocrafting/PatternUnbakedModel.java @@ -19,16 +19,18 @@ public class PatternUnbakedModel implements UnbakedModel { private static final ResourceLocation EMPTY_MODEL = createIdentifier("item/pattern/empty"); private static final ResourceLocation CRAFTING_MODEL = createIdentifier("item/pattern/crafting"); + private static final ResourceLocation PROCESSING_MODEL = createIdentifier("item/pattern/processing"); @Override public Collection getDependencies() { - return Set.of(EMPTY_MODEL, CRAFTING_MODEL); + return Set.of(EMPTY_MODEL, CRAFTING_MODEL, PROCESSING_MODEL); } @Override public void resolveParents(final Function resolver) { resolver.apply(EMPTY_MODEL).resolveParents(resolver); resolver.apply(CRAFTING_MODEL).resolveParents(resolver); + resolver.apply(PROCESSING_MODEL).resolveParents(resolver); } @Nullable @@ -39,7 +41,8 @@ public BakedModel bake(final ModelBaker baker, return new PatternBakedModel( baker, requireNonNull(baker.bake(EMPTY_MODEL, state)), - requireNonNull(baker.bake(CRAFTING_MODEL, state)) + requireNonNull(baker.bake(CRAFTING_MODEL, state)), + requireNonNull(baker.bake(PROCESSING_MODEL, state)) ); } } diff --git a/refinedstorage-fabric/src/main/resources/refinedstorage.accesswidener b/refinedstorage-fabric/src/main/resources/refinedstorage.accesswidener index f65de0bc5..3e09e10d3 100644 --- a/refinedstorage-fabric/src/main/resources/refinedstorage.accesswidener +++ b/refinedstorage-fabric/src/main/resources/refinedstorage.accesswidener @@ -7,3 +7,4 @@ accessible class net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl accessible method net/minecraft/client/resources/model/ModelBakery$BakedCacheKey (Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/math/Transformation;Z)V accessible method net/minecraft/client/gui/GuiGraphics renderTooltipInternal (Lnet/minecraft/client/gui/Font;Ljava/util/List;IILnet/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipPositioner;)V accessible method net/minecraft/client/renderer/block/model/ItemOverrides ()V +mutable field net/minecraft/world/inventory/Slot y I diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilderImpl.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilderImpl.java index e38890ba5..a1fb8af66 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilderImpl.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilderImpl.java @@ -14,7 +14,7 @@ @API(status = API.Status.STABLE, since = "2.0.0-milestone.2.4") public class GridViewBuilderImpl implements GridViewBuilder { private final GridResourceFactory resourceFactory; - private final ResourceList backingList = new ResourceListImpl(); + private final ResourceList backingList = ResourceListImpl.create(); private final Map trackedResources = new HashMap<>(); private final GridSortingType identitySortingType; private final GridSortingType defaultSortingType; diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImpl.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImpl.java index 49394645e..9c0eed56f 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImpl.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImpl.java @@ -249,7 +249,7 @@ public List getViewList() { @Override public ResourceList copyBackingList() { - final ResourceList copy = new ResourceListImpl(); + final ResourceList copy = ResourceListImpl.create(); backingList.getAll().forEach(copy::add); return copy; } diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java index d91397489..825d9d852 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java @@ -4,10 +4,10 @@ import com.refinedmods.refinedstorage.common.AbstractClientModInitializer; import com.refinedmods.refinedstorage.common.api.support.HelpTooltipComponent; import com.refinedmods.refinedstorage.common.api.upgrade.AbstractUpgradeItem; -import com.refinedmods.refinedstorage.common.autocrafting.CraftingPatternClientTooltipComponent; import com.refinedmods.refinedstorage.common.autocrafting.PatternBlockEntityWithoutLevelRenderer; import com.refinedmods.refinedstorage.common.autocrafting.PatternItem; import com.refinedmods.refinedstorage.common.autocrafting.PatternItemColor; +import com.refinedmods.refinedstorage.common.autocrafting.PatternTooltipCache; import com.refinedmods.refinedstorage.common.configurationcard.ConfigurationCardItemPropertyFunction; import com.refinedmods.refinedstorage.common.content.BlockEntities; import com.refinedmods.refinedstorage.common.content.Blocks; @@ -222,20 +222,8 @@ public static void onRegisterTooltipFactories(final RegisterClientTooltipCompone : createRegulatorUpgradeClientTooltipComponent(component.configuredResource(), help); } ); - e.register( - PatternItem.CraftingPatternTooltipComponent.class, - component -> { - final ClientTooltipComponent help = HelpClientTooltipComponent.create(component.helpText()); - return new CompositeClientTooltipComponent(List.of( - new CraftingPatternClientTooltipComponent( - component.width(), - component.height(), - component.craftingPattern() - ), - help - )); - } - ); + e.register(PatternItem.CraftingPatternTooltipComponent.class, PatternTooltipCache::getComponent); + e.register(PatternItem.ProcessingPatternTooltipComponent.class, PatternTooltipCache::getComponent); } private static CompositeClientTooltipComponent createRegulatorUpgradeClientTooltipComponent( diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/PlatformImpl.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/PlatformImpl.java index c660a3a0c..8c8cf08ab 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/PlatformImpl.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/PlatformImpl.java @@ -51,6 +51,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -403,4 +404,9 @@ public NetworkNodeContainerProvider getContainerProviderSafely(final Level level public int getItemColor(final ItemStack stack, final int tintIndex) { return Minecraft.getInstance().getItemColors().getColor(stack, tintIndex); } + + @Override + public void setSlotY(final Slot slot, final int y) { + slot.y = y; + } } diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternBakedModel.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternBakedModel.java index 144b5f4bd..f3f939298 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternBakedModel.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternBakedModel.java @@ -10,9 +10,12 @@ class PatternBakedModel extends BakedModelWrapper { private final ItemOverrides itemOverrides; - PatternBakedModel(final ModelBaker modelBaker, final BakedModel emptyModel, final BakedModel craftingModel) { + PatternBakedModel(final ModelBaker modelBaker, + final BakedModel emptyModel, + final BakedModel craftingModel, + final BakedModel processingModel) { super(emptyModel); - this.itemOverrides = new PatternItemOverrides(modelBaker, emptyModel, craftingModel); + this.itemOverrides = new PatternItemOverrides(modelBaker, emptyModel, craftingModel, processingModel); } @Override diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternUnbakedGeometry.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternUnbakedGeometry.java index dcd6221af..017d33f17 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternUnbakedGeometry.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/autocrafting/PatternUnbakedGeometry.java @@ -19,6 +19,7 @@ public class PatternUnbakedGeometry implements IUnbakedGeometry { private static final ResourceLocation EMPTY_MODEL = createIdentifier("item/pattern/empty"); private static final ResourceLocation CRAFTING_MODEL = createIdentifier("item/pattern/crafting"); + private static final ResourceLocation PROCESSING_MODEL = createIdentifier("item/pattern/processing"); @Override public BakedModel bake(final IGeometryBakingContext ctx, @@ -29,7 +30,8 @@ public BakedModel bake(final IGeometryBakingContext ctx, return new PatternBakedModel( modelBaker, requireNonNull(modelBaker.bake(EMPTY_MODEL, modelState, function)), - requireNonNull(modelBaker.bake(CRAFTING_MODEL, modelState, function)) + requireNonNull(modelBaker.bake(CRAFTING_MODEL, modelState, function)), + requireNonNull(modelBaker.bake(PROCESSING_MODEL, modelState, function)) ); } @@ -38,5 +40,6 @@ public void resolveParents(final Function modelG final IGeometryBakingContext context) { modelGetter.apply(EMPTY_MODEL).resolveParents(modelGetter); modelGetter.apply(CRAFTING_MODEL).resolveParents(modelGetter); + modelGetter.apply(PROCESSING_MODEL).resolveParents(modelGetter); } } diff --git a/refinedstorage-neoforge/src/main/resources/META-INF/accesstransformer.cfg b/refinedstorage-neoforge/src/main/resources/META-INF/accesstransformer.cfg index 7b36b1489..3f2063b65 100644 --- a/refinedstorage-neoforge/src/main/resources/META-INF/accesstransformer.cfg +++ b/refinedstorage-neoforge/src/main/resources/META-INF/accesstransformer.cfg @@ -1,2 +1,3 @@ public net.minecraft.client.gui.components.EditBox canLoseFocus public net.minecraft.client.gui.GuiGraphics renderTooltipInternal(Lnet/minecraft/client/gui/Font;Ljava/util/List;IILnet/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipPositioner;)V +public-f net.minecraft.world.inventory.Slot y \ No newline at end of file diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestFixtures.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestFixtures.java index ba433377d..37328b2c8 100644 --- a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestFixtures.java +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestFixtures.java @@ -15,8 +15,6 @@ import com.refinedmods.refinedstorage.api.resource.list.ResourceListImpl; import com.refinedmods.refinedstorage.network.test.fake.FakePermissions; -import java.util.LinkedHashMap; - public final class NetworkTestFixtures { public static final ComponentMapFactory NETWORK_COMPONENT_MAP_FACTORY = new ComponentMapFactory<>(); @@ -32,7 +30,7 @@ public final class NetworkTestFixtures { ); NETWORK_COMPONENT_MAP_FACTORY.addFactory( StorageNetworkComponent.class, - network -> new StorageNetworkComponentImpl(new ResourceListImpl(new LinkedHashMap<>())) + network -> new StorageNetworkComponentImpl(ResourceListImpl.orderPreserving()) ); NETWORK_COMPONENT_MAP_FACTORY.addFactory( SecurityNetworkComponent.class, diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/storage/ExposedStorage.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/storage/ExposedStorage.java index 403db7e6f..0d9987cbb 100644 --- a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/storage/ExposedStorage.java +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/storage/ExposedStorage.java @@ -17,7 +17,7 @@ class ExposedStorage extends AbstractImmutableConfiguredProxyStorage implements CompositeStorage { protected ExposedStorage(final StorageConfiguration config) { - super(config, new CompositeStorageImpl(new ResourceListImpl())); + super(config, new CompositeStorageImpl(ResourceListImpl.create())); } long getCapacity() { diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/storagetransfer/StorageTransferNetworkNodeTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/storagetransfer/StorageTransferNetworkNodeTest.java index 9a0763f5a..9ee64fdf1 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/storagetransfer/StorageTransferNetworkNodeTest.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/storagetransfer/StorageTransferNetworkNodeTest.java @@ -17,7 +17,6 @@ import com.refinedmods.refinedstorage.network.test.NetworkTest; import com.refinedmods.refinedstorage.network.test.SetupNetwork; -import java.util.LinkedHashMap; import java.util.Set; import org.junit.jupiter.api.BeforeEach; @@ -57,7 +56,7 @@ void shouldNotTransferWithoutNetwork(@InjectNetworkStorageComponent final Storag // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source); @@ -78,7 +77,7 @@ void shouldNotTransferWhenInactive(@InjectNetworkStorageComponent final StorageN // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source); @@ -140,14 +139,14 @@ public long extract(final ResourceKey resource, source0.insert(A, 1, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source0); - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 35, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(1, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(2, source2); @@ -181,14 +180,14 @@ void shouldInsertAllowlist(@InjectNetworkStorageComponent final StorageNetworkCo // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 35, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set((sut.getSize() / 2) - 2, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set((sut.getSize() / 2) - 1, source2); @@ -220,14 +219,14 @@ void shouldInsertBlocklist(@InjectNetworkStorageComponent final StorageNetworkCo // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 35, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(1, source2); @@ -278,7 +277,7 @@ void shouldNotifyListenerWhenReadyInsertingAllResources( // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source.insert(C, 5, Action.EXECUTE, EmptyActor.INSTANCE); @@ -298,12 +297,12 @@ void shouldNotifyListenerWhenReadyInsertingAllResources( @Test void shouldNotifyListenerWhenReadyInsertingAllResourcesAndUsingFilterButInsertedNothing() { // Arrange - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(1, source2); @@ -333,13 +332,13 @@ void shouldNotifyListenerWhenReadyInsertingAllResourcesAndUsingFilterButStillIns // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(1, source2); @@ -369,14 +368,14 @@ void shouldNotNotifyListenerWhenReadyInsertingAllResourcesAndNetworkIsFull( // Arrange networkStorage.addSource(new LimitedStorageImpl(15)); - final Storage source1 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source1 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source1.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(C, 5, Action.EXECUTE, EmptyActor.INSTANCE); source1.insert(D, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(0, source1); - final Storage source2 = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source2 = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source2.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); provider.set(1, source2); @@ -597,12 +596,12 @@ void shouldNotifyListenerWhenReadyExtractingAllResourcesAndUsingFilterButStillEx @InjectNetworkStorageComponent final StorageNetworkComponent networkStorage ) { // Arrange - networkStorage.addSource(new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>()))); + networkStorage.addSource(new InMemoryStorageImpl(ResourceListImpl.orderPreserving())); networkStorage.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); networkStorage.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); networkStorage.insert(C, 5, Action.EXECUTE, EmptyActor.INSTANCE); - final Storage source = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); provider.set(0, source); sut.setProvider(provider); @@ -663,7 +662,7 @@ void shouldRespectNormalizer( // Arrange networkStorage.addSource(new InMemoryStorageImpl()); - final Storage source = new InMemoryStorageImpl(new ResourceListImpl(new LinkedHashMap<>())); + final Storage source = new InMemoryStorageImpl(ResourceListImpl.orderPreserving()); source.insert(A, 5, Action.EXECUTE, EmptyActor.INSTANCE); source.insert(A_ALTERNATIVE, 5, Action.EXECUTE, EmptyActor.INSTANCE); source.insert(B, 5, Action.EXECUTE, EmptyActor.INSTANCE); diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/storage/StorageNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/storage/StorageNetworkComponentImplTest.java index b7beebb1d..c79cc9c67 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/storage/StorageNetworkComponentImplTest.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/storage/StorageNetworkComponentImplTest.java @@ -37,7 +37,7 @@ class StorageNetworkComponentImplTest { @BeforeEach void setUp() { - sut = new StorageNetworkComponentImpl(new ResourceListImpl()); + sut = new StorageNetworkComponentImpl(ResourceListImpl.create()); storage1 = new StorageNetworkNode(0, 0, 1); storage1.setNetwork(new NetworkImpl(NetworkTestFixtures.NETWORK_COMPONENT_MAP_FACTORY)); diff --git a/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/ResourceAmount.java b/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/ResourceAmount.java index 5c6398c89..b9f697637 100644 --- a/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/ResourceAmount.java +++ b/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/ResourceAmount.java @@ -31,6 +31,10 @@ public long getAmount() { return amount; } + public ResourceAmount copy() { + return new ResourceAmount(resource, amount); + } + /** * Increments with the given amount. * diff --git a/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImpl.java b/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImpl.java index f26778ec8..42aaae19a 100644 --- a/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImpl.java +++ b/refinedstorage-resource-api/src/main/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImpl.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; @@ -17,12 +18,16 @@ public class ResourceListImpl implements ResourceList { private final Map entries; - public ResourceListImpl(final Map entries) { + private ResourceListImpl(final Map entries) { this.entries = entries; } - public ResourceListImpl() { - this(new HashMap<>()); + public static ResourceListImpl create() { + return new ResourceListImpl(new HashMap<>()); + } + + public static ResourceListImpl orderPreserving() { + return new ResourceListImpl(new LinkedHashMap<>()); } @Override diff --git a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ProxyResourceListTest.java b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ProxyResourceListTest.java index 326fb994f..fb0f9aa52 100644 --- a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ProxyResourceListTest.java +++ b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ProxyResourceListTest.java @@ -3,7 +3,7 @@ class ProxyResourceListTest extends AbstractResourceListTest { @Override protected ResourceList createList() { - return new AbstractProxyResourceList(new ResourceListImpl()) { + return new AbstractProxyResourceList(ResourceListImpl.create()) { }; } } diff --git a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImplTest.java b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImplTest.java index 7cf73397e..f8c1259ca 100644 --- a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImplTest.java +++ b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/ResourceListImplTest.java @@ -3,6 +3,6 @@ class ResourceListImplTest extends AbstractResourceListTest { @Override protected ResourceList createList() { - return new ResourceListImpl(); + return ResourceListImpl.create(); } } diff --git a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/listenable/ListenableResourceListTest.java b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/listenable/ListenableResourceListTest.java index d23729ea9..24aa02530 100644 --- a/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/listenable/ListenableResourceListTest.java +++ b/refinedstorage-resource-api/src/test/java/com/refinedmods/refinedstorage/api/resource/list/listenable/ListenableResourceListTest.java @@ -21,7 +21,7 @@ class ListenableResourceListTest { @BeforeEach void setUp() { listener = new FakeResourceListListener(); - list = new ResourceListImpl(); + list = ResourceListImpl.create(); sut = new ListenableResourceList(list); } diff --git a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/InMemoryStorageImpl.java b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/InMemoryStorageImpl.java index 6a558c8c3..0d7a9ad77 100644 --- a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/InMemoryStorageImpl.java +++ b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/InMemoryStorageImpl.java @@ -23,7 +23,7 @@ public InMemoryStorageImpl(final ResourceList list) { } public InMemoryStorageImpl() { - this(new ResourceListImpl()); + this(ResourceListImpl.create()); } @Override diff --git a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/external/ExternalStorage.java b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/external/ExternalStorage.java index 15e519539..96694ff2f 100644 --- a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/external/ExternalStorage.java +++ b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/external/ExternalStorage.java @@ -20,7 +20,7 @@ public class ExternalStorage implements CompositeAwareChild { private final ExternalStorageProvider provider; private final Set parents = new HashSet<>(); - private final ResourceList cache = new ResourceListImpl(); + private final ResourceList cache = ResourceListImpl.create(); private final ExternalStorageListener listener; public ExternalStorage(final ExternalStorageProvider provider, final ExternalStorageListener listener) { @@ -111,7 +111,7 @@ private void removeFromCache(final ResourceKey resource, final long amount) { } private ResourceList buildCache() { - final ResourceList list = new ResourceListImpl(); + final ResourceList list = ResourceListImpl.create(); provider.iterator().forEachRemaining(list::add); return list; } diff --git a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/root/RootStorageImpl.java b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/root/RootStorageImpl.java index 92735fd32..c38172f67 100644 --- a/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/root/RootStorageImpl.java +++ b/refinedstorage-storage-api/src/main/java/com/refinedmods/refinedstorage/api/storage/root/RootStorageImpl.java @@ -24,7 +24,7 @@ public class RootStorageImpl implements RootStorage { private final ListenableResourceList list; public RootStorageImpl() { - this(new ResourceListImpl()); + this(ResourceListImpl.create()); } public RootStorageImpl(final ResourceList list) { diff --git a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/CompositeStorageImplTest.java b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/CompositeStorageImplTest.java index db2dcbfc4..f956e531d 100644 --- a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/CompositeStorageImplTest.java +++ b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/CompositeStorageImplTest.java @@ -27,7 +27,7 @@ class CompositeStorageImplTest { @BeforeEach void setUp() { - sut = new CompositeStorageImpl(new ResourceListImpl()); + sut = new CompositeStorageImpl(ResourceListImpl.create()); } @Test diff --git a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/ExtractCompositeStorageImplTest.java b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/ExtractCompositeStorageImplTest.java index 576a54b49..b5d12bf59 100644 --- a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/ExtractCompositeStorageImplTest.java +++ b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/ExtractCompositeStorageImplTest.java @@ -23,7 +23,7 @@ class ExtractCompositeStorageImplTest { @BeforeEach void setUp() { - sut = new CompositeStorageImpl(new ResourceListImpl()); + sut = new CompositeStorageImpl(ResourceListImpl.create()); } @ParameterizedTest diff --git a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/InsertCompositeStorageImplTest.java b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/InsertCompositeStorageImplTest.java index a71b35f5d..6dab1918f 100644 --- a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/InsertCompositeStorageImplTest.java +++ b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/InsertCompositeStorageImplTest.java @@ -22,7 +22,7 @@ class InsertCompositeStorageImplTest { @BeforeEach void setUp() { - sut = new CompositeStorageImpl(new ResourceListImpl()); + sut = new CompositeStorageImpl(ResourceListImpl.create()); } @ParameterizedTest diff --git a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/SubCompositeCompositeStorageImplTest.java b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/SubCompositeCompositeStorageImplTest.java index 6bfff4f0c..9e3cd603d 100644 --- a/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/SubCompositeCompositeStorageImplTest.java +++ b/refinedstorage-storage-api/src/test/java/com/refinedmods/refinedstorage/api/storage/composite/SubCompositeCompositeStorageImplTest.java @@ -19,13 +19,13 @@ class SubCompositeCompositeStorageImplTest { @BeforeEach void setUp() { - sut = new CompositeStorageImpl(new ResourceListImpl()); + sut = new CompositeStorageImpl(ResourceListImpl.create()); } @Test void testAddingSubCompositeShouldAddAllResourcesToParent() { // Arrange - final CompositeStorage subComposite = new CompositeStorageImpl(new ResourceListImpl()); + final CompositeStorage subComposite = new CompositeStorageImpl(ResourceListImpl.create()); subComposite.addSource(new InMemoryStorageImpl()); subComposite.insert(A, 10, Action.EXECUTE, EmptyActor.INSTANCE); @@ -41,7 +41,7 @@ void testAddingSubCompositeShouldAddAllResourcesToParent() { @Test void testRemovingSubCompositeShouldRemoveAllResourcesFromParent() { // Arrange - final CompositeStorage subComposite = new CompositeStorageImpl(new ResourceListImpl()); + final CompositeStorage subComposite = new CompositeStorageImpl(ResourceListImpl.create()); subComposite.addSource(new InMemoryStorageImpl()); subComposite.insert(A, 10, Action.EXECUTE, EmptyActor.INSTANCE); @@ -62,7 +62,7 @@ void testRemovingSubCompositeShouldRemoveAllResourcesFromParent() { @Test void testAddingSourceToSubCompositeShouldNotifyParent() { // Arrange - final CompositeStorage subComposite = new CompositeStorageImpl(new ResourceListImpl()); + final CompositeStorage subComposite = new CompositeStorageImpl(ResourceListImpl.create()); final Storage subStorage = new InMemoryStorageImpl(); subStorage.insert(B, 10, Action.EXECUTE, EmptyActor.INSTANCE); @@ -89,7 +89,7 @@ void testAddingSourceToSubCompositeShouldNotifyParent() { @Test void testRemovingSourceFromSubCompositeShouldNotifyParent() { // Arrange - final CompositeStorage subComposite = new CompositeStorageImpl(new ResourceListImpl()); + final CompositeStorage subComposite = new CompositeStorageImpl(ResourceListImpl.create()); final Storage subStorage = new InMemoryStorageImpl(); subStorage.insert(B, 10, Action.EXECUTE, EmptyActor.INSTANCE);