diff options
Diffstat (limited to 'runtime/src/main/java')
6 files changed, 162 insertions, 23 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java index 3c3ddd9cf..94ead5360 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java @@ -37,7 +37,6 @@ 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.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; @@ -64,34 +63,34 @@ public class AutoCraftingEvaluator { public static AutoCraftingResult evaluateAutoCrafting(boolean actuallyCrafting, boolean stackedCrafting, Display display, Supplier<Collection<ResourceLocation>> idsSupplier) { AbstractContainerScreen<?> containerScreen = REIRuntime.getInstance().getPreviousContainerScreen(); AutoCraftingResult result = new AutoCraftingResult(); - final List<Component> errorTooltip = new ArrayList<>(); + final List<Tooltip.Entry> errorTooltip = new ArrayList<>(); result.tooltipRenderer = (pos, sink) -> { - List<Component> str = new ArrayList<>(errorTooltip); + List<Tooltip.Entry> str = new ArrayList<>(errorTooltip); if (ConfigObject.getInstance().isFavoritesEnabled()) { - str.add(new TextComponent(" ")); - str.add(new TranslatableComponent("text.rei.save.recipes", new TextComponent(ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName().getString().toUpperCase(Locale.ROOT)).withStyle(ChatFormatting.BOLD)).withStyle(ChatFormatting.GRAY)); + 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 && idsSupplier != null) { Collection<ResourceLocation> locations = idsSupplier.get(); if (!locations.isEmpty()) { - str.add(new TextComponent(" ")); + str.add(Tooltip.entry(new TextComponent(" "))); for (ResourceLocation location : locations) { String t = I18n.get("text.rei.recipe_id", "", location.toString()); if (t.startsWith("\n")) { t = t.substring("\n".length()); } - str.add(new TextComponent(t).withStyle(ChatFormatting.GRAY)); + str.add(Tooltip.entry(new TextComponent(t).withStyle(ChatFormatting.GRAY))); } } } - sink.accept(Tooltip.create(pos, str)); + sink.accept(Tooltip.from(pos, str)); }; if (containerScreen == null) { - errorTooltip.add(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED)); + errorTooltip.add(Tooltip.entry(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED))); return result; } @@ -147,38 +146,46 @@ public class AutoCraftingEvaluator { if (!result.hasApplicable) { errorTooltip.clear(); - errorTooltip.add(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED)); + errorTooltip.add(Tooltip.entry(new TranslatableComponent("error.rei.not.supported.move.items").withStyle(ChatFormatting.RED))); return result; } if (errors.isEmpty()) { errorTooltip.clear(); - errorTooltip.add(new TranslatableComponent("text.auto_craft.move_items")); + errorTooltip.add(Tooltip.entry(new TranslatableComponent("text.auto_craft.move_items"))); if (successfulResult != null) { successfulResult.fillTooltip(errorTooltip); } } else { errorTooltip.clear(); - List<Component> tooltipsFilled = new ArrayList<>(); + List<Tooltip.Entry> tooltipsFilled = new ArrayList<>(); for (TransferHandler.Result error : errors) { error.fillTooltip(tooltipsFilled); } if (errors.size() == 1) { - for (Component tooltipFilled : tooltipsFilled) { - MutableComponent colored = tooltipFilled.copy().withStyle(ChatFormatting.RED); - if (!CollectionUtils.anyMatch(errorTooltip, ss -> ss.getString().equalsIgnoreCase(tooltipFilled.getString()))) { - errorTooltip.add(colored); + 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(new TranslatableComponent("error.rei.multi.errors").withStyle(ChatFormatting.RED)); - for (Component tooltipFilled : tooltipsFilled) { - MutableComponent colored = new TextComponent("- ").withStyle(ChatFormatting.RED) - .append(tooltipFilled.copy().withStyle(ChatFormatting.RED)); - if (!CollectionUtils.anyMatch(errorTooltip, ss -> ss.getString().equalsIgnoreCase(colored.getString()))) { - errorTooltip.add(colored); + 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); } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/MissingStacksTooltip.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/MissingStacksTooltip.java new file mode 100644 index 000000000..1a6868104 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/MissingStacksTooltip.java @@ -0,0 +1,107 @@ +/* + * 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.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.math.Matrix4f; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.SimpleDisplayRenderer; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.util.Mth; +import net.minecraft.world.inventory.tooltip.TooltipComponent; + +import java.util.List; + +public class MissingStacksTooltip implements ClientTooltipComponent, TooltipComponent { + private static final int MAX_WIDTH = 200; + private final List<EntryIngredient> stacks; + + public MissingStacksTooltip(List<EntryIngredient> stacks) { + this.stacks = SimpleDisplayRenderer.simplify(stacks); + } + + @Override + public int getHeight() { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int height = Math.min(6, Mth.ceil(stacks.size() / (float) w)) * entrySize + 2; + height += 12; + return height; + } + + @Override + public int getWidth(Font font) { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int size = stacks.size(); + int width = Math.min(size, w) * entrySize; + width = Math.max(width, font.width(new TranslatableComponent("text.rei.missing"))); + return width; + } + + @Override + public void renderImage(Font font, int x, int y, PoseStack poses, ItemRenderer renderer, int z) { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int i = 0; + poses.pushPose(); + poses.translate(0, 0, z + 50); + for (EntryIngredient entry : stacks) { + int x1 = x + (i % w) * entrySize; + int y1 = y + 13 + (i / w) * entrySize; + i++; + if (i / w > 5) { + MultiBufferSource.BufferSource source = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + Component text = new TextComponent("+" + (stacks.size() - w * 6 + 1)).withStyle(ChatFormatting.GRAY); + font.drawInBatch(text, x1 + entrySize / 2 - font.width(text) / 2, y1 + entrySize / 2 - 1, -1, true, poses.last().pose(), source, false, 0, 15728880); + source.endBatch(); + break; + } else { + EntryStack<?> stack; + if (entry.isEmpty()) stack = EntryStack.empty(); + else if (entry.size() == 1) stack = entry.get(0); + else stack = entry.get(Mth.floor((System.currentTimeMillis() / 1000 % (double) entry.size()))); + stack.render(poses, new Rectangle(x1, y1, entrySize, entrySize), -1000, -1000, 0); + } + } + poses.popPose(); + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f pose, MultiBufferSource.BufferSource buffers) { + font.drawInBatch(new TranslatableComponent("text.rei.missing").withStyle(ChatFormatting.GRAY), + x, y + 2, -1, true, pose, buffers, false, 0, 15728880); + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java index 20ec402c7..43b20634b 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/transfer/TransferHandlerRegistryImpl.java @@ -27,12 +27,16 @@ 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.api.common.entry.EntryIngredient; +import me.shedaniel.rei.impl.ClientInternals; +import net.minecraft.world.inventory.tooltip.TooltipComponent; import org.jetbrains.annotations.ApiStatus; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.function.Function; @ApiStatus.Internal public class TransferHandlerRegistryImpl implements TransferHandlerRegistry { @@ -58,4 +62,8 @@ public class TransferHandlerRegistryImpl implements TransferHandlerRegistry { public Iterator<TransferHandler> iterator() { return Iterators.unmodifiableIterator(handlers.iterator()); } + + static { + ClientInternals.attachInstance((Function<List<EntryIngredient>, TooltipComponent>) MissingStacksTooltip::new, "missingTooltip"); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java b/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java index e428812e3..3eb159506 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java @@ -41,6 +41,8 @@ import me.shedaniel.rei.api.common.transfer.info.MenuInfoContext; import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry; import me.shedaniel.rei.api.common.transfer.info.MenuTransferException; import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; @@ -51,8 +53,10 @@ import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; import java.util.ArrayList; +import java.util.Collection; import java.util.List; @Environment(EnvType.CLIENT) @@ -92,7 +96,8 @@ public class DefaultCategoryHandler implements TransferHandler { .renderer((matrices, mouseX, mouseY, delta, widgets, bounds, d) -> { menuInfo.renderMissingInput(menuInfoContext, oldInputs, missingIndices, matrices, mouseX, mouseY, delta, widgets, bounds); menuInfo.renderMissingInput(menuInfoContext, input, missing, missingIndicesSet, matrices, mouseX, mouseY, delta, widgets, bounds); - }); + }) + .tooltipMissing(CollectionUtils.map(missing, ingredient -> EntryIngredients.ofItemStacks(ingredient.get()))); } if (!ClientHelper.getInstance().canUseMovePackets()) { return Result.createFailed(new TranslatableComponent("error.rei.not.on.server")); diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java index 7646fa1e8..bf76ab9ad 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java @@ -153,6 +153,12 @@ public class FluidEntryDefinition implements EntryDefinition<FluidStack>, EntryS return new ItemStack(bucket); } + @Nullable + @Override + public FluidStack add(FluidStack o1, FluidStack o2) { + return o1.copyWithAmount(o1.getAmount() + o2.getAmount()); + } + @Override public long hash(EntryStack<FluidStack> entry, FluidStack value, ComparisonContext context) { int code = 1; diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java index 9d8418e27..0777a6772 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java @@ -138,6 +138,12 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer return value.copy(); } + @Nullable + @Override + public ItemStack add(ItemStack o1, ItemStack o2) { + return ItemStackHooks.copyWithCount(o1, o1.getCount() + o2.getCount()); + } + @Override public long hash(EntryStack<ItemStack> entry, ItemStack value, ComparisonContext context) { int code = 1; |
