Skip to content

Commit

Permalink
feat: autocrafting transfer support
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulvdberge committed Oct 12, 2024
1 parent dadfbb6 commit 8be7546
Show file tree
Hide file tree
Showing 32 changed files with 615 additions and 218 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/issue-for-unsupported-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
uses: refinedmods/refinedarchitect/.github/workflows/issue-for-unsupported-version.yml@v0.19.1
2 changes: 1 addition & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 - REI Integration'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/resolved-issue-locking.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ on:
- cron: '0 0 * * *'
jobs:
lock:
uses: refinedmods/refinedarchitect/.github/workflows/resolved-issue-locking.yml@v0.17.1
uses: refinedmods/refinedarchitect/.github/workflows/resolved-issue-locking.yml@v0.19.1
2 changes: 1 addition & 1 deletion .github/workflows/validate-branch-name.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
uses: refinedmods/refinedarchitect/.github/workflows/validate-branch-name.yml@v0.19.1
2 changes: 1 addition & 1 deletion .github/workflows/validate-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
uses: refinedmods/refinedarchitect/.github/workflows/validate-changelog.yml@v0.19.1
2 changes: 1 addition & 1 deletion .github/workflows/validate-commit-messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
uses: refinedmods/refinedarchitect/.github/workflows/validate-commit-messages.yml@v0.19.1
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.3.1] - 2024-08-11

