From 4ec5bd7cf6ce301261211355657c93d04e5d5010 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Sat, 5 Oct 2024 20:13:13 +0200 Subject: [PATCH] feat: autocrafting transfer support --- .github/workflows/build.yml | 2 +- .github/workflows/draft-release.yml | 2 +- .../issue-for-unsupported-version.yml | 2 +- .github/workflows/publish-release.yml | 2 +- .github/workflows/resolved-issue-locking.yml | 2 +- .github/workflows/validate-branch-name.yml | 2 +- .github/workflows/validate-changelog.yml | 2 +- .../workflows/validate-commit-messages.yml | 2 +- CHANGELOG.md | 9 ++ README.md | 1 - gradle.properties | 8 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../emi/common/AbstractEmiRecipeHandler.java | 16 ++ .../common/CraftingGridEmiRecipeHandler.java | 138 +++++++++++++++--- .../common/PatternGridEmiRecipeHandler.java | 83 ++++++++++- .../emi/common/TransferInput.java | 8 + .../emi/common/TransferInputType.java | 7 + .../emi/common/TransferType.java | 13 ++ .../lang/en_us.json | 7 +- .../build.gradle.kts | 7 +- .../src/main/resources/fabric.mod.json | 2 +- .../build.gradle.kts | 7 +- .../META-INF/neoforge.mods.toml | 2 +- 23 files changed, 281 insertions(+), 45 deletions(-) create mode 100644 refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/AbstractEmiRecipeHandler.java create mode 100644 refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInput.java create mode 100644 refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInputType.java create mode 100644 refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferType.java rename refinedstorage-emi-integration-neoforge/src/main/{resources => templates}/META-INF/neoforge.mods.toml (94%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ba2c44..856e83b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ on: types: [ opened, synchronize, reopened ] jobs: build: - uses: refinedmods/refinedarchitect/.github/workflows/build.yml@v0.17.1 + uses: refinedmods/refinedarchitect/.github/workflows/build.yml@v0.19.1 with: mutation-testing: false secrets: inherit diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index e21ed03..c6d98d5 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -17,7 +17,7 @@ on: type: string jobs: draft: - uses: refinedmods/refinedarchitect/.github/workflows/draft-release.yml@v0.17.1 + uses: refinedmods/refinedarchitect/.github/workflows/draft-release.yml@v0.19.1 with: release-type: ${{ inputs.release-type }} version-number-override: ${{ inputs.version-number-override }} diff --git a/.github/workflows/issue-for-unsupported-version.yml b/.github/workflows/issue-for-unsupported-version.yml index f8ce865..002c2ac 100644 --- a/.github/workflows/issue-for-unsupported-version.yml +++ b/.github/workflows/issue-for-unsupported-version.yml @@ -4,4 +4,4 @@ on: types: [ labeled, unlabeled, reopened ] jobs: unsupported-labeler: - uses: refinedmods/refinedarchitect/.github/workflows/issue-for-unsupported-version.yml@v0.17.1 \ No newline at end of file + uses: refinedmods/refinedarchitect/.github/workflows/issue-for-unsupported-version.yml@v0.19.1 \ No newline at end of file diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 673e76e..dd558fb 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -7,7 +7,7 @@ on: - closed jobs: publish-release: - uses: refinedmods/refinedarchitect/.github/workflows/publish-release.yml@v0.17.1 + uses: refinedmods/refinedarchitect/.github/workflows/publish-release.yml@v0.19.1 secrets: inherit with: project-name: 'Refined Storage - EMI Integration' diff --git a/.github/workflows/resolved-issue-locking.yml b/.github/workflows/resolved-issue-locking.yml index 67112b4..f8dbbdf 100644 --- a/.github/workflows/resolved-issue-locking.yml +++ b/.github/workflows/resolved-issue-locking.yml @@ -4,4 +4,4 @@ on: - cron: '0 0 * * *' jobs: lock: - uses: refinedmods/refinedarchitect/.github/workflows/resolved-issue-locking.yml@v0.17.1 \ No newline at end of file + uses: refinedmods/refinedarchitect/.github/workflows/resolved-issue-locking.yml@v0.19.1 \ No newline at end of file diff --git a/.github/workflows/validate-branch-name.yml b/.github/workflows/validate-branch-name.yml index ce5e06e..c1733fb 100644 --- a/.github/workflows/validate-branch-name.yml +++ b/.github/workflows/validate-branch-name.yml @@ -2,4 +2,4 @@ name: Validate branch name on: [ pull_request ] jobs: validate-branch-name: - uses: refinedmods/refinedarchitect/.github/workflows/validate-branch-name.yml@v0.17.1 \ No newline at end of file + uses: refinedmods/refinedarchitect/.github/workflows/validate-branch-name.yml@v0.19.1 \ No newline at end of file diff --git a/.github/workflows/validate-changelog.yml b/.github/workflows/validate-changelog.yml index db04af1..f5fb9ae 100644 --- a/.github/workflows/validate-changelog.yml +++ b/.github/workflows/validate-changelog.yml @@ -4,4 +4,4 @@ on: types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ] jobs: validate-changelog: - uses: refinedmods/refinedarchitect/.github/workflows/validate-changelog.yml@v0.17.1 \ No newline at end of file + uses: refinedmods/refinedarchitect/.github/workflows/validate-changelog.yml@v0.19.1 \ No newline at end of file diff --git a/.github/workflows/validate-commit-messages.yml b/.github/workflows/validate-commit-messages.yml index 043dba2..620b9e8 100644 --- a/.github/workflows/validate-commit-messages.yml +++ b/.github/workflows/validate-commit-messages.yml @@ -2,4 +2,4 @@ name: Validate commit messages on: [ pull_request ] jobs: validate-commit-messages: - uses: refinedmods/refinedarchitect/.github/workflows/validate-commit-messages.yml@v0.17.1 \ No newline at end of file + uses: refinedmods/refinedarchitect/.github/workflows/validate-commit-messages.yml@v0.19.1 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dc42d1..75ae410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- The recipe transfer support in the Pattern Grid and Crafting Grid now indicates whether all or some resources are autocraftable. +- You can now start autocrafting for missing autocraftable items from the Crafting Grid via the recipe transfer. + +### Fixed + +- Support for Refined Storage v2.0.0-milestone.4.8. + ## [0.4.1] - 2024-08-11 ### Fixed diff --git a/README.md b/README.md index 5e66d33..6e0b687 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,6 @@ Adds support for: - [Crowdin](https://crowdin.com/project/refined-storage-emi-integration) - [Discord](https://discordapp.com/invite/VYzsydb) - [Twitter](https://twitter.com/refinedmods) -- [Mastodon](https://anvil.social/@refinedmods) ## Building diff --git a/gradle.properties b/gradle.properties index 89753fc..7b70adc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,9 @@ -refinedarchitectVersion=0.17.1 -refinedstorageVersion=2.0.0-milestone.4.7 +refinedarchitectVersion=0.19.1 +refinedstorageVersion=2.0.0-milestone.4.8 emiVersion=1.1.11+1.21 # Gradle org.gradle.jvmargs=-Xmx1G +org.gradle.configureondemand=true +org.gradle.caching=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.problems=warn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a441313..9355b41 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/AbstractEmiRecipeHandler.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/AbstractEmiRecipeHandler.java new file mode 100644 index 0000000..137b2fe --- /dev/null +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/AbstractEmiRecipeHandler.java @@ -0,0 +1,16 @@ +package com.refinedmods.refinedstorage.emi.common; + +import com.refinedmods.refinedstorage.common.grid.AutocraftableResourceHint; + +import dev.emi.emi.api.recipe.handler.EmiRecipeHandler; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; +import net.minecraft.world.inventory.AbstractContainerMenu; + +abstract class AbstractEmiRecipeHandler implements EmiRecipeHandler { + protected static final int AUTOCRAFTABLE_COLOR = AutocraftableResourceHint.AUTOCRAFTABLE.getColor(); + + protected static ClientTooltipComponent createAutocraftableHint(final Component component) { + return ClientTooltipComponent.create(component.copy().withColor(AUTOCRAFTABLE_COLOR).getVisualOrderText()); + } +} diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/CraftingGridEmiRecipeHandler.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/CraftingGridEmiRecipeHandler.java index db16152..8c56fda 100644 --- a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/CraftingGridEmiRecipeHandler.java +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/CraftingGridEmiRecipeHandler.java @@ -1,18 +1,25 @@ package com.refinedmods.refinedstorage.emi.common; +import com.refinedmods.refinedstorage.api.grid.view.GridView; +import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.list.MutableResourceList; +import com.refinedmods.refinedstorage.api.resource.list.MutableResourceListImpl; import com.refinedmods.refinedstorage.api.resource.list.ResourceList; +import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.grid.CraftingGridContainerMenu; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import com.refinedmods.refinedstorage.common.support.tooltip.HelpClientTooltipComponent; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import com.mojang.blaze3d.systems.RenderSystem; +import dev.emi.emi.EmiPort; import dev.emi.emi.api.recipe.EmiCraftingRecipe; import dev.emi.emi.api.recipe.EmiPlayerInventory; import dev.emi.emi.api.recipe.EmiRecipe; import dev.emi.emi.api.recipe.handler.EmiCraftContext; -import dev.emi.emi.api.recipe.handler.EmiRecipeHandler; import dev.emi.emi.api.stack.EmiIngredient; import dev.emi.emi.api.stack.EmiStack; import dev.emi.emi.api.widget.Bounds; @@ -20,9 +27,19 @@ import dev.emi.emi.api.widget.Widget; import dev.emi.emi.runtime.EmiDrawContext; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; + +import static com.refinedmods.refinedstorage.emi.common.Common.MOD_ID; +import static java.util.Comparator.comparingLong; + +class CraftingGridEmiRecipeHandler extends AbstractEmiRecipeHandler { + private static final Component CTRL_CLICK_TO_AUTOCRAFT = Component.translatable( + "gui.%s.transfer.ctrl_click_to_autocraft".formatted(MOD_ID) + ); -class CraftingGridEmiRecipeHandler implements EmiRecipeHandler { @Override public EmiPlayerInventory getInventory(final AbstractContainerScreen screen) { final ResourceList available = screen.getMenu().getAvailableListForRecipeTransfer(); @@ -42,33 +59,30 @@ public boolean supportsRecipe(final EmiRecipe recipe) { @Override public boolean canCraft(final EmiRecipe recipe, final EmiCraftContext context) { - final ResourceList available = context.getScreenHandler().getAvailableListForRecipeTransfer(); - return !hasMissingItems(recipe.getInputs(), available); - } - - private boolean hasMissingItems(final List inputs, final ResourceList available) { - for (final EmiIngredient input : inputs) { - if (input.isEmpty()) { - continue; - } - if (!isAvailable(available, input)) { - return true; - } - } - return false; + return true; } - private boolean isAvailable(final ResourceList available, final EmiIngredient input) { + private static TransferInput toTransferInput(final GridView view, + final MutableResourceList available, + final EmiIngredient input) { final List possibilities = getItems(input); for (final ItemResource possibility : possibilities) { if (available.remove(possibility, 1).isPresent()) { - return true; + return new TransferInput(TransferInputType.AVAILABLE, null); } } - return false; + final List autocraftingPossibilities = possibilities + .stream() + .filter(view::isAutocraftable) + .sorted(comparingLong(view::getAmount)) + .toList(); + if (!autocraftingPossibilities.isEmpty()) { + return new TransferInput(TransferInputType.AUTOCRAFTABLE, autocraftingPossibilities.getFirst()); + } + return new TransferInput(TransferInputType.MISSING, null); } - private List getItems(final EmiIngredient ingredient) { + private static List getItems(final EmiIngredient ingredient) { return ingredient.getEmiStacks() .stream() .map(EmiStack::getItemStack) @@ -79,9 +93,21 @@ private List getItems(final EmiIngredient ingredient) { @Override public boolean craft(final EmiRecipe recipe, final EmiCraftContext context) { + final MutableResourceList available = context.getScreenHandler().getAvailableListForRecipeTransfer(); + final List transferInputs = recipe.getInputs() + .stream() + .filter(input -> !input.isEmpty()) + .map(input -> toTransferInput(context.getScreenHandler().getView(), available, input)) + .toList(); + final TransferType transferType = getTransferType(transferInputs); + if (transferType.canOpenAutocraftingPreview() && Screen.hasControlDown()) { + final List craftingRequests = createCraftingRequests(transferInputs); + RefinedStorageApi.INSTANCE.openAutocraftingPreview(craftingRequests, context.getScreen()); + return false; + } final List> inputs = recipe.getInputs() .stream() - .map(this::getItems) + .map(CraftingGridEmiRecipeHandler::getItems) .toList(); context.getScreenHandler().transferRecipe(inputs); return true; @@ -94,16 +120,80 @@ public void render(final EmiRecipe recipe, final GuiGraphics draw) { final EmiDrawContext context = EmiDrawContext.wrap(draw); RenderSystem.enableDepthTest(); - final ResourceList available = craftContext.getScreenHandler().getAvailableListForRecipeTransfer(); + final MutableResourceList available = craftContext.getScreenHandler().getAvailableListForRecipeTransfer(); + final GridView view = craftContext.getScreenHandler().getView(); for (final Widget widget : widgets) { if (!(widget instanceof SlotWidget slotWidget)) { continue; } final EmiIngredient stack = slotWidget.getStack(); final Bounds bounds = slotWidget.getBounds(); - if (slotWidget.getRecipe() == null && !stack.isEmpty() && !isAvailable(available, stack)) { - context.fill(bounds.x(), bounds.y(), bounds.width(), bounds.height(), 0x44FF0000); + if (slotWidget.getRecipe() == null && !stack.isEmpty()) { + final TransferInput transferInput = toTransferInput(view, available, stack); + if (transferInput.type() == TransferInputType.MISSING) { + context.fill(bounds.x(), bounds.y(), bounds.width(), bounds.height(), 0x44FF0000); + } else if (transferInput.type() == TransferInputType.AUTOCRAFTABLE) { + context.fill(bounds.x(), bounds.y(), bounds.width(), bounds.height(), AUTOCRAFTABLE_COLOR); + } + } + } + } + + @Override + public List getTooltip(final EmiRecipe recipe, + final EmiCraftContext context) { + final MutableResourceList available = context.getScreenHandler().getAvailableListForRecipeTransfer(); + final List transferInputs = recipe.getInputs() + .stream() + .filter(input -> !input.isEmpty()) + .map(input -> toTransferInput(context.getScreenHandler().getView(), available, input)) + .toList(); + final TransferType transferType = getTransferType(transferInputs); + return calculateTooltip(transferType); + } + + private List calculateTooltip(final TransferType type) { + return switch (type) { + case MISSING -> List.of(ClientTooltipComponent.create(EmiPort.ordered(NOT_ENOUGH_INGREDIENTS))); + case MISSING_BUT_ALL_AUTOCRAFTABLE -> List.of( + createAutocraftableHint( + Component.translatable("gui.%s.transfer.missing_but_all_autocraftable".formatted(MOD_ID)) + ), + HelpClientTooltipComponent.createAlwaysDisplayed(CTRL_CLICK_TO_AUTOCRAFT) + ); + case MISSING_BUT_SOME_AUTOCRAFTABLE -> List.of( + createAutocraftableHint( + Component.translatable("gui.%s.transfer.missing_but_some_autocraftable".formatted(MOD_ID)) + ), + HelpClientTooltipComponent.createAlwaysDisplayed(CTRL_CLICK_TO_AUTOCRAFT) + ); + default -> Collections.emptyList(); + }; + } + + private TransferType getTransferType(final List transferInputs) { + if (transferInputs.stream().allMatch(input -> input.type() == TransferInputType.AVAILABLE)) { + return TransferType.AVAILABLE; + } + final boolean hasMissing = transferInputs.stream().anyMatch(input -> input.type() == TransferInputType.MISSING); + final boolean hasAutocraftable = transferInputs.stream() + .anyMatch(input -> input.type() == TransferInputType.AUTOCRAFTABLE); + if (hasMissing && hasAutocraftable) { + return TransferType.MISSING_BUT_SOME_AUTOCRAFTABLE; + } else if (hasAutocraftable) { + return TransferType.MISSING_BUT_ALL_AUTOCRAFTABLE; + } + return TransferType.MISSING; + } + + private static List createCraftingRequests(final List transferInputs) { + final MutableResourceList requests = MutableResourceListImpl.orderPreserving(); + for (final TransferInput transferInput : transferInputs) { + if (transferInput.type() == TransferInputType.AUTOCRAFTABLE + && transferInput.autocraftableResource() != null) { + requests.add(transferInput.autocraftableResource(), 1); } } + return requests.copyState().stream().toList(); } } diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/PatternGridEmiRecipeHandler.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/PatternGridEmiRecipeHandler.java index 12eb365..bdd2702 100644 --- a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/PatternGridEmiRecipeHandler.java +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/PatternGridEmiRecipeHandler.java @@ -1,13 +1,17 @@ package com.refinedmods.refinedstorage.emi.common; +import com.refinedmods.refinedstorage.api.grid.view.GridView; import com.refinedmods.refinedstorage.api.resource.ResourceAmount; +import com.refinedmods.refinedstorage.api.resource.ResourceKey; import com.refinedmods.refinedstorage.common.api.RefinedStorageApi; import com.refinedmods.refinedstorage.common.autocrafting.PatternGridContainerMenu; import com.refinedmods.refinedstorage.common.support.resource.ItemResource; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import com.mojang.blaze3d.systems.RenderSystem; import dev.emi.emi.api.recipe.EmiPlayerInventory; import dev.emi.emi.api.recipe.EmiRecipe; import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; @@ -15,9 +19,25 @@ import dev.emi.emi.api.recipe.handler.EmiRecipeHandler; import dev.emi.emi.api.stack.EmiIngredient; import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.api.widget.Bounds; +import dev.emi.emi.api.widget.SlotWidget; +import dev.emi.emi.api.widget.Widget; +import dev.emi.emi.runtime.EmiDrawContext; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; + +import static com.refinedmods.refinedstorage.emi.common.Common.MOD_ID; + +class PatternGridEmiRecipeHandler extends AbstractEmiRecipeHandler { + private static final List ALL_AUTOCRAFTABLE_TOOLTIP = List.of( + createAutocraftableHint(Component.translatable("gui.%s.transfer.all_autocraftable".formatted(MOD_ID))) + ); + private static final List SOME_AUTOCRAFTABLE_TOOLTIP = List.of( + createAutocraftableHint(Component.translatable("gui.%s.transfer.some_autocraftable".formatted(MOD_ID))) + ); -class PatternGridEmiRecipeHandler implements EmiRecipeHandler { @Override public EmiPlayerInventory getInventory(final AbstractContainerScreen screen) { return new EmiPlayerInventory(List.of()); @@ -102,21 +122,76 @@ private void transferProcessingRecipe(final EmiRecipe recipe, final EmiCraftContext context) { final List> inputs = recipe.getInputs() .stream() - .map(this::getResources) + .map(PatternGridEmiRecipeHandler::getResourceAmounts) .toList(); final List> outputs = recipe.getOutputs() .stream() - .map(this::getResources) + .map(PatternGridEmiRecipeHandler::getResourceAmounts) .toList(); context.getScreenHandler().transferProcessingRecipe(inputs, outputs); } + @Override + public void render(final EmiRecipe recipe, + final EmiCraftContext craftContext, + final List widgets, + final GuiGraphics draw) { + final EmiDrawContext context = EmiDrawContext.wrap(draw); + RenderSystem.enableDepthTest(); + final GridView view = craftContext.getScreenHandler().getView(); + for (final Widget widget : widgets) { + if (!(widget instanceof SlotWidget slotWidget)) { + continue; + } + final EmiIngredient stack = slotWidget.getStack(); + final Bounds bounds = slotWidget.getBounds(); + if (slotWidget.getRecipe() == null && !stack.isEmpty()) { + final boolean autocraftable = getResourceAmounts(stack) + .stream() + .anyMatch(resourceAmount -> view.isAutocraftable(resourceAmount.resource())); + if (autocraftable) { + context.fill(bounds.x(), bounds.y(), bounds.width(), bounds.height(), AUTOCRAFTABLE_COLOR); + } + } + } + } + + @Override + public List getTooltip(final EmiRecipe recipe, + final EmiCraftContext context) { + final GridView view = context.getScreenHandler().getView(); + final List> inputs = recipe.getInputs() + .stream() + .filter(input -> !input.isEmpty()) + .map(PatternGridEmiRecipeHandler::getResources) + .toList(); + final boolean allAutocraftable = inputs.stream() + .allMatch(possibilities -> possibilities.stream().anyMatch(view::isAutocraftable)); + if (allAutocraftable) { + return ALL_AUTOCRAFTABLE_TOOLTIP; + } + final boolean someAutocraftable = inputs.stream() + .anyMatch(possibilities -> possibilities.stream().anyMatch(view::isAutocraftable)); + if (someAutocraftable) { + return SOME_AUTOCRAFTABLE_TOOLTIP; + } + return Collections.emptyList(); + } + + private static List getResourceAmounts(final EmiIngredient ingredient) { + return ingredient.getEmiStacks() + .stream() + .flatMap(emiStack -> RefinedStorageApi.INSTANCE.getIngredientConverter().convertToResourceAmount(emiStack) + .stream()) + .collect(Collectors.toList()); + } - private List getResources(final EmiIngredient ingredient) { + private static List getResources(final EmiIngredient ingredient) { return ingredient.getEmiStacks() .stream() .flatMap(emiStack -> RefinedStorageApi.INSTANCE.getIngredientConverter().convertToResourceAmount(emiStack) .stream()) + .map(ResourceAmount::resource) .collect(Collectors.toList()); } } diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInput.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInput.java new file mode 100644 index 0000000..33badd1 --- /dev/null +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInput.java @@ -0,0 +1,8 @@ +package com.refinedmods.refinedstorage.emi.common; + +import com.refinedmods.refinedstorage.common.support.resource.ItemResource; + +import javax.annotation.Nullable; + +record TransferInput(TransferInputType type, @Nullable ItemResource autocraftableResource) { +} diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInputType.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInputType.java new file mode 100644 index 0000000..1504726 --- /dev/null +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferInputType.java @@ -0,0 +1,7 @@ +package com.refinedmods.refinedstorage.emi.common; + +enum TransferInputType { + AVAILABLE, + MISSING, + AUTOCRAFTABLE +} diff --git a/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferType.java b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferType.java new file mode 100644 index 0000000..66d3cff --- /dev/null +++ b/refinedstorage-emi-integration-common/src/main/java/com/refinedmods/refinedstorage/emi/common/TransferType.java @@ -0,0 +1,13 @@ +package com.refinedmods.refinedstorage.emi.common; + +enum TransferType { + AVAILABLE, + MISSING, + MISSING_BUT_ALL_AUTOCRAFTABLE, + MISSING_BUT_SOME_AUTOCRAFTABLE; + + boolean canOpenAutocraftingPreview() { + return this == TransferType.MISSING_BUT_ALL_AUTOCRAFTABLE + || this == TransferType.MISSING_BUT_SOME_AUTOCRAFTABLE; + } +} diff --git a/refinedstorage-emi-integration-common/src/main/resources/assets/refinedstorage_emi_integration/lang/en_us.json b/refinedstorage-emi-integration-common/src/main/resources/assets/refinedstorage_emi_integration/lang/en_us.json index f51b90b..c83eced 100644 --- a/refinedstorage-emi-integration-common/src/main/resources/assets/refinedstorage_emi_integration/lang/en_us.json +++ b/refinedstorage-emi-integration-common/src/main/resources/assets/refinedstorage_emi_integration/lang/en_us.json @@ -3,5 +3,10 @@ "gui.refinedstorage_emi_integration.grid.synchronizer.help": "Sync the search box text to the EMI filter.", "gui.refinedstorage_emi_integration.grid.synchronizer.two_way": "EMI two-way", "gui.refinedstorage_emi_integration.grid.synchronizer.two_way.help": "Sync the search box text to the EMI filter, and the EMI filter to the search box text.", - "alias.emi.refinedstorage1_disk_manipulator": "Disk Manipulator" + "alias.emi.refinedstorage1_disk_manipulator": "Disk Manipulator", + "gui.refinedstorage_emi_integration.transfer.missing_but_all_autocraftable": "Missing items, all are autocraftable", + "gui.refinedstorage_emi_integration.transfer.missing_but_some_autocraftable": "Missing items, some are autocraftable", + "gui.refinedstorage_emi_integration.transfer.ctrl_click_to_autocraft": "CTRL + click to autocraft", + "gui.refinedstorage_emi_integration.transfer.all_autocraftable": "All are autocraftable", + "gui.refinedstorage_emi_integration.transfer.some_autocraftable": "Some are autocraftable" } \ No newline at end of file diff --git a/refinedstorage-emi-integration-fabric/build.gradle.kts b/refinedstorage-emi-integration-fabric/build.gradle.kts index 3124366..91d1cae 100644 --- a/refinedstorage-emi-integration-fabric/build.gradle.kts +++ b/refinedstorage-emi-integration-fabric/build.gradle.kts @@ -27,7 +27,6 @@ repositories { refinedarchitect { modId = "refinedstorage_emi_integration" fabric() - compileWithProject(project(":refinedstorage-emi-integration-common")) publishing { maven = true } @@ -40,7 +39,13 @@ base { val refinedstorageVersion: String by project val emiVersion: String by project +val commonJava by configurations.existing +val commonResources by configurations.existing + dependencies { + compileOnly(project(":refinedstorage-emi-integration-common")) + commonJava(project(path = ":refinedstorage-emi-integration-common", configuration = "commonJava")) + commonResources(project(path = ":refinedstorage-emi-integration-common", configuration = "commonResources")) modApi("com.refinedmods.refinedstorage:refinedstorage-fabric:${refinedstorageVersion}") modRuntimeOnly("dev.emi:emi-fabric:${emiVersion}") modCompileOnlyApi("dev.emi:emi-fabric:${emiVersion}") diff --git a/refinedstorage-emi-integration-fabric/src/main/resources/fabric.mod.json b/refinedstorage-emi-integration-fabric/src/main/resources/fabric.mod.json index 6c2f57d..1e41084 100644 --- a/refinedstorage-emi-integration-fabric/src/main/resources/fabric.mod.json +++ b/refinedstorage-emi-integration-fabric/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "fabricloader": ">=0.14.6", "fabric-api": "*", "minecraft": "~1.21", - "refinedstorage": ">=2.0.0-milestone.4.7", + "refinedstorage": ">=2.0.0-milestone.4.8", "emi": ">=1.1.10", "java": ">=17" } diff --git a/refinedstorage-emi-integration-neoforge/build.gradle.kts b/refinedstorage-emi-integration-neoforge/build.gradle.kts index 379e987..10595f1 100644 --- a/refinedstorage-emi-integration-neoforge/build.gradle.kts +++ b/refinedstorage-emi-integration-neoforge/build.gradle.kts @@ -19,7 +19,6 @@ repositories { refinedarchitect { modId = "refinedstorage_emi_integration" neoForge() - compileWithProject(project(":refinedstorage-emi-integration-common")) publishing { maven = true } @@ -32,7 +31,13 @@ base { val refinedstorageVersion: String by project val emiVersion: String by project +val commonJava by configurations.existing +val commonResources by configurations.existing + dependencies { + compileOnly(project(":refinedstorage-emi-integration-common")) + commonJava(project(path = ":refinedstorage-emi-integration-common", configuration = "commonJava")) + commonResources(project(path = ":refinedstorage-emi-integration-common", configuration = "commonResources")) api("com.refinedmods.refinedstorage:refinedstorage-neoforge:${refinedstorageVersion}") runtimeOnly("dev.emi:emi-neoforge:${emiVersion}") compileOnlyApi("dev.emi:emi-neoforge:${emiVersion}") diff --git a/refinedstorage-emi-integration-neoforge/src/main/resources/META-INF/neoforge.mods.toml b/refinedstorage-emi-integration-neoforge/src/main/templates/META-INF/neoforge.mods.toml similarity index 94% rename from refinedstorage-emi-integration-neoforge/src/main/resources/META-INF/neoforge.mods.toml rename to refinedstorage-emi-integration-neoforge/src/main/templates/META-INF/neoforge.mods.toml index 3ec6d7d..e99c0fe 100644 --- a/refinedstorage-emi-integration-neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/refinedstorage-emi-integration-neoforge/src/main/templates/META-INF/neoforge.mods.toml @@ -14,7 +14,7 @@ EMI integration for Refined Storage. [[dependencies.refinedstorage_emi_integration]] modId = "refinedstorage" type = "required" -versionRange = "2.0.0-milestone.4.7" +versionRange = "2.0.0-milestone.4.8" side = "BOTH" [[dependencies.refinedstorage_emi_integration]] modId = "emi"