From eb58e1dabc43dddc61ae9b93efa28b1faf65a7b1 Mon Sep 17 00:00:00 2001 From: slprime <31038811+slprime@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:39:41 +0300 Subject: [PATCH] Improve Recipe Badge (#909) --- .../java/codechicken/nei/PositionedStack.java | 9 ++ .../java/codechicken/nei/recipe/Badge.java | 98 +++++++++++++ .../nei/recipe/NEIRecipeWidget.java | 133 ++++++------------ 3 files changed, 152 insertions(+), 88 deletions(-) create mode 100644 src/main/java/codechicken/nei/recipe/Badge.java diff --git a/src/main/java/codechicken/nei/PositionedStack.java b/src/main/java/codechicken/nei/PositionedStack.java index a4384344..b6a0269a 100644 --- a/src/main/java/codechicken/nei/PositionedStack.java +++ b/src/main/java/codechicken/nei/PositionedStack.java @@ -13,6 +13,7 @@ import net.minecraftforge.oredict.OreDictionary; import codechicken.nei.api.ItemFilter; import codechicken.nei.api.ItemInfo; +import codechicken.nei.recipe.Badge; import codechicken.nei.recipe.GuiRecipe; import codechicken.nei.recipe.StackInfo; @@ -86,6 +87,10 @@ public class PositionedStack { for (ItemStack item : items) if (item.stackSize > i) item.stackSize = i; } + public List getBadges() { + return null; + } + public String getCustomBadge() { return null; } @@ -94,6 +99,10 @@ public class PositionedStack { return this.chance; } + public void setChance(int chance) { + this.chance = chance; + } + public PositionedStack copy() { PositionedStack pStack = new PositionedStack( Arrays.stream(this.items).map(ItemStack::copy).toArray(ItemStack[]::new), diff --git a/src/main/java/codechicken/nei/recipe/Badge.java b/src/main/java/codechicken/nei/recipe/Badge.java new file mode 100644 index 00000000..01711c90 --- /dev/null +++ b/src/main/java/codechicken/nei/recipe/Badge.java @@ -0,0 +1,98 @@ +package codechicken.nei.recipe; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import net.minecraft.util.EnumChatFormatting; + +import codechicken.lib.vec.Rectangle4i; +import codechicken.nei.NEIClientUtils; +import codechicken.nei.NEIClientUtils.Alignment; + +public class Badge { + + protected final String text; + protected final List tooltip; + protected int badgeTextColor = 0xFDD835; + protected boolean shadow = false; + protected Alignment alignment = Alignment.TopLeft; + + public Badge(String text, String... tooltip) { + this.text = text; + this.tooltip = Arrays.stream(tooltip).map(t -> EnumChatFormatting.GRAY + t).collect(Collectors.toList()); + this.badgeTextColor = getHexValue( + NEIClientUtils.getTextColorOrDefault("recipe.badge.color", "0xFFAA00"), + 0xFFAA00); + } + + public String getText() { + return this.text; + } + + public List getTooltip() { + return this.tooltip; + } + + public Badge setColor(int color) { + this.badgeTextColor = color; + return this; + } + + public int getColor() { + return this.badgeTextColor; + } + + public Badge setShadow(boolean shadow) { + this.shadow = shadow; + return this; + } + + public boolean hasShadow() { + return this.shadow; + } + + public Badge setAlignment(Alignment alignment) { + this.alignment = alignment; + return this; + } + + public Alignment getAlignment() { + return this.alignment; + } + + private static int getHexValue(String color, int defaultValue) { + try { + return (int) Long.parseLong(color.replace("0x", ""), 16); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public void draw(Rectangle4i rect) { + NEIClientUtils.drawNEIOverlayText(getText(), rect, 0.5f, getColor(), hasShadow(), getAlignment()); + } + + public static Badge notConsumed() { + return new Badge( + NEIClientUtils.translate("recipe.badge.nc"), + NEIClientUtils.translate("recipe.badge.nc.tooltip")); + } + + public static Badge notConsumedParallel() { + return new Badge( + NEIClientUtils.translate("recipe.badge.ncp"), + NEIClientUtils.translate("recipe.badge.ncp.tooltip")); + } + + public static Badge consumeChance(float chance) { + final String chanceText = NEIClientUtils.formatChance(chance); + return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.consume", chanceText)); + } + + public static Badge outputChance(float chance) { + final String chanceText = NEIClientUtils.formatChance(chance); + return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.output", chanceText)); + } + +} diff --git a/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java b/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java index 504ef06d..47d7a471 100644 --- a/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java +++ b/src/main/java/codechicken/nei/recipe/NEIRecipeWidget.java @@ -15,7 +15,6 @@ import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.common.MinecraftForge; import org.lwjgl.opengl.GL11; @@ -26,7 +25,6 @@ import codechicken.lib.vec.Rectangle4i; import codechicken.nei.FavoriteRecipes; import codechicken.nei.NEIClientConfig; import codechicken.nei.NEIClientUtils; -import codechicken.nei.NEIClientUtils.Alignment; import codechicken.nei.NEIServerUtils; import codechicken.nei.PositionedStack; import codechicken.nei.Widget; @@ -40,81 +38,10 @@ import codechicken.nei.util.NEIMouseUtils; public class NEIRecipeWidget extends Widget { - private static class Badge { - - protected final String text; - protected final String tooltip; - protected int badgeTextColor = 0xFDD835; - - public Badge(String text, String tooltip, int badgeTextColor) { - this.text = text; - this.tooltip = tooltip; - this.badgeTextColor = badgeTextColor; - } - - public Badge(String text, String tooltip) { - this( - text, - tooltip, - getHexValue(NEIClientUtils.getTextColorOrDefault("recipe.badge.color", "0xFFAA00"), 0xFFAA00)); - } - - public String getText() { - return this.text; - } - - public String getTooltip() { - return this.tooltip; - } - - public int getColor() { - return this.badgeTextColor; - } - - private static int getHexValue(String color, int defaultValue) { - try { - return (int) Long.parseLong(color.replace("0x", ""), 16); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public static Badge of(PositionedStack pStack, boolean input) { - final String badge = pStack.getCustomBadge(); - - if (badge != null) { - return badge.isEmpty() ? null : new Badge(badge, ""); - } - - if (input) { - if (StackInfo.getAmount(pStack.item) == 0) { - return new Badge( - NEIClientUtils.translate("recipe.badge.nc"), - NEIClientUtils.translate("recipe.badge.nc.tooltip")); - } else if (pStack.getChance() == 0) { - return new Badge( - NEIClientUtils.translate("recipe.badge.ncp"), - NEIClientUtils.translate("recipe.badge.ncp.tooltip")); - } else if (pStack.getChance() != PositionedStack.CHANCE_FULL) { - final String chanceText = NEIClientUtils - .formatChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL); - return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.consume", chanceText)); - } - } else if (pStack.getChance() != PositionedStack.CHANCE_FULL) { - final String chanceText = NEIClientUtils - .formatChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL); - return new Badge(chanceText, NEIClientUtils.translate("recipe.badge.chance.output", chanceText)); - } - - return null; - } - - } - protected AcceptsFollowingTooltipLineHandler acceptsFollowingTooltipLineHandler; protected final Map favoriteIndexes = new WeakHashMap<>(); protected final Map> permutations = new WeakHashMap<>(); - protected final Map badgeCache = new WeakHashMap<>(); + protected final Map> badgeCache = new WeakHashMap<>(); protected int favoriteRevision = -1; protected boolean update = true; protected int cycleticks = 0; @@ -330,17 +257,46 @@ public class NEIRecipeWidget extends Widget { } } - protected void drawBadge(PositionedStack pStack, boolean input) { - final Badge badge = this.badgeCache.computeIfAbsent(pStack, k -> Badge.of(k, input)); + protected List getBadges(PositionedStack pStack, boolean input) { - if (badge != null && !badge.getText().isEmpty()) { - NEIClientUtils.drawNEIOverlayText( - badge.getText(), - new Rectangle4i(pStack.relx, pStack.rely, 16, 16), - 0.5f, - badge.getColor(), - true, - Alignment.TopLeft); + return this.badgeCache.computeIfAbsent(pStack, k -> { + final List badges = k.getBadges(); + + if (badges == null) { + final String customBadge = k.getCustomBadge(); + + if (customBadge != null) { + return customBadge.isEmpty() ? Collections.emptyList() + : Collections.singletonList(new Badge(customBadge)); + } + + if (input) { + if (StackInfo.getAmount(pStack.item) == 0) { + return Collections.singletonList(Badge.notConsumed()); + } else if (pStack.getChance() == 0) { + return Collections.singletonList(Badge.notConsumedParallel()); + } else if (pStack.getChance() != PositionedStack.CHANCE_FULL) { + return Collections.singletonList( + Badge.consumeChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL)); + } + } else if (pStack.getChance() != PositionedStack.CHANCE_FULL) { + return Collections.singletonList( + Badge.outputChance(pStack.getChance() / (float) PositionedStack.CHANCE_FULL)); + } + + return Collections.emptyList(); + } + + return badges; + }); + + } + + protected void drawBadge(PositionedStack pStack, boolean input) { + final List badges = getBadges(pStack, input); + + for (Badge badge : badges) { + badge.draw(new Rectangle4i(pStack.relx, pStack.rely, 16, 16)); } } @@ -459,11 +415,12 @@ public class NEIRecipeWidget extends Widget { final PositionedStack hovered = getPositionedStackMouseOver(mousex, mousey); if (hovered != null && this.handlerInfo.getShowBadge()) { - final Badge badge = this.badgeCache - .computeIfAbsent(hovered, k -> Badge.of(k, getOutputs().indexOf(k) == -1)); + final List badges = getBadges(hovered, getOutputs().indexOf(hovered) == -1); - if (badge != null && !badge.getTooltip().isEmpty()) { - tooltip.add(EnumChatFormatting.GRAY + badge.getTooltip()); + for (Badge badge : badges) { + if (badge.getTooltip() != null && !badge.getTooltip().isEmpty()) { + tooltip.addAll(badge.getTooltip()); + } } }