1.0.0
This commit is contained in:
@@ -11,7 +11,7 @@ loom_version=1.14-SNAPSHOT
|
||||
# Mod metadata
|
||||
mod.id=iconsenhanced
|
||||
mod.name=Icons Enhanced
|
||||
mod.version=0.1.0
|
||||
mod.version=1.0.0
|
||||
mod.group=dev.dekin
|
||||
mod.description=Client-only suite of enchantment and UI improvements.
|
||||
mod.license=Apache-2.0
|
||||
|
||||
@@ -4,6 +4,8 @@ import dev.dekin.iconsenhanced.common.BorderColorLogic;
|
||||
import dev.dekin.iconsenhanced.common.ConfigManager;
|
||||
import dev.dekin.iconsenhanced.common.IconsEnhancedConfig;
|
||||
import dev.dekin.iconsenhanced.mixin.AbstractContainerScreenAccessor;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
@@ -30,6 +32,9 @@ public final class BorderRenderer {
|
||||
}
|
||||
|
||||
int thickness = clamp(config.borders.thickness, 1, 3);
|
||||
boolean redrawItems = config.tooltips.enabled && config.tooltips.showIcons;
|
||||
Minecraft client = redrawItems ? Minecraft.getInstance() : null;
|
||||
Font font = redrawItems ? client.font : null;
|
||||
AbstractContainerScreenAccessor accessor = (AbstractContainerScreenAccessor) handled;
|
||||
int left = accessor.iconsenhanced$getLeftPos();
|
||||
int top = accessor.iconsenhanced$getTopPos();
|
||||
@@ -39,21 +44,33 @@ public final class BorderRenderer {
|
||||
if (stack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
int slotX = left + slot.x;
|
||||
int slotY = top + slot.y;
|
||||
int color = COLOR_LOGIC.resolve(stack);
|
||||
drawBorder(graphics, left + slot.x, top + slot.y, thickness, color);
|
||||
if ((color >>> 24) == 0) {
|
||||
continue;
|
||||
}
|
||||
drawBorder(graphics, slotX, slotY, thickness, color);
|
||||
if (redrawItems) {
|
||||
graphics.renderItem(stack, slotX, slotY);
|
||||
graphics.renderItemDecorations(font, stack, slotX, slotY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawBorder(GuiGraphics graphics, int x, int y, int thickness, int color) {
|
||||
int outerX = x - thickness;
|
||||
int outerY = y - thickness;
|
||||
int outerSize = 16 + thickness * 2;
|
||||
int outerX2 = outerX + outerSize;
|
||||
int outerY2 = outerY + outerSize;
|
||||
graphics.fill(outerX, outerY, outerX2, outerY + thickness, color);
|
||||
graphics.fill(outerX, outerY2 - thickness, outerX2, outerY2, color);
|
||||
graphics.fill(outerX, outerY, outerX + thickness, outerY2, color);
|
||||
graphics.fill(outerX2 - thickness, outerY, outerX2, outerY2, color);
|
||||
int left = x;
|
||||
int top = y;
|
||||
int right = x + 16;
|
||||
int bottom = y + 16;
|
||||
int innerLeft = left + 1;
|
||||
int innerRight = right - 1;
|
||||
int innerTop = top + 1;
|
||||
int innerBottom = bottom - 1;
|
||||
graphics.fill(innerLeft, top, innerRight, top + thickness, color);
|
||||
graphics.fill(innerLeft, bottom - thickness, innerRight, bottom, color);
|
||||
graphics.fill(left, innerTop, left + thickness, innerBottom, color);
|
||||
graphics.fill(right - thickness, innerTop, right, innerBottom, color);
|
||||
}
|
||||
|
||||
private static int clamp(int value, int min, int max) {
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
package dev.dekin.iconsenhanced.client;
|
||||
|
||||
import dev.dekin.iconsenhanced.common.IconAtlas;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
//? if >=1.21.6 {
|
||||
import net.minecraft.client.renderer.RenderPipelines;
|
||||
//?}
|
||||
//? if <1.21.6 {
|
||||
/*import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import org.joml.Matrix4f;
|
||||
*///?}
|
||||
|
||||
public final class DurabilityTooltipComponent implements ClientTooltipComponent {
|
||||
private static final int TEXT_PADDING = 4;
|
||||
private static final int DETAIL_COLOR = 0xFFAAAAAA;
|
||||
private static final int TEXT_COLOR = 0xFFFFFFFF;
|
||||
private static final float DETAIL_SCALE = 0.85f;
|
||||
private static final int ICON_Y_OFFSET = -1;
|
||||
//? if <1.21.6 {
|
||||
/*private static final int FULL_BRIGHT = 0xF000F0;
|
||||
*///?}
|
||||
|
||||
private final int iconSize;
|
||||
private final int current;
|
||||
private final int max;
|
||||
private final int percent;
|
||||
private final int percentColor;
|
||||
private final Component label;
|
||||
private final String percentText;
|
||||
private final String detailText;
|
||||
|
||||
public DurabilityTooltipComponent(DurabilityTooltipData data) {
|
||||
this.iconSize = Math.max(8, data.iconSize());
|
||||
this.current = data.current();
|
||||
this.max = data.max();
|
||||
this.percent = data.percent();
|
||||
this.percentColor = data.percentColor();
|
||||
this.label = data.label();
|
||||
this.percentText = " " + percent + "%";
|
||||
this.detailText = " (" + current + "/" + max + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(Font font) {
|
||||
int textStart = iconSize + TEXT_PADDING;
|
||||
int labelWidth = font.width(label);
|
||||
int percentWidth = font.width(percentText);
|
||||
int detailWidth = (int) Math.ceil(font.width(detailText) * DETAIL_SCALE);
|
||||
return textStart + labelWidth + percentWidth + detailWidth;
|
||||
}
|
||||
|
||||
//? if >=1.21.2 {
|
||||
@Override
|
||||
public int getHeight(Font font) {
|
||||
return Math.max(iconSize, font.lineHeight);
|
||||
}
|
||||
//?} else {
|
||||
/*@Override
|
||||
public int getHeight() {
|
||||
return Math.max(iconSize, 9);
|
||||
}
|
||||
*///?}
|
||||
|
||||
//? if >=1.21.2 {
|
||||
@Override
|
||||
public boolean showTooltipWithItemInHand() {
|
||||
return true;
|
||||
}
|
||||
//?}
|
||||
|
||||
//? if >=1.21.6 {
|
||||
@Override
|
||||
public void renderText(GuiGraphics graphics, Font font, int x, int y) {
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int textX = x + iconSize + TEXT_PADDING;
|
||||
int textY = y + (rowHeight - font.lineHeight) / 2;
|
||||
|
||||
graphics.drawString(font, label, textX, textY, TEXT_COLOR, true);
|
||||
int labelWidth = font.width(label);
|
||||
int percentX = textX + labelWidth;
|
||||
graphics.drawString(font, percentText, percentX, textY, colorWithAlpha(percentColor), true);
|
||||
int percentWidth = font.width(percentText);
|
||||
int detailX = percentX + percentWidth;
|
||||
|
||||
graphics.pose().pushMatrix();
|
||||
graphics.pose().translate(detailX, textY);
|
||||
graphics.pose().scale(DETAIL_SCALE, DETAIL_SCALE);
|
||||
graphics.drawString(font, detailText, 0, 0, DETAIL_COLOR, true);
|
||||
graphics.pose().popMatrix();
|
||||
}
|
||||
//?} else {
|
||||
/*@Override
|
||||
public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) {
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int textX = x + iconSize + TEXT_PADDING;
|
||||
int textY = y + (rowHeight - font.lineHeight) / 2;
|
||||
|
||||
font.drawInBatch(label, textX, textY, TEXT_COLOR, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
int labelWidth = font.width(label);
|
||||
int percentX = textX + labelWidth;
|
||||
Component percentComponent = Component.literal(percentText);
|
||||
font.drawInBatch(percentComponent, percentX, textY, colorWithAlpha(percentColor), true, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
int percentWidth = font.width(percentText);
|
||||
int detailX = percentX + percentWidth;
|
||||
|
||||
Matrix4f smallMatrix = new Matrix4f(matrix);
|
||||
smallMatrix.translate(detailX, textY, 0);
|
||||
smallMatrix.scale(DETAIL_SCALE, DETAIL_SCALE, 1.0f);
|
||||
Component detailComponent = Component.literal(detailText);
|
||||
font.drawInBatch(detailComponent, 0, 0, DETAIL_COLOR, true, smallMatrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
}
|
||||
*///?}
|
||||
|
||||
//? if >=1.21.2 {
|
||||
@Override
|
||||
public void renderImage(Font font, int x, int y, int width, int height, GuiGraphics graphics) {
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int iconY = y + (rowHeight - iconSize) / 2 + ICON_Y_OFFSET;
|
||||
if (iconY < y) {
|
||||
iconY = y;
|
||||
}
|
||||
drawIcon(graphics, x, iconY);
|
||||
}
|
||||
//?} else {
|
||||
/*@Override
|
||||
public void renderImage(Font font, int x, int y, GuiGraphics graphics) {
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int iconY = y + (rowHeight - iconSize) / 2 + ICON_Y_OFFSET;
|
||||
if (iconY < y) {
|
||||
iconY = y;
|
||||
}
|
||||
drawIcon(graphics, x, iconY);
|
||||
}
|
||||
*///?}
|
||||
|
||||
private void drawIcon(GuiGraphics graphics, int x, int y) {
|
||||
IconAtlas.IconSprite sprite = IconAtlas.get("anvil");
|
||||
float scale = iconSize / (float) IconAtlas.ICON_SOURCE_SIZE;
|
||||
drawIconLayer(graphics, x + 1, y + 1, sprite, scale, shadowColor(TEXT_COLOR));
|
||||
drawIconLayer(graphics, x, y, sprite, scale, TEXT_COLOR);
|
||||
}
|
||||
|
||||
private static void drawIconLayer(GuiGraphics graphics, int x, int y, IconAtlas.IconSprite sprite, float scale, int color) {
|
||||
//? if >=1.21.6 {
|
||||
graphics.pose().pushMatrix();
|
||||
graphics.pose().translate(x, y);
|
||||
graphics.pose().scale(scale, scale);
|
||||
//?} else {
|
||||
/*graphics.pose().pushPose();
|
||||
graphics.pose().translate(x, y, 0);
|
||||
graphics.pose().scale(scale, scale, 1.0f);
|
||||
*///?}
|
||||
blit(graphics, 0, 0, sprite.u, sprite.v, sprite.size, color);
|
||||
//? if >=1.21.6 {
|
||||
graphics.pose().popMatrix();
|
||||
//?} else {
|
||||
/*graphics.pose().popPose();
|
||||
*///?}
|
||||
}
|
||||
|
||||
private static void blit(GuiGraphics graphics, int x, int y, int u, int v, int size, int color) {
|
||||
//? if >=1.21.6 {
|
||||
graphics.blit(RenderPipelines.GUI_TEXTURED, IconAtlas.ATLAS, x, y, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE, color);
|
||||
//?} else if >=1.21.2 {
|
||||
/*graphics.blit(RenderType::guiTextured, IconAtlas.ATLAS, x, y, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE, color);
|
||||
*///?} else {
|
||||
/*applyColor(graphics, color);
|
||||
graphics.blit(IconAtlas.ATLAS, x, y, 0, (float) u, (float) v, size, size, IconAtlas.ATLAS_SIZE, IconAtlas.ATLAS_SIZE);
|
||||
resetColor(graphics);
|
||||
*///?}
|
||||
}
|
||||
|
||||
private static int shadowColor(int color) {
|
||||
int a = (color >>> 24) & 0xFF;
|
||||
int r = (color >>> 16) & 0xFF;
|
||||
int g = (color >>> 8) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
r = (int) (r * 0.35f);
|
||||
g = (int) (g * 0.35f);
|
||||
b = (int) (b * 0.35f);
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
private static int colorWithAlpha(int rgb) {
|
||||
return 0xFF000000 | (rgb & 0xFFFFFF);
|
||||
}
|
||||
|
||||
//? if <1.21.2 {
|
||||
/*private static void applyColor(GuiGraphics graphics, int argb) {
|
||||
float a = ((argb >>> 24) & 0xFF) / 255f;
|
||||
float r = ((argb >>> 16) & 0xFF) / 255f;
|
||||
float g = ((argb >>> 8) & 0xFF) / 255f;
|
||||
float b = (argb & 0xFF) / 255f;
|
||||
graphics.setColor(r, g, b, a);
|
||||
}
|
||||
|
||||
private static void resetColor(GuiGraphics graphics) {
|
||||
graphics.setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
*///?}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.dekin.iconsenhanced.client;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
|
||||
public final class DurabilityTooltipData implements TooltipComponent {
|
||||
private final int iconSize;
|
||||
private final int current;
|
||||
private final int max;
|
||||
private final int percent;
|
||||
private final int percentColor;
|
||||
private final Component label;
|
||||
|
||||
public DurabilityTooltipData(int iconSize, int current, int max, int percent, int percentColor, Component label) {
|
||||
this.iconSize = iconSize;
|
||||
this.current = current;
|
||||
this.max = max;
|
||||
this.percent = percent;
|
||||
this.percentColor = percentColor;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public int iconSize() {
|
||||
return iconSize;
|
||||
}
|
||||
|
||||
public int current() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public int max() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public int percent() {
|
||||
return percent;
|
||||
}
|
||||
|
||||
public int percentColor() {
|
||||
return percentColor;
|
||||
}
|
||||
|
||||
public Component label() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
private static final int ROW_GAP = 2;
|
||||
private static final int TEXT_PADDING = 4;
|
||||
private static final int BADGE_BG = 0xAA000000;
|
||||
private static final int BADGE_TEXT = 0xFFFFFFFF;
|
||||
private static final int BADGE_TEXT = 0xFFFFFFFF;
|
||||
private static final int ICON_Y_OFFSET = -1;
|
||||
//? if <1.21.6 {
|
||||
/*private static final int FULL_BRIGHT = 0xF000F0;
|
||||
*///?}
|
||||
@@ -34,7 +35,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
|
||||
public EnchantTooltipComponent(EnchantTooltipData data) {
|
||||
this.layout = data.layout();
|
||||
this.iconSize = Math.max(4, data.iconSize());
|
||||
this.iconSize = Math.max(1, data.iconSize());
|
||||
this.showLevelBadge = data.showLevelBadge();
|
||||
}
|
||||
|
||||
@@ -91,15 +92,18 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
int yOffset = 0;
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int textX = x + iconSize + TEXT_PADDING;
|
||||
for (Row row : layout.rows()) {
|
||||
for (int i = 0; i < layout.rows().size(); i++) {
|
||||
Row row = layout.rows().get(i);
|
||||
int textY = y + yOffset + (rowHeight - font.lineHeight) / 2;
|
||||
graphics.drawString(font, row.text, textX, textY, 0xFFFFFFFF, false);
|
||||
graphics.drawString(font, row.text, textX, textY, 0xFFFFFFFF, true);
|
||||
yOffset += rowHeight;
|
||||
for (Component desc : row.descriptions) {
|
||||
graphics.drawString(font, desc, textX, y + yOffset, 0xFFFFFFFF, false);
|
||||
graphics.drawString(font, desc, textX, y + yOffset, 0xFFFFFFFF, true);
|
||||
yOffset += font.lineHeight;
|
||||
}
|
||||
yOffset += ROW_GAP;
|
||||
if (i < layout.rows().size() - 1) {
|
||||
yOffset += ROW_GAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
//?} else {
|
||||
@@ -108,15 +112,18 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
int yOffset = 0;
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
int textX = x + iconSize + TEXT_PADDING;
|
||||
for (Row row : layout.rows()) {
|
||||
for (int i = 0; i < layout.rows().size(); i++) {
|
||||
Row row = layout.rows().get(i);
|
||||
int textY = y + yOffset + (rowHeight - font.lineHeight) / 2;
|
||||
font.drawInBatch(row.text, textX, textY, 0xFFFFFFFF, false, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
font.drawInBatch(row.text, textX, textY, 0xFFFFFFFF, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
yOffset += rowHeight;
|
||||
for (Component desc : row.descriptions) {
|
||||
font.drawInBatch(desc, textX, y + yOffset, 0xFFFFFFFF, false, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
font.drawInBatch(desc, textX, y + yOffset, 0xFFFFFFFF, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, FULL_BRIGHT);
|
||||
yOffset += font.lineHeight;
|
||||
}
|
||||
yOffset += ROW_GAP;
|
||||
if (i < layout.rows().size() - 1) {
|
||||
yOffset += ROW_GAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
*///?}
|
||||
@@ -136,15 +143,22 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
private void renderIcons(Font font, int x, int y, GuiGraphics graphics) {
|
||||
int yOffset = 0;
|
||||
int rowHeight = Math.max(iconSize, font.lineHeight);
|
||||
for (Row row : layout.rows()) {
|
||||
int iconY = y + yOffset + (rowHeight - iconSize) / 2;
|
||||
for (int i = 0; i < layout.rows().size(); i++) {
|
||||
Row row = layout.rows().get(i);
|
||||
int baseY = y + yOffset;
|
||||
int iconY = baseY + (rowHeight - iconSize) / 2 + ICON_Y_OFFSET;
|
||||
if (iconY < baseY) {
|
||||
iconY = baseY;
|
||||
}
|
||||
drawIcon(graphics, x, iconY, row.iconKey, row.text);
|
||||
if (showLevelBadge) {
|
||||
drawBadge(graphics, font, x, iconY, row.level);
|
||||
}
|
||||
yOffset += rowHeight;
|
||||
yOffset += row.descriptions.size() * font.lineHeight;
|
||||
yOffset += ROW_GAP;
|
||||
if (i < layout.rows().size() - 1) {
|
||||
yOffset += ROW_GAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +166,11 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
IconAtlas.IconSprite sprite = IconAtlas.get(key);
|
||||
float scale = iconSize / (float) IconAtlas.ICON_SOURCE_SIZE;
|
||||
int color = resolveColor(text);
|
||||
drawIconLayer(graphics, x + 1, y + 1, sprite, scale, shadowColor(color));
|
||||
drawIconLayer(graphics, x, y, sprite, scale, color);
|
||||
}
|
||||
|
||||
private static void drawIconLayer(GuiGraphics graphics, int x, int y, IconAtlas.IconSprite sprite, float scale, int color) {
|
||||
//? if >=1.21.6 {
|
||||
graphics.pose().pushMatrix();
|
||||
graphics.pose().translate(x, y);
|
||||
@@ -180,7 +199,7 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
int badgeX = x + iconSize - badgeWidth;
|
||||
int badgeY = y - 1;
|
||||
graphics.fill(badgeX, badgeY, badgeX + badgeWidth, badgeY + badgeHeight, BADGE_BG);
|
||||
graphics.drawString(font, text, badgeX + 1, badgeY + 1, BADGE_TEXT, false);
|
||||
graphics.drawString(font, text, badgeX + 1, badgeY + 1, BADGE_TEXT, true);
|
||||
}
|
||||
|
||||
private static String levelToString(int level) {
|
||||
@@ -210,6 +229,17 @@ public final class EnchantTooltipComponent implements ClientTooltipComponent {
|
||||
return 0xFF000000 | color.getValue();
|
||||
}
|
||||
|
||||
private static int shadowColor(int color) {
|
||||
int a = (color >>> 24) & 0xFF;
|
||||
int r = (color >>> 16) & 0xFF;
|
||||
int g = (color >>> 8) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
r = (int) (r * 0.35f);
|
||||
g = (int) (g * 0.35f);
|
||||
b = (int) (b * 0.35f);
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
//? if <1.21.2 {
|
||||
/*private static void applyColor(GuiGraphics graphics, int argb) {
|
||||
float a = ((argb >>> 24) & 0xFF) / 255f;
|
||||
|
||||
@@ -17,29 +17,38 @@ import dev.dekin.iconsenhanced.mixin.AbstractContainerScreenAccessor;
|
||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.TooltipComponentCallback;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
//? if >=1.21.6 {
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.DefaultTooltipPositioner;
|
||||
//?}
|
||||
//? if <1.21.6 {
|
||||
/*import java.util.Optional;
|
||||
*///?}
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
//? if <1.21.6 {
|
||||
/*import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector2ic;
|
||||
*///?}
|
||||
|
||||
public final class TooltipAugmenter {
|
||||
private static final EnchantmentAdapter ADAPTER = new DefaultEnchantmentAdapter();
|
||||
private static final EnchantSortLogic SORT_LOGIC = new EnchantSortLogic();
|
||||
private static final ThreadLocal<Boolean> CAPTURE = ThreadLocal.withInitial(() -> Boolean.FALSE);
|
||||
private static final ThreadLocal<EnchantTooltipData> CAPTURED_DATA = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Integer> CAPTURED_ENCHANT_INDEX = new ThreadLocal<>();
|
||||
private static final ThreadLocal<DurabilityTooltipData> CAPTURED_DURABILITY = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Integer> CAPTURED_DURABILITY_INDEX = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Boolean> SUPPRESS_VANILLA = ThreadLocal.withInitial(() -> Boolean.FALSE);
|
||||
private static final ThreadLocal<Slot> SAVED_HOVERED = new ThreadLocal<>();
|
||||
private static boolean LATE_REGISTERED = false;
|
||||
private static final int DURABILITY_GREEN = 0x55FF55;
|
||||
private static final int DURABILITY_ORANGE = 0xFFAA00;
|
||||
private static final int DURABILITY_RED = 0xFF5555;
|
||||
|
||||
private TooltipAugmenter() {
|
||||
}
|
||||
@@ -58,6 +67,9 @@ public final class TooltipAugmenter {
|
||||
if (data instanceof EnchantTooltipData enchData) {
|
||||
return new EnchantTooltipComponent(enchData);
|
||||
}
|
||||
if (data instanceof DurabilityTooltipData durabilityData) {
|
||||
return new DurabilityTooltipComponent(durabilityData);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -124,47 +136,31 @@ public final class TooltipAugmenter {
|
||||
Minecraft client = Minecraft.getInstance();
|
||||
List<Component> lines;
|
||||
EnchantTooltipData data = null;
|
||||
DurabilityTooltipData durabilityData = null;
|
||||
Integer enchantIndex = null;
|
||||
Integer durabilityIndex = null;
|
||||
TooltipComponent baseData = stack.getTooltipImage().orElse(null);
|
||||
try {
|
||||
CAPTURE.set(Boolean.TRUE);
|
||||
CAPTURED_DATA.remove();
|
||||
CAPTURED_ENCHANT_INDEX.remove();
|
||||
CAPTURED_DURABILITY.remove();
|
||||
CAPTURED_DURABILITY_INDEX.remove();
|
||||
lines = Screen.getTooltipFromItem(client, stack);
|
||||
if (config.tooltips.showIcons) {
|
||||
data = CAPTURED_DATA.get();
|
||||
}
|
||||
data = CAPTURED_DATA.get();
|
||||
enchantIndex = CAPTURED_ENCHANT_INDEX.get();
|
||||
durabilityData = CAPTURED_DURABILITY.get();
|
||||
durabilityIndex = CAPTURED_DURABILITY_INDEX.get();
|
||||
} finally {
|
||||
CAPTURE.remove();
|
||||
CAPTURED_DATA.remove();
|
||||
CAPTURED_ENCHANT_INDEX.remove();
|
||||
CAPTURED_DURABILITY.remove();
|
||||
CAPTURED_DURABILITY_INDEX.remove();
|
||||
}
|
||||
|
||||
//? if >=1.21.6 {
|
||||
graphics.nextStratum();
|
||||
List<ClientTooltipComponent> components = new ArrayList<>(lines.size() + (data == null ? 0 : 1));
|
||||
for (Component line : lines) {
|
||||
components.add(ClientTooltipComponent.create(line.getVisualOrderText()));
|
||||
}
|
||||
if (data != null) {
|
||||
ClientTooltipComponent custom = TooltipComponentCallback.EVENT.invoker().getComponent(data);
|
||||
if (custom != null) {
|
||||
components.add(custom);
|
||||
}
|
||||
}
|
||||
if (baseData != null && baseData != data) {
|
||||
components.add(ClientTooltipComponent.create(baseData));
|
||||
}
|
||||
graphics.renderTooltip(client.font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null);
|
||||
//?} else {
|
||||
/*TooltipComponent combined;
|
||||
if (data == null) {
|
||||
combined = baseData;
|
||||
} else if (baseData == null || baseData == data) {
|
||||
combined = data;
|
||||
} else {
|
||||
combined = new CombinedTooltipData(data, baseData);
|
||||
}
|
||||
Optional<TooltipComponent> tooltipData = combined == null ? Optional.empty() : Optional.of(combined);
|
||||
graphics.renderTooltip(client.font, lines, tooltipData, mouseX, mouseY);
|
||||
*///?}
|
||||
List<ClientTooltipComponent> components = buildComponents(lines, data, enchantIndex, durabilityData, durabilityIndex, baseData);
|
||||
renderTooltipComponents(graphics, client.font, components, mouseX, mouseY);
|
||||
}
|
||||
|
||||
private static void onTooltip(ItemStack stack, List<Component> lines) {
|
||||
@@ -179,43 +175,56 @@ public final class TooltipAugmenter {
|
||||
}
|
||||
|
||||
List<EnchEntry> entries = ADAPTER.getEnchantments(stack);
|
||||
if (entries.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TooltipBlock block = TooltipBlock.find(lines, entries);
|
||||
if (!block.contiguous) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<EnchEntry> sorted = SORT_LOGIC.sort(entries, config.tooltips);
|
||||
TooltipBlock block = entries.isEmpty() ? null : TooltipBlock.find(lines, entries);
|
||||
List<EnchEntry> sorted = entries.isEmpty() ? entries : SORT_LOGIC.sort(entries, config.tooltips);
|
||||
//? if >=1.21.9 {
|
||||
boolean shiftDown = Minecraft.getInstance().hasShiftDown();
|
||||
//?} else {
|
||||
/*boolean shiftDown = Screen.hasShiftDown();*/
|
||||
//?}
|
||||
boolean hasDescriptions = config.tooltips.showDescriptions && hasAnyDescriptions(sorted);
|
||||
boolean canAugment = !entries.isEmpty() && block != null && block.contiguous;
|
||||
boolean hasDescriptions = canAugment && config.tooltips.showDescriptions && hasAnyDescriptions(sorted);
|
||||
Component hint = hasDescriptions && !shiftDown ? TooltipTextUtil.getShiftHint() : null;
|
||||
DurabilityTooltipData durabilityData = buildDurabilityData(stack, config.tooltips);
|
||||
boolean hasEnchantBlock = !entries.isEmpty() && block != null && block.contiguous;
|
||||
List<Component> enchantLines = List.of();
|
||||
if (hasEnchantBlock) {
|
||||
boolean shouldReplace = config.tooltips.reorderEnchantments || config.tooltips.showDescriptions;
|
||||
List<EnchEntry> ordered = config.tooltips.reorderEnchantments ? sorted : entries;
|
||||
if (shouldReplace) {
|
||||
enchantLines = buildTextLines(ordered, config.tooltips.showDescriptions, shiftDown);
|
||||
} else {
|
||||
enchantLines = new ArrayList<>(lines.subList(block.start, block.end + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(CAPTURE.get()) && config.tooltips.showIcons) {
|
||||
EnchantTooltipData data = buildTooltipData(sorted, config.tooltips, shiftDown);
|
||||
CAPTURED_DATA.set(data);
|
||||
block.remove(lines);
|
||||
if (hasDescriptions && !shiftDown) {
|
||||
lines.add(block.start, TooltipTextUtil.getShiftHint());
|
||||
boolean insertEnchantComponent = hasEnchantBlock;
|
||||
if (insertEnchantComponent) {
|
||||
List<EnchEntry> iconEntries = config.tooltips.reorderEnchantments ? sorted : entries;
|
||||
EnchantTooltipData data = buildTooltipData(iconEntries, config.tooltips, shiftDown);
|
||||
CAPTURED_DATA.set(data);
|
||||
}
|
||||
if (durabilityData != null) {
|
||||
CAPTURED_DURABILITY.set(durabilityData);
|
||||
}
|
||||
ReorderedLines reordered = reorderLines(lines, block, List.of(), insertEnchantComponent,
|
||||
null, durabilityData != null, hint);
|
||||
lines.clear();
|
||||
lines.addAll(reordered.lines);
|
||||
if (insertEnchantComponent) {
|
||||
CAPTURED_ENCHANT_INDEX.set(reordered.enchantIndex);
|
||||
}
|
||||
if (durabilityData != null) {
|
||||
CAPTURED_DURABILITY_INDEX.set(reordered.durabilityIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.tooltips.reorderEnchantments && !config.tooltips.showDescriptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<EnchEntry> ordered = config.tooltips.reorderEnchantments ? sorted : entries;
|
||||
List<Component> replacement = buildTextLines(ordered, config.tooltips.showDescriptions, shiftDown);
|
||||
if (hasDescriptions && !shiftDown) {
|
||||
replacement.add(TooltipTextUtil.getShiftHint());
|
||||
}
|
||||
block.replace(lines, replacement);
|
||||
Component durabilityLine = buildDurabilityLine(durabilityData);
|
||||
ReorderedLines reordered = reorderLines(lines, block, enchantLines, false, durabilityLine, false, hint);
|
||||
lines.clear();
|
||||
lines.addAll(reordered.lines);
|
||||
} catch (Exception e) {
|
||||
IconsEnhanced.LOGGER.warn("Tooltip augmentation failed.", e);
|
||||
}
|
||||
@@ -227,6 +236,49 @@ public final class TooltipAugmenter {
|
||||
}
|
||||
}
|
||||
|
||||
private static DurabilityTooltipData buildDurabilityData(ItemStack stack, IconsEnhancedConfig.Tooltips tooltips) {
|
||||
if (stack == null || !stack.isDamageableItem()) {
|
||||
return null;
|
||||
}
|
||||
int max = stack.getMaxDamage();
|
||||
if (max <= 0) {
|
||||
return null;
|
||||
}
|
||||
int current = max - stack.getDamageValue();
|
||||
if (current < 0) {
|
||||
current = 0;
|
||||
}
|
||||
int percent = Math.round((current / (float) max) * 100f);
|
||||
if (percent < 0) {
|
||||
percent = 0;
|
||||
} else if (percent > 100) {
|
||||
percent = 100;
|
||||
}
|
||||
int percentColor = durabilityPercentColor(percent);
|
||||
Component label = Component.literal("Durability:");
|
||||
return new DurabilityTooltipData(tooltips.iconSize, current, max, percent, percentColor, label);
|
||||
}
|
||||
|
||||
private static Component buildDurabilityLine(DurabilityTooltipData data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
MutableComponent label = data.label().copy().withStyle(style -> style.withColor(0xFFFFFF));
|
||||
Component percent = Component.literal(" " + data.percent() + "%").withStyle(style -> style.withColor(data.percentColor()));
|
||||
Component detail = Component.literal(" (" + data.current() + "/" + data.max() + ")").withStyle(style -> style.withColor(0xAAAAAA));
|
||||
return label.append(percent).append(detail);
|
||||
}
|
||||
|
||||
private static int durabilityPercentColor(int percent) {
|
||||
if (percent <= 33) {
|
||||
return DURABILITY_RED;
|
||||
}
|
||||
if (percent <= 66) {
|
||||
return DURABILITY_ORANGE;
|
||||
}
|
||||
return DURABILITY_GREEN;
|
||||
}
|
||||
|
||||
private static EnchantTooltipData buildTooltipData(List<EnchEntry> entries, IconsEnhancedConfig.Tooltips tooltips, boolean shiftDown) {
|
||||
List<TooltipLayoutModel.Row> rows = new ArrayList<>();
|
||||
boolean showDescriptions = tooltips.showDescriptions && shiftDown;
|
||||
@@ -255,6 +307,117 @@ public final class TooltipAugmenter {
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static List<ClientTooltipComponent> buildComponents(List<Component> lines, EnchantTooltipData data, Integer enchantIndex,
|
||||
DurabilityTooltipData durabilityData, Integer durabilityIndex, TooltipComponent baseData) {
|
||||
ClientTooltipComponent enchantComponent = data == null ? null : TooltipComponentCallback.EVENT.invoker().getComponent(data);
|
||||
ClientTooltipComponent durabilityComponent = durabilityData == null ? null : TooltipComponentCallback.EVENT.invoker().getComponent(durabilityData);
|
||||
ClientTooltipComponent baseComponent = baseData == null ? null : ClientTooltipComponent.create(baseData);
|
||||
int extra = 0;
|
||||
if (enchantComponent != null) {
|
||||
extra++;
|
||||
}
|
||||
if (durabilityComponent != null) {
|
||||
extra++;
|
||||
}
|
||||
if (baseComponent != null) {
|
||||
extra++;
|
||||
}
|
||||
List<ClientTooltipComponent> components = new ArrayList<>(lines.size() + extra);
|
||||
|
||||
int insertEnchant = enchantComponent == null || enchantIndex == null ? -1 : Math.max(0, Math.min(enchantIndex, lines.size()));
|
||||
int insertDurability = durabilityComponent == null || durabilityIndex == null ? -1 : Math.max(0, Math.min(durabilityIndex, lines.size()));
|
||||
int insertBase = baseComponent == null ? -1 : (lines.isEmpty() ? 0 : 1);
|
||||
|
||||
for (int i = 0; i <= lines.size(); i++) {
|
||||
if (i == insertEnchant && enchantComponent != null) {
|
||||
components.add(enchantComponent);
|
||||
}
|
||||
if (i == insertBase && baseComponent != null) {
|
||||
components.add(baseComponent);
|
||||
}
|
||||
if (i == insertDurability && durabilityComponent != null) {
|
||||
components.add(durabilityComponent);
|
||||
}
|
||||
if (i < lines.size()) {
|
||||
components.add(ClientTooltipComponent.create(lines.get(i).getVisualOrderText()));
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
private static void renderTooltipComponents(GuiGraphics graphics, Font font, List<ClientTooltipComponent> components, int mouseX, int mouseY) {
|
||||
if (components.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
//? if >=1.21.6 {
|
||||
graphics.nextStratum();
|
||||
graphics.renderTooltip(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null);
|
||||
//?} else {
|
||||
/*int width = 0;
|
||||
int height = components.size() == 1 ? -2 : 0;
|
||||
for (ClientTooltipComponent component : components) {
|
||||
width = Math.max(width, component.getWidth(font));
|
||||
height += componentHeight(component, font);
|
||||
}
|
||||
|
||||
Vector2ic pos = DefaultTooltipPositioner.INSTANCE.positionTooltip(graphics.guiWidth(), graphics.guiHeight(), mouseX, mouseY, width, height);
|
||||
int x = pos.x();
|
||||
int y = pos.y();
|
||||
int tooltipWidth = width;
|
||||
int tooltipHeight = height;
|
||||
graphics.pose().pushPose();
|
||||
//? if >=1.21.2 {
|
||||
TooltipRenderUtil.renderTooltipBackground(graphics, x, y, tooltipWidth, tooltipHeight, 400, null);
|
||||
//?} else {
|
||||
graphics.drawManaged(() -> TooltipRenderUtil.renderTooltipBackground(graphics, x, y, tooltipWidth, tooltipHeight, 400));
|
||||
//?}
|
||||
graphics.pose().translate(0, 0, 400);
|
||||
|
||||
//? if >=1.21.2 {
|
||||
graphics.drawSpecial(buffer -> {
|
||||
int yText = y;
|
||||
Matrix4f matrix = graphics.pose().last().pose();
|
||||
MultiBufferSource.BufferSource source = (MultiBufferSource.BufferSource) buffer;
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
ClientTooltipComponent component = components.get(i);
|
||||
component.renderText(font, x, yText, matrix, source);
|
||||
yText += componentHeight(component, font) + (i == 0 ? 2 : 0);
|
||||
}
|
||||
});
|
||||
//?} else {
|
||||
int yText = y;
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
ClientTooltipComponent component = components.get(i);
|
||||
Matrix4f matrix = graphics.pose().last().pose();
|
||||
component.renderText(font, x, yText, matrix, graphics.bufferSource());
|
||||
yText += componentHeight(component, font) + (i == 0 ? 2 : 0);
|
||||
}
|
||||
//?}
|
||||
|
||||
int yImage = y;
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
ClientTooltipComponent component = components.get(i);
|
||||
//? if >=1.21.2 {
|
||||
component.renderImage(font, x, yImage, width, height, graphics);
|
||||
//?} else {
|
||||
component.renderImage(font, x, yImage, graphics);
|
||||
//?}
|
||||
yImage += componentHeight(component, font) + (i == 0 ? 2 : 0);
|
||||
}
|
||||
graphics.pose().popPose();
|
||||
*///?}
|
||||
}
|
||||
|
||||
//? if <1.21.6 {
|
||||
/*private static int componentHeight(ClientTooltipComponent component, Font font) {
|
||||
//? if >=1.21.2 {
|
||||
return component.getHeight(font);
|
||||
//?} else {
|
||||
return component.getHeight();
|
||||
//?}
|
||||
}
|
||||
*///?}
|
||||
|
||||
private static boolean hasAnyDescriptions(List<EnchEntry> entries) {
|
||||
for (EnchEntry entry : entries) {
|
||||
if (TooltipTextUtil.hasDescription(entry.descKey)) {
|
||||
@@ -264,6 +427,79 @@ public final class TooltipAugmenter {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ReorderedLines reorderLines(List<Component> original, TooltipBlock block, List<Component> enchantLines,
|
||||
boolean insertEnchantComponent, Component durabilityLine, boolean insertDurabilityComponent, Component hint) {
|
||||
List<Component> details = new ArrayList<>();
|
||||
Component nameLine = null;
|
||||
if (!original.isEmpty()) {
|
||||
nameLine = original.get(0);
|
||||
}
|
||||
for (int i = 1; i < original.size(); i++) {
|
||||
if (block != null && block.contiguous && i >= block.start && i <= block.end) {
|
||||
continue;
|
||||
}
|
||||
details.add(original.get(i));
|
||||
}
|
||||
|
||||
List<Component> result = new ArrayList<>(original.size() + 6);
|
||||
if (nameLine != null) {
|
||||
result.add(nameLine);
|
||||
}
|
||||
|
||||
int enchantIndex = -1;
|
||||
if (insertEnchantComponent) {
|
||||
enchantIndex = result.size();
|
||||
} else if (enchantLines != null && !enchantLines.isEmpty()) {
|
||||
result.addAll(enchantLines);
|
||||
}
|
||||
|
||||
boolean hasEnchant = insertEnchantComponent || (enchantLines != null && !enchantLines.isEmpty());
|
||||
boolean hasDurability = insertDurabilityComponent || durabilityLine != null;
|
||||
|
||||
if (hasEnchant && (hasDurability || !details.isEmpty() || hint != null)) {
|
||||
result.add(blankLine());
|
||||
}
|
||||
|
||||
int durabilityIndex = -1;
|
||||
if (hasDurability) {
|
||||
if (durabilityLine != null) {
|
||||
result.add(durabilityLine);
|
||||
} else {
|
||||
durabilityIndex = result.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (!details.isEmpty()) {
|
||||
result.addAll(details);
|
||||
}
|
||||
|
||||
if (!details.isEmpty() && hint != null) {
|
||||
result.add(blankLine());
|
||||
}
|
||||
|
||||
if (hint != null) {
|
||||
result.add(hint);
|
||||
}
|
||||
|
||||
return new ReorderedLines(result, enchantIndex, durabilityIndex);
|
||||
}
|
||||
|
||||
private static Component blankLine() {
|
||||
return Component.literal("");
|
||||
}
|
||||
|
||||
private static final class ReorderedLines {
|
||||
private final List<Component> lines;
|
||||
private final Integer enchantIndex;
|
||||
private final Integer durabilityIndex;
|
||||
|
||||
private ReorderedLines(List<Component> lines, Integer enchantIndex, Integer durabilityIndex) {
|
||||
this.lines = lines;
|
||||
this.enchantIndex = enchantIndex;
|
||||
this.durabilityIndex = durabilityIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private static Slot findHoveredSlot(AbstractContainerScreen<?> screen, int mouseX, int mouseY) {
|
||||
AbstractContainerScreenAccessor accessor = (AbstractContainerScreenAccessor) screen;
|
||||
int left = accessor.iconsenhanced$getLeftPos();
|
||||
@@ -291,15 +527,6 @@ public final class TooltipAugmenter {
|
||||
this.contiguous = contiguous;
|
||||
}
|
||||
|
||||
private void remove(List<Component> lines) {
|
||||
lines.subList(start, end + 1).clear();
|
||||
}
|
||||
|
||||
private void replace(List<Component> lines, List<Component> replacement) {
|
||||
lines.subList(start, end + 1).clear();
|
||||
lines.addAll(start, replacement);
|
||||
}
|
||||
|
||||
private static TooltipBlock find(List<Component> lines, List<EnchEntry> entries) {
|
||||
Set<String> names = new HashSet<>();
|
||||
for (EnchEntry entry : entries) {
|
||||
|
||||
@@ -12,8 +12,9 @@ import net.minecraft.network.chat.Style;
|
||||
|
||||
public final class TooltipTextUtil {
|
||||
private static final Map<String, List<Component>> CACHE = new HashMap<>();
|
||||
private static final Style DESCRIPTION_STYLE = Style.EMPTY;
|
||||
private static final Style DESCRIPTION_STYLE = Style.EMPTY.withColor(0xAAAAAA);
|
||||
private static final Style HINT_STYLE = Style.EMPTY.withColor(0xAAAAAA);
|
||||
private static final Style SHIFT_STYLE = Style.EMPTY.withColor(0xFCA800);
|
||||
|
||||
private TooltipTextUtil() {
|
||||
}
|
||||
@@ -36,7 +37,8 @@ public final class TooltipTextUtil {
|
||||
}
|
||||
|
||||
public static Component getShiftHint() {
|
||||
return Component.translatable("iconsenhanced.tooltip.shift").setStyle(HINT_STYLE);
|
||||
Component shiftKey = Component.translatable("iconsenhanced.tooltip.shift_key").setStyle(SHIFT_STYLE);
|
||||
return Component.translatable("iconsenhanced.tooltip.shift", shiftKey).setStyle(HINT_STYLE);
|
||||
}
|
||||
|
||||
public static Component withNumericLevel(Component baseName, int level) {
|
||||
|
||||
@@ -1,115 +1,34 @@
|
||||
package dev.dekin.iconsenhanced.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import dev.dekin.iconsenhanced.IconsEnhanced;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
|
||||
public final class BorderColorLogic {
|
||||
private final Map<String, Integer> rarityColors = new HashMap<>();
|
||||
private final Map<String, Integer> customRuleColors = new HashMap<>();
|
||||
private boolean enchantedOverride;
|
||||
private int enchantedColor;
|
||||
private boolean useCustomRules;
|
||||
private String mode;
|
||||
private int alpha;
|
||||
|
||||
public void applyConfig(IconsEnhancedConfig config) {
|
||||
IconsEnhancedConfig.Borders borders = config.borders;
|
||||
rarityColors.clear();
|
||||
for (Map.Entry<String, String> entry : borders.rarityColors.entrySet()) {
|
||||
rarityColors.put(entry.getKey(), parseColor(entry.getValue(), 0xFFAAAAAA));
|
||||
}
|
||||
|
||||
customRuleColors.clear();
|
||||
for (IconsEnhancedConfig.CustomBorderRule rule : borders.customRules) {
|
||||
String id = normalizeId(rule.itemId);
|
||||
if (id == null) {
|
||||
IconsEnhanced.LOGGER.warn("Invalid border rule item id: {}", rule.itemId);
|
||||
continue;
|
||||
}
|
||||
customRuleColors.put(id, parseColor(rule.color, 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
enchantedOverride = borders.enchantedOverride.enabled;
|
||||
enchantedColor = parseColor(borders.enchantedOverride.color, 0xFFFFD700);
|
||||
useCustomRules = borders.useCustomRules;
|
||||
mode = borders.mode == null ? "RARITY" : borders.mode.trim().toUpperCase();
|
||||
alpha = clamp(borders.alpha, 0, 255);
|
||||
}
|
||||
|
||||
public int resolve(ItemStack stack) {
|
||||
String itemId = BuiltInRegistries.ITEM.getKey(stack.getItem()).toString();
|
||||
if (useCustomRules) {
|
||||
Integer ruleColor = customRuleColors.get(itemId);
|
||||
if (ruleColor != null) {
|
||||
return withAlpha(ruleColor, alpha);
|
||||
}
|
||||
Rarity rarity = stack.getRarity();
|
||||
if (rarity == Rarity.COMMON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (enchantedOverride && stack.isEnchanted()) {
|
||||
return withAlpha(enchantedColor, alpha);
|
||||
ChatFormatting formatting = rarityColor(rarity);
|
||||
if (formatting == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ("CUSTOM".equals(mode)) {
|
||||
Integer ruleColor = customRuleColors.get(itemId);
|
||||
if (ruleColor != null) {
|
||||
return withAlpha(ruleColor, alpha);
|
||||
}
|
||||
Integer rgb = formatting.getColor();
|
||||
if (rgb == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rarityColor = rarityColors.getOrDefault(rarityKey(stack.getRarity()), 0xFFAAAAAA);
|
||||
return withAlpha(rarityColor, alpha);
|
||||
return 0xFF000000 | rgb;
|
||||
}
|
||||
|
||||
private static String normalizeId(String raw) {
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
String cleaned = raw.trim().toLowerCase(Locale.ROOT);
|
||||
if (cleaned.isEmpty() || !cleaned.contains(":")) {
|
||||
return null;
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
private static String rarityKey(Rarity rarity) {
|
||||
if (rarity == Rarity.UNCOMMON) {
|
||||
return "uncommon";
|
||||
}
|
||||
if (rarity == Rarity.RARE) {
|
||||
return "rare";
|
||||
}
|
||||
if (rarity == Rarity.EPIC) {
|
||||
return "epic";
|
||||
}
|
||||
return "common";
|
||||
}
|
||||
|
||||
private static int parseColor(String value, int fallback) {
|
||||
if (value == null) {
|
||||
return fallback;
|
||||
}
|
||||
try {
|
||||
String cleaned = value.trim();
|
||||
if (cleaned.isEmpty()) {
|
||||
return fallback;
|
||||
}
|
||||
return (int) Long.decode(cleaned).longValue();
|
||||
} catch (NumberFormatException ex) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
private static int withAlpha(int color, int alpha) {
|
||||
return (color & 0x00FFFFFF) | ((alpha & 0xFF) << 24);
|
||||
}
|
||||
|
||||
private static int clamp(int value, int min, int max) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
private static ChatFormatting rarityColor(Rarity rarity) {
|
||||
//? if >=1.20.5 {
|
||||
return rarity.color();
|
||||
//?} else {
|
||||
/*return rarity.color;*/
|
||||
//?}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public final class IconAtlas {
|
||||
register("default", 10);
|
||||
register("sword", 11);
|
||||
register("trident", 12);
|
||||
register("anvil", 13);
|
||||
}
|
||||
|
||||
private IconAtlas() {
|
||||
|
||||
@@ -97,7 +97,7 @@ public final class IconsEnhancedConfig {
|
||||
public boolean cursesLast = true;
|
||||
public boolean showDescriptions = true;
|
||||
public boolean showIcons = true;
|
||||
public int iconSize = 10;
|
||||
public int iconSize = 8;
|
||||
public boolean showLevelBadge = true;
|
||||
public List<String> customPriorityList = defaultCustomPriorityList();
|
||||
|
||||
@@ -107,6 +107,10 @@ public final class IconsEnhancedConfig {
|
||||
sortMode = "CUSTOM_PRIORITY_LIST";
|
||||
changed = true;
|
||||
}
|
||||
if (iconSize == 9 || iconSize == 7 || iconSize == 6 || iconSize == 5 || iconSize == 4 || iconSize == 3 || iconSize == 2 || iconSize == 1) {
|
||||
iconSize = 8;
|
||||
changed = true;
|
||||
}
|
||||
if (customPriorityList == null || customPriorityList.isEmpty()) {
|
||||
customPriorityList = defaultCustomPriorityList();
|
||||
changed = true;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Halte Shift für Details.",
|
||||
"iconsenhanced.tooltip.shift": "Halte %s für Details.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Erhöht die Abbaugeschwindigkeit unter Wasser.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Erhöht den Schaden gegen Arthropoden und verlangsamt sie.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Verflucht: kann nicht entfernt werden.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Hold Shift for details.",
|
||||
"iconsenhanced.tooltip.shift": "Hold %s for details.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Increases underwater mining speed.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Increases damage to arthropods and slows them.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Cursed: cannot be removed.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Manten Shift para ver detalles.",
|
||||
"iconsenhanced.tooltip.shift": "Manten %s para ver detalles.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta la velocidad de minado bajo el agua.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta el dano a artropodos y los ralentiza.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Maldito: no se puede quitar.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Maintenez Maj pour les détails.",
|
||||
"iconsenhanced.tooltip.shift": "Maintenez %s pour les détails.",
|
||||
"iconsenhanced.tooltip.shift_key": "Maj",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Augmente la vitesse de minage sous l'eau.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Augmente les dégâts aux arthropodes et les ralentit.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Maudit : ne peut pas être retiré.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Tieni premuto Shift per i dettagli.",
|
||||
"iconsenhanced.tooltip.shift": "Tieni premuto %s per i dettagli.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta la velocità di minare sott'acqua.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta i danni agli artropodi e li rallenta.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Maledetto: non può essere rimosso.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Segure Shift para ver detalhes.",
|
||||
"iconsenhanced.tooltip.shift": "Segure %s para ver detalhes.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Aumenta a velocidade de mineração debaixo d'água.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Aumenta o dano contra artrópodes e os desacelera.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Amaldiçoado: não pode ser removido.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "Удерживайте Shift для подробностей.",
|
||||
"iconsenhanced.tooltip.shift": "Удерживайте %s для подробностей.",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "Увеличивает скорость добычи под водой.",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "Увеличивает урон по членистоногим и замедляет их.",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "Проклятие: нельзя снять.",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"iconsenhanced.tooltip.shift": "按住Shift查看详情。",
|
||||
"iconsenhanced.tooltip.shift": "按住%s查看详情。",
|
||||
"iconsenhanced.tooltip.shift_key": "Shift",
|
||||
"iconsenhanced.desc.minecraft.aqua_affinity": "提高水下挖掘速度。",
|
||||
"iconsenhanced.desc.minecraft.bane_of_arthropods": "提高对节肢生物的伤害并使其减速。",
|
||||
"iconsenhanced.desc.minecraft.binding_curse": "诅咒:无法移除。",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"texture": {
|
||||
"blur": false,
|
||||
"clamp": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user