diff options
Diffstat (limited to 'runtime-engine/transfer-handlers/src/main/java')
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()); + } +} |