### Fixed
Expand Down
8 changes: 6 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
refinedarchitectVersion=0.17.1
refinedstorageVersion=2.0.0-milestone.4.7
refinedarchitectVersion=0.19.1
refinedstorageVersion=2.0.0-milestone.4.8
# https://linkie.shedaniel.dev/dependencies?loader=neoforge&version=1.21
# https://linkie.shedaniel.dev/dependencies?loader=fabric&version=1.21
architecturyVersion=13.0.3
clothConfigVersion=15.0.127
reiVersion=16.0.729
# Gradle
org.gradle.jvmargs=-Xmx1G
org.gradle.configureondemand=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
"gui.refinedstorage_rei_integration.grid.synchronizer.help": "Sync the search box text to the REI filter.",
"gui.refinedstorage_rei_integration.grid.synchronizer.two_way": "REI two-way",
"gui.refinedstorage_rei_integration.grid.synchronizer.two_way.help": "Sync the search box text to the REI filter, and the REI filter to the search box text.",
"block.refinedstorage_rei_integration.controller.fully_charged": "Fully charged Controllers"
"block.refinedstorage_rei_integration.controller.fully_charged": "Fully charged Controllers",
"gui.refinedstorage_rei_integration.transfer.missing": "Missing items",
"gui.refinedstorage_rei_integration.transfer.missing_but_all_autocraftable": "Missing items, all are autocraftable",
"gui.refinedstorage_rei_integration.transfer.missing_but_some_autocraftable": "Missing items, some are autocraftable",
"gui.refinedstorage_rei_integration.transfer.ctrl_click_to_autocraft": "CTRL + click to autocraft",
"gui.refinedstorage_rei_integration.transfer.all_autocraftable": "All are autocraftable",
"gui.refinedstorage_rei_integration.transfer.some_autocraftable": "Some are autocraftable"
}
7 changes: 6 additions & 1 deletion refinedstorage-rei-integration-fabric/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ repositories {
refinedarchitect {
modId = "refinedstorage_rei_integration"
fabric()
compileWithProject(project(":refinedstorage-rei-integration-common"))
publishing {
maven = true
}
Expand All @@ -38,7 +37,13 @@ val architecturyVersion: String by project
val clothConfigVersion: String by project
val reiVersion: String by project

val commonJava by configurations.existing
val commonResources by configurations.existing

dependencies {
compileOnly(project(":refinedstorage-rei-integration-common"))
commonJava(project(path = ":refinedstorage-rei-integration-common", configuration = "commonJava"))
commonResources(project(path = ":refinedstorage-rei-integration-common", configuration = "commonResources"))
modApi("com.refinedmods.refinedstorage:refinedstorage-fabric:${refinedstorageVersion}")
modApi("dev.architectury:architectury-fabric:${architecturyVersion}")
modApi("me.shedaniel.cloth:cloth-config-fabric:${clothConfigVersion}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.refinedmods.refinedstorage.rei.fabric;

import com.refinedmods.refinedstorage.common.grid.AutocraftableResourceHint;

import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.gui.widgets.Slot;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandler;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;

abstract class AbstractTransferHandler implements TransferHandler {
protected static final int AUTOCRAFTABLE_COLOR = AutocraftableResourceHint.AUTOCRAFTABLE.getColor();

protected static MutableComponent createAutocraftableHint(final Component component) {
return component.copy().withColor(AUTOCRAFTABLE_COLOR);
}

protected static void renderSlotHighlight(final GuiGraphics graphics, final Slot slot, final int color) {
final PoseStack poseStack = graphics.pose();
poseStack.pushPose();
poseStack.translate(0, 0, 50);
final Rectangle innerBounds = slot.getInnerBounds();
graphics.fill(
innerBounds.x,
innerBounds.y,
innerBounds.getMaxX(),
innerBounds.getMaxY(),
color
);
poseStack.popPose();
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
package com.refinedmods.refinedstorage.rei.fabric;

import com.refinedmods.refinedstorage.api.resource.list.ResourceList;
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.common.api.RefinedStorageApi;
import com.refinedmods.refinedstorage.common.grid.CraftingGridContainerMenu;
import com.refinedmods.refinedstorage.common.support.resource.ItemResource;

import java.awt.Color;
import java.util.List;
import java.util.stream.Collectors;

import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.gui.widgets.Slot;
import me.shedaniel.rei.api.client.gui.widgets.Widget;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandler;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRenderer;
import me.shedaniel.rei.api.common.entry.EntryIngredient;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.plugin.common.BuiltinPlugin;
import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCraftingDisplay;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.world.item.ItemStack;

class CraftingGridTransferHandler implements TransferHandler {
import static com.refinedmods.refinedstorage.rei.common.Common.MOD_ID;
import static java.util.Comparator.comparingLong;

class CraftingGridTransferHandler extends AbstractTransferHandler {
private static final Color MISSING_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.4f);
private static final Component MISSING = Component.translatable("gui.%s.transfer.missing".formatted(MOD_ID))
.withStyle(ChatFormatting.RED);
private static final Component CTRL_CLICK_TO_AUTOCRAFT = Component
.translatable("gui.%s.transfer.ctrl_click_to_autocraft".formatted(MOD_ID))
.withStyle(Style.EMPTY.withItalic(true).withColor(ChatFormatting.WHITE));
private static final Component MISSING_BUT_ALL_AUTOCRAFTABLE = createAutocraftableHint(
Component.translatable("gui.%s.transfer.missing_but_all_autocraftable".formatted(MOD_ID))
).append("\n").append(CTRL_CLICK_TO_AUTOCRAFT);
private static final Component MISSING_BUT_AUTOCRAFTABLE = createAutocraftableHint(
Component.translatable("gui.%s.transfer.missing_but_some_autocraftable".formatted(MOD_ID))
).append("\n").append(CTRL_CLICK_TO_AUTOCRAFT);

@Override

Check failure on line 46 in refinedstorage-rei-integration-fabric/src/main/java/com/refinedmods/refinedstorage/rei/fabric/CraftingGridTransferHandler.java

View workflow job for this annotation

GitHub Actions / build / build

Return count is 5 (max allowed for non-void methods/lambdas is 4).
public Result handle(final Context context) {
Expand All @@ -34,51 +51,87 @@ public Result handle(final Context context) {
return Result.createNotApplicable();
}
final List<EntryIngredient> ingredients = defaultCraftingDisplay.getOrganisedInputEntries(3, 3);
final MutableResourceList available = containerMenu.getAvailableListForRecipeTransfer();
final GridView view = containerMenu.getView();
final TransferInputs transferInputs = getTransferInputs(view, ingredients, available);
final TransferType type = transferInputs.getType();
if (context.isActuallyCrafting()) {
doTransfer(ingredients, containerMenu);
if (type.canOpenAutocraftingPreview() && Screen.hasControlDown()) {
final List<ResourceAmount> craftingRequests = transferInputs.createCraftingRequests();
RefinedStorageApi.INSTANCE.openAutocraftingPreview(craftingRequests, context.getContainerScreen());
return Result.createSuccessful().blocksFurtherHandling(false);
} else {
doTransfer(ingredients, containerMenu);
}
return Result.createSuccessful().blocksFurtherHandling();
}
final ResourceList available = containerMenu.getAvailableListForRecipeTransfer();
final MissingIngredients missingIngredients = findMissingIngredients(ingredients, available);
if (missingIngredients.isEmpty()) {
if (type == TransferType.AVAILABLE) {
return Result.createSuccessful().blocksFurtherHandling();
}
return Result.createSuccessful()
.color(MISSING_COLOR.getRGB())
.tooltipMissing(missingIngredients.getIngredients())
.renderer(createMissingItemsRenderer(missingIngredients))
.color(getColor(type))
.tooltip(getTooltip(type))
.renderer(createTransferInputsRenderer(transferInputs))
.blocksFurtherHandling();
}

private static int getColor(final TransferType type) {
return switch (type) {
case MISSING -> MISSING_COLOR.getRGB();
case MISSING_BUT_ALL_AUTOCRAFTABLE, MISSING_BUT_SOME_AUTOCRAFTABLE -> AUTOCRAFTABLE_COLOR;
default -> 0;
};
}

private static Component getTooltip(final TransferType type) {
return switch (type) {
case MISSING -> MISSING;
case MISSING_BUT_ALL_AUTOCRAFTABLE -> MISSING_BUT_ALL_AUTOCRAFTABLE;
case MISSING_BUT_SOME_AUTOCRAFTABLE -> MISSING_BUT_AUTOCRAFTABLE;
default -> Component.empty();
};
}

private void doTransfer(final List<EntryIngredient> ingredients, final CraftingGridContainerMenu containerMenu) {
final List<List<ItemResource>> inputs = getInputs(ingredients);
containerMenu.transferRecipe(inputs);
}

private MissingIngredients findMissingIngredients(final List<EntryIngredient> ingredients,
final ResourceList available) {
final MissingIngredients missingIngredients = new MissingIngredients();
private TransferInputs getTransferInputs(final GridView view,
final List<EntryIngredient> ingredients,
final MutableResourceList available) {
final TransferInputs transferInputs = new TransferInputs();
for (int i = 0; i < ingredients.size(); ++i) {
final EntryIngredient ingredient = ingredients.get(i);
if (ingredient.isEmpty()) {
continue;
}
if (!isAvailable(available, ingredient)) {
missingIngredients.addIngredient(ingredient, i);
}
final TransferInput transferInput = toTransferInput(view, available, ingredient);
transferInputs.addInput(i, transferInput);
}
return missingIngredients;
return transferInputs;
}

private boolean isAvailable(final ResourceList available, final EntryIngredient ingredient) {
private TransferInput toTransferInput(final GridView view,
final MutableResourceList available,
final EntryIngredient ingredient) {
final List<ItemStack> possibilities = convertIngredientToItemStacks(ingredient);
for (final ItemStack possibility : possibilities) {
final ItemResource possibilityResource = ItemResource.ofItemStack(possibility);
if (available.remove(possibilityResource, 1).isPresent()) {
return true;
return new TransferInput(ingredient, TransferInputType.AVAILABLE, null);
}
}
return false;
final List<ItemResource> autocraftingPossibilities = possibilities
.stream()
.map(ItemResource::ofItemStack)
.filter(view::isAutocraftable)
.sorted(comparingLong(view::getAmount))
.toList();
if (!autocraftingPossibilities.isEmpty()) {
return new TransferInput(ingredient, TransferInputType.AUTOCRAFTABLE, autocraftingPossibilities.getFirst());
}
return new TransferInput(ingredient, TransferInputType.MISSING, null);
}

private List<List<ItemResource>> getInputs(final List<EntryIngredient> ingredients) {
Expand All @@ -96,31 +149,22 @@ private List<ItemStack> convertIngredientToItemStacks(final EntryIngredient ingr
);
}

private TransferHandlerRenderer createMissingItemsRenderer(final MissingIngredients missingIngredients) {
private TransferHandlerRenderer createTransferInputsRenderer(final TransferInputs transferInputs) {
return (graphics, mouseX, mouseY, delta, widgets, bounds, display) -> {
int index = 0;
for (final Widget widget : widgets) {
if (widget instanceof Slot slot
&& slot.getNoticeMark() == Slot.INPUT
&& missingIngredients.isMissing(index++)) {
renderMissingItemOverlay(graphics, slot);
if (widget instanceof Slot slot && slot.getNoticeMark() == Slot.INPUT) {
final TransferInput input = transferInputs.getInput(index++);
if (input == null) {
continue;
}
if (input.type() == TransferInputType.MISSING) {
renderSlotHighlight(graphics, slot, MISSING_COLOR.getRGB());
} else if (input.type() == TransferInputType.AUTOCRAFTABLE) {
renderSlotHighlight(graphics, slot, AUTOCRAFTABLE_COLOR);
}
}
}
};
}

private void renderMissingItemOverlay(final GuiGraphics graphics, final Slot slot) {
final PoseStack poseStack = graphics.pose();
poseStack.pushPose();
poseStack.translate(0, 0, 400);
final Rectangle innerBounds = slot.getInnerBounds();
graphics.fill(
innerBounds.x,
innerBounds.y,
innerBounds.getMaxX(),
innerBounds.getMaxY(),
MISSING_COLOR.getRGB()
);
poseStack.popPose();
}
}
Loading

0 comments on commit 8be7546

Please sign in to comment.