From c561c66afe0437eb397095fabd8e4b803af9c4a0 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Thu, 29 Aug 2024 18:36:09 +0200 Subject: [PATCH 01/14] feat: pattern registration --- .github/CONTRIBUTING.md | 33 +++--- .../build.gradle.kts | 31 +++++ .../api/autocrafting/Pattern.java | 12 ++ .../api/autocrafting/PatternRepository.java | 16 +++ .../autocrafting/PatternRepositoryImpl.java | 34 ++++++ .../api/autocrafting/package-info.java | 7 ++ .../api/autocrafting/FakeResources.java | 9 ++ .../PatternRepositoryImplTest.java | 95 +++++++++++++++ .../api/autocrafting/SimplePattern.java | 18 +++ .../api/autocrafting/package-info.java | 7 ++ refinedstorage-common-api/build.gradle.kts | 1 + .../common/api/RefinedStorageApi.java | 2 +- .../common/api/RefinedStorageApiProxy.java | 2 +- .../common/api/autocrafting/Pattern.java | 7 -- .../api/autocrafting/PatternProviderItem.java | 2 + .../common/AbstractModInitializer.java | 7 ++ .../common/RefinedStorageApiImpl.java | 2 +- .../autocrafting/CrafterBlockEntity.java | 39 ++++-- .../autocrafting/CrafterContainerMenu.java | 5 +- .../common/autocrafting/CraftingPattern.java | 8 +- .../common/autocrafting/PatternInventory.java | 50 ++++++++ .../common/autocrafting/PatternItem.java | 2 +- .../autocrafting/ProcessingPattern.java | 9 +- .../autocrafting/SmithingTablePattern.java | 9 +- .../autocrafting/StonecutterPattern.java | 9 +- refinedstorage-fabric/build.gradle.kts | 1 + refinedstorage-neoforge/build.gradle.kts | 1 + refinedstorage-network-api/build.gradle.kts | 1 + .../AutocraftingNetworkComponent.java | 10 ++ .../network/autocrafting/PatternProvider.java | 13 ++ .../network/autocrafting/package-info.java | 7 ++ .../api/network/storage/StorageProvider.java | 1 + .../network/test/AddNetworkNode.java | 2 + .../InjectNetworkAutocraftingComponent.java | 12 ++ .../network/test/NetworkTest.java | 3 + .../network/test/NetworkTestExtension.java | 45 +++++-- .../network/test/NetworkTestFixtures.java | 7 ++ .../PatternProviderNetworkNodeFactory.java | 16 +++ .../network/test/NetworkNodeFactoryTest.java | 3 + .../test/NetworkTestExtensionTest.java | 11 ++ .../AutocraftingNetworkComponentImpl.java | 47 ++++++++ .../impl/autocrafting/package-info.java | 7 ++ .../PatternProviderNetworkNode.java | 57 +++++++++ .../node/patternprovider/package-info.java | 7 ++ .../AutocraftingNetworkComponentImplTest.java | 76 ++++++++++++ .../impl/autocrafting/SimplePattern.java | 19 +++ .../PatternProviderNetworkNodeTest.java | 111 ++++++++++++++++++ settings.gradle.kts | 1 + 48 files changed, 820 insertions(+), 54 deletions(-) create mode 100644 refinedstorage-autocrafting-api/build.gradle.kts create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepository.java create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java create mode 100644 refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/FakeResources.java create mode 100644 refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java create mode 100644 refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java create mode 100644 refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java delete mode 100644 refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternInventory.java create mode 100644 refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java create mode 100644 refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/PatternProvider.java create mode 100644 refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/package-info.java create mode 100644 refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/InjectNetworkAutocraftingComponent.java create mode 100644 refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/nodefactory/PatternProviderNetworkNodeFactory.java create mode 100644 refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java create mode 100644 refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/package-info.java create mode 100644 refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNode.java create mode 100644 refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/package-info.java create mode 100644 refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java create mode 100644 refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java create mode 100644 refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 16ae93331..23708d507 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -265,19 +265,20 @@ Refined Storage is split up into various modules. Most modules aren't dependent the `refinedstorage-common`, `refinedstorage-neoforge` and `refinedstorage-fabric` modules have dependencies on Minecraft. -| Name | Use in addons | Description | -|-------------------------------|---------------|----------------------------------------------------------------------------------------------------------| -| `refinedstorage-core-api` | ✔️ | Contains some utility classes and enums. | -| `refinedstorage-grid-api` | ✔️ | Contains Grid related functionality. | -| `refinedstorage-network-api` | ✔️ | Contains storage network related functionality. | -| `refinedstorage-network` | ❌ | Contains implementations of `refinedstorage-network-api`. | -| `refinedstorage-network-test` | ✔️ | JUnit extension which helps with setting up a network and a network node for testing. | -| `refinedstorage-query-parser` | ✔️ | A query parser, contains a lexer and parser. Only used for Grid query parsing. | -| `refinedstorage-resource-api` | ✔️ | Contains API for handling resources. | -| `refinedstorage-storage-api` | ✔️ | Contains storage related functionality. | -| `refinedstorage-common-api` | ✔️ | Implements the various Refined Storage API modules for use in Minecraft. | -| `refinedstorage-common` | ❌ | Common mod code. Most gameplay code is in here. | -| `refinedstorage-fabric-api` | ✔️ | Additional API for the Fabric platform. | -| `refinedstorage-fabric` | ❌ | The platform module for Fabric. This module contains Fabric specific code. | -| `refinedstorage-neoforge-api` | ✔️ | Additional API for the NeoForge platform. | -| `refinedstorage-neoforge` | ❌ | The platform module for NeoForge. This module contains NeoForge specific code and the integration tests. | +| Name | Use in addons | Description | +|-----------------------------------|---------------|----------------------------------------------------------------------------------------------------------| +| `refinedstorage-core-api` | ✔️ | Contains some utility classes and enums. | +| `refinedstorage-grid-api` | ✔️ | Contains Grid related functionality. | +| `refinedstorage-autocrafting-api` | ✔️ | Contains autocrafting related functionality. | +| `refinedstorage-network-api` | ✔️ | Contains storage network related functionality. | +| `refinedstorage-network` | ❌ | Contains implementations of `refinedstorage-network-api`. | +| `refinedstorage-network-test` | ✔️ | JUnit extension which helps with setting up a network and a network node for testing. | +| `refinedstorage-query-parser` | ✔️ | A query parser, contains a lexer and parser. Only used for Grid query parsing. | +| `refinedstorage-resource-api` | ✔️ | Contains API for handling resources. | +| `refinedstorage-storage-api` | ✔️ | Contains storage related functionality. | +| `refinedstorage-common-api` | ✔️ | Implements the various Refined Storage API modules for use in Minecraft. | +| `refinedstorage-common` | ❌ | Common mod code. Most gameplay code is in here. | +| `refinedstorage-fabric-api` | ✔️ | Additional API for the Fabric platform. | +| `refinedstorage-fabric` | ❌ | The platform module for Fabric. This module contains Fabric specific code. | +| `refinedstorage-neoforge-api` | ✔️ | Additional API for the NeoForge platform. | +| `refinedstorage-neoforge` | ❌ | The platform module for NeoForge. This module contains NeoForge specific code and the integration tests. | diff --git a/refinedstorage-autocrafting-api/build.gradle.kts b/refinedstorage-autocrafting-api/build.gradle.kts new file mode 100644 index 000000000..959cd6fcd --- /dev/null +++ b/refinedstorage-autocrafting-api/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("refinedarchitect.base") +} + +refinedarchitect { + testing() + mutationTesting() + javadoc() + publishing { + maven = true + } +} + +base { + archivesName.set("refinedstorage-autocrafting-api") +} + +dependencies { + api(libs.apiguardian) + api(project(":refinedstorage-resource-api")) + api(project(":refinedstorage-core-api")) + api(project(":refinedstorage-storage-api")) + api(project(":refinedstorage-query-parser")) + implementation(libs.slf4j.api) + testImplementation(libs.junit.api) + testImplementation(libs.junit.params) + testImplementation(libs.assertj) + testImplementation(libs.mockito) + testRuntimeOnly(libs.junit.engine) + testRuntimeOnly(libs.slf4j.impl) +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java new file mode 100644 index 000000000..b82c4ac72 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java @@ -0,0 +1,12 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Set; + +import org.apiguardian.api.API; + +@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6") +public interface Pattern { + Set<ResourceKey> getOutputs(); +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepository.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepository.java new file mode 100644 index 000000000..01433fc7f --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepository.java @@ -0,0 +1,16 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Set; + +import org.apiguardian.api.API; + +@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.8") +public interface PatternRepository { + void add(Pattern pattern); + + void remove(Pattern pattern); + + Set<ResourceKey> getOutputs(); +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java new file mode 100644 index 000000000..9104779de --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java @@ -0,0 +1,34 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.HashSet; +import java.util.Set; + +public class PatternRepositoryImpl implements PatternRepository { + private final Set<Pattern> patterns = new HashSet<>(); + private final Set<ResourceKey> outputs = new HashSet<>(); + + @Override + public void add(final Pattern pattern) { + patterns.add(pattern); + outputs.addAll(pattern.getOutputs()); + } + + @Override + public void remove(final Pattern pattern) { + patterns.remove(pattern); + for (final ResourceKey output : pattern.getOutputs()) { + final boolean noOtherPatternHasThisOutput = patterns.stream() + .noneMatch(otherPattern -> otherPattern.getOutputs().contains(output)); + if (noOtherPatternHasThisOutput) { + outputs.remove(output); + } + } + } + + @Override + public Set<ResourceKey> getOutputs() { + return outputs; + } +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java new file mode 100644 index 000000000..1a9026f18 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/FakeResources.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/FakeResources.java new file mode 100644 index 000000000..e7a9b3a4c --- /dev/null +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/FakeResources.java @@ -0,0 +1,9 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +public enum FakeResources implements ResourceKey { + A, + B, + C +} diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java new file mode 100644 index 000000000..94f3e5a1f --- /dev/null +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java @@ -0,0 +1,95 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class PatternRepositoryImplTest { + private PatternRepositoryImpl sut; + + @BeforeEach + void setUp() { + sut = new PatternRepositoryImpl(); + } + + @Test + void testDefaultState() { + // Assert + assertThat(sut.getOutputs()).isEmpty(); + } + + @Test + void shouldAddPattern() { + // Act + sut.add(new SimplePattern(FakeResources.A)); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactly(FakeResources.A); + } + + @Test + void shouldAddMultiplePatterns() { + // Act + sut.add(new SimplePattern(FakeResources.A)); + sut.add(new SimplePattern(FakeResources.B)); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder( + FakeResources.A, + FakeResources.B + ); + } + + @Test + void shouldRemovePattern() { + // Arrange + final SimplePattern a = new SimplePattern(FakeResources.A); + final SimplePattern b = new SimplePattern(FakeResources.B); + + sut.add(a); + sut.add(b); + + // Act + sut.remove(a); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactly(FakeResources.B); + } + + @Test + void shouldRemoveMultiplePatterns() { + // Arrange + final SimplePattern a = new SimplePattern(FakeResources.A); + final SimplePattern b = new SimplePattern(FakeResources.B); + + sut.add(a); + sut.add(b); + + // Act + sut.remove(a); + sut.remove(b); + + // Assert + assertThat(sut.getOutputs()).isEmpty(); + } + + @Test + void shouldRemovePatternButNotRemoveOutputIfAnotherPatternStillHasThatOutput() { + // Arrange + final SimplePattern a = new SimplePattern(FakeResources.A); + final SimplePattern b = new SimplePattern(FakeResources.B, FakeResources.A); + + sut.add(a); + sut.add(b); + + // Act + sut.remove(a); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder( + FakeResources.A, + FakeResources.B + ); + } +} \ No newline at end of file diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java new file mode 100644 index 000000000..345dae527 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java @@ -0,0 +1,18 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Set; + +public class SimplePattern implements Pattern { + private final Set<ResourceKey> outputs; + + public SimplePattern(final ResourceKey... outputs) { + this.outputs = Set.of(outputs); + } + + @Override + public Set<ResourceKey> getOutputs() { + return outputs; + } +} diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java new file mode 100644 index 000000000..1a9026f18 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.api.autocrafting; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-common-api/build.gradle.kts b/refinedstorage-common-api/build.gradle.kts index a0ab6c7e1..35bbe7b06 100644 --- a/refinedstorage-common-api/build.gradle.kts +++ b/refinedstorage-common-api/build.gradle.kts @@ -21,4 +21,5 @@ dependencies { api(project(":refinedstorage-resource-api")) api(project(":refinedstorage-network-api")) api(project(":refinedstorage-grid-api")) + api(project(":refinedstorage-autocrafting-api")) } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java index 1894a2642..a96e5fb72 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApi.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.api; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.core.component.ComponentMapFactory; import com.refinedmods.refinedstorage.api.network.Network; import com.refinedmods.refinedstorage.api.network.NetworkComponent; @@ -7,7 +8,6 @@ import com.refinedmods.refinedstorage.api.network.node.NetworkNode; import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; import com.refinedmods.refinedstorage.api.resource.ResourceKey; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.common.api.constructordestructor.ConstructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.constructordestructor.DestructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.exporter.ExporterTransferStrategyFactory; diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java index 0d8e2e3d5..24c147598 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/RefinedStorageApiProxy.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.api; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.core.component.ComponentMapFactory; import com.refinedmods.refinedstorage.api.network.Network; import com.refinedmods.refinedstorage.api.network.NetworkComponent; @@ -7,7 +8,6 @@ import com.refinedmods.refinedstorage.api.network.node.NetworkNode; import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; import com.refinedmods.refinedstorage.api.resource.ResourceKey; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.common.api.constructordestructor.ConstructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.constructordestructor.DestructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.exporter.ExporterTransferStrategyFactory; 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 deleted file mode 100644 index 0bcbc0f31..000000000 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/Pattern.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.refinedmods.refinedstorage.common.api.autocrafting; - -import org.apiguardian.api.API; - -@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6") -public interface Pattern { -} diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/PatternProviderItem.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/PatternProviderItem.java index 3a5796e15..641fb5db2 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/PatternProviderItem.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/autocrafting/PatternProviderItem.java @@ -1,5 +1,7 @@ package com.refinedmods.refinedstorage.common.api.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; + import java.util.Optional; import java.util.UUID; import javax.annotation.Nullable; 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 8a59585e3..75373db79 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 @@ -1,6 +1,9 @@ package com.refinedmods.refinedstorage.common; +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent; +import com.refinedmods.refinedstorage.api.network.impl.autocrafting.AutocraftingNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.energy.EnergyNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.node.GraphNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.security.SecurityNetworkComponentImpl; @@ -264,6 +267,10 @@ private void registerNetworkComponents() { SecurityNetworkComponent.class, network -> new SecurityNetworkComponentImpl(RefinedStorageApi.INSTANCE.createDefaultSecurityPolicy()) ); + RefinedStorageApi.INSTANCE.getNetworkComponentMapFactory().addFactory( + AutocraftingNetworkComponent.class, + network -> new AutocraftingNetworkComponentImpl(new PatternRepositoryImpl()) + ); } private void registerWirelessTransmitterRangeModifiers() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java index 6b75e9080..41ccefd5e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/RefinedStorageApiImpl.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.core.component.ComponentMapFactory; import com.refinedmods.refinedstorage.api.network.Network; import com.refinedmods.refinedstorage.api.network.NetworkBuilder; @@ -11,7 +12,6 @@ import com.refinedmods.refinedstorage.api.network.security.SecurityPolicy; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; import com.refinedmods.refinedstorage.common.api.constructordestructor.ConstructorStrategyFactory; import com.refinedmods.refinedstorage.common.api.constructordestructor.DestructorStrategyFactory; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java index 557f17485..533cccb20 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterBlockEntity.java @@ -1,6 +1,7 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.network.impl.node.SimpleNetworkNode; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode; import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; @@ -39,8 +40,8 @@ import static com.refinedmods.refinedstorage.common.support.AbstractDirectionalBlock.tryExtractDirection; -public class CrafterBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity<SimpleNetworkNode> - implements ExtendedMenuProvider<CrafterData>, BlockEntityWithDrops { +public class CrafterBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity<PatternProviderNetworkNode> + implements ExtendedMenuProvider<CrafterData>, BlockEntityWithDrops, PatternInventory.Listener { static final int PATTERNS = 9; private static final int MAX_CHAINED_CRAFTERS = 8; @@ -49,10 +50,7 @@ public class CrafterBlockEntity extends AbstractBaseNetworkNodeContainerBlockEnt private static final String TAG_LOCK_MODE = "lm"; private static final String TAG_PRIORITY = "pri"; - private final FilteredContainer patternContainer = new FilteredContainer( - PATTERNS, - stack -> level != null && isValidPattern(stack, level) - ); + private final PatternInventory patternContainer = new PatternInventory(this::getLevel); private final UpgradeContainer upgradeContainer; private LockMode lockMode = LockMode.NEVER; private int priority; @@ -62,17 +60,19 @@ public CrafterBlockEntity(final BlockPos pos, final BlockState state) { BlockEntities.INSTANCE.getCrafter(), pos, state, - new SimpleNetworkNode(Platform.INSTANCE.getConfig().getCrafter().getEnergyUsage()) + new PatternProviderNetworkNode(Platform.INSTANCE.getConfig().getCrafter().getEnergyUsage(), PATTERNS) ); this.upgradeContainer = new UpgradeContainer(UpgradeDestinations.CRAFTER, upgradeEnergyUsage -> { final long baseEnergyUsage = Platform.INSTANCE.getConfig().getCrafter().getEnergyUsage(); mainNetworkNode.setEnergyUsage(baseEnergyUsage + upgradeEnergyUsage); setChanged(); }); + patternContainer.addListener(container -> setChanged()); + patternContainer.setListener(this); } @Override - protected InWorldNetworkNodeContainer createMainContainer(final SimpleNetworkNode networkNode) { + protected InWorldNetworkNodeContainer createMainContainer(final PatternProviderNetworkNode networkNode) { return RefinedStorageApi.INSTANCE.createNetworkNodeContainer(this, networkNode) .connectionStrategy(new CrafterConnectionStrategy(this::getBlockState, getBlockPos())) .build(); @@ -268,6 +268,27 @@ void setPriority(final int priority) { setChanged(); } + @Override + public void setLevel(final Level level) { + super.setLevel(level); + if (level.isClientSide()) { + return; + } + for (int i = 0; i < patternContainer.getContainerSize(); ++i) { + patternChanged(i); + } + } + + @Override + public void patternChanged(final int slot) { + if (level == null) { + return; + } + final Pattern pattern = RefinedStorageApi.INSTANCE.getPattern(patternContainer.getItem(slot), level) + .orElse(null); + mainNetworkNode.setPattern(slot, pattern); + } + @Override protected boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState oldBlockState, final BlockState newBlockState) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterContainerMenu.java index 0a9e4cee6..32cf774c0 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CrafterContainerMenu.java @@ -22,9 +22,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import static com.refinedmods.refinedstorage.common.autocrafting.CrafterBlockEntity.PATTERNS; -import static com.refinedmods.refinedstorage.common.autocrafting.CrafterBlockEntity.isValidPattern; - public class CrafterContainerMenu extends AbstractBaseContainerMenu { private static final int PATTERN_SLOT_X = 8; private static final int PATTERN_SLOT_Y = 20; @@ -46,7 +43,7 @@ public CrafterContainerMenu(final int syncId, final Inventory playerInventory, f registerProperty(new ClientProperty<>(CrafterPropertyTypes.LOCK_MODE, LockMode.NEVER)); registerProperty(new ClientProperty<>(CrafterPropertyTypes.PRIORITY, 0)); addSlots( - new FilteredContainer(PATTERNS, stack -> isValidPattern(stack, playerInventory.player.level())), + new PatternInventory(playerInventory.player::level), new UpgradeContainer(UpgradeDestinations.CRAFTER) ); this.name = Component.empty(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java index ea44243cd..c05d5a76c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java @@ -1,11 +1,17 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import java.util.List; +import java.util.Set; record CraftingPattern(List<List<PlatformResourceKey>> inputs, ResourceAmount output, List<ResourceAmount> byproducts) implements Pattern { + @Override + public Set<ResourceKey> getOutputs() { + return Set.of(output.resource()); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternInventory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternInventory.java new file mode 100644 index 000000000..d18aa5603 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/PatternInventory.java @@ -0,0 +1,50 @@ +package com.refinedmods.refinedstorage.common.autocrafting; + +import com.refinedmods.refinedstorage.api.core.NullableType; +import com.refinedmods.refinedstorage.common.support.FilteredContainer; + +import java.util.Optional; +import java.util.function.Supplier; +import javax.annotation.Nullable; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +import static com.refinedmods.refinedstorage.common.autocrafting.CrafterBlockEntity.PATTERNS; +import static com.refinedmods.refinedstorage.common.autocrafting.CrafterBlockEntity.isValidPattern; + +class PatternInventory extends FilteredContainer { + @Nullable + private Listener listener; + + PatternInventory(final Supplier<@NullableType Level> levelSupplier) { + super(PATTERNS, + stack -> Optional.ofNullable(levelSupplier.get()).map(level -> isValidPattern(stack, level)).orElse(false)); + } + + void setListener(@Nullable final Listener listener) { + this.listener = listener; + } + + @Override + public ItemStack removeItem(final int slot, final int amount) { + // Forge InvWrapper calls this instead of setItem. + final ItemStack result = super.removeItem(slot, amount); + if (listener != null) { + listener.patternChanged(slot); + } + return result; + } + + @Override + public void setItem(final int slot, final ItemStack stack) { + super.setItem(slot, stack); + if (listener != null) { + listener.patternChanged(slot); + } + } + + interface Listener { + void patternChanged(int slot); + } +} 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 dbb5295d8..28fe9d79e 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 @@ -1,8 +1,8 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.common.api.autocrafting.PatternProviderItem; import com.refinedmods.refinedstorage.common.api.support.HelpTooltipComponent; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java index b57eee859..bb62e136e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java @@ -1,9 +1,16 @@ package com.refinedmods.refinedstorage.common.autocrafting; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; record ProcessingPattern(List<ResourceAmount> inputs, List<ResourceAmount> outputs) implements Pattern { + @Override + public Set<ResourceKey> getOutputs() { + return outputs.stream().map(ResourceAmount::resource).collect(Collectors.toSet()); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java index 97a1c4520..4511879f4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java @@ -1,8 +1,15 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Set; + record SmithingTablePattern(ItemResource template, ItemResource base, ItemResource addition, ItemResource output) implements Pattern { + @Override + public Set<ResourceKey> getOutputs() { + return Set.of(output); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java index e325ac647..4b4333177 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java @@ -1,7 +1,14 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.common.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Set; + record StonecutterPattern(ItemResource input, ItemResource output) implements Pattern { + @Override + public Set<ResourceKey> getOutputs() { + return Set.of(output); + } } diff --git a/refinedstorage-fabric/build.gradle.kts b/refinedstorage-fabric/build.gradle.kts index c730faadc..f1cae6473 100644 --- a/refinedstorage-fabric/build.gradle.kts +++ b/refinedstorage-fabric/build.gradle.kts @@ -25,6 +25,7 @@ refinedarchitect { addProject(project(":refinedstorage-network-api")) addProject(project(":refinedstorage-network")) addProject(project(":refinedstorage-grid-api")) + addProject(project(":refinedstorage-autocrafting-api")) addProject(project(":refinedstorage-query-parser")) publishing { maven = true diff --git a/refinedstorage-neoforge/build.gradle.kts b/refinedstorage-neoforge/build.gradle.kts index d8bfbe328..ebb56d715 100644 --- a/refinedstorage-neoforge/build.gradle.kts +++ b/refinedstorage-neoforge/build.gradle.kts @@ -16,6 +16,7 @@ refinedarchitect { compileWithProject(project(":refinedstorage-network-api")) compileWithProject(project(":refinedstorage-network")) compileWithProject(project(":refinedstorage-grid-api")) + compileWithProject(project(":refinedstorage-autocrafting-api")) compileWithProject(project(":refinedstorage-query-parser")) publishing { maven = true diff --git a/refinedstorage-network-api/build.gradle.kts b/refinedstorage-network-api/build.gradle.kts index 8da8c8ed1..3cb28e7ef 100644 --- a/refinedstorage-network-api/build.gradle.kts +++ b/refinedstorage-network-api/build.gradle.kts @@ -19,4 +19,5 @@ dependencies { api(project(":refinedstorage-resource-api")) api(project(":refinedstorage-storage-api")) api(project(":refinedstorage-grid-api")) + api(project(":refinedstorage-autocrafting-api")) } diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java new file mode 100644 index 000000000..392287596 --- /dev/null +++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java @@ -0,0 +1,10 @@ +package com.refinedmods.refinedstorage.api.network.autocrafting; + +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; +import com.refinedmods.refinedstorage.api.network.NetworkComponent; + +import org.apiguardian.api.API; + +@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.8") +public interface AutocraftingNetworkComponent extends NetworkComponent, PatternRepository { +} diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/PatternProvider.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/PatternProvider.java new file mode 100644 index 000000000..0b229b584 --- /dev/null +++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/PatternProvider.java @@ -0,0 +1,13 @@ +package com.refinedmods.refinedstorage.api.network.autocrafting; + +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; + +import java.util.Set; + +import org.apiguardian.api.API; + +@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.8") +@FunctionalInterface +public interface PatternProvider { + Set<Pattern> getPatterns(); +} diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/package-info.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/package-info.java new file mode 100644 index 000000000..13a776e5e --- /dev/null +++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.api.network.autocrafting; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/storage/StorageProvider.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/storage/StorageProvider.java index b1437aa19..be814ff1c 100644 --- a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/storage/StorageProvider.java +++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/storage/StorageProvider.java @@ -16,6 +16,7 @@ * a provided {@link Storage}. */ @API(status = API.Status.STABLE, since = "2.0.0-milestone.1.2") +@FunctionalInterface public interface StorageProvider { /** * This method is called when a {@link com.refinedmods.refinedstorage.api.network.node.NetworkNode} is added or diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/AddNetworkNode.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/AddNetworkNode.java index 1fbdb0d6c..1723b0ffe 100644 --- a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/AddNetworkNode.java +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/AddNetworkNode.java @@ -17,6 +17,8 @@ @interface Property { String key(); + int intValue() default -1; + long longValue() default -1; boolean boolValue() default false; diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/InjectNetworkAutocraftingComponent.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/InjectNetworkAutocraftingComponent.java new file mode 100644 index 000000000..7912c1b51 --- /dev/null +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/InjectNetworkAutocraftingComponent.java @@ -0,0 +1,12 @@ +package com.refinedmods.refinedstorage.network.test; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface InjectNetworkAutocraftingComponent { + String networkId() default "default"; +} diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTest.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTest.java index bf3070406..471d6c1e4 100644 --- a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTest.java +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTest.java @@ -8,6 +8,7 @@ import com.refinedmods.refinedstorage.api.network.impl.node.grid.GridNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.iface.InterfaceNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.importer.ImporterNetworkNode; +import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.relay.RelayInputNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.relay.RelayOutputNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.storage.StorageNetworkNode; @@ -19,6 +20,7 @@ import com.refinedmods.refinedstorage.network.test.nodefactory.GridNetworkNodeFactory; import com.refinedmods.refinedstorage.network.test.nodefactory.ImporterNetworkNodeFactory; import com.refinedmods.refinedstorage.network.test.nodefactory.InterfaceNetworkNodeFactory; +import com.refinedmods.refinedstorage.network.test.nodefactory.PatternProviderNetworkNodeFactory; import com.refinedmods.refinedstorage.network.test.nodefactory.RelayInputNetworkNodeFactory; import com.refinedmods.refinedstorage.network.test.nodefactory.RelayOutputNetworkNodeFactory; import com.refinedmods.refinedstorage.network.test.nodefactory.SimpleNetworkNodeFactory; @@ -47,5 +49,6 @@ @RegisterNetworkNode(value = RelayInputNetworkNodeFactory.class, clazz = RelayInputNetworkNode.class) @RegisterNetworkNode(value = RelayOutputNetworkNodeFactory.class, clazz = RelayOutputNetworkNode.class) @RegisterNetworkNode(value = StorageTransferNetworkNodeFactory.class, clazz = StorageTransferNetworkNode.class) +@RegisterNetworkNode(value = PatternProviderNetworkNodeFactory.class, clazz = PatternProviderNetworkNode.class) public @interface NetworkTest { } diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtension.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtension.java index 4821e31db..916b06bc0 100644 --- a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtension.java +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtension.java @@ -2,6 +2,7 @@ import com.refinedmods.refinedstorage.api.core.Action; import com.refinedmods.refinedstorage.api.network.Network; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyStorage; import com.refinedmods.refinedstorage.api.network.impl.NetworkImpl; @@ -20,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; import org.junit.jupiter.api.extension.BeforeEachCallback; @@ -29,6 +31,14 @@ import org.junit.jupiter.api.extension.ParameterResolver; public class NetworkTestExtension implements BeforeEachCallback, ParameterResolver { + private static final Set<Class<? extends Annotation>> SUPPORTED_ANNOTATIONS = Set.of( + InjectNetworkStorageComponent.class, + InjectNetworkEnergyComponent.class, + InjectNetworkSecurityComponent.class, + InjectNetworkAutocraftingComponent.class, + InjectNetwork.class + ); + private final Map<String, Network> networkMap = new HashMap<>(); private final Map<Class<? extends NetworkNode>, NetworkNodeFactory> networkNodeFactories = new HashMap<>(); @@ -149,9 +159,7 @@ private void addNetworkNode(final Object testInstance, final Field field) { if (annotation != null) { final Class<?> type = field.getType(); final Map<String, Object> properties = getProperties(annotation.properties()); - final NetworkNode resolvedNode = networkNodeFactories.get(type).create( - properties - ); + final NetworkNode resolvedNode = networkNodeFactories.get(type).create(properties); final Network network = networkMap.get(annotation.networkId()); registerNetworkNode(testInstance, field, resolvedNode, network); } @@ -160,13 +168,21 @@ private void addNetworkNode(final Object testInstance, final Field field) { private Map<String, Object> getProperties(final AddNetworkNode.Property[] properties) { final Map<String, Object> result = new HashMap<>(); for (final AddNetworkNode.Property property : properties) { - result.put(property.key(), property.longValue() == -1 - ? property.boolValue() - : property.longValue()); + result.put(property.key(), getPropertyValue(property)); } return result; } + private Object getPropertyValue(final AddNetworkNode.Property property) { + if (property.intValue() != -1) { + return property.intValue(); + } + if (property.longValue() != -1) { + return property.longValue(); + } + return property.boolValue(); + } + private void registerNetworkNode(final Object testInstance, final Field field, final NetworkNode networkNode, @@ -190,10 +206,12 @@ private void setField(final Object instance, final Field field, final Object val @Override public boolean supportsParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException { - return parameterContext.isAnnotated(InjectNetworkStorageComponent.class) - || parameterContext.isAnnotated(InjectNetworkEnergyComponent.class) - || parameterContext.isAnnotated(InjectNetworkSecurityComponent.class) - || parameterContext.isAnnotated(InjectNetwork.class); + for (final var supportedAnnotation : SUPPORTED_ANNOTATIONS) { + if (parameterContext.isAnnotated(supportedAnnotation)) { + return true; + } + } + return false; } @Override @@ -208,6 +226,9 @@ public Object resolveParameter(final ParameterContext parameterContext, .or(() -> parameterContext .findAnnotation(InjectNetworkSecurityComponent.class) .map(annotation -> (Object) getNetworkSecurity(annotation.networkId()))) + .or(() -> parameterContext + .findAnnotation(InjectNetworkAutocraftingComponent.class) + .map(annotation -> (Object) getNetworkAutocrafting(annotation.networkId()))) .or(() -> parameterContext .findAnnotation(InjectNetwork.class) .map(annotation -> networkMap.get(annotation.value()))) @@ -225,4 +246,8 @@ private EnergyNetworkComponent getNetworkEnergy(final String networkId) { private SecurityNetworkComponent getNetworkSecurity(final String networkId) { return networkMap.get(networkId).getComponent(SecurityNetworkComponent.class); } + + private AutocraftingNetworkComponent getNetworkAutocrafting(final String networkId) { + return networkMap.get(networkId).getComponent(AutocraftingNetworkComponent.class); + } } 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 37328b2c8..2ad303b6c 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 @@ -1,9 +1,12 @@ package com.refinedmods.refinedstorage.network.test; +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl; import com.refinedmods.refinedstorage.api.core.component.ComponentMapFactory; import com.refinedmods.refinedstorage.api.network.Network; import com.refinedmods.refinedstorage.api.network.NetworkComponent; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent; +import com.refinedmods.refinedstorage.api.network.impl.autocrafting.AutocraftingNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.energy.EnergyNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.node.GraphNetworkComponentImpl; import com.refinedmods.refinedstorage.api.network.impl.security.SecurityNetworkComponentImpl; @@ -36,6 +39,10 @@ public final class NetworkTestFixtures { SecurityNetworkComponent.class, network -> new SecurityNetworkComponentImpl(SecurityPolicy.of(FakePermissions.ALLOW_BY_DEFAULT)) ); + NETWORK_COMPONENT_MAP_FACTORY.addFactory( + AutocraftingNetworkComponent.class, + network -> new AutocraftingNetworkComponentImpl(new PatternRepositoryImpl()) + ); } private NetworkTestFixtures() { diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/nodefactory/PatternProviderNetworkNodeFactory.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/nodefactory/PatternProviderNetworkNodeFactory.java new file mode 100644 index 000000000..042638d62 --- /dev/null +++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/nodefactory/PatternProviderNetworkNodeFactory.java @@ -0,0 +1,16 @@ +package com.refinedmods.refinedstorage.network.test.nodefactory; + +import com.refinedmods.refinedstorage.api.network.impl.node.AbstractNetworkNode; +import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode; + +import java.util.Map; + +public class PatternProviderNetworkNodeFactory extends AbstractNetworkNodeFactory { + public static final String PROPERTY_SIZE = "size"; + + @Override + protected AbstractNetworkNode innerCreate(final Map<String, Object> properties) { + final int size = (int) properties.getOrDefault(PROPERTY_SIZE, 9); + return new PatternProviderNetworkNode(getEnergyUsage(properties), size); + } +} diff --git a/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkNodeFactoryTest.java b/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkNodeFactoryTest.java index 55612ee4d..cb72b74cc 100644 --- a/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkNodeFactoryTest.java +++ b/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkNodeFactoryTest.java @@ -8,6 +8,7 @@ import com.refinedmods.refinedstorage.api.network.impl.node.grid.GridNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.iface.InterfaceNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.importer.ImporterNetworkNode; +import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.relay.RelayInputNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.relay.RelayOutputNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.storage.StorageNetworkNode; @@ -44,6 +45,8 @@ class NetworkNodeFactoryTest { RelayOutputNetworkNode relayOutput; @AddNetworkNode StorageTransferNetworkNode storageTransfer; + @AddNetworkNode + PatternProviderNetworkNode patternProvider; @Test void testInitialization() { diff --git a/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtensionTest.java b/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtensionTest.java index e28daaa0e..decfcdf32 100644 --- a/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtensionTest.java +++ b/refinedstorage-network-test/src/test/java/com/refinedmods/refinedstorage/network/test/NetworkTestExtensionTest.java @@ -1,6 +1,7 @@ package com.refinedmods.refinedstorage.network.test; import com.refinedmods.refinedstorage.api.network.Network; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent; import com.refinedmods.refinedstorage.api.network.impl.node.SimpleNetworkNode; import com.refinedmods.refinedstorage.api.network.impl.node.storage.StorageNetworkNode; @@ -157,6 +158,16 @@ void shouldInjectNetworkSecurityComponent( assertThat(networkSecurityB).isSameAs(b.getComponent(SecurityNetworkComponent.class)); } + @Test + void shouldInjectNetworkAutocraftingComponent( + @InjectNetworkAutocraftingComponent(networkId = "a") final AutocraftingNetworkComponent networkAutocraftingA, + @InjectNetworkAutocraftingComponent(networkId = "b") final AutocraftingNetworkComponent networkAutocraftingB + ) { + // Assert + assertThat(networkAutocraftingA).isSameAs(a.getComponent(AutocraftingNetworkComponent.class)); + assertThat(networkAutocraftingB).isSameAs(b.getComponent(AutocraftingNetworkComponent.class)); + } + @Test void shouldInjectNetworkThroughParameter( @InjectNetwork("a") final Network injectedA, diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java new file mode 100644 index 000000000..6d3db761e --- /dev/null +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java @@ -0,0 +1,47 @@ +package com.refinedmods.refinedstorage.api.network.impl.autocrafting; + +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; +import com.refinedmods.refinedstorage.api.network.autocrafting.PatternProvider; +import com.refinedmods.refinedstorage.api.network.node.container.NetworkNodeContainer; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Set; + +public class AutocraftingNetworkComponentImpl implements AutocraftingNetworkComponent { + private final PatternRepository patternRepository; + + public AutocraftingNetworkComponentImpl(final PatternRepository patternRepository) { + this.patternRepository = patternRepository; + } + + @Override + public void onContainerAdded(final NetworkNodeContainer container) { + if (container.getNode() instanceof PatternProvider provider) { + provider.getPatterns().forEach(patternRepository::add); + } + } + + @Override + public void onContainerRemoved(final NetworkNodeContainer container) { + if (container.getNode() instanceof PatternProvider provider) { + provider.getPatterns().forEach(patternRepository::remove); + } + } + + @Override + public void add(final Pattern pattern) { + patternRepository.add(pattern); + } + + @Override + public void remove(final Pattern pattern) { + patternRepository.remove(pattern); + } + + @Override + public Set<ResourceKey> getOutputs() { + return patternRepository.getOutputs(); + } +} diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/package-info.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/package-info.java new file mode 100644 index 000000000..62db52cda --- /dev/null +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.api.network.impl.autocrafting; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNode.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNode.java new file mode 100644 index 000000000..7a74782a1 --- /dev/null +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNode.java @@ -0,0 +1,57 @@ +package com.refinedmods.refinedstorage.api.network.impl.node.patternprovider; + +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; +import com.refinedmods.refinedstorage.api.network.autocrafting.PatternProvider; +import com.refinedmods.refinedstorage.api.network.impl.node.SimpleNetworkNode; + +import java.util.Arrays; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +public class PatternProviderNetworkNode extends SimpleNetworkNode implements PatternProvider { + private final Pattern[] patterns; + + public PatternProviderNetworkNode(final long energyUsage, final int patterns) { + super(energyUsage); + this.patterns = new Pattern[patterns]; + } + + public void setPattern(final int index, @Nullable final Pattern pattern) { + final Pattern oldPattern = patterns[index]; + if (oldPattern != null && network != null) { + network.getComponent(AutocraftingNetworkComponent.class).remove(oldPattern); + } + patterns[index] = pattern; + if (pattern != null && network != null) { + network.getComponent(AutocraftingNetworkComponent.class).add(pattern); + } + } + + @Override + protected void onActiveChanged(final boolean newActive) { + super.onActiveChanged(newActive); + if (!newActive && network != null) { + final AutocraftingNetworkComponent component = network.getComponent(AutocraftingNetworkComponent.class); + for (final Pattern pattern : patterns) { + if (pattern != null) { + component.remove(pattern); + } + } + } else if (newActive && network != null) { + final AutocraftingNetworkComponent component = network.getComponent(AutocraftingNetworkComponent.class); + for (final Pattern pattern : patterns) { + if (pattern != null) { + component.add(pattern); + } + } + } + } + + @Override + public Set<Pattern> getPatterns() { + return Arrays.stream(patterns).filter(Objects::nonNull).collect(Collectors.toSet()); + } +} diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/package-info.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/package-info.java new file mode 100644 index 000000000..74c61e624 --- /dev/null +++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@FieldsAndMethodsAreNonnullByDefault +package com.refinedmods.refinedstorage.api.network.impl.node.patternprovider; + +import com.refinedmods.refinedstorage.api.core.FieldsAndMethodsAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java new file mode 100644 index 000000000..d63b45027 --- /dev/null +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java @@ -0,0 +1,76 @@ +package com.refinedmods.refinedstorage.api.network.impl.autocrafting; + +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl; +import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode; +import com.refinedmods.refinedstorage.api.network.node.container.NetworkNodeContainer; +import com.refinedmods.refinedstorage.network.test.fake.FakeResources; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class AutocraftingNetworkComponentImplTest { + private AutocraftingNetworkComponentImpl sut; + + @BeforeEach + void setUp() { + sut = new AutocraftingNetworkComponentImpl(new PatternRepositoryImpl()); + } + + @Test + void shouldAddPatternsFromPatternProvider() { + // Arrange + final PatternProviderNetworkNode provider = new PatternProviderNetworkNode(0, 5); + provider.setPattern(1, new SimplePattern(FakeResources.A)); + + final NetworkNodeContainer container = () -> provider; + + // Act + sut.onContainerAdded(container); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactly(FakeResources.A); + } + + @Test + void shouldRemovePatternsFromPatternProvider() { + // Arrange + final PatternProviderNetworkNode provider = new PatternProviderNetworkNode(0, 5); + provider.setPattern(1, new SimplePattern(FakeResources.A)); + + final NetworkNodeContainer container = () -> provider; + sut.onContainerAdded(container); + + // Act + sut.onContainerRemoved(container); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().isEmpty(); + } + + @Test + void shouldAddPatternManually() { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + + // Act + sut.add(pattern); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().containsExactly(FakeResources.A); + } + + @Test + void shouldRemovePatternManually() { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.add(pattern); + + // Act + sut.remove(pattern); + + // Assert + assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().isEmpty(); + } +} \ No newline at end of file diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java new file mode 100644 index 000000000..7e2b26d57 --- /dev/null +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java @@ -0,0 +1,19 @@ +package com.refinedmods.refinedstorage.api.network.impl.autocrafting; + +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; + +import java.util.Set; + +public class SimplePattern implements Pattern { + private final Set<ResourceKey> outputs; + + public SimplePattern(final ResourceKey... outputs) { + this.outputs = Set.of(outputs); + } + + @Override + public Set<ResourceKey> getOutputs() { + return outputs; + } +} diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java new file mode 100644 index 000000000..e585c4a0a --- /dev/null +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java @@ -0,0 +1,111 @@ +package com.refinedmods.refinedstorage.api.network.impl.node.patternprovider; + +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; +import com.refinedmods.refinedstorage.api.network.impl.autocrafting.SimplePattern; +import com.refinedmods.refinedstorage.network.test.AddNetworkNode; +import com.refinedmods.refinedstorage.network.test.InjectNetworkAutocraftingComponent; +import com.refinedmods.refinedstorage.network.test.NetworkTest; +import com.refinedmods.refinedstorage.network.test.SetupNetwork; +import com.refinedmods.refinedstorage.network.test.fake.FakeResources; +import com.refinedmods.refinedstorage.network.test.nodefactory.PatternProviderNetworkNodeFactory; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +@NetworkTest +@SetupNetwork +class PatternProviderNetworkNodeTest { + @AddNetworkNode(properties = { + @AddNetworkNode.Property(key = PatternProviderNetworkNodeFactory.PROPERTY_SIZE, intValue = 3) + }) + private PatternProviderNetworkNode sut; + + @Test + void testDefaultState( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Assert + assertThat(sut.getPatterns()).isEmpty(); + assertThat(autocrafting.getOutputs()).isEmpty(); + } + + @Test + void shouldSetPatternAndNotifyNetwork( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Act + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.setPattern(0, pattern); + + // Assert + assertThat(sut.getPatterns()).containsExactly(pattern); + assertThat(autocrafting.getOutputs()).containsExactly(FakeResources.A); + } + + @Test + void shouldRemovePatternAndNotifyNetwork( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.setPattern(0, pattern); + + // Act + sut.setPattern(0, null); + + // Assert + assertThat(sut.getPatterns()).isEmpty(); + assertThat(autocrafting.getOutputs()).isEmpty(); + } + + @Test + void shouldReplacePatternAndNotifyNetwork( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.setPattern(0, pattern); + + // Act + final SimplePattern replacedPattern = new SimplePattern(FakeResources.B); + sut.setPattern(0, replacedPattern); + + // Assert + assertThat(sut.getPatterns()).containsExactly(replacedPattern); + assertThat(autocrafting.getOutputs()).containsExactly(FakeResources.B); + } + + @Test + void shouldRemovePatternsFromNetworkWhenInactive( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.setPattern(0, pattern); + + // Act + sut.setActive(false); + + // Assert + assertThat(sut.getPatterns()).containsExactly(pattern); + assertThat(autocrafting.getOutputs()).isEmpty(); + } + + @Test + void shouldAddPatternsFromNetworkWhenActive( + @InjectNetworkAutocraftingComponent final AutocraftingNetworkComponent autocrafting + ) { + // Arrange + final SimplePattern pattern = new SimplePattern(FakeResources.A); + sut.setPattern(0, pattern); + sut.setActive(false); + + // Act + sut.setActive(true); + + // Assert + assertThat(sut.getPatterns()).containsExactly(pattern); + assertThat(autocrafting.getOutputs()).containsExactly(FakeResources.A); + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index fb2b9aa5f..c3279b9d2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include("refinedstorage-resource-api") include("refinedstorage-storage-api") include("refinedstorage-query-parser") include("refinedstorage-grid-api") +include("refinedstorage-autocrafting-api") include("refinedstorage-network-api") include("refinedstorage-network") include("refinedstorage-common-api") From faa559617fc73f1861f35aea236369984a731ccc Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Fri, 30 Aug 2024 19:24:29 +0200 Subject: [PATCH 02/14] feat: the grid now knows what is craftable --- .idea/dictionaries/refinedstorage.xml | 1 + config/checkstyle/checkstyle.xml | 2 +- .../PatternRepositoryImplTest.java | 2 +- .../refinedstorage/common/api/grid/Grid.java | 4 + .../view/AbstractPlatformGridResource.java | 11 ++- .../api/support/resource/ResourceType.java | 2 +- .../common/grid/AbstractGridBlockEntity.java | 15 +++ .../grid/AbstractGridContainerMenu.java | 1 + .../refinedstorage/common/grid/GridData.java | 9 +- .../common/grid/WirelessGrid.java | 7 ++ .../grid/screen/AbstractGridScreen.java | 40 +++++--- .../AbstractFluidGridResourceFactory.java | 5 +- .../view/AbstractItemGridResourceFactory.java | 5 +- .../view/CompositeGridResourceFactory.java | 4 +- .../common/grid/view/FluidGridResource.java | 5 +- .../common/grid/view/ItemGridResource.java | 5 +- .../storage/portablegrid/PortableGrid.java | 7 ++ .../common/support/ResourceSlotRendering.java | 4 +- .../support/resource/FluidResourceType.java | 4 +- .../support/resource/ItemResourceType.java | 4 +- .../assets/refinedstorage/lang/en_us.json | 1 + .../api/grid/view/GridResource.java | 2 + .../api/grid/view/GridResourceFactory.java | 5 +- .../api/grid/view/GridViewBuilder.java | 8 ++ .../api/grid/view/GridViewBuilderImpl.java | 10 ++ .../api/grid/view/GridViewImpl.java | 52 ++++++---- .../grid/query/GridQueryParserImplTest.java | 9 +- .../api/grid/view/GridResourceImpl.java | 16 +++ .../api/grid/view/GridViewImplTest.java | 99 ++++++++++++++++++- .../AutocraftingNetworkComponentImplTest.java | 2 +- .../PatternProviderNetworkNodeTest.java | 2 +- 31 files changed, 286 insertions(+), 57 deletions(-) diff --git a/.idea/dictionaries/refinedstorage.xml b/.idea/dictionaries/refinedstorage.xml index 3ce828eb4..74576b5dd 100644 --- a/.idea/dictionaries/refinedstorage.xml +++ b/.idea/dictionaries/refinedstorage.xml @@ -5,6 +5,7 @@ <w>autocrafting</w> <w>autoselected</w> <w>blocklist</w> + <w>craftable</w> <w>crafter</w> <w>crafters</w> <w>cullface</w> diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 17c992bd4..5f3d43e3b 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -22,7 +22,7 @@ <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> </module> <module name="FileLength"> - <property name="max" value="750"/> + <property name="max" value="800"/> </module> <module name="NewlineAtEndOfFile"/> <module name="JavadocPackage"/> diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java index 94f3e5a1f..e357b796f 100644 --- a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImplTest.java @@ -92,4 +92,4 @@ void shouldRemovePatternButNotRemoveOutputIfAnotherPatternStillHasThatOutput() { FakeResources.B ); } -} \ No newline at end of file +} diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java index 92e194e46..a493a55c0 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/Grid.java @@ -5,9 +5,11 @@ import com.refinedmods.refinedstorage.api.storage.Actor; import com.refinedmods.refinedstorage.api.storage.Storage; import com.refinedmods.refinedstorage.api.storage.TrackedResourceAmount; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; import java.util.List; +import java.util.Set; import net.minecraft.server.level.ServerPlayer; import org.apiguardian.api.API; @@ -24,5 +26,7 @@ public interface Grid { List<TrackedResourceAmount> getResources(Class<? extends Actor> actorType); + Set<PlatformResourceKey> getCraftableResources(); + GridOperations createOperations(ResourceType resourceType, ServerPlayer player); } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java index 01ebaa119..ff6451526 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java @@ -18,14 +18,17 @@ public abstract class AbstractPlatformGridResource<T extends PlatformResourceKey protected final T resource; private final String name; private final Map<GridResourceAttributeKey, Set<String>> attributes; + private final boolean craftable; private boolean zeroed; protected AbstractPlatformGridResource(final T resource, final String name, - final Map<GridResourceAttributeKey, Set<String>> attributes) { + final Map<GridResourceAttributeKey, Set<String>> attributes, + final boolean craftable) { this.resource = resource; this.name = name; this.attributes = attributes; + this.craftable = craftable; } @Override @@ -58,6 +61,11 @@ public void setZeroed(final boolean zeroed) { this.zeroed = zeroed; } + @Override + public boolean isCraftable() { + return craftable; + } + @Nullable @Override public PlatformResourceKey getResourceForRecipeMods() { @@ -70,6 +78,7 @@ public String toString() { + "resource=" + resource + ", name='" + name + '\'' + ", attributes=" + attributes + + ", craftable=" + craftable + ", zeroed=" + zeroed + '}'; } diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceType.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceType.java index 4f02ddefa..d31f1e176 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceType.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/support/resource/ResourceType.java @@ -29,7 +29,7 @@ public interface ResourceType { double getDisplayAmount(long amount); - Optional<GridResource> toGridResource(ResourceKey resource); + Optional<GridResource> toGridResource(ResourceKey resource, boolean craftable); long getInterfaceExportLimit(); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java index 4de556a45..c29cc6df3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridBlockEntity.java @@ -3,6 +3,7 @@ import com.refinedmods.refinedstorage.api.grid.operations.GridOperations; import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcher; import com.refinedmods.refinedstorage.api.network.Network; +import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent; import com.refinedmods.refinedstorage.api.network.impl.node.container.NetworkNodeContainerPriorities; import com.refinedmods.refinedstorage.api.network.impl.node.grid.GridNetworkNode; import com.refinedmods.refinedstorage.api.network.storage.StorageNetworkComponent; @@ -15,12 +16,15 @@ import com.refinedmods.refinedstorage.common.api.security.PlatformSecurityNetworkComponent; import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; import com.refinedmods.refinedstorage.common.api.support.network.InWorldNetworkNodeContainer; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; import com.refinedmods.refinedstorage.common.support.AbstractDirectionalBlock; import com.refinedmods.refinedstorage.common.support.network.AbstractBaseNetworkNodeContainerBlockEntity; import com.refinedmods.refinedstorage.common.support.network.ColoredConnectionStrategy; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerPlayer; @@ -53,6 +57,17 @@ public List<TrackedResourceAmount> getResources(final Class<? extends Actor> act .getResources(actorType); } + @Override + public Set<PlatformResourceKey> getCraftableResources() { + return requireNonNull(mainNetworkNode.getNetwork()) + .getComponent(AutocraftingNetworkComponent.class) + .getOutputs() + .stream() + .filter(PlatformResourceKey.class::isInstance) + .map(PlatformResourceKey.class::cast) + .collect(Collectors.toSet()); + } + @Override public GridOperations createOperations(final ResourceType resourceType, final ServerPlayer player) { final Network network = requireNonNull(mainNetworkNode.getNetwork()); 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 45fdf9efa..544c62915 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 @@ -106,6 +106,7 @@ protected AbstractGridContainerMenu( resource.resourceAmount().amount(), resource.trackedResource().orElse(null) )); + gridData.craftableResources().forEach(viewBuilder::withCraftableResource); this.view = viewBuilder.build(); this.view.setSortingDirection(Platform.INSTANCE.getConfig().getGrid().getSortingDirection()); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridData.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridData.java index a5b8b63aa..b6b086048 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridData.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridData.java @@ -5,18 +5,21 @@ import com.refinedmods.refinedstorage.api.storage.tracked.TrackedResource; import com.refinedmods.refinedstorage.common.api.grid.Grid; import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.storage.StorageCodecs; import com.refinedmods.refinedstorage.common.support.resource.ResourceCodecs; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; -public record GridData(boolean active, List<GridResource> resources) { +public record GridData(boolean active, List<GridResource> resources, Set<PlatformResourceKey> craftableResources) { public static final StreamCodec<RegistryFriendlyByteBuf, GridData> STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.BOOL, GridData::active, ByteBufCodecs.collection(ArrayList::new, StreamCodec.composite( @@ -24,13 +27,15 @@ public record GridData(boolean active, List<GridResource> resources) { StorageCodecs.TRACKED_RESOURCE_OPTIONAL_STREAM_CODEC, GridResource::trackedResource, GridResource::new )), GridData::resources, + ByteBufCodecs.collection(HashSet::new, ResourceCodecs.STREAM_CODEC), GridData::craftableResources, GridData::new ); public static GridData of(final Grid grid) { return new GridData( grid.isGridActive(), - grid.getResources(PlayerActor.class).stream().map(GridResource::of).toList() + grid.getResources(PlayerActor.class).stream().map(GridResource::of).toList(), + grid.getCraftableResources() ); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java index c7041aa98..e471c6e77 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGrid.java @@ -16,11 +16,13 @@ import com.refinedmods.refinedstorage.common.api.security.PlatformSecurityNetworkComponent; import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; import com.refinedmods.refinedstorage.common.api.support.network.item.NetworkItemContext; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; import net.minecraft.server.level.ServerPlayer; @@ -76,6 +78,11 @@ public List<TrackedResourceAmount> getResources(final Class<? extends Actor> act return getStorage().map(storage -> storage.getResources(actorType)).orElse(Collections.emptyList()); } + @Override + public Set<PlatformResourceKey> getCraftableResources() { + return Collections.emptySet(); + } + @Override public GridOperations createOperations(final ResourceType resourceType, final ServerPlayer player) { return getStorage() diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 6d24be377..71a8f9633 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -35,6 +35,7 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; @@ -48,6 +49,7 @@ import static com.refinedmods.refinedstorage.common.support.Sprites.SEARCH_SIZE; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslationKey; import static java.util.Objects.requireNonNullElse; public abstract class AbstractGridScreen<T extends AbstractGridContainerMenu> extends AbstractStretchingScreen<T> { @@ -273,15 +275,32 @@ private void renderAmount(final GuiGraphics graphics, if (!(resource instanceof PlatformGridResource platformResource)) { return; } - final String text = resource.isZeroed() ? "0" : platformResource.getDisplayedAmount(getMenu().getView()); - final int color = resource.isZeroed() - ? requireNonNullElse(ChatFormatting.RED.getColor(), 15) - : requireNonNullElse(ChatFormatting.WHITE.getColor(), 15); + final long amount = platformResource.getAmount(getMenu().getView()); + final String text = getAmountText(resource, platformResource, amount); + final int color = getAmountColor(resource, amount); final boolean large = (minecraft != null && minecraft.isEnforceUnicode()) || Platform.INSTANCE.getConfig().getGrid().isLargeFont(); ResourceSlotRendering.renderAmount(graphics, slotX, slotY, text, color, large); } + private int getAmountColor(final GridResource resource, final long amount) { + if (amount == 0 && resource.isCraftable()) { + return requireNonNullElse(ChatFormatting.WHITE.getColor(), 15); + } else if (resource.isZeroed()) { + return requireNonNullElse(ChatFormatting.RED.getColor(), 15); + } + return requireNonNullElse(ChatFormatting.WHITE.getColor(), 15); + } + + private String getAmountText(final GridResource resource, + final PlatformGridResource platformResource, + final long amount) { + if (amount == 0 && resource.isCraftable()) { + return I18n.get(createTranslationKey("gui", "grid.craft")); + } + return platformResource.getDisplayedAmount(getMenu().getView()); + } + private void renderDisabledSlot(final GuiGraphics graphics, final int slotX, final int slotY) { graphics.fillGradient( RenderType.guiOverlay(), slotX, slotY, slotX + 16, slotY + 16, DISABLED_SLOT_COLOR, DISABLED_SLOT_COLOR, 0 @@ -326,10 +345,11 @@ private void renderHoveredResourceTooltip(final GuiGraphics graphics, platformResource.getTooltipImage(), lines ); - if (Platform.INSTANCE.getConfig().getGrid().isDetailedTooltip()) { - addDetailedTooltip(view, platformResource, processedLines); - } - if (!platformResource.isZeroed()) { + final long amount = platformResource.getAmount(getMenu().getView()); + if (amount > 0) { + if (Platform.INSTANCE.getConfig().getGrid().isDetailedTooltip()) { + addDetailedTooltip(view, platformResource, processedLines); + } processedLines.addAll(platformResource.getExtractionHints(getMenu().getCarried(), getMenu().getView())); } Platform.INSTANCE.renderTooltip(graphics, processedLines, mouseX, mouseY); @@ -338,9 +358,7 @@ private void renderHoveredResourceTooltip(final GuiGraphics graphics, private void addDetailedTooltip(final GridView view, final PlatformGridResource platformResource, final List<ClientTooltipComponent> lines) { - final String amountInTooltip = platformResource.isZeroed() - ? "0" - : platformResource.getAmountInTooltip(getMenu().getView()); + final String amountInTooltip = platformResource.getAmountInTooltip(getMenu().getView()); lines.add(new SmallTextClientTooltipComponent( createTranslation("misc", "total", amountInTooltip).withStyle(ChatFormatting.GRAY) )); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java index 27fa5fb16..6129d5283 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java @@ -15,7 +15,7 @@ public abstract class AbstractFluidGridResourceFactory implements GridResourceFactory { @Override - public Optional<GridResource> apply(final ResourceKey resource) { + public Optional<GridResource> apply(final ResourceKey resource, final boolean craftable) { if (!(resource instanceof FluidResource fluidResource)) { return Optional.empty(); } @@ -30,7 +30,8 @@ public Optional<GridResource> apply(final ResourceKey resource) { modId, modName, tags, - tooltip + tooltip, + craftable )); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java index fe3af6975..4411ac082 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java @@ -18,7 +18,7 @@ public abstract class AbstractItemGridResourceFactory implements GridResourceFactory { @Override - public Optional<GridResource> apply(final ResourceKey resource) { + public Optional<GridResource> apply(final ResourceKey resource, final boolean craftable) { if (!(resource instanceof ItemResource itemResource)) { return Optional.empty(); } @@ -36,7 +36,8 @@ public Optional<GridResource> apply(final ResourceKey resource) { modId, modName, tags, - tooltip + tooltip, + craftable )); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/CompositeGridResourceFactory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/CompositeGridResourceFactory.java index fad231cfa..e73b6275b 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/CompositeGridResourceFactory.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/CompositeGridResourceFactory.java @@ -16,10 +16,10 @@ public CompositeGridResourceFactory(final PlatformRegistry<ResourceType> resourc } @Override - public Optional<GridResource> apply(final ResourceKey resource) { + public Optional<GridResource> apply(final ResourceKey resource, final boolean craftable) { return resourceTypeRegistry.getAll() .stream() - .flatMap(type -> type.toGridResource(resource).stream()) + .flatMap(type -> type.toGridResource(resource, craftable).stream()) .findFirst(); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java index 63dae70de..bc9697a5c 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java @@ -41,13 +41,14 @@ public FluidGridResource(final FluidResource resource, final String modId, final String modName, final Set<String> tags, - final String tooltip) { + final String tooltip, + final boolean craftable) { super(resource, name, Map.of( GridResourceAttributeKeys.MOD_ID, Set.of(modId), GridResourceAttributeKeys.MOD_NAME, Set.of(modName), GridResourceAttributeKeys.TAGS, tags, GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) - )); + ), craftable); this.id = BuiltInRegistries.FLUID.getId(resource.fluid()); this.rendering = RefinedStorageApi.INSTANCE.getResourceRendering(FluidResource.class); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java index 6abbfedfc..2bdf5ae01 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java @@ -41,13 +41,14 @@ public ItemGridResource(final ItemResource resource, final String modId, final String modName, final Set<String> tags, - final String tooltip) { + final String tooltip, + final boolean craftable) { super(resource, name, Map.of( GridResourceAttributeKeys.MOD_ID, Set.of(modId), GridResourceAttributeKeys.MOD_NAME, Set.of(modName), GridResourceAttributeKeys.TAGS, tags, GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) - )); + ), craftable); this.id = Item.getId(resource.item()); this.itemStack = itemStack; this.itemResource = resource; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java index 90d548274..f7455d5fc 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/storage/portablegrid/PortableGrid.java @@ -17,11 +17,13 @@ import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.grid.Grid; import com.refinedmods.refinedstorage.common.api.storage.PlayerActor; +import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType; import com.refinedmods.refinedstorage.common.storage.DiskInventory; import java.util.Collections; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; import net.minecraft.server.level.ServerPlayer; @@ -110,6 +112,11 @@ public List<TrackedResourceAmount> getResources(final Class<? extends Actor> act )).toList(); } + @Override + public Set<PlatformResourceKey> getCraftableResources() { + return Collections.emptySet(); + } + @Override public GridOperations createOperations(final ResourceType resourceType, final ServerPlayer player) { if (storage == null) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java index 96a3c1420..4cd868c58 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/ResourceSlotRendering.java @@ -66,7 +66,7 @@ public static void renderAmount(final GuiGraphics graphics, public static void renderAmount(final GuiGraphics graphics, final int x, final int y, - final String amount, + final String text, final int color, final boolean large) { final Font font = Minecraft.getInstance().font; @@ -77,7 +77,7 @@ public static void renderAmount(final GuiGraphics graphics, if (!large) { poseStack.scale(0.5F, 0.5F, 1); } - graphics.drawString(font, amount, (large ? 16 : 30) - font.width(amount), large ? 8 : 22, color, true); + graphics.drawString(font, text, (large ? 16 : 30) - font.width(text), large ? 8 : 22, color, true); poseStack.popPose(); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/FluidResourceType.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/FluidResourceType.java index dc1bb66c3..3d57926f7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/FluidResourceType.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/FluidResourceType.java @@ -26,8 +26,8 @@ class FluidResourceType implements ResourceType { private static final ResourceLocation SPRITE = createIdentifier("widget/side_button/resource_type/fluid"); @Override - public Optional<GridResource> toGridResource(final ResourceKey resource) { - return Platform.INSTANCE.getFluidGridResourceFactory().apply(resource); + public Optional<GridResource> toGridResource(final ResourceKey resource, final boolean craftable) { + return Platform.INSTANCE.getFluidGridResourceFactory().apply(resource, craftable); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ItemResourceType.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ItemResourceType.java index 6c32328e0..3cda9e40e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ItemResourceType.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/resource/ItemResourceType.java @@ -26,8 +26,8 @@ class ItemResourceType implements ResourceType { private static final ResourceLocation SPRITE = createIdentifier("widget/side_button/resource_type/item"); @Override - public Optional<GridResource> toGridResource(final ResourceKey resource) { - return Platform.INSTANCE.getItemGridResourceFactory().apply(resource); + public Optional<GridResource> toGridResource(final ResourceKey resource, final boolean craftable) { + return Platform.INSTANCE.getItemGridResourceFactory().apply(resource, craftable); } @Override 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 4a2418c59..2c65188fa 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 @@ -61,6 +61,7 @@ "gui.refinedstorage.grid.resource_type": "Resource type", "gui.refinedstorage.grid.resource_type.all": "All", "gui.refinedstorage.grid.resource_type.help": "Filter specific resource types.", + "gui.refinedstorage.grid.craft": "Craft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", "gui.refinedstorage.crafting_grid.move.inventory": "Move items to inventory", "gui.refinedstorage.pattern_grid.create_pattern": "Create pattern", diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java index 20b613552..50f787073 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java @@ -23,4 +23,6 @@ public interface GridResource { boolean isZeroed(); void setZeroed(boolean zeroed); + + boolean isCraftable(); } diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceFactory.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceFactory.java index 64289636b..55913ebe4 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceFactory.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceFactory.java @@ -15,8 +15,9 @@ public interface GridResourceFactory { /** * Transforms a {@link com.refinedmods.refinedstorage.api.resource.ResourceKey} into a {@link GridResource}. * - * @param resource the resource + * @param resource the resource + * @param craftable whether the resource is craftable * @return the grid resource, if applicable */ - Optional<GridResource> apply(ResourceKey resource); + Optional<GridResource> apply(ResourceKey resource, boolean craftable); } diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilder.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilder.java index 9bd00df04..99ca4573f 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilder.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridViewBuilder.java @@ -22,6 +22,14 @@ public interface GridViewBuilder { */ GridViewBuilder withResource(ResourceKey resource, long amount, @Nullable TrackedResource trackedResource); + /** + * Adds a resource into the view and marks it as craftable. + * + * @param resource the resource + * @return this builder + */ + GridViewBuilder withCraftableResource(ResourceKey resource); + /** * @return a {@link GridView} with the specified resources */ 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 a1fb8af66..0514a0f54 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 @@ -6,7 +6,9 @@ import com.refinedmods.refinedstorage.api.storage.tracked.TrackedResource; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; import org.apiguardian.api.API; @@ -15,6 +17,7 @@ public class GridViewBuilderImpl implements GridViewBuilder { private final GridResourceFactory resourceFactory; private final ResourceList backingList = ResourceListImpl.create(); + private final Set<ResourceKey> craftableResources = new HashSet<>(); private final Map<ResourceKey, TrackedResource> trackedResources = new HashMap<>(); private final GridSortingType identitySortingType; private final GridSortingType defaultSortingType; @@ -36,12 +39,19 @@ public GridViewBuilder withResource(final ResourceKey resource, return this; } + @Override + public GridViewBuilder withCraftableResource(final ResourceKey resource) { + craftableResources.add(resource); + return this; + } + @Override public GridView build() { return new GridViewImpl( resourceFactory, backingList, trackedResources, + craftableResources, identitySortingType, 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 e0a82b56b..c1c123d34 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 @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.BiPredicate; import javax.annotation.Nullable; @@ -27,6 +28,7 @@ public class GridViewImpl implements GridView { private final Comparator<GridResource> identitySort; private final GridResourceFactory resourceFactory; private final Map<ResourceKey, TrackedResource> trackedResources = new HashMap<>(); + private final Set<ResourceKey> craftableResources; private ViewList viewList = new ViewList(new ArrayList<>(), new HashMap<>()); private GridSortingType sortingType; @@ -42,10 +44,12 @@ public class GridViewImpl implements GridView { * @param initialTrackedResources initial tracked resources state * @param identitySortingType a sorting type required to keep a consistent sorting order with quantity sorting * @param defaultSortingType the default sorting type + * @param craftableResources resources which are craftable and must stay in the view list */ public GridViewImpl(final GridResourceFactory resourceFactory, final ResourceList backingList, final Map<ResourceKey, TrackedResource> initialTrackedResources, + final Set<ResourceKey> craftableResources, final GridSortingType identitySortingType, final GridSortingType defaultSortingType) { this.resourceFactory = resourceFactory; @@ -53,6 +57,7 @@ public GridViewImpl(final GridResourceFactory resourceFactory, this.sortingType = defaultSortingType; this.backingList = backingList; this.trackedResources.putAll(initialTrackedResources); + this.craftableResources = craftableResources; } @Override @@ -106,19 +111,31 @@ private ViewList createViewList() { final List<GridResource> list = new ArrayList<>(); final Map<ResourceKey, GridResource> index = new HashMap<>(); for (final ResourceKey resource : backingList.getAll()) { - final GridResource existingGridResource = viewList.index.get(resource); - if (existingGridResource != null) { - tryAddGridResourceIntoViewList(existingGridResource, list, index, resource); - } else { - resourceFactory.apply(resource).ifPresent( - gridResource -> tryAddGridResourceIntoViewList(gridResource, list, index, resource) - ); + tryAddResourceIntoViewList(resource, list, index, craftableResources.contains(resource)); + } + for (final ResourceKey craftableResource : craftableResources) { + if (!index.containsKey(craftableResource)) { + tryAddResourceIntoViewList(craftableResource, list, index, true); } } list.sort(getComparator()); return new ViewList(list, index); } + private void tryAddResourceIntoViewList(final ResourceKey resource, + final List<GridResource> list, + final Map<ResourceKey, GridResource> index, + final boolean craftable) { + final GridResource existingGridResource = viewList.index.get(resource); + if (existingGridResource != null) { + tryAddGridResourceIntoViewList(existingGridResource, list, index, resource); + } else { + resourceFactory.apply(resource, craftable).ifPresent( + gridResource -> tryAddGridResourceIntoViewList(gridResource, list, index, resource) + ); + } + } + private void tryAddGridResourceIntoViewList(final GridResource gridResource, final List<GridResource> list, final Map<ResourceKey, GridResource> index, @@ -141,13 +158,13 @@ public void onChange(final ResourceKey resource, if (gridResource != null) { LOGGER.debug("{} was already found in the view list", resource); if (gridResource.isZeroed()) { - reinsertZeroedResourceIntoViewList(resource, operationResult, gridResource); + reinsertZeroedResourceIntoViewList(resource, gridResource); } else { handleChangeForExistingResource(resource, operationResult, gridResource); } } else { LOGGER.debug("{} is a new resource, adding it into the view list if filter allows it", resource); - handleChangeForNewResource(resource, operationResult); + handleChangeForNewResource(resource); } } @@ -168,11 +185,12 @@ private void updateOrRemoveTrackedResource(final ResourceKey resource, } } - private void reinsertZeroedResourceIntoViewList(final ResourceKey resource, - final ResourceList.OperationResult operationResult, - final GridResource oldGridResource) { + private void reinsertZeroedResourceIntoViewList(final ResourceKey resource, final GridResource oldGridResource) { LOGGER.debug("{} was zeroed, unzeroing", resource); - final GridResource newResource = resourceFactory.apply(operationResult.resource()).orElseThrow(); + final GridResource newResource = resourceFactory.apply( + resource, + craftableResources.contains(resource) + ).orElseThrow(); viewList.index.put(resource, newResource); final int index = CoreValidations.validateNotNegative( viewList.list.indexOf(oldGridResource), @@ -201,7 +219,7 @@ private void updateExistingResourceInViewList(final ResourceKey resource, final GridResource gridResource, final boolean noLongerAvailable) { viewList.list.remove(gridResource); - if (noLongerAvailable) { + if (noLongerAvailable && !craftableResources.contains(resource)) { viewList.index.remove(resource); notifyListener(); } else { @@ -210,9 +228,9 @@ private void updateExistingResourceInViewList(final ResourceKey resource, } } - private void handleChangeForNewResource(final ResourceKey resource, - final ResourceList.OperationResult operationResult) { - final GridResource gridResource = resourceFactory.apply(operationResult.resource()).orElseThrow(); + private void handleChangeForNewResource(final ResourceKey resource) { + final GridResource gridResource = resourceFactory.apply(resource, false) + .orElseThrow(); if (filter.test(this, gridResource)) { LOGGER.debug("Filter allowed, actually adding {}", resource); viewList.index.put(resource, gridResource); diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java index 8d69ad560..4c1d63774 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java @@ -13,6 +13,7 @@ import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -33,9 +34,10 @@ class GridQueryParserImplTest { ); private final GridView view = new GridViewImpl( - resource -> Optional.of(new GridResourceImpl(resource)), + (resource, craftable) -> Optional.of(new GridResourceImpl(resource)), ResourceListImpl.create(), new HashMap<>(), + new HashSet<>(), v -> Comparator.comparing(GridResource::getName), v -> Comparator.comparingLong(resource -> resource.getAmount(v)) ); @@ -330,5 +332,10 @@ public boolean isZeroed() { public void setZeroed(final boolean zeroed) { throw new UnsupportedOperationException(); } + + @Override + public boolean isCraftable() { + return false; + } } } diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java index ae11dd59e..271b37b4b 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java @@ -11,14 +11,20 @@ public class GridResourceImpl implements GridResource { private final ResourceKey resource; private final Map<GridResourceAttributeKey, Set<String>> attributes; + private boolean craftable; private boolean zeroed; public GridResourceImpl(final ResourceKey resource) { + this(resource, false); + } + + public GridResourceImpl(final ResourceKey resource, final boolean craftable) { this.resource = resource; this.attributes = Map.of( FakeGridResourceAttributeKeys.MOD_ID, Set.of(resource.toString()), FakeGridResourceAttributeKeys.MOD_NAME, Set.of(resource.toString()) ); + this.craftable = craftable; } public GridResourceImpl zeroed() { @@ -26,6 +32,11 @@ public GridResourceImpl zeroed() { return this; } + public GridResourceImpl craftable() { + craftable = true; + return this; + } + @Override public Optional<TrackedResource> getTrackedResource(final GridView view) { return view.getTrackedResource(resource); @@ -56,6 +67,11 @@ public void setZeroed(final boolean zeroed) { this.zeroed = zeroed; } + @Override + public boolean isCraftable() { + return craftable; + } + @Override public String toString() { return resource.toString(); diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java index 7b5efb742..9a19aa20d 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java @@ -28,7 +28,7 @@ class GridViewImplTest { @BeforeEach void setUp() { - viewBuilder = getViewBuilder(resource -> Optional.of(new GridResourceImpl(resource))); + viewBuilder = getViewBuilder((resource, craftable) -> Optional.of(new GridResourceImpl(resource, craftable))); } private static GridViewBuilderImpl getViewBuilder(final GridResourceFactory resourceFactory) { @@ -47,7 +47,7 @@ void shouldAddResourcesWithSameNameButDifferentIdentity() { // Arrange final GridViewBuilder builder = getViewBuilder( - resourceAmount -> Optional.of(new GridResourceWithMetadata(resourceAmount)) + (resource, craftable) -> Optional.of(new GridResourceWithMetadata(resource)) ); final GridView view = builder.build(); @@ -656,6 +656,101 @@ void shouldClear() { assertThat(view.getAmount(D)).isZero(); } + @Test + void shouldIncludeCraftableResourceInViewList() { + // Arrange + final GridView view = viewBuilder + .withResource(A, 15, null) + .withCraftableResource(B) + .build(); + + // Act + view.sort(); + + // Assert + assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder( + new GridResourceImpl(A), + new GridResourceImpl(B).craftable() + ); + assertThat(view.getAmount(A)).isEqualTo(15); + assertThat(view.getAmount(B)).isZero(); + assertThat(view.copyBackingList().copyState()).usingRecursiveFieldByFieldElementComparator() + .containsExactly(new ResourceAmount(A, 15)); + } + + @Test + void shouldIncludeCraftableResourceInViewListEvenIfItIsInTheBackingList() { + // Arrange + final GridView view = viewBuilder + .withResource(A, 15, null) + .withCraftableResource(A) + .build(); + + // Act + view.sort(); + + // Assert + assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( + new GridResourceImpl(A).craftable() + ); + assertThat(view.getAmount(A)).isEqualTo(15); + assertThat(view.copyBackingList().copyState()) + .usingRecursiveFieldByFieldElementComparator() + .containsExactly(new ResourceAmount(A, 15)); + } + + @Test + void shouldNotRemoveCraftableResource() { + // Arrange + final GridView view = viewBuilder + .withResource(A, 15, null) + .withCraftableResource(A) + .build(); + + view.sort(); + + // Act + view.onChange(A, -15, null); + + // Assert + assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( + new GridResourceImpl(A).craftable() + ); + assertThat(view.getAmount(A)).isZero(); + assertThat(view.copyBackingList().copyState()).isEmpty(); + } + + @Test + void shouldNotRemoveCraftableResourceEvenWhenPreventingSorting() { + // Arrange + final GridView view = viewBuilder + .withResource(A, 15, null) + .withCraftableResource(A) + .build(); + + view.sort(); + view.setPreventSorting(true); + + // Act & assert + view.onChange(A, -15, null); + + assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( + new GridResourceImpl(A).zeroed().craftable() + ); + assertThat(view.getAmount(A)).isZero(); + assertThat(view.copyBackingList().copyState()).isEmpty(); + + view.onChange(A, 1, null); + + assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( + new GridResourceImpl(A).craftable() + ); + assertThat(view.getAmount(A)).isEqualTo(1); + assertThat(view.copyBackingList().copyState()).usingRecursiveFieldByFieldElementComparator().containsExactly( + new ResourceAmount(A, 1) + ); + } + private record ResourceWithMetadata(ResourceKey resource, int metadata) implements ResourceKey { } diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java index d63b45027..2b4b0a7b8 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java @@ -73,4 +73,4 @@ void shouldRemovePatternManually() { // Assert assertThat(sut.getOutputs()).usingRecursiveFieldByFieldElementComparator().isEmpty(); } -} \ No newline at end of file +} diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java index e585c4a0a..1c9412b48 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/node/patternprovider/PatternProviderNetworkNodeTest.java @@ -108,4 +108,4 @@ void shouldAddPatternsFromNetworkWhenActive( assertThat(sut.getPatterns()).containsExactly(pattern); assertThat(autocrafting.getOutputs()).containsExactly(FakeResources.A); } -} \ No newline at end of file +} From aed747347a79aa41af7d008fdac7578b2790a8ae Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Fri, 30 Aug 2024 19:29:20 +0200 Subject: [PATCH 03/14] chore: change wording of not chained help --- .../common/autocrafting/PatternGridScreen.java | 4 ++-- .../assets/refinedstorage/lang/en_us.json | 2 +- .../side_button/crafter_lock_mode/never.png | Bin 174 -> 175 bytes 3 files changed, 3 insertions(+), 3 deletions(-) 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 3b10fbd67..f8f76f606 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 @@ -30,8 +30,8 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslationAsHeading; import static java.util.Objects.requireNonNull; -public class PatternGridScreen extends AbstractGridScreen<PatternGridContainerMenu> implements - PatternGridContainerMenu.PatternGridListener { +public class PatternGridScreen extends AbstractGridScreen<PatternGridContainerMenu> + implements PatternGridContainerMenu.PatternGridListener { static final int INSET_PADDING = 4; static final int INSET_WIDTH = 138; static final int INSET_HEIGHT = 71; 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 2c65188fa..4af0a608b 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 @@ -197,7 +197,7 @@ "gui.refinedstorage.crafter.chained.help": "This crafter is part of a chain.", "gui.refinedstorage.crafter.chained.head_help": "This crafter is the head of the chain.", "gui.refinedstorage.crafter.not_chained": "Not chained", - "gui.refinedstorage.crafter.not_chained.help": "You can connect multiple crafters together if you have more than 9 patterns to insert into a single target machine.", + "gui.refinedstorage.crafter.not_chained.help": "If another crafter is facing this one, they'll form a chain, allowing you to have more patterns going into a single machine.", "item.refinedstorage.controller.help": "Provides the storage network with energy. Multiple are allowed in a single storage network.", "item.refinedstorage.creative_controller.help": "Provides the storage network with an infinite source of energy.", "item.refinedstorage.disk_drive.help": "Accepts storage disks to provide the storage network with storage space.", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/crafter_lock_mode/never.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/crafter_lock_mode/never.png index f6432fe9c0413a03068701fef73074ac1a4db6e4..55d093476291e072d5cd5c42778791bd2830dcd6 100644 GIT binary patch delta 109 zcmZ3-xSnx>XWAhK2EId#q8eTe3=9k|o-U3d7XHZ+zZwL+k{PtMSN{)ClaR44<5?cX z)38pGWkY8pgYXnJX`Vfd5sZ5Olb9tGy*-Spa(J2@miX#i5Hv7gU<i-ll{kM>X93VW N22WQ%mvv4FO#tc>AU*&9 delta 108 zcmZ3_xQ=mxXX;@F2EN0L$MaXDFfcGUd%8G=SokMP{Av*NN^bb{>C^uJHHnh4vPU7^ zj2BFs8O#g?5}GchG&h<vXdieQpTnS>!kOvT-<v4Vv89vMiiwSlfjfuacA7Br0ibaV Mp00i_>zopr0A{)+1poj5 From cea095e6dd9f8761afa1d34b76eff1beb9689576 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sat, 31 Aug 2024 08:31:42 +0200 Subject: [PATCH 04/14] refactor: convert patterns to regular classes The equals/hashCode must be the ID. Otherwise, multiple exact same patterns would only occur once in the network pattern set. And when you remove a pattern at that point, even if there is another still present, the pattern would be removed entirely from the set since it's stored once because it's the same pattern, even if duplicated. This also makes it easier to cache the output resources properly. --- .../api/autocrafting/AbstractPattern.java | 29 ++++++++++++ .../api/autocrafting/Pattern.java | 2 +- .../autocrafting/PatternRepositoryImpl.java | 6 +-- .../api/autocrafting/SimplePattern.java | 2 +- .../common/autocrafting/CraftingPattern.java | 36 ++++++++++++--- ...CraftingPatternClientTooltipComponent.java | 8 ++-- .../common/autocrafting/PatternItem.java | 42 +++++++++-------- .../common/autocrafting/PatternRendering.java | 10 ++--- .../autocrafting/ProcessingPattern.java | 28 ++++++++++-- .../autocrafting/SmithingTablePattern.java | 45 ++++++++++++++++--- ...ingTablePatternClientTooltipComponent.java | 10 ++--- .../autocrafting/StonecutterPattern.java | 28 ++++++++++-- ...necutterPatternClientTooltipComponent.java | 6 +-- .../impl/autocrafting/SimplePattern.java | 2 +- 14 files changed, 195 insertions(+), 59 deletions(-) create mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java new file mode 100644 index 000000000..9e9b30761 --- /dev/null +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java @@ -0,0 +1,29 @@ +package com.refinedmods.refinedstorage.api.autocrafting; + +import java.util.Objects; +import java.util.UUID; + +public abstract class AbstractPattern implements Pattern { + private final UUID id; + + public AbstractPattern(final UUID id) { + this.id = id; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final AbstractPattern that = (AbstractPattern) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } +} diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java index b82c4ac72..b4c84cf0d 100644 --- a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Pattern.java @@ -8,5 +8,5 @@ @API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6") public interface Pattern { - Set<ResourceKey> getOutputs(); + Set<ResourceKey> getOutputResources(); } diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java index 9104779de..27c2ec929 100644 --- a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java +++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/PatternRepositoryImpl.java @@ -12,15 +12,15 @@ public class PatternRepositoryImpl implements PatternRepository { @Override public void add(final Pattern pattern) { patterns.add(pattern); - outputs.addAll(pattern.getOutputs()); + outputs.addAll(pattern.getOutputResources()); } @Override public void remove(final Pattern pattern) { patterns.remove(pattern); - for (final ResourceKey output : pattern.getOutputs()) { + for (final ResourceKey output : pattern.getOutputResources()) { final boolean noOtherPatternHasThisOutput = patterns.stream() - .noneMatch(otherPattern -> otherPattern.getOutputs().contains(output)); + .noneMatch(otherPattern -> otherPattern.getOutputResources().contains(output)); if (noOtherPatternHasThisOutput) { outputs.remove(output); } diff --git a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java index 345dae527..3d43c06b4 100644 --- a/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java +++ b/refinedstorage-autocrafting-api/src/test/java/com/refinedmods/refinedstorage/api/autocrafting/SimplePattern.java @@ -12,7 +12,7 @@ public SimplePattern(final ResourceKey... outputs) { } @Override - public Set<ResourceKey> getOutputs() { + public Set<ResourceKey> getOutputResources() { return outputs; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java index c05d5a76c..3545c9aab 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java @@ -1,17 +1,43 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import java.util.List; import java.util.Set; +import java.util.UUID; + +// TODO: help tooltip for fuzzy mode tooltip +// TODO: help tooltip offset -2 +class CraftingPattern extends AbstractPattern { + private final List<List<PlatformResourceKey>> inputs; + private final ResourceAmount output; + private final List<ResourceAmount> byproducts; + private final Set<ResourceKey> outputResources; + + CraftingPattern(final UUID id, + final List<List<PlatformResourceKey>> inputs, + final ResourceAmount output, + final List<ResourceAmount> byproducts) { + super(id); + this.inputs = inputs; + this.output = output; + this.outputResources = Set.of(output.resource()); + this.byproducts = byproducts; + } -record CraftingPattern(List<List<PlatformResourceKey>> inputs, ResourceAmount output, List<ResourceAmount> byproducts) - implements Pattern { @Override - public Set<ResourceKey> getOutputs() { - return Set.of(output.resource()); + public Set<ResourceKey> getOutputResources() { + return outputResources; + } + + List<List<PlatformResourceKey>> getInputs() { + return inputs; + } + + ResourceAmount getOutput() { + return output; } } 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 934acb854..9987552f7 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 @@ -45,14 +45,14 @@ class CraftingPatternClientTooltipComponent implements ClientTooltipComponent { this.width = width; this.height = height; this.craftingPattern = craftingPattern; - final ItemResource outputResource = craftingPattern.output().resource() instanceof ItemResource itemResource + final ItemResource outputResource = craftingPattern.getOutput().resource() instanceof ItemResource itemResource ? itemResource : null; this.outputStack = outputResource != null - ? outputResource.toItemStack(craftingPattern.output().amount()) + ? outputResource.toItemStack(craftingPattern.getOutput().amount()) : null; this.outputText = outputResource != null - ? Component.literal(String.format("%dx ", craftingPattern.output().amount())) + ? Component.literal(String.format("%dx ", craftingPattern.getOutput().amount())) .append(outputResource.toItemStack().getHoverName()) .withStyle(ChatFormatting.GRAY) : null; } @@ -96,7 +96,7 @@ private void renderInputSlots(final int x, final int y, final GuiGraphics graphi private void renderInputSlot(final int x, final int y, final GuiGraphics graphics, final int sx, final int sy) { graphics.blitSprite(SLOT, x + sx * 18, y + sy * 18, 18, 18); final int index = sy * width + sx; - final List<PlatformResourceKey> inputs = craftingPattern.inputs().get(index); + final List<PlatformResourceKey> inputs = craftingPattern.getInputs().get(index); if (!inputs.isEmpty()) { final int idx = currentCycle % inputs.size(); final PlatformResourceKey resource = inputs.get(idx); 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 28fe9d79e..f29f1e38e 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 @@ -159,29 +159,29 @@ public Optional<Pattern> getPattern(final ItemStack stack, final Level level) { return Optional.empty(); } return switch (state.type()) { - case CRAFTING -> getCraftingPattern(stack, level); - case PROCESSING -> getProcessingPattern(stack); - case STONECUTTER -> getStonecutterPattern(stack, level); - case SMITHING_TABLE -> getSmithingTablePattern(stack, level); + case CRAFTING -> getCraftingPattern(state.id(), stack, level); + case PROCESSING -> getProcessingPattern(state.id(), stack); + case STONECUTTER -> getStonecutterPattern(state.id(), stack, level); + case SMITHING_TABLE -> getSmithingTablePattern(state.id(), stack, level); }; } - private Optional<Pattern> getCraftingPattern(final ItemStack stack, final Level level) { + private Optional<Pattern> getCraftingPattern(final UUID id, final ItemStack stack, final Level level) { final CraftingPatternState craftingState = stack.get(DataComponents.INSTANCE.getCraftingPatternState()); if (craftingState == null) { return Optional.empty(); } - return getCraftingPattern(level, craftingState); + return getCraftingPattern(id, level, craftingState); } - private Optional<Pattern> getCraftingPattern(final Level level, final CraftingPatternState state) { + private Optional<Pattern> getCraftingPattern(final UUID id, final Level level, final CraftingPatternState state) { final RecipeMatrixContainer craftingMatrix = getFilledCraftingMatrix(state); final CraftingInput.Positioned positionedCraftingInput = craftingMatrix.asPositionedCraftInput(); final CraftingInput craftingInput = positionedCraftingInput.input(); return level.getRecipeManager() .getRecipeFor(RecipeType.CRAFTING, craftingInput, level) .map(RecipeHolder::value) - .map(recipe -> toCraftingPattern(level, recipe, craftingInput, state)); + .map(recipe -> toCraftingPattern(id, level, recipe, craftingInput, state)); } private RecipeMatrixContainer getFilledCraftingMatrix(final CraftingPatternState state) { @@ -194,14 +194,15 @@ private RecipeMatrixContainer getFilledCraftingMatrix(final CraftingPatternState return craftingMatrix; } - private CraftingPattern toCraftingPattern(final Level level, + private CraftingPattern toCraftingPattern(final UUID id, + final Level level, final CraftingRecipe recipe, final CraftingInput craftingInput, final CraftingPatternState state) { final List<List<PlatformResourceKey>> inputs = getInputs(recipe, state); final ResourceAmount output = getOutput(level, recipe, craftingInput); final List<ResourceAmount> byproducts = getByproducts(recipe, craftingInput); - return new CraftingPattern(inputs, output, byproducts); + return new CraftingPattern(id, inputs, output, byproducts); } private List<List<PlatformResourceKey>> getInputs(final CraftingRecipe recipe, final CraftingPatternState state) { @@ -237,25 +238,26 @@ private List<ResourceAmount> getByproducts(final CraftingRecipe recipe, final Cr .toList(); } - private Optional<Pattern> getProcessingPattern(final ItemStack stack) { + private Optional<Pattern> getProcessingPattern(final UUID id, 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())); + return Optional.of(new ProcessingPattern(id, state.getFlatInputs(), state.getFlatOutputs())); } - private Optional<Pattern> getStonecutterPattern(final ItemStack stack, final Level level) { + private Optional<Pattern> getStonecutterPattern(final UUID id, final ItemStack stack, final Level level) { final StonecutterPatternState state = stack.get(DataComponents.INSTANCE.getStonecutterPatternState()); if (state == null) { return Optional.empty(); } - return getStonecutterPattern(level, state); + return getStonecutterPattern(id, level, state); } - private Optional<Pattern> getStonecutterPattern(final Level level, final StonecutterPatternState state) { + private Optional<Pattern> getStonecutterPattern(final UUID id, final Level level, + final StonecutterPatternState state) { final SingleRecipeInput input = new SingleRecipeInput(state.input().toItemStack()); final ItemStack selectedOutput = state.selectedOutput().toItemStack(); final var recipes = level.getRecipeManager().getRecipesFor(RecipeType.STONECUTTING, input, level); @@ -263,6 +265,7 @@ private Optional<Pattern> getStonecutterPattern(final Level level, final Stonecu final ItemStack output = recipe.value().assemble(input, level.registryAccess()); if (ItemStack.isSameItemSameComponents(output, selectedOutput)) { return Optional.of(new StonecutterPattern( + id, state.input(), ItemResource.ofItemStack(output) )); @@ -271,15 +274,17 @@ private Optional<Pattern> getStonecutterPattern(final Level level, final Stonecu return Optional.empty(); } - private Optional<Pattern> getSmithingTablePattern(final ItemStack stack, final Level level) { + private Optional<Pattern> getSmithingTablePattern(final UUID id, final ItemStack stack, final Level level) { final SmithingTablePatternState state = stack.get(DataComponents.INSTANCE.getSmithingTablePatternState()); if (state == null) { return Optional.empty(); } - return getSmithingTablePattern(level, state); + return getSmithingTablePattern(id, level, state); } - private Optional<Pattern> getSmithingTablePattern(final Level level, final SmithingTablePatternState state) { + private Optional<Pattern> getSmithingTablePattern(final UUID id, + final Level level, + final SmithingTablePatternState state) { final SmithingRecipeInput input = new SmithingRecipeInput( state.template().toItemStack(), state.base().toItemStack(), @@ -287,6 +292,7 @@ private Optional<Pattern> getSmithingTablePattern(final Level level, final Smith ); return level.getRecipeManager().getRecipeFor(RecipeType.SMITHING, input, level) .map(recipe -> new SmithingTablePattern( + id, state.template(), state.base(), state.addition(), 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 462a4503a..3a7755bfe 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 @@ -42,16 +42,16 @@ public static Optional<ItemStack> getOutput(final ItemStack stack) { } return RefinedStorageApi.INSTANCE.getPattern(stack, level).map(pattern -> switch (pattern) { case CraftingPattern craftingPattern - when craftingPattern.output().resource() instanceof ItemResource itemResource -> + when craftingPattern.getOutput().resource() instanceof ItemResource itemResource -> itemResource.toItemStack(); case ProcessingPattern processingPattern - when processingPattern.outputs().size() == 1 - && processingPattern.outputs().getFirst().resource() instanceof ItemResource itemResource -> + when processingPattern.getOutputs().size() == 1 + && processingPattern.getOutputs().getFirst().resource() instanceof ItemResource itemResource -> itemResource.toItemStack(); case StonecutterPattern stonecutterPattern - when stonecutterPattern.output() instanceof ItemResource itemResource -> itemResource.toItemStack(); + when stonecutterPattern.getOutput() instanceof ItemResource itemResource -> itemResource.toItemStack(); case SmithingTablePattern smithingTablePattern - when smithingTablePattern.output() instanceof ItemResource itemResource -> itemResource.toItemStack(); + when smithingTablePattern.getOutput() instanceof ItemResource itemResource -> itemResource.toItemStack(); default -> null; }); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java index bb62e136e..d658f4fc8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java @@ -1,16 +1,36 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; -record ProcessingPattern(List<ResourceAmount> inputs, List<ResourceAmount> outputs) implements Pattern { +class ProcessingPattern extends AbstractPattern { + private final List<ResourceAmount> inputs; + private final List<ResourceAmount> outputs; + private final Set<ResourceKey> outputResources; + + ProcessingPattern(final UUID id, final List<ResourceAmount> inputs, final List<ResourceAmount> outputs) { + super(id); + this.inputs = inputs; + this.outputs = outputs; + this.outputResources = outputs.stream().map(ResourceAmount::resource).collect(Collectors.toSet()); + } + @Override - public Set<ResourceKey> getOutputs() { - return outputs.stream().map(ResourceAmount::resource).collect(Collectors.toSet()); + public Set<ResourceKey> getOutputResources() { + return outputResources; + } + + List<ResourceAmount> getInputs() { + return inputs; + } + + List<ResourceAmount> getOutputs() { + return outputs; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java index 4511879f4..fb9f7daf4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java @@ -1,15 +1,50 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; import java.util.Set; +import java.util.UUID; + +class SmithingTablePattern extends AbstractPattern { + private final ItemResource template; + private final ItemResource base; + private final ItemResource addition; + private final ItemResource output; + private final Set<ResourceKey> outputResources; + + SmithingTablePattern(final UUID id, + final ItemResource template, + final ItemResource base, + final ItemResource addition, + final ItemResource output) { + super(id); + this.template = template; + this.base = base; + this.addition = addition; + this.output = output; + this.outputResources = Set.of(output); + } -record SmithingTablePattern(ItemResource template, ItemResource base, ItemResource addition, ItemResource output) - implements Pattern { @Override - public Set<ResourceKey> getOutputs() { - return Set.of(output); + public Set<ResourceKey> getOutputResources() { + return outputResources; + } + + ItemResource getTemplate() { + return template; + } + + ItemResource getBase() { + return base; + } + + ItemResource getAddition() { + return addition; + } + + ItemResource getOutput() { + return output; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java index 312cc58e2..e9c4bc3cc 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePatternClientTooltipComponent.java @@ -23,7 +23,7 @@ class SmithingTablePatternClientTooltipComponent implements ClientTooltipCompone private final SmithingTablePattern pattern; SmithingTablePatternClientTooltipComponent(final SmithingTablePattern pattern) { - this.outputText = getOutputText(pattern.output()); + this.outputText = getOutputText(pattern.getOutput()); this.pattern = pattern; } @@ -33,11 +33,11 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap final int slotsY = y + 9 + 2; graphics.blitSprite(Sprites.SLOT, x, slotsY, 18, 18); final ResourceRendering rendering = RefinedStorageApi.INSTANCE.getResourceRendering(ItemResource.class); - rendering.render(pattern.template(), graphics, x + 1, slotsY + 1); + rendering.render(pattern.getTemplate(), graphics, x + 1, slotsY + 1); graphics.blitSprite(Sprites.SLOT, x + 18, slotsY, 18, 18); - rendering.render(pattern.base(), graphics, x + 18 + 1, slotsY + 1); + rendering.render(pattern.getBase(), graphics, x + 18 + 1, slotsY + 1); graphics.blitSprite(Sprites.SLOT, x + 18 + 18, slotsY, 18, 18); - rendering.render(pattern.addition(), graphics, x + 18 + 18 + 1, slotsY + 1); + rendering.render(pattern.getAddition(), graphics, x + 18 + 18 + 1, slotsY + 1); graphics.blitSprite( LIGHT_ARROW, x + (18 * 3) + ARROW_SPACING, @@ -47,7 +47,7 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap ); final int lastSlotX = x + (18 * 3) + ARROW_SPACING + LIGHT_ARROW_WIDTH + ARROW_SPACING; graphics.blitSprite(Sprites.SLOT, lastSlotX, slotsY, 18, 18); - rendering.render(pattern.output(), graphics, lastSlotX + 1, slotsY + 1); + rendering.render(pattern.getOutput(), graphics, lastSlotX + 1, slotsY + 1); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java index 4b4333177..bb17d7f21 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java @@ -1,14 +1,34 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; import java.util.Set; +import java.util.UUID; + +class StonecutterPattern extends AbstractPattern { + private final ItemResource input; + private final ItemResource output; + private final Set<ResourceKey> outputResources; + + StonecutterPattern(final UUID id, final ItemResource input, final ItemResource output) { + super(id); + this.input = input; + this.output = output; + this.outputResources = Set.of(output); + } -record StonecutterPattern(ItemResource input, ItemResource output) implements Pattern { @Override - public Set<ResourceKey> getOutputs() { - return Set.of(output); + public Set<ResourceKey> getOutputResources() { + return outputResources; + } + + ItemResource getInput() { + return input; + } + + ItemResource getOutput() { + return output; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java index eeff7d187..b749148dd 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPatternClientTooltipComponent.java @@ -25,9 +25,9 @@ class StonecutterPatternClientTooltipComponent implements ClientTooltipComponent private final PlatformResourceKey output; StonecutterPatternClientTooltipComponent(final StonecutterPattern pattern) { - this.outputText = getOutputText(pattern.output()); - this.input = pattern.input(); - this.output = pattern.output(); + this.outputText = getOutputText(pattern.getOutput()); + this.input = pattern.getInput(); + this.output = pattern.getOutput(); } @Override diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java index 7e2b26d57..4ebb15448 100644 --- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java +++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/SimplePattern.java @@ -13,7 +13,7 @@ public SimplePattern(final ResourceKey... outputs) { } @Override - public Set<ResourceKey> getOutputs() { + public Set<ResourceKey> getOutputResources() { return outputs; } } From eecc1ab0df28be0af374b57d949f64562ebe324f Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sat, 31 Aug 2024 08:44:33 +0200 Subject: [PATCH 05/14] feat: the tooltip for the fuzzy mode checkbox is now a help tooltip --- .../common/autocrafting/CraftingPattern.java | 2 -- .../CraftingPatternGridRenderer.java | 10 +++---- .../tooltip/HelpClientTooltipComponent.java | 30 ++++++++----------- .../support/widget/CustomCheckboxWidget.java | 14 +++++++++ 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java index 3545c9aab..8b5cedf74 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java @@ -9,8 +9,6 @@ import java.util.Set; import java.util.UUID; -// TODO: help tooltip for fuzzy mode tooltip -// TODO: help tooltip offset -2 class CraftingPattern extends AbstractPattern { private final List<List<PlatformResourceKey>> inputs; private final ResourceAmount output; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternGridRenderer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternGridRenderer.java index cd6c530cc..8b94a7b49 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternGridRenderer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPatternGridRenderer.java @@ -8,7 +8,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; -import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; @@ -55,13 +55,13 @@ private CustomCheckboxWidget createFuzzyModeCheckbox() { CustomCheckboxWidget.Size.SMALL ); checkbox.setOnPressed((c, selected) -> menu.setFuzzyMode(selected)); - checkbox.setTooltip(getFuzzyModeTooltip(menu.isFuzzyMode())); + checkbox.setHelpTooltip(getFuzzyModeTooltip(menu.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 static Component getFuzzyModeTooltip(final boolean fuzzyMode) { + return fuzzyMode ? FUZZY_MODE_ON_HELP : FUZZY_MODE_OFF_HELP; } @Override @@ -91,7 +91,7 @@ public void fuzzyModeChanged(final boolean newFuzzyMode) { return; } fuzzyModeCheckbox.setSelected(newFuzzyMode); - fuzzyModeCheckbox.setTooltip(getFuzzyModeTooltip(newFuzzyMode)); + fuzzyModeCheckbox.setHelpTooltip(getFuzzyModeTooltip(newFuzzyMode)); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java index 8a61efc7d..375b88fd8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java @@ -25,27 +25,31 @@ public class HelpClientTooltipComponent implements ClientTooltipComponent { ); private static final Style STYLE = Style.EMPTY.withColor(0xFF129ED9); private static final int MAX_CHARS = 200; + private static final int HELP_ICON_SIZE = 20; + private static final int HELP_ICON_MARGIN = 4; private final List<FormattedCharSequence> lines; private final float scale; + private final int paddingTop; - private HelpClientTooltipComponent(final Component text) { + private HelpClientTooltipComponent(final Component text, final int paddingTop) { this.lines = Language.getInstance().getVisualOrder( Minecraft.getInstance().font.getSplitter().splitLines(text, MAX_CHARS, STYLE) ); this.scale = SmallText.getScale(); + this.paddingTop = paddingTop; } @Override public int getHeight() { - return Math.max(20 + 4, (9 * lines.size()) + 4); + return Math.max(HELP_ICON_SIZE + paddingTop, (9 * lines.size()) + paddingTop); } @Override public int getWidth(final Font font) { int width = 0; for (final FormattedCharSequence line : lines) { - final int lineWidth = 20 + 4 + (int) (font.width(line) * scale); + final int lineWidth = HELP_ICON_SIZE + HELP_ICON_MARGIN + (int) (font.width(line) * scale); if (lineWidth > width) { width = lineWidth; } @@ -59,36 +63,28 @@ public void renderText(final Font font, final int y, final Matrix4f pose, final MultiBufferSource.BufferSource buffer) { - final int xx = x + 20 + 4; - int yy = y + 4; + final int xx = x + HELP_ICON_SIZE + HELP_ICON_MARGIN; + int yy = y + paddingTop; for (final FormattedCharSequence line : lines) { - SmallText.render( - font, - line, - xx, - yy, - scale, - pose, - buffer - ); + SmallText.render(font, line, xx, yy, scale, pose, buffer); yy += 9; } } @Override public void renderImage(final Font font, final int x, final int y, final GuiGraphics graphics) { - graphics.blitSprite(SPRITE, x, y + 2, 20, 20); + graphics.blitSprite(SPRITE, x, y + (paddingTop / 2), HELP_ICON_SIZE, HELP_ICON_SIZE); } public static ClientTooltipComponent create(final Component text) { if (hasShiftDown()) { - return createAlwaysDisplayed(text); + return new HelpClientTooltipComponent(text, 4); } else { return PRESS_SHIFT_FOR_HELP; } } public static ClientTooltipComponent createAlwaysDisplayed(final Component text) { - return new HelpClientTooltipComponent(text); + return new HelpClientTooltipComponent(text, 0); } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/CustomCheckboxWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/CustomCheckboxWidget.java index 173534d67..054f9929a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/CustomCheckboxWidget.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/widget/CustomCheckboxWidget.java @@ -1,5 +1,9 @@ package com.refinedmods.refinedstorage.common.support.widget; +import com.refinedmods.refinedstorage.common.support.AbstractBaseScreen; +import com.refinedmods.refinedstorage.common.support.tooltip.HelpClientTooltipComponent; + +import java.util.List; import javax.annotation.Nullable; import com.mojang.blaze3d.systems.RenderSystem; @@ -32,6 +36,8 @@ public class CustomCheckboxWidget extends AbstractButton { @Nullable private OnPressed onPressed; + @Nullable + private Component helpTooltip; public CustomCheckboxWidget(final int x, final int y, @@ -59,6 +65,11 @@ private static int getWidth(final int maxWidth, final Component text, final Font return Math.min(maxWidth, size.widthHeight + CHECKBOX_TEXT_SPACING + font.width(text)); } + + public void setHelpTooltip(@Nullable final Component helpTooltip) { + this.helpTooltip = helpTooltip; + } + public void setOnPressed(@Nullable final OnPressed onPressed) { this.onPressed = onPressed; } @@ -92,6 +103,9 @@ public void updateWidgetNarration(final NarrationElementOutput output) { @Override public void renderWidget(final GuiGraphics graphics, final int mouseX, final int mouseY, final float partialTicks) { final Minecraft minecraft = Minecraft.getInstance(); + if (isHovered && helpTooltip != null && minecraft.screen instanceof AbstractBaseScreen<?> screen) { + screen.setDeferredTooltip(List.of(HelpClientTooltipComponent.createAlwaysDisplayed(helpTooltip))); + } RenderSystem.enableDepthTest(); final Font font = minecraft.font; graphics.setColor(1.0F, 1.0F, 1.0F, this.alpha); From 7c35657ba4d6d0c8389ba2f90f361e3adfccf7bb Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 10:50:50 +0200 Subject: [PATCH 06/14] feat: craftable grid slots now have a highlight and tooltip --- .../grid/screen/AbstractGridScreen.java | 34 ++++++---- .../CraftableClientTooltipComponent.java | 62 ++++++++++++++++++ .../tooltip/HelpClientTooltipComponent.java | 8 +-- .../common/support/tooltip/SmallText.java | 34 +++++++--- .../SmallTextClientTooltipComponent.java | 6 +- .../assets/refinedstorage/lang/en_us.json | 2 + .../textures/gui/sprites/grid/craftable.png | Bin 0 -> 217 bytes .../sprites/{grid_row.png => grid/row.png} | Bin 8 files changed, 114 insertions(+), 32 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid/craftable.png rename refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/{grid_row.png => grid/row.png} (100%) diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 71a8f9633..b9bc09694 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -52,12 +52,14 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslationKey; import static java.util.Objects.requireNonNullElse; +// TODO: help tooltip to enable focus mode +// TODO: help tooltips for the rest of grid?? public abstract class AbstractGridScreen<T extends AbstractGridContainerMenu> extends AbstractStretchingScreen<T> { protected static final int CLEAR_BUTTON_SIZE = 7; private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGridScreen.class); - private static final ResourceLocation ROW_SPRITE = createIdentifier("grid_row"); + private static final ResourceLocation ROW_SPRITE = createIdentifier("grid/row"); private static final int MODIFIED_JUST_NOW_MAX_SECONDS = 10; private static final int COLUMNS = 9; private static final int DISABLED_SLOT_COLOR = 0xFF5B5B5B; @@ -262,6 +264,9 @@ private void renderResourceWithAmount(final GuiGraphics graphics, final int slotX, final int slotY, final GridResource resource) { + if (resource.isCraftable()) { + graphics.fill(slotX, slotY, slotX + 16, slotY + 16, 0xBF9F7F50); + } if (resource instanceof PlatformGridResource platformResource) { platformResource.render(graphics, slotX, slotY); } @@ -316,9 +321,9 @@ protected void renderTooltip(final GuiGraphics graphics, final int x, final int } private void renderOverStorageAreaTooltip(final GuiGraphics graphics, final int x, final int y) { - final PlatformGridResource resource = getCurrentGridResource(); - if (resource != null) { - renderHoveredResourceTooltip(graphics, x, y, menu.getView(), resource); + final PlatformGridResource gridResource = getCurrentGridResource(); + if (gridResource != null) { + renderHoveredResourceTooltip(graphics, x, y, menu.getView(), gridResource); return; } final ItemStack carried = getMenu().getCarried(); @@ -333,24 +338,27 @@ private void renderHoveredResourceTooltip(final GuiGraphics graphics, final int mouseX, final int mouseY, final GridView view, - final PlatformGridResource platformResource) { - final ItemStack stackContext = platformResource instanceof ItemGridResource itemGridResource + final PlatformGridResource gridResource) { + final ItemStack stackContext = gridResource instanceof ItemGridResource itemGridResource ? itemGridResource.getItemStack() : ItemStack.EMPTY; - final List<Component> lines = platformResource.getTooltip(); + final List<Component> lines = gridResource.getTooltip(); final List<ClientTooltipComponent> processedLines = Platform.INSTANCE.processTooltipComponents( stackContext, graphics, mouseX, - platformResource.getTooltipImage(), + gridResource.getTooltipImage(), lines ); - final long amount = platformResource.getAmount(getMenu().getView()); + final long amount = gridResource.getAmount(getMenu().getView()); + if (amount > 0 && Platform.INSTANCE.getConfig().getGrid().isDetailedTooltip()) { + addDetailedTooltip(view, gridResource, processedLines); + } + if (gridResource.isCraftable()) { + processedLines.add(new CraftableClientTooltipComponent(amount == 0)); + } if (amount > 0) { - if (Platform.INSTANCE.getConfig().getGrid().isDetailedTooltip()) { - addDetailedTooltip(view, platformResource, processedLines); - } - processedLines.addAll(platformResource.getExtractionHints(getMenu().getCarried(), getMenu().getView())); + processedLines.addAll(gridResource.getExtractionHints(getMenu().getCarried(), getMenu().getView())); } Platform.INSTANCE.renderTooltip(graphics, processedLines, mouseX, mouseY); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java new file mode 100644 index 000000000..5dd4e2e77 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java @@ -0,0 +1,62 @@ +package com.refinedmods.refinedstorage.common.grid.screen; + +import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; + +class CraftableClientTooltipComponent implements ClientTooltipComponent { + private static final ResourceLocation ICON = createIdentifier("grid/craftable"); + private static final int ICON_SIZE = 9; + private static final int ICON_MARGIN = 4; + + private static final Component EMPTY = createTranslation("gui", "grid.craftable.click_to_craft"); + private static final Component EXISTING = createTranslation("gui", "grid.craftable.ctrl_click_to_craft"); + + private final Component text; + + CraftableClientTooltipComponent(final boolean empty) { + this.text = empty ? EMPTY : EXISTING; + } + + @Override + public int getHeight() { + return ICON_SIZE + 2; + } + + @Override + public int getWidth(final Font font) { + return ICON_SIZE + ICON_MARGIN + (int) (font.width(text) * SmallText.getScale()); + } + + @Override + public void renderText(final Font font, + final int x, + final int y, + final Matrix4f matrix, + final MultiBufferSource.BufferSource bufferSource) { + final int yOffset = SmallText.isSmall() ? 2 : 0; + SmallText.render( + font, + text.getVisualOrderText(), + x + ICON_SIZE + ICON_MARGIN, + y + yOffset, + 0x9F7F50, + matrix, + bufferSource + ); + } + + @Override + public void renderImage(final Font font, final int x, final int y, final GuiGraphics graphics) { + graphics.blitSprite(ICON, x, y, ICON_SIZE, ICON_SIZE); + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java index 375b88fd8..8dcfc12cb 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/HelpClientTooltipComponent.java @@ -29,14 +29,12 @@ public class HelpClientTooltipComponent implements ClientTooltipComponent { private static final int HELP_ICON_MARGIN = 4; private final List<FormattedCharSequence> lines; - private final float scale; private final int paddingTop; private HelpClientTooltipComponent(final Component text, final int paddingTop) { this.lines = Language.getInstance().getVisualOrder( Minecraft.getInstance().font.getSplitter().splitLines(text, MAX_CHARS, STYLE) ); - this.scale = SmallText.getScale(); this.paddingTop = paddingTop; } @@ -49,7 +47,7 @@ public int getHeight() { public int getWidth(final Font font) { int width = 0; for (final FormattedCharSequence line : lines) { - final int lineWidth = HELP_ICON_SIZE + HELP_ICON_MARGIN + (int) (font.width(line) * scale); + final int lineWidth = HELP_ICON_SIZE + HELP_ICON_MARGIN + (int) (font.width(line) * SmallText.getScale()); if (lineWidth > width) { width = lineWidth; } @@ -66,7 +64,7 @@ public void renderText(final Font font, final int xx = x + HELP_ICON_SIZE + HELP_ICON_MARGIN; int yy = y + paddingTop; for (final FormattedCharSequence line : lines) { - SmallText.render(font, line, xx, yy, scale, pose, buffer); + SmallText.render(font, line, xx, yy, pose, buffer); yy += 9; } } @@ -78,7 +76,7 @@ public void renderImage(final Font font, final int x, final int y, final GuiGrap public static ClientTooltipComponent create(final Component text) { if (hasShiftDown()) { - return new HelpClientTooltipComponent(text, 4); + return new HelpClientTooltipComponent(text, SmallText.isSmall() ? 4 : 0); } else { return PRESS_SHIFT_FOR_HELP; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java index 8d71dee69..a4756a8c2 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallText.java @@ -10,24 +10,38 @@ public final class SmallText { private SmallText() { } - static float getScale() { - return Minecraft.getInstance().isEnforceUnicode() ? 1F : 0.7F; + public static float getScale() { + return isSmall() ? 0.7F : 1F; } - static void render(final Font font, - final FormattedCharSequence text, - final int x, - final int y, - final float scale, - final Matrix4f pose, - final MultiBufferSource.BufferSource buffer) { + public static boolean isSmall() { + return !Minecraft.getInstance().isEnforceUnicode(); + } + + public static void render(final Font font, + final FormattedCharSequence text, + final int x, + final int y, + final Matrix4f pose, + final MultiBufferSource.BufferSource buffer) { + render(font, text, x, y, -1, pose, buffer); + } + + public static void render(final Font font, + final FormattedCharSequence text, + final int x, + final int y, + final int color, + final Matrix4f pose, + final MultiBufferSource.BufferSource buffer) { + final float scale = getScale(); final Matrix4f scaled = new Matrix4f(pose); scaled.scale(scale, scale, 1); font.drawInBatch( text, x / scale, (y / scale) + 1, - -1, + color, true, scaled, buffer, diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallTextClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallTextClientTooltipComponent.java index 20190dafb..843547fde 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallTextClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/tooltip/SmallTextClientTooltipComponent.java @@ -19,8 +19,7 @@ public void renderText(final Font font, final int y, final Matrix4f pose, final MultiBufferSource.BufferSource buffer) { - final float scale = SmallText.getScale(); - SmallText.render(font, text.getVisualOrderText(), x, y, scale, pose, buffer); + SmallText.render(font, text.getVisualOrderText(), x, y, pose, buffer); } @Override @@ -30,7 +29,6 @@ public int getHeight() { @Override public int getWidth(final Font font) { - final float scale = SmallText.getScale(); - return (int) (font.width(text) * scale); + return (int) (font.width(text) * SmallText.getScale()); } } 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 4af0a608b..cbaed480b 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 @@ -62,6 +62,8 @@ "gui.refinedstorage.grid.resource_type.all": "All", "gui.refinedstorage.grid.resource_type.help": "Filter specific resource types.", "gui.refinedstorage.grid.craft": "Craft", + "gui.refinedstorage.grid.craft.click_to_craft": "Click to craft", + "gui.refinedstorage.grid.craft.ctrl_click_to_craft": "CTRL + click to craft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", "gui.refinedstorage.crafting_grid.move.inventory": "Move items to inventory", "gui.refinedstorage.pattern_grid.create_pattern": "Create pattern", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid/craftable.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid/craftable.png new file mode 100644 index 0000000000000000000000000000000000000000..769fc851ff9e62824bb71f516488641d20521ec1 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>3?#4ne^UZdjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCil21AIbU3knJn5)wK)J3T!;v$M13*9W8r8QSQ}0OjNSPHh8HoFzei!T+Iv zA=tk{2qakG5n0T@z;_sg8IR|$NC65OdAc};NQ9f7<m6&d;9))}x9!<~{cYM(9uggy wN#`y!Xo&B5ue!>QKV<JzOMQiJiq#YN{GKpAx%HZ@9;lna)78&qol`;+0ARaAw*UYD literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid_row.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid/row.png similarity index 100% rename from refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid_row.png rename to refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/grid/row.png From 91231d0f752a648fd2e5508c2758d3faa0c836d8 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 11:10:51 +0200 Subject: [PATCH 07/14] feat: pattern and crafting grid slots now have a craftable highlight hint isActive and isHighlightable is checked, to avoid rendering the background on processing matrix slots which should be rendered in the scissor instead. --- .../PatternGridContainerMenu.java | 28 ++++++- .../ProcessingPatternGridRenderer.java | 33 +++++++-- .../grid/AbstractGridContainerMenu.java | 9 +++ .../grid/CraftingGridContainerMenu.java | 15 ++++ .../grid/screen/AbstractGridScreen.java | 62 +++++++++++++++- .../CraftableClientTooltipComponent.java | 21 +++++- .../common/support/AbstractBaseScreen.java | 73 +++++++++---------- .../assets/refinedstorage/lang/en_us.json | 1 + .../api/grid/view/GridView.java | 6 ++ .../api/grid/view/GridViewImpl.java | 5 ++ .../api/grid/view/GridViewImplTest.java | 6 ++ 11 files changed, 204 insertions(+), 55 deletions(-) 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 b9b52dd28..45747deb0 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,6 +1,7 @@ package com.refinedmods.refinedstorage.common.autocrafting; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.ResourceContainer; import com.refinedmods.refinedstorage.common.content.Menus; import com.refinedmods.refinedstorage.common.grid.AbstractGridContainerMenu; @@ -80,8 +81,8 @@ public PatternGridContainerMenu(final int syncId, this.stonecutterInput = new StonecutterInputContainer(playerInventory.player::level); this.smithingTableMatrix = new RecipeMatrixContainer(null, 3, 1); this.smithingTableResult = new ResultContainer(); - this.smithingTableRecipes = - playerInventory.player.level().getRecipeManager().getAllRecipesFor(RecipeType.SMITHING); + this.smithingTableRecipes = playerInventory.player.level().getRecipeManager() + .getAllRecipesFor(RecipeType.SMITHING); onScreenReady(0); registerProperty(new ClientProperty<>(PropertyTypes.REDSTONE_MODE, RedstoneMode.IGNORE)); registerProperty(new ClientProperty<>(PatternGridPropertyTypes.PATTERN_TYPE, patternGridData.patternType()) { @@ -183,7 +184,7 @@ boolean canCreatePattern() { public void onScreenReady(final int playerInventoryY) { super.onScreenReady(playerInventoryY); transferManager.clear(); - addSmithingTableSlots(playerInventoryY); + addSmithingTableSlots(playerInventoryY); // these must be always first for the smithing table helpers addPatternSlots(playerInventoryY); addCraftingMatrixSlots(playerInventoryY); addProcessingMatrixSlots(playerInventoryY); @@ -232,6 +233,27 @@ boolean isPatternInOutput(final ItemStack stack) { return patternOutputSlot != null && patternOutputSlot.getItem() == stack; } + @Nullable + @Override + public ResourceKey getCraftableResource(final Slot slot) { + final boolean isInputItem = slot.container == craftingMatrix + || slot.container == stonecutterInput + || slot.container == smithingTableMatrix; + final boolean isResultItem = slot.container == craftingResult + || slot.container == smithingTableResult; + if (isInputItem || isResultItem) { + return ItemResource.ofItemStack(slot.getItem()); + } else if (slot instanceof ProcessingMatrixResourceSlot processingMatrixSlot) { + return processingMatrixSlot.getResource(); + } + return super.getCraftableResource(slot); + } + + @Override + public boolean isLargeSlot(final Slot slot) { + return slot.container == craftingResult || super.isLargeSlot(slot); + } + private void addCraftingMatrixSlots(final int playerInventoryY) { for (int y = 0; y < 3; ++y) { for (int x = 0; x < 3; ++x) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java index 077717777..7ef910d8b 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java @@ -1,6 +1,7 @@ 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.ResourceSlotRendering; import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; import com.refinedmods.refinedstorage.common.support.widget.ScrollbarWidget; @@ -239,18 +240,34 @@ private void renderMatrixSlots(final GuiGraphics graphics, if (resourceSlot.isActive() && resourceSlot instanceof ProcessingMatrixResourceSlot matrixSlot && matrixSlot.isInput() == input) { - ResourceSlotRendering.render(graphics, resourceSlot, leftPos, topPos); - final boolean hovering = mouseX >= resourceSlot.x + leftPos - && mouseX < resourceSlot.x + leftPos + 16 - && mouseY >= resourceSlot.y + topPos - && mouseY < resourceSlot.y + topPos + 16; - if (hovering && canInteractWithResourceSlot(resourceSlot, mouseX, mouseY)) { - renderSlotHighlight(graphics, leftPos + resourceSlot.x, topPos + resourceSlot.y, 0); - } + renderMatrixSlot(graphics, mouseX, mouseY, resourceSlot, matrixSlot); } } } + private void renderMatrixSlot(final GuiGraphics graphics, + final int mouseX, + final int mouseY, + final ResourceSlot resourceSlot, + final ProcessingMatrixResourceSlot matrixSlot) { + if (matrixSlot.getResource() != null && menu.getView().isCraftable(matrixSlot.getResource())) { + AbstractGridScreen.renderCraftableBackground( + graphics, + resourceSlot.x + leftPos, + resourceSlot.y + topPos, + false + ); + } + ResourceSlotRendering.render(graphics, resourceSlot, leftPos, topPos); + final boolean hovering = mouseX >= resourceSlot.x + leftPos + && mouseX < resourceSlot.x + leftPos + 16 + && mouseY >= resourceSlot.y + topPos + && mouseY < resourceSlot.y + topPos + 16; + if (hovering && canInteractWithResourceSlot(resourceSlot, mouseX, mouseY)) { + renderSlotHighlight(graphics, leftPos + resourceSlot.x, topPos + resourceSlot.y, 0); + } + } + @Override public boolean canInteractWithResourceSlot(final ResourceSlot resourceSlot, final double mouseX, 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 544c62915..f87729e78 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 @@ -425,4 +425,13 @@ protected boolean canTransferSlot(final Slot slot) { public void onClear() { view.clear(); } + + @Nullable + public ResourceKey getCraftableResource(final Slot slot) { + return null; + } + + public boolean isLargeSlot(final Slot slot) { + return false; + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java index fc2f93701..452c1f30e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java @@ -2,6 +2,7 @@ import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.resource.list.ResourceList; import com.refinedmods.refinedstorage.common.content.Menus; import com.refinedmods.refinedstorage.common.grid.view.ItemGridResource; @@ -174,4 +175,18 @@ public void stopFilteringBasedOnCraftingMatrixItems() { getView().setFilterAndSort(filterBeforeFilteringBasedOnCraftingMatrixItems); filterBeforeFilteringBasedOnCraftingMatrixItems = null; } + + @Nullable + @Override + public ResourceKey getCraftableResource(final Slot slot) { + if (slot.container == craftingGrid.getCraftingMatrix() || slot.container == craftingGrid.getCraftingResult()) { + return ItemResource.ofItemStack(slot.getItem()); + } + return super.getCraftableResource(slot); + } + + @Override + public boolean isLargeSlot(final Slot slot) { + return slot.container == craftingGrid.getCraftingResult() || super.isLargeSlot(slot); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index b9bc09694..bad7c2d70 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -4,6 +4,7 @@ import com.refinedmods.refinedstorage.api.grid.operations.GridInsertMode; import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.api.storage.tracked.TrackedResource; import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; @@ -16,6 +17,7 @@ import com.refinedmods.refinedstorage.common.support.Sprites; import com.refinedmods.refinedstorage.common.support.containermenu.DisabledSlot; import com.refinedmods.refinedstorage.common.support.containermenu.PropertyTypes; +import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; import com.refinedmods.refinedstorage.common.support.stretching.AbstractStretchingScreen; import com.refinedmods.refinedstorage.common.support.tooltip.SmallTextClientTooltipComponent; @@ -236,6 +238,22 @@ private void renderCell(final GuiGraphics graphics, } } + @Override + protected List<ClientTooltipComponent> getResourceSlotTooltip(final ResourceKey resource, final ResourceSlot slot) { + final List<ClientTooltipComponent> tooltip = super.getResourceSlotTooltip(resource, slot); + final ResourceKey craftableResource = getMenu().getCraftableResource(slot); + if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { + tooltip.add(CraftableClientTooltipComponent.craftable()); + } + return tooltip; + } + + @Override + protected void renderSlot(final GuiGraphics guiGraphics, final Slot slot) { + tryRenderCraftableBackground(guiGraphics, slot); + super.renderSlot(guiGraphics, slot); + } + private void renderSlot(final GuiGraphics graphics, final int mouseX, final int mouseY, @@ -260,12 +278,22 @@ private void renderSlot(final GuiGraphics graphics, } } + private void tryRenderCraftableBackground(final GuiGraphics guiGraphics, final Slot slot) { + if (!slot.isHighlightable() || !slot.isActive()) { + return; + } + final ResourceKey craftableResource = getMenu().getCraftableResource(slot); + if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { + renderCraftableBackground(guiGraphics, slot.x, slot.y, getMenu().isLargeSlot(slot)); + } + } + private void renderResourceWithAmount(final GuiGraphics graphics, final int slotX, final int slotY, final GridResource resource) { if (resource.isCraftable()) { - graphics.fill(slotX, slotY, slotX + 16, slotY + 16, 0xBF9F7F50); + renderCraftableBackground(graphics, slotX, slotY, false); } if (resource instanceof PlatformGridResource platformResource) { platformResource.render(graphics, slotX, slotY); @@ -273,6 +301,14 @@ private void renderResourceWithAmount(final GuiGraphics graphics, renderAmount(graphics, slotX, slotY, resource); } + public static void renderCraftableBackground(final GuiGraphics graphics, + final int slotX, + final int slotY, + final boolean large) { + final int offset = large ? 4 : 0; + graphics.fill(slotX - offset, slotY - offset, slotX + 16 + offset, slotY + 16 + offset, 0xBF9F7F50); + } + private void renderAmount(final GuiGraphics graphics, final int slotX, final int slotY, @@ -314,10 +350,28 @@ private void renderDisabledSlot(final GuiGraphics graphics, final int slotX, fin @Override protected void renderTooltip(final GuiGraphics graphics, final int x, final int y) { - super.renderTooltip(graphics, x, y); if (isOverStorageArea(x, y)) { renderOverStorageAreaTooltip(graphics, x, y); + return; + } + if (getMenu().getCarried().isEmpty() && hoveredSlot != null && hoveredSlot.hasItem()) { + final ResourceKey craftableResource = getMenu().getCraftableResource(hoveredSlot); + if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { + final ItemStack item = hoveredSlot.getItem(); + final List<Component> lines = getTooltipFromContainerItem(item); + final List<ClientTooltipComponent> processedLines = Platform.INSTANCE.processTooltipComponents( + item, + graphics, + x, + item.getTooltipImage(), + lines + ); + processedLines.add(CraftableClientTooltipComponent.craftable()); + Platform.INSTANCE.renderTooltip(graphics, processedLines, x, y); + return; + } } + super.renderTooltip(graphics, x, y); } private void renderOverStorageAreaTooltip(final GuiGraphics graphics, final int x, final int y) { @@ -355,7 +409,9 @@ private void renderHoveredResourceTooltip(final GuiGraphics graphics, addDetailedTooltip(view, gridResource, processedLines); } if (gridResource.isCraftable()) { - processedLines.add(new CraftableClientTooltipComponent(amount == 0)); + processedLines.add(amount == 0 + ? CraftableClientTooltipComponent.empty() + : CraftableClientTooltipComponent.existing()); } if (amount > 0) { processedLines.addAll(gridResource.getExtractionHints(getMenu().getCarried(), getMenu().getView())); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java index 5dd4e2e77..a9015e32f 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java @@ -18,13 +18,26 @@ class CraftableClientTooltipComponent implements ClientTooltipComponent { private static final int ICON_SIZE = 9; private static final int ICON_MARGIN = 4; - private static final Component EMPTY = createTranslation("gui", "grid.craftable.click_to_craft"); - private static final Component EXISTING = createTranslation("gui", "grid.craftable.ctrl_click_to_craft"); + private static final Component CRAFTABLE = createTranslation("gui", "grid.craft.craftable"); + private static final Component EMPTY = createTranslation("gui", "grid.craft.click_to_craft"); + private static final Component EXISTING = createTranslation("gui", "grid.craft.ctrl_click_to_craft"); private final Component text; - CraftableClientTooltipComponent(final boolean empty) { - this.text = empty ? EMPTY : EXISTING; + private CraftableClientTooltipComponent(final Component text) { + this.text = text; + } + + static CraftableClientTooltipComponent craftable() { + return new CraftableClientTooltipComponent(CRAFTABLE); + } + + static CraftableClientTooltipComponent empty() { + return new CraftableClientTooltipComponent(EMPTY); + } + + static CraftableClientTooltipComponent existing() { + return new CraftableClientTooltipComponent(EXISTING); } @Override 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 de2279751..57ef1c420 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 @@ -166,7 +166,7 @@ protected void renderTooltip(final GuiGraphics graphics, final int x, final int } } if (hoveredSlot instanceof ResourceSlot resourceSlot && canInteractWithResourceSlot(resourceSlot, x, y)) { - final List<ClientTooltipComponent> tooltip = getResourceTooltip(menu.getCarried(), resourceSlot); + final List<ClientTooltipComponent> tooltip = getResourceSlotTooltip(menu.getCarried(), resourceSlot); if (!tooltip.isEmpty()) { Platform.INSTANCE.renderTooltip(graphics, tooltip, x, y); return; @@ -195,23 +195,49 @@ private List<ClientTooltipComponent> getUpgradeTooltip(final ItemStack carried, return lines; } - public List<ClientTooltipComponent> getResourceTooltip(final ItemStack carried, final ResourceSlot resourceSlot) { - final ResourceKey resource = resourceSlot.getResource(); + public final List<ClientTooltipComponent> getResourceSlotTooltip(final ItemStack carried, final ResourceSlot slot) { + final ResourceKey resource = slot.getResource(); if (resource == null) { - return getTooltipForEmptySlot(carried, resourceSlot); + return getTooltipForEmptyResourceSlot(carried, slot); } - return getTooltipForResource(resource, resourceSlot); + return getResourceSlotTooltip(resource, slot); } - private List<ClientTooltipComponent> getTooltipForEmptySlot(final ItemStack carried, - final ResourceSlot resourceSlot) { - if (resourceSlot.isDisabled() || resourceSlot.supportsItemSlotInteractions()) { + protected List<ClientTooltipComponent> getResourceSlotTooltip(final ResourceKey resource, final ResourceSlot slot) { + final List<ClientTooltipComponent> tooltip = RefinedStorageApi.INSTANCE + .getResourceRendering(resource.getClass()) + .getTooltip(resource) + .stream() + .map(Component::getVisualOrderText) + .map(ClientTooltipComponent::create) + .collect(Collectors.toList()); + if (!slot.isDisabled() && !slot.supportsItemSlotInteractions()) { + addResourceSlotTooltips(slot, tooltip); + } + if (slot.supportsItemSlotInteractions()) { + RefinedStorageApi.INSTANCE.getResourceContainerInsertStrategies() + .stream() + .flatMap(strategy -> strategy.getConversionInfo(resource, getMenu().getCarried()).stream()) + .map(conversionInfo -> MouseClientTooltipComponent.itemConversion( + MouseClientTooltipComponent.Type.LEFT, + conversionInfo.from(), + conversionInfo.to(), + null + )) + .forEach(tooltip::add); + } + return tooltip; + } + + private List<ClientTooltipComponent> getTooltipForEmptyResourceSlot(final ItemStack carried, + final ResourceSlot slot) { + if (slot.isDisabled() || slot.supportsItemSlotInteractions()) { return Collections.emptyList(); } final List<ClientTooltipComponent> tooltip = new ArrayList<>(); tooltip.add(EMPTY_FILTER); - tooltip.addAll(getResourceSlotHelpTooltip(carried, resourceSlot)); - tooltip.add(HelpClientTooltipComponent.create(resourceSlot.getHelpText())); + tooltip.addAll(getResourceSlotHelpTooltip(carried, slot)); + tooltip.add(HelpClientTooltipComponent.create(slot.getHelpText())); return tooltip; } @@ -239,33 +265,6 @@ private List<ClientTooltipComponent> getResourceSlotHelpTooltip(final ItemStack return lines; } - private List<ClientTooltipComponent> getTooltipForResource(final ResourceKey resource, - final ResourceSlot resourceSlot) { - final List<ClientTooltipComponent> tooltip = RefinedStorageApi.INSTANCE - .getResourceRendering(resource.getClass()) - .getTooltip(resource) - .stream() - .map(Component::getVisualOrderText) - .map(ClientTooltipComponent::create) - .collect(Collectors.toList()); - if (!resourceSlot.isDisabled() && !resourceSlot.supportsItemSlotInteractions()) { - addResourceSlotTooltips(resourceSlot, tooltip); - } - if (resourceSlot.supportsItemSlotInteractions()) { - RefinedStorageApi.INSTANCE.getResourceContainerInsertStrategies() - .stream() - .flatMap(strategy -> strategy.getConversionInfo(resource, getMenu().getCarried()).stream()) - .map(conversionInfo -> MouseClientTooltipComponent.itemConversion( - MouseClientTooltipComponent.Type.LEFT, - conversionInfo.from(), - conversionInfo.to(), - null - )) - .forEach(tooltip::add); - } - return tooltip; - } - protected void addResourceSlotTooltips(final ResourceSlot slot, final List<ClientTooltipComponent> tooltip) { if (slot.canModifyAmount()) { tooltip.add(CLICK_TO_CONFIGURE_AMOUNT); 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 cbaed480b..3a29a2fd5 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 @@ -62,6 +62,7 @@ "gui.refinedstorage.grid.resource_type.all": "All", "gui.refinedstorage.grid.resource_type.help": "Filter specific resource types.", "gui.refinedstorage.grid.craft": "Craft", + "gui.refinedstorage.grid.craft.craftable": "This resource is craftable", "gui.refinedstorage.grid.craft.click_to_craft": "Click to craft", "gui.refinedstorage.grid.craft.ctrl_click_to_craft": "CTRL + click to craft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridView.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridView.java index df1f422c9..0604761f7 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridView.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridView.java @@ -70,6 +70,12 @@ public interface GridView { */ long getAmount(ResourceKey resource); + /** + * @param resource the resource + * @return whether its craftable + */ + boolean isCraftable(ResourceKey resource); + /** * Sorts the view list. * Applies sorting and filtering rules. 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 c1c123d34..69ca892ee 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 @@ -100,6 +100,11 @@ public long getAmount(final ResourceKey resource) { return backingList.get(resource); } + @Override + public boolean isCraftable(final ResourceKey resource) { + return craftableResources.contains(resource); + } + @Override public void sort() { LOGGER.info("Sorting grid view"); diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java index 9a19aa20d..bd36dd114 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java @@ -672,6 +672,8 @@ void shouldIncludeCraftableResourceInViewList() { new GridResourceImpl(A), new GridResourceImpl(B).craftable() ); + assertThat(view.isCraftable(A)).isFalse(); + assertThat(view.isCraftable(B)).isTrue(); assertThat(view.getAmount(A)).isEqualTo(15); assertThat(view.getAmount(B)).isZero(); assertThat(view.copyBackingList().copyState()).usingRecursiveFieldByFieldElementComparator() @@ -693,6 +695,7 @@ void shouldIncludeCraftableResourceInViewListEvenIfItIsInTheBackingList() { assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(A).craftable() ); + assertThat(view.isCraftable(A)).isTrue(); assertThat(view.getAmount(A)).isEqualTo(15); assertThat(view.copyBackingList().copyState()) .usingRecursiveFieldByFieldElementComparator() @@ -716,6 +719,7 @@ void shouldNotRemoveCraftableResource() { assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(A).craftable() ); + assertThat(view.isCraftable(A)).isTrue(); assertThat(view.getAmount(A)).isZero(); assertThat(view.copyBackingList().copyState()).isEmpty(); } @@ -737,6 +741,7 @@ void shouldNotRemoveCraftableResourceEvenWhenPreventingSorting() { assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(A).zeroed().craftable() ); + assertThat(view.isCraftable(A)).isTrue(); assertThat(view.getAmount(A)).isZero(); assertThat(view.copyBackingList().copyState()).isEmpty(); @@ -745,6 +750,7 @@ void shouldNotRemoveCraftableResourceEvenWhenPreventingSorting() { assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(A).craftable() ); + assertThat(view.isCraftable(A)).isTrue(); assertThat(view.getAmount(A)).isEqualTo(1); assertThat(view.copyBackingList().copyState()).usingRecursiveFieldByFieldElementComparator().containsExactly( new ResourceAmount(A, 1) From 6b2e9ffa5de1215addb2915ea6cfad7df23cbdfa Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 14:43:37 +0200 Subject: [PATCH 08/14] feat: grid view type Use term "autocraftable" instead of "craftable" everywhere as that makes it more clear what it means. --- .idea/dictionaries/refinedstorage.xml | 1 + .../refinedstorage/common/Config.java | 5 ++ .../grid/AbstractGridContainerMenu.java | 23 +++++- .../common/grid/GridViewType.java | 15 ++++ .../grid/screen/AbstractGridScreen.java | 12 ++-- ... AutocraftableClientTooltipComponent.java} | 22 +++--- .../grid/screen/ViewTypeSideButtonWidget.java | 67 ++++++++++++++++++ .../assets/refinedstorage/lang/en_us.json | 12 +++- .../widget/side_button/grid/view_type/all.png | Bin 0 -> 167 bytes .../grid/view_type/autocraftable.png | Bin 0 -> 164 bytes .../grid/view_type/non_autocraftable.png | Bin 0 -> 216 bytes .../refinedstorage/fabric/ConfigImpl.java | 14 ++++ .../refinedstorage/neoforge/ConfigImpl.java | 19 +++++ 13 files changed, 168 insertions(+), 22 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridViewType.java rename refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/{CraftableClientTooltipComponent.java => AutocraftableClientTooltipComponent.java} (74%) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ViewTypeSideButtonWidget.java create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/all.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/autocraftable.png create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/non_autocraftable.png diff --git a/.idea/dictionaries/refinedstorage.xml b/.idea/dictionaries/refinedstorage.xml index 74576b5dd..5731caf61 100644 --- a/.idea/dictionaries/refinedstorage.xml +++ b/.idea/dictionaries/refinedstorage.xml @@ -2,6 +2,7 @@ <dictionary name="refinedstorage"> <words> <w>allowlist</w> + <w>autocraftable</w> <w>autocrafting</w> <w>autoselected</w> <w>blocklist</w> diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java index 79641b639..018cdc3c4 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java @@ -3,6 +3,7 @@ import com.refinedmods.refinedstorage.api.grid.view.GridSortingDirection; import com.refinedmods.refinedstorage.common.grid.CraftingGridMatrixCloseBehavior; import com.refinedmods.refinedstorage.common.grid.GridSortingTypes; +import com.refinedmods.refinedstorage.common.grid.GridViewType; import com.refinedmods.refinedstorage.common.support.stretching.ScreenSize; import java.util.Optional; @@ -105,6 +106,10 @@ interface GridEntry extends SimpleEnergyUsageEntry { void setSortingType(GridSortingTypes sortingType); + GridViewType getViewType(); + + void setViewType(GridViewType viewType); + Optional<ResourceLocation> getResourceType(); void setResourceType(ResourceLocation resourceTypeId); 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 f87729e78..1652c87bb 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 @@ -111,7 +111,7 @@ protected AbstractGridContainerMenu( this.view = viewBuilder.build(); this.view.setSortingDirection(Platform.INSTANCE.getConfig().getGrid().getSortingDirection()); this.view.setSortingType(Platform.INSTANCE.getConfig().getGrid().getSortingType()); - this.view.setFilterAndSort(filterResourceType()); + this.view.setFilterAndSort(createBaseFilter()); this.synchronizer = loadSynchronizer(); this.resourceTypeFilter = loadResourceType(); @@ -139,7 +139,11 @@ protected AbstractGridContainerMenu( initStrategies((ServerPlayer) playerInventory.player); } - private BiPredicate<GridView, GridResource> filterResourceType() { + private BiPredicate<GridView, GridResource> createBaseFilter() { + return createResourceTypeFilter().and(createViewTypeFilter()); + } + + private BiPredicate<GridView, GridResource> createResourceTypeFilter() { return (v, resource) -> resource instanceof PlatformGridResource platformResource && Platform.INSTANCE.getConfig().getGrid().getResourceType().flatMap(resourceTypeId -> RefinedStorageApi.INSTANCE @@ -149,6 +153,10 @@ private BiPredicate<GridView, GridResource> filterResourceType() { ).orElse(true); } + private BiPredicate<GridView, GridResource> createViewTypeFilter() { + return (v, resource) -> Platform.INSTANCE.getConfig().getGrid().getViewType().accepts(resource.isCraftable()); + } + private static GridViewBuilder createViewBuilder() { return new GridViewBuilderImpl( new CompositeGridResourceFactory(RefinedStorageApi.INSTANCE.getResourceTypeRegistry()), @@ -184,6 +192,15 @@ public void setSortingType(final GridSortingTypes sortingType) { view.sort(); } + public GridViewType getViewType() { + return Platform.INSTANCE.getConfig().getGrid().getViewType(); + } + + public void setViewType(final GridViewType viewType) { + Platform.INSTANCE.getConfig().getGrid().setViewType(viewType); + view.sort(); + } + public void setSearchBox(final GridSearchBox searchBox) { this.searchBox = searchBox; registerViewUpdatingListener(searchBox); @@ -199,7 +216,7 @@ private void registerViewUpdatingListener(final GridSearchBox theSearchBox) { private boolean onSearchTextChanged(final String text) { try { - view.setFilterAndSort(QUERY_PARSER.parse(text).and(filterResourceType())); + view.setFilterAndSort(QUERY_PARSER.parse(text).and(createBaseFilter())); return true; } catch (GridQueryParserException e) { view.setFilterAndSort((v, resource) -> false); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridViewType.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridViewType.java new file mode 100644 index 000000000..2eed45c67 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/GridViewType.java @@ -0,0 +1,15 @@ +package com.refinedmods.refinedstorage.common.grid; + +public enum GridViewType { + ALL, + CRAFTABLE, + NON_CRAFTABLE; + + boolean accepts(final boolean craftable) { + return switch (this) { + case ALL -> true; + case CRAFTABLE -> craftable; + case NON_CRAFTABLE -> !craftable; + }; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index bad7c2d70..6e9c855b8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -56,6 +56,7 @@ // TODO: help tooltip to enable focus mode // TODO: help tooltips for the rest of grid?? +// TODO: remove zeroed system public abstract class AbstractGridScreen<T extends AbstractGridContainerMenu> extends AbstractStretchingScreen<T> { protected static final int CLEAR_BUTTON_SIZE = 7; @@ -110,10 +111,11 @@ protected void init(final int rows) { if (getMenu().hasProperty(PropertyTypes.REDSTONE_MODE)) { addSideButton(new RedstoneModeSideButtonWidget(getMenu().getProperty(PropertyTypes.REDSTONE_MODE))); } + addSideButton(new ViewTypeSideButtonWidget(getMenu())); + addSideButton(new ResourceTypeSideButtonWidget(getMenu())); addSideButton(new SortingDirectionSideButtonWidget(getMenu())); addSideButton(new SortingTypeSideButtonWidget(getMenu())); addSideButton(new AutoSelectedSideButtonWidget(getMenu())); - addSideButton(new ResourceTypeSideButtonWidget(getMenu())); final boolean onlyHasNoopSynchronizer = RefinedStorageApi.INSTANCE.getGridSynchronizerRegistry() .getAll() @@ -243,7 +245,7 @@ protected List<ClientTooltipComponent> getResourceSlotTooltip(final ResourceKey final List<ClientTooltipComponent> tooltip = super.getResourceSlotTooltip(resource, slot); final ResourceKey craftableResource = getMenu().getCraftableResource(slot); if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { - tooltip.add(CraftableClientTooltipComponent.craftable()); + tooltip.add(AutocraftableClientTooltipComponent.autocraftable()); } return tooltip; } @@ -366,7 +368,7 @@ protected void renderTooltip(final GuiGraphics graphics, final int x, final int item.getTooltipImage(), lines ); - processedLines.add(CraftableClientTooltipComponent.craftable()); + processedLines.add(AutocraftableClientTooltipComponent.autocraftable()); Platform.INSTANCE.renderTooltip(graphics, processedLines, x, y); return; } @@ -410,8 +412,8 @@ private void renderHoveredResourceTooltip(final GuiGraphics graphics, } if (gridResource.isCraftable()) { processedLines.add(amount == 0 - ? CraftableClientTooltipComponent.empty() - : CraftableClientTooltipComponent.existing()); + ? AutocraftableClientTooltipComponent.empty() + : AutocraftableClientTooltipComponent.existing()); } if (amount > 0) { processedLines.addAll(gridResource.getExtractionHints(getMenu().getCarried(), getMenu().getView())); diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java similarity index 74% rename from refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java rename to refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java index a9015e32f..7a61527d2 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftableClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java @@ -13,31 +13,31 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; -class CraftableClientTooltipComponent implements ClientTooltipComponent { +class AutocraftableClientTooltipComponent implements ClientTooltipComponent { private static final ResourceLocation ICON = createIdentifier("grid/craftable"); private static final int ICON_SIZE = 9; private static final int ICON_MARGIN = 4; - private static final Component CRAFTABLE = createTranslation("gui", "grid.craft.craftable"); - private static final Component EMPTY = createTranslation("gui", "grid.craft.click_to_craft"); - private static final Component EXISTING = createTranslation("gui", "grid.craft.ctrl_click_to_craft"); + private static final Component AUTOCRAFTABLE = createTranslation("gui", "grid.autocraftable"); + private static final Component EMPTY = createTranslation("gui", "grid.click_to_autocraft"); + private static final Component EXISTING = createTranslation("gui", "grid.ctrl_click_to_autocraft"); private final Component text; - private CraftableClientTooltipComponent(final Component text) { + private AutocraftableClientTooltipComponent(final Component text) { this.text = text; } - static CraftableClientTooltipComponent craftable() { - return new CraftableClientTooltipComponent(CRAFTABLE); + static AutocraftableClientTooltipComponent autocraftable() { + return new AutocraftableClientTooltipComponent(AUTOCRAFTABLE); } - static CraftableClientTooltipComponent empty() { - return new CraftableClientTooltipComponent(EMPTY); + static AutocraftableClientTooltipComponent empty() { + return new AutocraftableClientTooltipComponent(EMPTY); } - static CraftableClientTooltipComponent existing() { - return new CraftableClientTooltipComponent(EXISTING); + static AutocraftableClientTooltipComponent existing() { + return new AutocraftableClientTooltipComponent(EXISTING); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ViewTypeSideButtonWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ViewTypeSideButtonWidget.java new file mode 100644 index 000000000..af148a083 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ViewTypeSideButtonWidget.java @@ -0,0 +1,67 @@ +package com.refinedmods.refinedstorage.common.grid.screen; + +import com.refinedmods.refinedstorage.common.grid.AbstractGridContainerMenu; +import com.refinedmods.refinedstorage.common.grid.GridViewType; +import com.refinedmods.refinedstorage.common.support.widget.AbstractSideButtonWidget; + +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; + +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; +import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; + +class ViewTypeSideButtonWidget extends AbstractSideButtonWidget { + private static final MutableComponent TITLE = createTranslation("gui", "grid.view_type"); + private static final MutableComponent SUBTEXT_ALL = createTranslation("gui", "grid.view_type.all"); + private static final MutableComponent SUBTEXT_AUTOCRAFTABLE = + createTranslation("gui", "grid.view_type.autocraftable"); + private static final MutableComponent SUBTEXT_NON_AUTOCRAFTABLE = + createTranslation("gui", "grid.view_type.non_autocraftable"); + private static final ResourceLocation ALL = createIdentifier("widget/side_button/grid/view_type/all"); + private static final ResourceLocation CRAFTABLE = + createIdentifier("widget/side_button/grid/view_type/autocraftable"); + private static final ResourceLocation NON_CRAFTABLE = + createIdentifier("widget/side_button/grid/view_type/non_autocraftable"); + + private final AbstractGridContainerMenu menu; + + ViewTypeSideButtonWidget(final AbstractGridContainerMenu menu) { + super(createPressAction(menu)); + this.menu = menu; + } + + private static OnPress createPressAction(final AbstractGridContainerMenu menu) { + return btn -> menu.setViewType(toggle(menu.getViewType())); + } + + private static GridViewType toggle(final GridViewType sortingType) { + return switch (sortingType) { + case ALL -> GridViewType.CRAFTABLE; + case CRAFTABLE -> GridViewType.NON_CRAFTABLE; + case NON_CRAFTABLE -> GridViewType.ALL; + }; + } + + @Override + protected ResourceLocation getSprite() { + return switch (menu.getViewType()) { + case ALL -> ALL; + case CRAFTABLE -> CRAFTABLE; + case NON_CRAFTABLE -> NON_CRAFTABLE; + }; + } + + @Override + protected MutableComponent getTitle() { + return TITLE; + } + + @Override + protected MutableComponent getSubText() { + return switch (menu.getViewType()) { + case ALL -> SUBTEXT_ALL; + case CRAFTABLE -> SUBTEXT_AUTOCRAFTABLE; + case NON_CRAFTABLE -> SUBTEXT_NON_AUTOCRAFTABLE; + }; + } +} 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 3a29a2fd5..e5221b341 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 @@ -45,6 +45,10 @@ "gui.refinedstorage.storage.filter_mode.empty_warning": "Without any configured filters, no resources will be accepted in this storage.", "gui.refinedstorage.storage.filter_mode.allow.help": "Only allow resources into this storage that are configured in the filters.", "gui.refinedstorage.storage.filter_mode.block.help": "Disallow resources into this storage that are configured in the filters.", + "gui.refinedstorage.grid.view_type": "View type", + "gui.refinedstorage.grid.view_type.all": "All", + "gui.refinedstorage.grid.view_type.autocraftable": "Autocraftable", + "gui.refinedstorage.grid.view_type.non_autocraftable": "Non-autocraftable", "gui.refinedstorage.grid.sorting.direction": "Sorting direction", "gui.refinedstorage.grid.sorting.direction.ascending": "Ascending", "gui.refinedstorage.grid.sorting.direction.descending": "Descending", @@ -62,9 +66,9 @@ "gui.refinedstorage.grid.resource_type.all": "All", "gui.refinedstorage.grid.resource_type.help": "Filter specific resource types.", "gui.refinedstorage.grid.craft": "Craft", - "gui.refinedstorage.grid.craft.craftable": "This resource is craftable", - "gui.refinedstorage.grid.craft.click_to_craft": "Click to craft", - "gui.refinedstorage.grid.craft.ctrl_click_to_craft": "CTRL + click to craft", + "gui.refinedstorage.grid.autocraftable": "This resource is autocraftable", + "gui.refinedstorage.grid.click_to_autocraft": "Click to autocraft", + "gui.refinedstorage.grid.ctrl_click_to_autocraft": "CTRL + click to autocraft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", "gui.refinedstorage.crafting_grid.move.inventory": "Move items to inventory", "gui.refinedstorage.pattern_grid.create_pattern": "Create pattern", @@ -415,6 +419,8 @@ "text.autoconfig.refinedstorage.option.grid.sortingDirection.tooltip": "The sorting direction.", "text.autoconfig.refinedstorage.option.grid.sortingType": "Sorting type", "text.autoconfig.refinedstorage.option.grid.sortingType.tooltip": "The sorting type.", + "text.autoconfig.refinedstorage.option.grid.viewType": "View type", + "text.autoconfig.refinedstorage.option.grid.viewType.tooltip": "The view type.", "text.autoconfig.refinedstorage.option.craftingGrid": "Crafting Grid", "text.autoconfig.refinedstorage.option.craftingGrid.tooltip": "Configuration for the Crafting Grid.", "text.autoconfig.refinedstorage.option.craftingGrid.energyUsage": "Energy usage", diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/all.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/all.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d64d56d384136953344d7118dd4392f4b489bc GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK^spO#}Etu<Ujxa+cT>+aC%MVWxL1FW3XY{ zHa2b<+o~yo$K2Qy3N?gzR=j5lI=Didty!GSPBS=zfti^h_n9v1&resof#xuHy85}S Ib4q9e06Us3?EnA( literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/autocraftable.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/autocraftable.png new file mode 100644 index 0000000000000000000000000000000000000000..e9b9915389ca8e6acef2a6407d88da2121c3c58f GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK}$~;#}Etu<Ujxa+cT>+aC%MVWn0L2?b@~f zjuP_Hk^yg+UL9xBOIO}J@!$$^4Hkv>!Ec%x%^DgR8Cbow3g*puCI~cy!PC{xWt~$( F696;BFT?-< literal 0 HcmV?d00001 diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/non_autocraftable.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/gui/sprites/widget/side_button/grid/view_type/non_autocraftable.png new file mode 100644 index 0000000000000000000000000000000000000000..679b2c80f03c3ad56acaf9b0a5104636386dd299 GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0G|-o^73*kD=Q$+Q+Dl5AjMn~<QM$^Kg0D?yg;=KoCO|{#S9F5he4R} zc>anMkWx<<#}JL++&)G=1_Ku6kN@5MMIEn2Oq*w>SoVeWl2XU~ro$bxj)?@!XZ_*E zx;wVeJ!WB#xr0)abj4~1PW3}i@9NEn;FV4I#&Cv#vA&PTR}^R{gQu&X%Q~loCICOB BJ&^za literal 0 HcmV?d00001 diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java index a0e9899a3..1ef490941 100644 --- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java +++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java @@ -4,6 +4,7 @@ import com.refinedmods.refinedstorage.common.content.DefaultEnergyUsage; import com.refinedmods.refinedstorage.common.grid.CraftingGridMatrixCloseBehavior; import com.refinedmods.refinedstorage.common.grid.GridSortingTypes; +import com.refinedmods.refinedstorage.common.grid.GridViewType; import com.refinedmods.refinedstorage.common.support.stretching.ScreenSize; import com.refinedmods.refinedstorage.common.util.IdentifierUtil; @@ -309,6 +310,8 @@ private static class GridEntryImpl implements GridEntry { private GridSortingTypes sortingType = GridSortingTypes.QUANTITY; + private GridViewType viewType = GridViewType.ALL; + @Override public boolean isLargeFont() { return largeFont; @@ -387,6 +390,17 @@ public void setSortingType(final GridSortingTypes sortingType) { save(); } + @Override + public GridViewType getViewType() { + return viewType; + } + + @Override + public void setViewType(final GridViewType viewType) { + this.viewType = viewType; + save(); + } + @Override public Optional<ResourceLocation> getResourceType() { if (resourceType.trim().isBlank()) { diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java index 4228d679c..88fd8298e 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java @@ -1,10 +1,12 @@ package com.refinedmods.refinedstorage.neoforge; import com.refinedmods.refinedstorage.api.grid.view.GridSortingDirection; +import com.refinedmods.refinedstorage.api.grid.view.GridView; import com.refinedmods.refinedstorage.common.Config; import com.refinedmods.refinedstorage.common.content.DefaultEnergyUsage; import com.refinedmods.refinedstorage.common.grid.CraftingGridMatrixCloseBehavior; import com.refinedmods.refinedstorage.common.grid.GridSortingTypes; +import com.refinedmods.refinedstorage.common.grid.GridViewType; import com.refinedmods.refinedstorage.common.support.stretching.ScreenSize; import java.util.Optional; @@ -369,6 +371,7 @@ private class GridEntryImpl implements GridEntry { private final ModConfigSpec.ConfigValue<String> resourceType; private final ModConfigSpec.EnumValue<GridSortingDirection> sortingDirection; private final ModConfigSpec.EnumValue<GridSortingTypes> sortingType; + private final ModConfigSpec.EnumValue<GridViewType> viewType; GridEntryImpl() { builder.translation(translationKey("grid")).push("grid"); @@ -402,6 +405,9 @@ private class GridEntryImpl implements GridEntry { sortingType = builder .translation(translationKey("grid.sortingType")) .defineEnum("sortingType", GridSortingTypes.QUANTITY); + viewType = builder + .translation(translationKey("grid.viewType")) + .defineEnum("viewType", GridViewType.ALL); builder.pop(); } @@ -493,6 +499,19 @@ public void setSortingType(final GridSortingTypes sortingType) { } } + @Override + public GridViewType getViewType() { + return viewType.get(); + } + + @Override + public void setViewType(final GridViewType viewType) { + if (viewType != this.viewType.get()) { + this.viewType.set(viewType); + ConfigImpl.this.spec.save(); + } + } + @Override public Optional<ResourceLocation> getResourceType() { if (resourceType.get().trim().isBlank()) { From 9406c87ea91c1cbcaf4d6e77e6c790b47a51201d Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 14:45:33 +0200 Subject: [PATCH 09/14] chore: remove resource type help It's noise. --- .../common/grid/screen/ResourceTypeSideButtonWidget.java | 7 ------- .../main/resources/assets/refinedstorage/lang/en_us.json | 1 - 2 files changed, 8 deletions(-) diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ResourceTypeSideButtonWidget.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ResourceTypeSideButtonWidget.java index ec3c078c0..ef800fb44 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ResourceTypeSideButtonWidget.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/ResourceTypeSideButtonWidget.java @@ -4,7 +4,6 @@ import com.refinedmods.refinedstorage.common.grid.AbstractGridContainerMenu; import com.refinedmods.refinedstorage.common.support.widget.AbstractSideButtonWidget; -import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; @@ -14,7 +13,6 @@ class ResourceTypeSideButtonWidget extends AbstractSideButtonWidget { private static final MutableComponent TITLE = createTranslation("gui", "grid.resource_type"); private static final MutableComponent SUBTEXT_ALL = createTranslation("gui", "grid.resource_type.all"); - private static final Component HELP = createTranslation("gui", "grid.resource_type.help"); private static final ResourceLocation ALL = createIdentifier("widget/side_button/resource_type/all"); private final AbstractGridContainerMenu menu; @@ -50,9 +48,4 @@ protected MutableComponent getSubText() { } return resourceType.getTitle(); } - - @Override - protected Component getHelpText() { - return HELP; - } } 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 e5221b341..cd5e879f4 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 @@ -64,7 +64,6 @@ "gui.refinedstorage.grid.synchronization_mode.off.help": "Don't sync the search box text.", "gui.refinedstorage.grid.resource_type": "Resource type", "gui.refinedstorage.grid.resource_type.all": "All", - "gui.refinedstorage.grid.resource_type.help": "Filter specific resource types.", "gui.refinedstorage.grid.craft": "Craft", "gui.refinedstorage.grid.autocraftable": "This resource is autocraftable", "gui.refinedstorage.grid.click_to_autocraft": "Click to autocraft", From 84e840759fe519757d407fd3172d58dc298b1237 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 15:06:22 +0200 Subject: [PATCH 10/14] feat: autocraftable hint now also checks patterns in inventory --- .../PatternGridContainerMenu.java | 4 +- .../ProcessingPatternGridRenderer.java | 4 +- .../grid/AbstractGridContainerMenu.java | 39 ++++++++++- .../grid/AutocraftableResourceHint.java | 16 +++++ .../grid/CraftingGridContainerMenu.java | 4 +- .../grid/screen/AbstractGridScreen.java | 66 +++++++++++-------- .../AutocraftableClientTooltipComponent.java | 8 ++- .../support/AbstractBaseContainerMenu.java | 18 ++++- .../support/PlayerInventoryListener.java | 8 +++ .../common/support/PlayerInventorySlot.java | 40 +++++++++++ .../assets/refinedstorage/lang/en_us.json | 1 + 11 files changed, 169 insertions(+), 39 deletions(-) create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AutocraftableResourceHint.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventoryListener.java create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventorySlot.java 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 45747deb0..9216ba40a 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 @@ -235,7 +235,7 @@ boolean isPatternInOutput(final ItemStack stack) { @Nullable @Override - public ResourceKey getCraftableResource(final Slot slot) { + protected ResourceKey getResourceForAutocraftableHint(final Slot slot) { final boolean isInputItem = slot.container == craftingMatrix || slot.container == stonecutterInput || slot.container == smithingTableMatrix; @@ -246,7 +246,7 @@ public ResourceKey getCraftableResource(final Slot slot) { } else if (slot instanceof ProcessingMatrixResourceSlot processingMatrixSlot) { return processingMatrixSlot.getResource(); } - return super.getCraftableResource(slot); + return super.getResourceForAutocraftableHint(slot); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java index 7ef910d8b..2da20d010 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPatternGridRenderer.java @@ -1,6 +1,7 @@ package com.refinedmods.refinedstorage.common.autocrafting; import com.refinedmods.refinedstorage.common.Platform; +import com.refinedmods.refinedstorage.common.grid.AutocraftableResourceHint; import com.refinedmods.refinedstorage.common.grid.screen.AbstractGridScreen; import com.refinedmods.refinedstorage.common.support.ResourceSlotRendering; import com.refinedmods.refinedstorage.common.support.containermenu.ResourceSlot; @@ -255,7 +256,8 @@ private void renderMatrixSlot(final GuiGraphics graphics, graphics, resourceSlot.x + leftPos, resourceSlot.y + topPos, - false + false, + AutocraftableResourceHint.AUTOCRAFTABLE.getColor() ); } ResourceSlotRendering.render(graphics, resourceSlot, leftPos, topPos); 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 1652c87bb..8599226c3 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java @@ -1,5 +1,8 @@ package com.refinedmods.refinedstorage.common.grid; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; +import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl; import com.refinedmods.refinedstorage.api.grid.operations.GridExtractMode; import com.refinedmods.refinedstorage.api.grid.operations.GridInsertMode; import com.refinedmods.refinedstorage.api.grid.query.GridQueryParserException; @@ -72,6 +75,7 @@ public abstract class AbstractGridContainerMenu extends AbstractResourceContaine protected final Inventory playerInventory; private final GridView view; + private final PatternRepository playerInventoryPatterns = new PatternRepositoryImpl(); @Nullable private Grid grid; @Nullable @@ -247,7 +251,18 @@ public void removed(final Player playerEntity) { @Override public void onScreenReady(final int playerInventoryY) { resetSlots(); - addPlayerInventory(playerInventory, 8, playerInventoryY); + addPlayerInventory(playerInventory, 8, playerInventoryY, (before, after) -> { + final Pattern beforePattern = RefinedStorageApi.INSTANCE.getPattern(before, playerInventory.player.level()) + .orElse(null); + final Pattern afterPattern = RefinedStorageApi.INSTANCE.getPattern(after, playerInventory.player.level()) + .orElse(null); + if (beforePattern != null) { + playerInventoryPatterns.remove(beforePattern); + } + if (afterPattern != null) { + playerInventoryPatterns.add(afterPattern); + } + }); } public GridView getView() { @@ -444,7 +459,27 @@ public void onClear() { } @Nullable - public ResourceKey getCraftableResource(final Slot slot) { + public final AutocraftableResourceHint getAutocraftableResourceHint(final Slot slot) { + final ResourceKey resource = getResourceForAutocraftableHint(slot); + if (resource == null) { + return null; + } + return getAutocraftableResourceHint(resource); + } + + @Nullable + private AutocraftableResourceHint getAutocraftableResourceHint(final ResourceKey resource) { + if (view.isCraftable(resource)) { + return AutocraftableResourceHint.AUTOCRAFTABLE; + } + if (playerInventoryPatterns.getOutputs().contains(resource)) { + return AutocraftableResourceHint.PATTERN_IN_INVENTORY; + } + return null; + } + + @Nullable + protected ResourceKey getResourceForAutocraftableHint(final Slot slot) { return null; } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AutocraftableResourceHint.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AutocraftableResourceHint.java new file mode 100644 index 000000000..8760cce8d --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AutocraftableResourceHint.java @@ -0,0 +1,16 @@ +package com.refinedmods.refinedstorage.common.grid; + +public enum AutocraftableResourceHint { + AUTOCRAFTABLE(0xBF9F7F50), + PATTERN_IN_INVENTORY(0xBFFFD9A8); + + private final int color; + + AutocraftableResourceHint(final int color) { + this.color = color; + } + + public int getColor() { + return color; + } +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java index 452c1f30e..ba95b6e99 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/CraftingGridContainerMenu.java @@ -178,11 +178,11 @@ public void stopFilteringBasedOnCraftingMatrixItems() { @Nullable @Override - public ResourceKey getCraftableResource(final Slot slot) { + protected ResourceKey getResourceForAutocraftableHint(final Slot slot) { if (slot.container == craftingGrid.getCraftingMatrix() || slot.container == craftingGrid.getCraftingResult()) { return ItemResource.ofItemStack(slot.getItem()); } - return super.getCraftableResource(slot); + return super.getResourceForAutocraftableHint(slot); } @Override diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 6e9c855b8..3f4675fe9 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -11,6 +11,7 @@ import com.refinedmods.refinedstorage.common.api.grid.GridScrollMode; import com.refinedmods.refinedstorage.common.api.grid.view.PlatformGridResource; import com.refinedmods.refinedstorage.common.grid.AbstractGridContainerMenu; +import com.refinedmods.refinedstorage.common.grid.AutocraftableResourceHint; import com.refinedmods.refinedstorage.common.grid.NoopGridSynchronizer; import com.refinedmods.refinedstorage.common.grid.view.ItemGridResource; import com.refinedmods.refinedstorage.common.support.ResourceSlotRendering; @@ -243,16 +244,16 @@ private void renderCell(final GuiGraphics graphics, @Override protected List<ClientTooltipComponent> getResourceSlotTooltip(final ResourceKey resource, final ResourceSlot slot) { final List<ClientTooltipComponent> tooltip = super.getResourceSlotTooltip(resource, slot); - final ResourceKey craftableResource = getMenu().getCraftableResource(slot); - if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { - tooltip.add(AutocraftableClientTooltipComponent.autocraftable()); + final AutocraftableResourceHint autocraftableHint = getMenu().getAutocraftableResourceHint(slot); + if (autocraftableHint != null) { + tooltip.add(AutocraftableClientTooltipComponent.autocraftable(autocraftableHint)); } return tooltip; } @Override protected void renderSlot(final GuiGraphics guiGraphics, final Slot slot) { - tryRenderCraftableBackground(guiGraphics, slot); + tryRenderAutocraftableResourceHintBackground(guiGraphics, slot); super.renderSlot(guiGraphics, slot); } @@ -280,13 +281,13 @@ private void renderSlot(final GuiGraphics graphics, } } - private void tryRenderCraftableBackground(final GuiGraphics guiGraphics, final Slot slot) { + private void tryRenderAutocraftableResourceHintBackground(final GuiGraphics guiGraphics, final Slot slot) { if (!slot.isHighlightable() || !slot.isActive()) { return; } - final ResourceKey craftableResource = getMenu().getCraftableResource(slot); - if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { - renderCraftableBackground(guiGraphics, slot.x, slot.y, getMenu().isLargeSlot(slot)); + final AutocraftableResourceHint hint = getMenu().getAutocraftableResourceHint(slot); + if (hint != null) { + renderCraftableBackground(guiGraphics, slot.x, slot.y, getMenu().isLargeSlot(slot), hint.getColor()); } } @@ -295,7 +296,8 @@ private void renderResourceWithAmount(final GuiGraphics graphics, final int slotY, final GridResource resource) { if (resource.isCraftable()) { - renderCraftableBackground(graphics, slotX, slotY, false); + renderCraftableBackground(graphics, slotX, slotY, false, + AutocraftableResourceHint.AUTOCRAFTABLE.getColor()); } if (resource instanceof PlatformGridResource platformResource) { platformResource.render(graphics, slotX, slotY); @@ -306,9 +308,11 @@ private void renderResourceWithAmount(final GuiGraphics graphics, public static void renderCraftableBackground(final GuiGraphics graphics, final int slotX, final int slotY, - final boolean large) { + final boolean large, + final int color) { final int offset = large ? 4 : 0; - graphics.fill(slotX - offset, slotY - offset, slotX + 16 + offset, slotY + 16 + offset, 0xBF9F7F50); + graphics.fill(slotX - offset, slotY - offset, slotX + 16 + offset, slotY + 16 + offset, + color); } private void renderAmount(final GuiGraphics graphics, @@ -356,26 +360,34 @@ protected void renderTooltip(final GuiGraphics graphics, final int x, final int renderOverStorageAreaTooltip(graphics, x, y); return; } - if (getMenu().getCarried().isEmpty() && hoveredSlot != null && hoveredSlot.hasItem()) { - final ResourceKey craftableResource = getMenu().getCraftableResource(hoveredSlot); - if (craftableResource != null && getMenu().getView().isCraftable(craftableResource)) { - final ItemStack item = hoveredSlot.getItem(); - final List<Component> lines = getTooltipFromContainerItem(item); - final List<ClientTooltipComponent> processedLines = Platform.INSTANCE.processTooltipComponents( - item, - graphics, - x, - item.getTooltipImage(), - lines - ); - processedLines.add(AutocraftableClientTooltipComponent.autocraftable()); - Platform.INSTANCE.renderTooltip(graphics, processedLines, x, y); - return; - } + if (getMenu().getCarried().isEmpty() && tryRenderAutocraftableResourceHintTooltip(graphics, x, y)) { + return; } super.renderTooltip(graphics, x, y); } + private boolean tryRenderAutocraftableResourceHintTooltip(final GuiGraphics graphics, final int x, final int y) { + if (hoveredSlot == null || !hoveredSlot.hasItem()) { + return false; + } + final AutocraftableResourceHint hint = getMenu().getAutocraftableResourceHint(hoveredSlot); + if (hint == null) { + return false; + } + final ItemStack stack = hoveredSlot.getItem(); + final List<Component> lines = getTooltipFromContainerItem(stack); + final List<ClientTooltipComponent> processedLines = Platform.INSTANCE.processTooltipComponents( + stack, + graphics, + x, + stack.getTooltipImage(), + lines + ); + processedLines.add(AutocraftableClientTooltipComponent.autocraftable(hint)); + Platform.INSTANCE.renderTooltip(graphics, processedLines, x, y); + return true; + } + private void renderOverStorageAreaTooltip(final GuiGraphics graphics, final int x, final int y) { final PlatformGridResource gridResource = getCurrentGridResource(); if (gridResource != null) { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java index 7a61527d2..edd45007f 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AutocraftableClientTooltipComponent.java @@ -1,5 +1,6 @@ package com.refinedmods.refinedstorage.common.grid.screen; +import com.refinedmods.refinedstorage.common.grid.AutocraftableResourceHint; import com.refinedmods.refinedstorage.common.support.tooltip.SmallText; import net.minecraft.client.gui.Font; @@ -19,6 +20,7 @@ class AutocraftableClientTooltipComponent implements ClientTooltipComponent { private static final int ICON_MARGIN = 4; private static final Component AUTOCRAFTABLE = createTranslation("gui", "grid.autocraftable"); + private static final Component PATTERN_IN_INVENTORY = createTranslation("gui", "grid.pattern_in_inventory"); private static final Component EMPTY = createTranslation("gui", "grid.click_to_autocraft"); private static final Component EXISTING = createTranslation("gui", "grid.ctrl_click_to_autocraft"); @@ -28,8 +30,10 @@ private AutocraftableClientTooltipComponent(final Component text) { this.text = text; } - static AutocraftableClientTooltipComponent autocraftable() { - return new AutocraftableClientTooltipComponent(AUTOCRAFTABLE); + static AutocraftableClientTooltipComponent autocraftable(final AutocraftableResourceHint hint) { + return new AutocraftableClientTooltipComponent(hint == AutocraftableResourceHint.AUTOCRAFTABLE + ? AUTOCRAFTABLE + : PATTERN_IN_INVENTORY); } static AutocraftableClientTooltipComponent empty() { diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseContainerMenu.java index 4251106a8..befcfd50a 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseContainerMenu.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/AbstractBaseContainerMenu.java @@ -63,11 +63,20 @@ protected void resetSlots() { slots.clear(); } - protected void addPlayerInventory(final Inventory inventory, final int inventoryX, final int inventoryY) { + protected final void addPlayerInventory(final Inventory inventory, + final int inventoryX, + final int inventoryY) { + addPlayerInventory(inventory, inventoryX, inventoryY, null); + } + + protected final void addPlayerInventory(final Inventory inventory, + final int inventoryX, + final int inventoryY, + @Nullable final PlayerInventoryListener listener) { int id = 9; for (int y = 0; y < 3; y++) { for (int x = 0; x < 9; x++) { - addSlot(new Slot(inventory, id++, inventoryX + x * 18, inventoryY + y * 18)); + addSlot(new PlayerInventorySlot(inventory, id++, inventoryX + x * 18, inventoryY + y * 18, listener)); } } @@ -77,7 +86,10 @@ protected void addPlayerInventory(final Inventory inventory, final int inventory final int y = inventoryY + 4 + (3 * 18); final boolean disabled = disabledSlot != null && disabledSlot.isDisabledSlot(id); - addSlot(disabled ? new DisabledSlot(inventory, id, x, y) : new Slot(inventory, id, x, y)); + final Slot slot = disabled + ? new DisabledSlot(inventory, id, x, y) + : new PlayerInventorySlot(inventory, id, x, y, listener); + addSlot(slot); id++; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventoryListener.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventoryListener.java new file mode 100644 index 000000000..fd4128367 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventoryListener.java @@ -0,0 +1,8 @@ +package com.refinedmods.refinedstorage.common.support; + +import net.minecraft.world.item.ItemStack; + +@FunctionalInterface +public interface PlayerInventoryListener { + void changed(ItemStack before, ItemStack after); +} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventorySlot.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventorySlot.java new file mode 100644 index 000000000..879090aa0 --- /dev/null +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/support/PlayerInventorySlot.java @@ -0,0 +1,40 @@ +package com.refinedmods.refinedstorage.common.support; + +import javax.annotation.Nullable; + +import net.minecraft.world.Container; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +class PlayerInventorySlot extends Slot { + @Nullable + private final PlayerInventoryListener listener; + + PlayerInventorySlot(final Container container, + final int slot, + final int x, + final int y, + @Nullable final PlayerInventoryListener listener) { + super(container, slot, x, y); + this.listener = listener; + } + + @Override + public void set(final ItemStack stack) { + if (listener != null) { + listener.changed(getItem(), stack); + } + super.set(stack); + } + + @Override + public ItemStack remove(final int amount) { + if (listener != null) { + final ItemStack before = getItem().copy(); + final ItemStack result = super.remove(amount); + listener.changed(before, getItem()); + return result; + } + return super.remove(amount); + } +} 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 cd5e879f4..1db93f305 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 @@ -66,6 +66,7 @@ "gui.refinedstorage.grid.resource_type.all": "All", "gui.refinedstorage.grid.craft": "Craft", "gui.refinedstorage.grid.autocraftable": "This resource is autocraftable", + "gui.refinedstorage.grid.pattern_in_inventory": "This resource has a pattern in your inventory.", "gui.refinedstorage.grid.click_to_autocraft": "Click to autocraft", "gui.refinedstorage.grid.ctrl_click_to_autocraft": "CTRL + click to autocraft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", From 2c1a7571aef5e70fea7dd7d56610ad457b9fdf55 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 15:47:38 +0200 Subject: [PATCH 11/14] refactor: remove zeroed system for grid resources It was necessary because the backing list can never contain zero of a resource, and because the grid resources used to keep a reference to the resource amount in the list. So we needed the zeroed system to properly show "0" in the gui. However, now we just query the backing list for the amount, which can be 0. --- .../grid/view/AbstractPlatformGridResource.java | 12 ------------ .../common/grid/screen/AbstractGridScreen.java | 13 ++++++------- .../api/grid/view/GridResource.java | 4 ---- .../api/grid/view/GridViewImpl.java | 16 +++++++--------- .../api/grid/query/GridQueryParserImplTest.java | 10 ---------- .../api/grid/view/GridResourceImpl.java | 16 ---------------- .../api/grid/view/GridViewImplTest.java | 6 +++--- 7 files changed, 16 insertions(+), 61 deletions(-) diff --git a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java index ff6451526..a1d5a8008 100644 --- a/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java +++ b/refinedstorage-common-api/src/main/java/com/refinedmods/refinedstorage/common/api/grid/view/AbstractPlatformGridResource.java @@ -19,7 +19,6 @@ public abstract class AbstractPlatformGridResource<T extends PlatformResourceKey private final String name; private final Map<GridResourceAttributeKey, Set<String>> attributes; private final boolean craftable; - private boolean zeroed; protected AbstractPlatformGridResource(final T resource, final String name, @@ -51,16 +50,6 @@ public Set<String> getAttribute(final GridResourceAttributeKey key) { return attributes.getOrDefault(key, Collections.emptySet()); } - @Override - public boolean isZeroed() { - return zeroed; - } - - @Override - public void setZeroed(final boolean zeroed) { - this.zeroed = zeroed; - } - @Override public boolean isCraftable() { return craftable; @@ -79,7 +68,6 @@ public String toString() { + ", name='" + name + '\'' + ", attributes=" + attributes + ", craftable=" + craftable - + ", zeroed=" + zeroed + '}'; } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index 3f4675fe9..be1e09e5f 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -53,11 +53,9 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslationKey; -import static java.util.Objects.requireNonNullElse; // TODO: help tooltip to enable focus mode // TODO: help tooltips for the rest of grid?? -// TODO: remove zeroed system public abstract class AbstractGridScreen<T extends AbstractGridContainerMenu> extends AbstractStretchingScreen<T> { protected static final int CLEAR_BUTTON_SIZE = 7; @@ -331,12 +329,13 @@ private void renderAmount(final GuiGraphics graphics, } private int getAmountColor(final GridResource resource, final long amount) { - if (amount == 0 && resource.isCraftable()) { - return requireNonNullElse(ChatFormatting.WHITE.getColor(), 15); - } else if (resource.isZeroed()) { - return requireNonNullElse(ChatFormatting.RED.getColor(), 15); + if (amount == 0) { + if (resource.isCraftable()) { + return 0xFFFFFF; + } + return 0xFF5555; } - return requireNonNullElse(ChatFormatting.WHITE.getColor(), 15); + return 0xFFFFFF; } private String getAmountText(final GridResource resource, diff --git a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java index 50f787073..8000b9bdb 100644 --- a/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java +++ b/refinedstorage-grid-api/src/main/java/com/refinedmods/refinedstorage/api/grid/view/GridResource.java @@ -20,9 +20,5 @@ public interface GridResource { Set<String> getAttribute(GridResourceAttributeKey key); - boolean isZeroed(); - - void setZeroed(boolean zeroed); - boolean isCraftable(); } 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 69ca892ee..66e495708 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 @@ -155,15 +155,14 @@ private void tryAddGridResourceIntoViewList(final GridResource gridResource, public void onChange(final ResourceKey resource, final long amount, @Nullable final TrackedResource trackedResource) { + final boolean wasAvailable = backingList.contains(resource); final ResourceList.OperationResult operationResult = updateBackingList(resource, amount); - updateOrRemoveTrackedResource(resource, trackedResource); - final GridResource gridResource = viewList.index.get(resource); if (gridResource != null) { LOGGER.debug("{} was already found in the view list", resource); - if (gridResource.isZeroed()) { - reinsertZeroedResourceIntoViewList(resource, gridResource); + if (!wasAvailable) { + reinsertIntoViewList(resource, gridResource); } else { handleChangeForExistingResource(resource, operationResult, gridResource); } @@ -190,8 +189,8 @@ private void updateOrRemoveTrackedResource(final ResourceKey resource, } } - private void reinsertZeroedResourceIntoViewList(final ResourceKey resource, final GridResource oldGridResource) { - LOGGER.debug("{} was zeroed, unzeroing", resource); + private void reinsertIntoViewList(final ResourceKey resource, final GridResource oldGridResource) { + LOGGER.debug("{} was removed from backing list, reinserting now into the view list", resource); final GridResource newResource = resourceFactory.apply( resource, craftableResources.contains(resource) @@ -199,7 +198,7 @@ private void reinsertZeroedResourceIntoViewList(final ResourceKey resource, fina viewList.index.put(resource, newResource); final int index = CoreValidations.validateNotNegative( viewList.list.indexOf(oldGridResource), - "Cannot reinsert previously zeroed resource, it was not found" + "Failed to reinsert resource into view list, even though it was still present in the view index" ); viewList.list.set(index, newResource); } @@ -213,8 +212,7 @@ private void handleChangeForExistingResource(final ResourceKey resource, LOGGER.debug("Actually updating {} resource in the view list", resource); updateExistingResourceInViewList(resource, gridResource, noLongerAvailable); } else if (noLongerAvailable) { - LOGGER.debug("{} is no longer available, zeroing", resource); - gridResource.setZeroed(true); + LOGGER.debug("{} is no longer available", resource); } else { LOGGER.debug("{} can't be sorted, preventing sorting is on", resource); } diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java index 4c1d63774..3803ecf02 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/query/GridQueryParserImplTest.java @@ -323,16 +323,6 @@ public Set<String> getAttribute(final GridResourceAttributeKey key) { return attributes.getOrDefault(key, Set.of()); } - @Override - public boolean isZeroed() { - return false; - } - - @Override - public void setZeroed(final boolean zeroed) { - throw new UnsupportedOperationException(); - } - @Override public boolean isCraftable() { return false; diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java index 271b37b4b..71ff063dc 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridResourceImpl.java @@ -12,7 +12,6 @@ public class GridResourceImpl implements GridResource { private final ResourceKey resource; private final Map<GridResourceAttributeKey, Set<String>> attributes; private boolean craftable; - private boolean zeroed; public GridResourceImpl(final ResourceKey resource) { this(resource, false); @@ -27,11 +26,6 @@ public GridResourceImpl(final ResourceKey resource, final boolean craftable) { this.craftable = craftable; } - public GridResourceImpl zeroed() { - setZeroed(true); - return this; - } - public GridResourceImpl craftable() { craftable = true; return this; @@ -57,16 +51,6 @@ public Set<String> getAttribute(final GridResourceAttributeKey key) { return attributes.getOrDefault(key, Collections.emptySet()); } - @Override - public boolean isZeroed() { - return zeroed; - } - - @Override - public void setZeroed(final boolean zeroed) { - this.zeroed = zeroed; - } - @Override public boolean isCraftable() { return craftable; diff --git a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java index bd36dd114..67b253280 100644 --- a/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java +++ b/refinedstorage-grid-api/src/test/java/com/refinedmods/refinedstorage/api/grid/view/GridViewImplTest.java @@ -556,7 +556,7 @@ void shouldNotReorderWhenRemovingExistingResourceCompletelyAndPreventingSorting( assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(D), new GridResourceImpl(A), - new GridResourceImpl(B).zeroed() + new GridResourceImpl(B) ); assertThat(view.copyBackingList().copyState()) .usingRecursiveFieldByFieldElementComparator() @@ -609,7 +609,7 @@ void shouldReuseExistingResourceWhenPreventingSortingAndRemovingExistingResource assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( new GridResourceImpl(D), new GridResourceImpl(A), - new GridResourceImpl(B).zeroed() + new GridResourceImpl(B) ); // Re-insert the item @@ -739,7 +739,7 @@ void shouldNotRemoveCraftableResourceEvenWhenPreventingSorting() { view.onChange(A, -15, null); assertThat(view.getViewList()).usingRecursiveFieldByFieldElementComparator().containsExactly( - new GridResourceImpl(A).zeroed().craftable() + new GridResourceImpl(A).craftable() ); assertThat(view.isCraftable(A)).isTrue(); assertThat(view.getAmount(A)).isZero(); From f4d8167531d1165b57f1671d9a4542ecddb0e661 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 16:05:16 +0200 Subject: [PATCH 12/14] feat: make filter based on recipe items discoverable with help tooltip --- .../common/autocrafting/PatternRendering.java | 6 ++-- .../grid/screen/AbstractGridScreen.java | 2 -- .../grid/screen/CraftingGridScreen.java | 29 +++++++++++++++++++ .../assets/refinedstorage/lang/en_us.json | 1 + .../refinedstorage/neoforge/ConfigImpl.java | 1 - 5 files changed, 32 insertions(+), 7 deletions(-) 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 3a7755bfe..fc8962f16 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 @@ -48,10 +48,8 @@ public static Optional<ItemStack> getOutput(final ItemStack stack) { when processingPattern.getOutputs().size() == 1 && processingPattern.getOutputs().getFirst().resource() instanceof ItemResource itemResource -> itemResource.toItemStack(); - case StonecutterPattern stonecutterPattern - when stonecutterPattern.getOutput() instanceof ItemResource itemResource -> itemResource.toItemStack(); - case SmithingTablePattern smithingTablePattern - when smithingTablePattern.getOutput() instanceof ItemResource itemResource -> itemResource.toItemStack(); + case StonecutterPattern stonecutterPattern -> stonecutterPattern.getOutput().toItemStack(); + case SmithingTablePattern smithingTablePattern -> smithingTablePattern.getOutput().toItemStack(); default -> null; }); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java index be1e09e5f..89ba11179 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/AbstractGridScreen.java @@ -54,8 +54,6 @@ import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslationKey; -// TODO: help tooltip to enable focus mode -// TODO: help tooltips for the rest of grid?? public abstract class AbstractGridScreen<T extends AbstractGridContainerMenu> extends AbstractStretchingScreen<T> { protected static final int CLEAR_BUTTON_SIZE = 7; diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftingGridScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftingGridScreen.java index 0f6bd9878..d2b6a8dc6 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftingGridScreen.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/screen/CraftingGridScreen.java @@ -4,8 +4,10 @@ import com.refinedmods.refinedstorage.common.content.KeyMappings; import com.refinedmods.refinedstorage.common.grid.CraftingGridContainerMenu; import com.refinedmods.refinedstorage.common.grid.CraftingGridMatrixCloseBehavior; +import com.refinedmods.refinedstorage.common.support.tooltip.HelpClientTooltipComponent; import com.refinedmods.refinedstorage.common.support.widget.HoveredImageButton; +import java.util.List; import javax.annotation.Nullable; import net.minecraft.ChatFormatting; @@ -13,12 +15,14 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.components.WidgetSprites; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.ResultContainer; import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier; import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createTranslation; @@ -191,4 +195,29 @@ public void onClose() { protected ResourceLocation getTexture() { return TEXTURE; } + + @Override + protected void renderTooltip(final GuiGraphics graphics, final int x, final int y) { + final boolean hoveredSlotValidForHelp = hoveredSlot != null + && hoveredSlot.container instanceof ResultContainer + && hoveredSlot.hasItem(); + if (getMenu().getCarried().isEmpty() && hoveredSlotValidForHelp && !filteringBasedOnCraftingMatrixItems) { + final ItemStack stack = hoveredSlot.getItem(); + final List<Component> lines = getTooltipFromContainerItem(stack); + final List<ClientTooltipComponent> processedLines = Platform.INSTANCE.processTooltipComponents( + stack, + graphics, + x, + stack.getTooltipImage(), + lines + ); + processedLines.add(HelpClientTooltipComponent.create(createTranslation( + "gui", + "crafting_grid.press_shift_ctrl_to_only_show_items_used_in_crafting" + ))); + Platform.INSTANCE.renderTooltip(graphics, processedLines, x, y); + return; + } + super.renderTooltip(graphics, x, y); + } } 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 1db93f305..f278e5e54 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 @@ -71,6 +71,7 @@ "gui.refinedstorage.grid.ctrl_click_to_autocraft": "CTRL + click to autocraft", "gui.refinedstorage.crafting_grid.move.network": "Move items to network", "gui.refinedstorage.crafting_grid.move.inventory": "Move items to inventory", + "gui.refinedstorage.crafting_grid.press_shift_ctrl_to_only_show_items_used_in_crafting": "Press SHIFT + CTRL to only show items used in the recipe.", "gui.refinedstorage.pattern_grid.create_pattern": "Create pattern", "gui.refinedstorage.pattern_grid.clear": "Clear", "gui.refinedstorage.pattern_grid.fuzzy_mode": "Fuzzy mode", diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java index 88fd8298e..d92758624 100644 --- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java +++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java @@ -1,7 +1,6 @@ package com.refinedmods.refinedstorage.neoforge; import com.refinedmods.refinedstorage.api.grid.view.GridSortingDirection; -import com.refinedmods.refinedstorage.api.grid.view.GridView; import com.refinedmods.refinedstorage.common.Config; import com.refinedmods.refinedstorage.common.content.DefaultEnergyUsage; import com.refinedmods.refinedstorage.common.grid.CraftingGridMatrixCloseBehavior; From 5684bb79d69c0a8f1db3bef9e1e749e2aaf67594 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 16:14:22 +0200 Subject: [PATCH 13/14] docs: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5d204cb8..2b35d7e57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Lock until all outputs are received (new, facilitates easier "blocking mode" without redstone) - Lock until low redstone signal - Lock until high redstone signal +- Resources in the Grid that are autocraftable now display an orange backdrop and tooltip to indicate whether the resource is autocraftable at a glance. +- Slots used in the Pattern Grid for pattern encoding and Crafting Grid crafting matrix slots now display an orange backdrop and tooltip to indicate whether the item is autocraftable at a glance. This checks patterns from your network and from your inventory. +- Added help tooltip for filtering based on recipe items in the Crafting Grid. ### Fixed From 314776e435cadea03e442dbc63d62bd57d70c537 Mon Sep 17 00:00:00 2001 From: raoulvdberge <raoulvdberge@gmail.com> Date: Sun, 1 Sep 2024 17:03:57 +0200 Subject: [PATCH 14/14] chore: fix build problems --- .../api/autocrafting/AbstractPattern.java | 29 ------------------- .../common/autocrafting/CraftingPattern.java | 25 ++++++++++++++-- .../autocrafting/ProcessingPattern.java | 29 ++++++++++++++----- .../autocrafting/SmithingTablePattern.java | 25 ++++++++++++++-- .../autocrafting/StonecutterPattern.java | 25 ++++++++++++++-- .../AbstractFluidGridResourceFactory.java | 12 +++++--- .../view/AbstractItemGridResourceFactory.java | 12 +++++--- .../common/grid/view/FluidGridResource.java | 14 ++------- .../common/grid/view/ItemGridResource.java | 14 ++------- 9 files changed, 110 insertions(+), 75 deletions(-) delete mode 100644 refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java deleted file mode 100644 index 9e9b30761..000000000 --- a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/AbstractPattern.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.refinedmods.refinedstorage.api.autocrafting; - -import java.util.Objects; -import java.util.UUID; - -public abstract class AbstractPattern implements Pattern { - private final UUID id; - - public AbstractPattern(final UUID id) { - this.id = id; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final AbstractPattern that = (AbstractPattern) o; - return Objects.equals(id, that.id); - } - - @Override - public int hashCode() { - return Objects.hashCode(id); - } -} diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java index 8b5cedf74..b4e705e0d 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/CraftingPattern.java @@ -1,15 +1,17 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.UUID; -class CraftingPattern extends AbstractPattern { +class CraftingPattern implements Pattern { + private final UUID id; private final List<List<PlatformResourceKey>> inputs; private final ResourceAmount output; private final List<ResourceAmount> byproducts; @@ -19,7 +21,7 @@ class CraftingPattern extends AbstractPattern { final List<List<PlatformResourceKey>> inputs, final ResourceAmount output, final List<ResourceAmount> byproducts) { - super(id); + this.id = id; this.inputs = inputs; this.output = output; this.outputResources = Set.of(output.resource()); @@ -38,4 +40,21 @@ List<List<PlatformResourceKey>> getInputs() { ResourceAmount getOutput() { return output; } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CraftingPattern that = (CraftingPattern) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java index d658f4fc8..3240d43d8 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/ProcessingPattern.java @@ -1,21 +1,23 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -class ProcessingPattern extends AbstractPattern { +class ProcessingPattern implements Pattern { + private final UUID id; private final List<ResourceAmount> inputs; private final List<ResourceAmount> outputs; private final Set<ResourceKey> outputResources; ProcessingPattern(final UUID id, final List<ResourceAmount> inputs, final List<ResourceAmount> outputs) { - super(id); + this.id = id; this.inputs = inputs; this.outputs = outputs; this.outputResources = outputs.stream().map(ResourceAmount::resource).collect(Collectors.toSet()); @@ -26,11 +28,24 @@ public Set<ResourceKey> getOutputResources() { return outputResources; } - List<ResourceAmount> getInputs() { - return inputs; - } - List<ResourceAmount> getOutputs() { return outputs; } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ProcessingPattern that = (ProcessingPattern) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java index fb9f7daf4..602a187a7 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/SmithingTablePattern.java @@ -1,13 +1,15 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Objects; import java.util.Set; import java.util.UUID; -class SmithingTablePattern extends AbstractPattern { +class SmithingTablePattern implements Pattern { + private final UUID id; private final ItemResource template; private final ItemResource base; private final ItemResource addition; @@ -19,7 +21,7 @@ class SmithingTablePattern extends AbstractPattern { final ItemResource base, final ItemResource addition, final ItemResource output) { - super(id); + this.id = id; this.template = template; this.base = base; this.addition = addition; @@ -47,4 +49,21 @@ ItemResource getAddition() { ItemResource getOutput() { return output; } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final SmithingTablePattern that = (SmithingTablePattern) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java index bb17d7f21..181c81443 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/StonecutterPattern.java @@ -1,19 +1,21 @@ package com.refinedmods.refinedstorage.common.autocrafting; -import com.refinedmods.refinedstorage.api.autocrafting.AbstractPattern; +import com.refinedmods.refinedstorage.api.autocrafting.Pattern; import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Objects; import java.util.Set; import java.util.UUID; -class StonecutterPattern extends AbstractPattern { +class StonecutterPattern implements Pattern { + private final UUID id; private final ItemResource input; private final ItemResource output; private final Set<ResourceKey> outputResources; StonecutterPattern(final UUID id, final ItemResource input, final ItemResource output) { - super(id); + this.id = id; this.input = input; this.output = output; this.outputResources = Set.of(output); @@ -31,4 +33,21 @@ ItemResource getInput() { ItemResource getOutput() { return output; } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final StonecutterPattern that = (StonecutterPattern) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java index 6129d5283..1b0aad936 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractFluidGridResourceFactory.java @@ -3,8 +3,10 @@ import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridResourceFactory; import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.grid.GridResourceAttributeKeys; import com.refinedmods.refinedstorage.common.support.resource.FluidResource; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -27,10 +29,12 @@ public Optional<GridResource> apply(final ResourceKey resource, final boolean cr return Optional.of(new FluidGridResource( fluidResource, name, - modId, - modName, - tags, - tooltip, + Map.of( + GridResourceAttributeKeys.MOD_ID, Set.of(modId), + GridResourceAttributeKeys.MOD_NAME, Set.of(modName), + GridResourceAttributeKeys.TAGS, tags, + GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) + ), craftable )); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java index 4411ac082..dfd58ebf2 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/AbstractItemGridResourceFactory.java @@ -3,8 +3,10 @@ import com.refinedmods.refinedstorage.api.grid.view.GridResource; import com.refinedmods.refinedstorage.api.grid.view.GridResourceFactory; import com.refinedmods.refinedstorage.api.resource.ResourceKey; +import com.refinedmods.refinedstorage.common.api.grid.GridResourceAttributeKeys; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -33,10 +35,12 @@ public Optional<GridResource> apply(final ResourceKey resource, final boolean cr itemResource, itemStack, name, - modId, - modName, - tags, - tooltip, + Map.of( + GridResourceAttributeKeys.MOD_ID, Set.of(modId), + GridResourceAttributeKeys.MOD_NAME, Set.of(modName), + GridResourceAttributeKeys.TAGS, tags, + GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) + ), craftable )); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java index bc9697a5c..0ffecdb6e 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/FluidGridResource.java @@ -1,11 +1,11 @@ package com.refinedmods.refinedstorage.common.grid.view; import com.refinedmods.refinedstorage.api.grid.operations.GridExtractMode; +import com.refinedmods.refinedstorage.api.grid.view.GridResourceAttributeKey; import com.refinedmods.refinedstorage.api.grid.view.GridView; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; import com.refinedmods.refinedstorage.common.Platform; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; -import com.refinedmods.refinedstorage.common.api.grid.GridResourceAttributeKeys; import com.refinedmods.refinedstorage.common.api.grid.GridScrollMode; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridExtractionStrategy; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridScrollingStrategy; @@ -38,17 +38,9 @@ public class FluidGridResource extends AbstractPlatformGridResource<FluidResourc public FluidGridResource(final FluidResource resource, final String name, - final String modId, - final String modName, - final Set<String> tags, - final String tooltip, + final Map<GridResourceAttributeKey, Set<String>> attributes, final boolean craftable) { - super(resource, name, Map.of( - GridResourceAttributeKeys.MOD_ID, Set.of(modId), - GridResourceAttributeKeys.MOD_NAME, Set.of(modName), - GridResourceAttributeKeys.TAGS, tags, - GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) - ), craftable); + super(resource, name, attributes, craftable); this.id = BuiltInRegistries.FLUID.getId(resource.fluid()); this.rendering = RefinedStorageApi.INSTANCE.getResourceRendering(FluidResource.class); } diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java index 2bdf5ae01..0bc1a01d1 100644 --- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java +++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/view/ItemGridResource.java @@ -1,8 +1,8 @@ package com.refinedmods.refinedstorage.common.grid.view; import com.refinedmods.refinedstorage.api.grid.operations.GridExtractMode; +import com.refinedmods.refinedstorage.api.grid.view.GridResourceAttributeKey; import com.refinedmods.refinedstorage.api.grid.view.GridView; -import com.refinedmods.refinedstorage.common.api.grid.GridResourceAttributeKeys; import com.refinedmods.refinedstorage.common.api.grid.GridScrollMode; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridExtractionStrategy; import com.refinedmods.refinedstorage.common.api.grid.strategy.GridScrollingStrategy; @@ -38,17 +38,9 @@ public class ItemGridResource extends AbstractPlatformGridResource<ItemResource> public ItemGridResource(final ItemResource resource, final ItemStack itemStack, final String name, - final String modId, - final String modName, - final Set<String> tags, - final String tooltip, + final Map<GridResourceAttributeKey, Set<String>> attributes, final boolean craftable) { - super(resource, name, Map.of( - GridResourceAttributeKeys.MOD_ID, Set.of(modId), - GridResourceAttributeKeys.MOD_NAME, Set.of(modName), - GridResourceAttributeKeys.TAGS, tags, - GridResourceAttributeKeys.TOOLTIP, Set.of(tooltip) - ), craftable); + super(resource, name, attributes, craftable); this.id = Item.getId(resource.item()); this.itemStack = itemStack; this.itemResource = resource;