aboutsummaryrefslogtreecommitdiff
path: root/runtime-engine/transfer-handlers/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'runtime-engine/transfer-handlers/src/main/java')
-rw-r--r--runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/AutoCraftingEvaluatorImpl.java277
-rw-r--r--runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java68
2 files changed, 345 insertions, 0 deletions
diff --git a/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/AutoCraftingEvaluatorImpl.java b/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/AutoCraftingEvaluatorImpl.java
new file mode 100644
index 000000000..b694eaf91
--- /dev/null
+++ b/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/AutoCraftingEvaluatorImpl.java
@@ -0,0 +1,277 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.transfer;
+
+import me.shedaniel.math.Point;
+import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.api.client.gui.widgets.Tooltip;
+import me.shedaniel.rei.api.client.overlay.ScreenOverlay;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandler;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRenderer;
+import me.shedaniel.rei.api.common.display.Display;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.provider.AutoCraftingEvaluator;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
+import net.minecraft.client.resources.language.I18n;
+import net.minecraft.network.chat.MutableComponent;
+import net.minecraft.network.chat.TextComponent;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.resources.ResourceLocation;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+public class AutoCraftingEvaluatorImpl implements AutoCraftingEvaluator {
+ @Override
+ public Builder builder(Display display) {
+ return new Builder() {
+ private boolean actuallyCraft = false;
+ private boolean stacked = false;
+ @Nullable
+ private Collection<ResourceLocation> ids = display.provideInternalDisplayIds();
+ private boolean buildRenderer = false;
+ private boolean buildTooltipRenderer = false;
+
+ @Override
+ public Builder actuallyCraft() {
+ this.actuallyCraft = true;
+ return this;
+ }
+
+ @Override
+ public Builder stacked() {
+ this.stacked = true;
+ return this;
+ }
+
+ @Override
+ public Builder ids(@Nullable Collection<ResourceLocation> ids) {
+ this.ids = ids;
+ return this;
+ }
+
+ @Override
+ public Builder buildRenderer() {
+ this.buildRenderer = true;
+ return this;
+ }
+
+ @Override
+ public Builder buildTooltipRenderer() {
+ this.buildTooltipRenderer = true;
+ return this;
+ }
+
+ @Override
+ public Result get() {
+ return evaluateAutoCrafting(actuallyCraft, stacked, display, buildRenderer, buildTooltipRenderer, ids);
+ }
+ };
+ }
+
+ public static class AutoCraftingResult implements AutoCraftingEvaluator.Result {
+ public int tint = 0;
+ public boolean successful = false;
+ public TransferHandler successfulHandler;
+ public boolean hasApplicable = false;
+ public TransferHandlerRenderer renderer;
+ public BiConsumer<Point, Consumer<Tooltip>> tooltipRenderer;
+
+ @Override
+ public int getTint() {
+ return tint;
+ }
+
+ @Override
+ public boolean isSuccessful() {
+ return successful;
+ }
+
+ @Override
+ public TransferHandler getSuccessfulHandler() {
+ return successfulHandler;
+ }
+
+ @Override
+ public boolean isApplicable() {
+ return hasApplicable;
+ }
+
+ @Override
+ public TransferHandlerRenderer getRenderer() {
+ return renderer;
+ }
+
+ @Override
+ public BiConsumer<Point, Consumer<Tooltip>> getTooltipRenderer() {
+ return tooltipRenderer;
+ }
+ }
+
+ public static AutoCraftingResult evaluateAutoCrafting(boolean actuallyCrafting, boolean stackedCrafting, Display display,
+ boolean buildRenderer, boolean buildTooltipRenderer,
+ @Nullable Collection<ResourceLocation> ids) {
+ AbstractContainerScreen<?> containerScreen = REIRuntime.getInstance().getPreviousContainerScreen();
+ AutoCraftingResult result = new AutoCraftingResult();
+ final List<Tooltip.Entry> errorTooltip = new ArrayList<>();
+ result.tooltipRenderer = !buildTooltipRenderer ? null : (pos, sink) -> {
+ List<Tooltip.Entry> str = new ArrayList<>(errorTooltip);
+
+ if (ConfigObject.getInstance().isFavoritesEnabled()) {
+ str.add(Tooltip.entry(new TextComponent(" ")));
+ str.add(Tooltip.entry(new TranslatableComponent("text.rei.save.recipes", new TextComponent(ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName().getString().toUpperCase(Locale.ROOT)).withStyle(ChatFormatting.BOLD)).withStyle(ChatFormatting.GRAY)));
+ }
+
+ if (Minecraft.getInstance().options.advancedItemTooltips && ids != null && !ids.isEmpty()) {
+ str.add(Tooltip.entry(new TextComponent(" ")));
+ for (ResourceLocation location : ids) {
+ String t = I18n.get("text.rei.recipe_id", "", location.toString());
+ if (t.startsWith("\n")) {
+ t = t.substring("\n".length());
+ }
+ str.add(Tooltip.entry(new TextComponent(t).withStyle(ChatFormatting.GRAY)));
+ }
+ }
+
+ sink.accept(Tooltip.from(pos, str));
+ };
+
+ if (containerScreen == null) {
+ errorTooltip.add(Tooltip.entry(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED)));
+ return result;
+ }
+
+ List<TransferHandler.Result> errors = new ArrayList<>();
+ TransferHandler.Result successfulResult = null;
+ TransferHandler.Context context = TransferHandler.Context.create(actuallyCrafting, stackedCrafting, containerScreen, display);
+
+ for (TransferHandler transferHandler : TransferHandlerRegistry.getInstance()) {
+ try {
+ TransferHandler.Result transferResult = transferHandler.handle(context);
+
+ if (transferResult.isBlocking() && actuallyCrafting) {
+ if (transferResult.isReturningToScreen()) {
+ Minecraft.getInstance().setScreen(containerScreen);
+ REIRuntime.getInstance().getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay);
+ }
+
+ break;
+ }
+
+ if (transferResult.isApplicable()) {
+ result.hasApplicable = true;
+ result.tint = transferResult.getColor();
+
+ if (buildRenderer) {
+ TransferHandlerRenderer transferHandlerRenderer = transferResult.getRenderer(transferHandler, context);
+ if (transferHandlerRenderer != null) {
+ result.renderer = transferHandlerRenderer;
+ }
+ }
+
+ if (buildTooltipRenderer && transferResult.getTooltipRenderer() != null) {
+ BiConsumer<Point, TransferHandler.Result.TooltipSink> tooltipRenderer = transferResult.getTooltipRenderer();
+ result.tooltipRenderer = (point, tooltipConsumer) -> tooltipRenderer.accept(point, tooltipConsumer::accept);
+ }
+
+ if (transferResult.isSuccessful()) {
+ errors.clear();
+ successfulResult = transferResult;
+ result.successful = true;
+ result.successfulHandler = transferHandler;
+ break;
+ }
+
+ errors.add(transferResult);
+
+ if (transferResult.isBlocking()) {
+ break;
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (!buildTooltipRenderer) return result;
+
+ if (!result.hasApplicable) {
+ errorTooltip.clear();
+ errorTooltip.add(Tooltip.entry(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED)));
+ return result;
+ }
+
+ if (errors.isEmpty()) {
+ errorTooltip.clear();
+ errorTooltip.add(Tooltip.entry(new TranslatableComponent("text.auto_craft.move_items")));
+
+ if (successfulResult != null) {
+ successfulResult.fillTooltip(errorTooltip);
+ }
+ } else {
+ errorTooltip.clear();
+ List<Tooltip.Entry> tooltipsFilled = new ArrayList<>();
+ for (TransferHandler.Result error : errors) {
+ error.fillTooltip(tooltipsFilled);
+ }
+
+ if (errors.size() == 1) {
+ for (Tooltip.Entry tooltipFilled : tooltipsFilled) {
+ if (tooltipFilled.isText()) {
+ MutableComponent colored = tooltipFilled.getAsText().copy().withStyle(ChatFormatting.RED);
+ if (!CollectionUtils.anyMatch(errorTooltip, ss -> ss.isText() && ss.getAsText().getString().equalsIgnoreCase(colored.getString()))) {
+ errorTooltip.add(Tooltip.entry(colored));
+ }
+ } else {
+ errorTooltip.add(tooltipFilled);
+ }
+ }
+ } else {
+ errorTooltip.add(Tooltip.entry(new TranslatableComponent("error.rei.multi.errors").withStyle(ChatFormatting.RED)));
+ for (Tooltip.Entry tooltipFilled : tooltipsFilled) {
+ if (tooltipFilled.isText()) {
+ MutableComponent colored = new TextComponent("- ").withStyle(ChatFormatting.RED)
+ .append(tooltipFilled.getAsText().copy().withStyle(ChatFormatting.RED));
+ if (!CollectionUtils.anyMatch(errorTooltip, ss -> ss.isText() && ss.getAsText().getString().equalsIgnoreCase(colored.getString()))) {
+ errorTooltip.add(Tooltip.entry(colored));
+ }
+ } else {
+ errorTooltip.add(tooltipFilled);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java b/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java
new file mode 100644
index 000000000..e0b9fe05d
--- /dev/null
+++ b/runtime-engine/transfer-handlers/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java
@@ -0,0 +1,68 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.transfer;
+
+import com.google.common.collect.Iterators;
+import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandler;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
+import me.shedaniel.rei.impl.common.InternalLogger;
+import org.jetbrains.annotations.ApiStatus;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+@ApiStatus.Internal
+public class TransferHandlerRegistryImpl implements TransferHandlerRegistry {
+ private final List<TransferHandler> handlers = new ArrayList<>();
+
+ @Override
+ public void acceptPlugin(REIClientPlugin plugin) {
+ plugin.registerTransferHandlers(this);
+ }
+
+ @Override
+ public void startReload() {
+ handlers.clear();
+ }
+
+ @Override
+ public void endReload() {
+ InternalLogger.getInstance().debug("Registered %d transfer handlers", handlers.size());
+ }
+
+ @Override
+ public void register(TransferHandler handler) {
+ handlers.add(handler);
+ handlers.sort(Comparator.reverseOrder());
+ InternalLogger.getInstance().debug("Added transfer handler: %s [%.2f priority]", handler, handler.getPriority());
+ }
+
+ @Override
+ public Iterator<TransferHandler> iterator() {
+ return Iterators.unmodifiableIterator(handlers.iterator());
+ }
+}