diff options
author | Anthony Hilyard <anthony.hilyard@gmail.com> | 2021-12-31 15:22:21 -0800 |
---|---|---|
committer | Anthony Hilyard <anthony.hilyard@gmail.com> | 2021-12-31 15:22:21 -0800 |
commit | 2c50ee296e0daf85e6a087865b1d04bcebcbf565 (patch) | |
tree | 1d6976b1f08d7757b17d257220b33a2963e117fd /src | |
parent | 62d310bf8b3e559882d864f47de7828ea464d307 (diff) | |
download | Iceberg-2c50ee296e0daf85e6a087865b1d04bcebcbf565.tar.gz Iceberg-2c50ee296e0daf85e6a087865b1d04bcebcbf565.tar.bz2 Iceberg-2c50ee296e0daf85e6a087865b1d04bcebcbf565.zip |
Ported 1.0.28 and 1.0.29 update.
Diffstat (limited to 'src')
6 files changed, 215 insertions, 318 deletions
diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java index 7dd58b7..d0693e3 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java +++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java @@ -15,6 +15,22 @@ public final class RenderTooltipEvents { public RenderTooltipEvents() { } + public static final Event<RenderTooltipEvents.PreExt> PREEXT = EventFactory.createArrayBacked(RenderTooltipEvents.PreExt.class, + callbacks -> (stack, components, poseStack, x, y, screenWidth, screenHeight, font, comparison) -> { + PreExtResult result = new PreExtResult(InteractionResult.PASS, x, y, screenWidth, screenHeight, font); + for (RenderTooltipEvents.PreExt callback : callbacks) + { + result = callback.onPre(stack, components, poseStack, x, y, screenWidth, screenHeight, font, comparison); + + if (result.result != InteractionResult.PASS) + { + return result; + } + } + return result; + }); + + @Deprecated public static final Event<RenderTooltipEvents.Pre> PRE = EventFactory.createArrayBacked(RenderTooltipEvents.Pre.class, callbacks -> (stack, components, poseStack, x, y, screenWidth, screenHeight, maxWidth, font, comparison) -> { for (RenderTooltipEvents.Pre callback : callbacks) @@ -29,6 +45,17 @@ public final class RenderTooltipEvents return InteractionResult.PASS; }); + public static final Event<RenderTooltipEvents.ColorExt> COLOREXT = EventFactory.createArrayBacked(RenderTooltipEvents.ColorExt.class, + callbacks -> (stack, components, poseStack, x, y, font, backgroundStart, backgroundEnd, borderStart, borderEnd, comparison) -> { + ColorExtResult result = new ColorExtResult(backgroundStart, backgroundEnd, borderStart, borderEnd); + for (RenderTooltipEvents.ColorExt callback : callbacks) + { + result = callback.onColor(stack, components, poseStack, x, y, font, result.backgroundStart, result.backgroundEnd, result.borderStart, result.borderEnd, comparison); + } + return result; + }); + + @Deprecated public static final Event<RenderTooltipEvents.Color> COLOR = EventFactory.createArrayBacked(RenderTooltipEvents.Color.class, callbacks -> (stack, components, poseStack, x, y, font, background, borderStart, borderEnd, comparison) -> { ColorResult result = new ColorResult(background, borderStart, borderEnd); @@ -41,19 +68,33 @@ public final class RenderTooltipEvents public static final Event<RenderTooltipEvents.Post> POST = EventFactory.createArrayBacked(RenderTooltipEvents.Post.class, callbacks -> (stack, components, poseStack, x, y, font, width, height, comparison) -> { - for (RenderTooltipEvents.Post callback : callbacks) - { - callback.onPost(stack, components, poseStack, x, y, font, width, height, comparison); - } + for (RenderTooltipEvents.Post callback : callbacks) + { + callback.onPost(stack, components, poseStack, x, y, font, width, height, comparison); + } }); @FunctionalInterface + public interface PreExt + { + PreExtResult onPre(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, int screenWidth, int screenHeight, Font font, boolean comparison); + } + + @Deprecated + @FunctionalInterface public interface Pre { InteractionResult onPre(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, int screenWidth, int screenHeight, int maxWidth, Font font, boolean comparison); } @FunctionalInterface + public interface ColorExt + { + ColorExtResult onColor(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int backgroundStart, int backgroundEnd, int borderStart, int borderEnd, boolean comparison); + } + + @Deprecated + @FunctionalInterface public interface Color { ColorResult onColor(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, boolean comparison); @@ -65,5 +106,7 @@ public final class RenderTooltipEvents void onPost(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int width, int height, boolean comparison); } + public record PreExtResult(InteractionResult result, int x, int y, int screenWidth, int screenHeight, Font font) {} + public record ColorExtResult(int backgroundStart, int backgroundEnd, int borderStart, int borderEnd) {} public record ColorResult(int background, int borderStart, int borderEnd) {} } diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java index 06e0e90..55a97c3 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java @@ -3,6 +3,7 @@ package com.anthonyhilyard.iceberg.mixin; import java.util.List; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorExtResult; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.BufferBuilder; @@ -10,7 +11,6 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -37,11 +37,10 @@ public class ScreenMixin extends AbstractContainerEventHandler @Shadow protected Font font = null; - @Final @Shadow - private final List<GuiEventListener> children = Lists.newArrayList(); + private List<GuiEventListener> children = Lists.newArrayList(); - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "deprecation"}) @Inject(method = "renderTooltipInternal", at = @At(value = "HEAD"), cancellable = true) private void preRenderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, CallbackInfo info) { @@ -54,7 +53,16 @@ public class ScreenMixin extends AbstractContainerEventHandler if (hoveredSlot != null) { ItemStack tooltipStack = hoveredSlot.getItem(); - if (RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false) != InteractionResult.PASS) + InteractionResult result = RenderTooltipEvents.PREEXT.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, font, false).result(); + + if (result != InteractionResult.PASS) + { + info.cancel(); + } + + // Fire a pre event as well for compatibility. + result = RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false); + if (result != InteractionResult.PASS) { info.cancel(); } @@ -90,7 +98,7 @@ public class ScreenMixin extends AbstractContainerEventHandler } } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "deprecation"}) @Inject(method = "renderTooltipInternal", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V", shift = Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILEXCEPTION) @@ -112,20 +120,33 @@ public class ScreenMixin extends AbstractContainerEventHandler if (tooltipStack != ItemStack.EMPTY) { + int backgroundEnd = background; + // Do colors now, sure why not. - ColorResult result = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false); + ColorExtResult result = RenderTooltipEvents.COLOREXT.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, background, borderStart, borderEnd, false); if (result != null) { - background = result.background(); + background = result.backgroundStart(); + backgroundEnd = result.backgroundEnd(); borderStart = result.borderStart(); borderEnd = result.borderEnd(); } + // Fire a colors event as well for compatibility. + ColorResult colorResult = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false); + if (colorResult != null) + { + background = colorResult.background(); + borderStart = colorResult.borderStart(); + borderEnd = colorResult.borderEnd(); + } + + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 4, left + width + 3, top - 3, zIndex, background, background); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, background, background); - Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, background); - Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, background); - Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, background); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, backgroundEnd, backgroundEnd); + Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, backgroundEnd); + Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, backgroundEnd); + Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, backgroundEnd); Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3 + 1, left - 3 + 1, top + height + 3 - 1, zIndex, borderStart, borderEnd); Screen.fillGradient(matrix4f, bufferBuilder, left + width + 2, top - 3 + 1, left + width + 3, top + height + 3 - 1, zIndex, borderStart, borderEnd); Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top - 3 + 1, zIndex, borderStart, borderStart); diff --git a/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java b/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java deleted file mode 100644 index d82d0e5..0000000 --- a/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.anthonyhilyard.iceberg.network; - -import com.anthonyhilyard.iceberg.Loader; -import com.anthonyhilyard.iceberg.events.NewItemPickupCallback; - -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; -import net.fabricmc.fabric.api.networking.v1.PacketSender; -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.item.ItemStack; - -public final class IcebergNetworkProtocol -{ - private static final String VERSION = "v1"; - - private static final ResourceLocation SEND_ITEM_ID = new ResourceLocation(Loader.MODID, VERSION + '/' + String.valueOf(0)); - - public static void sendItemPickupEvent(ServerPlayer player, ItemStack item) - { - Loader.LOGGER.info("Sending item pickup event message!"); - if (!player.level.isClientSide) - { - // Build buffer. - FriendlyByteBuf buffer = PacketByteBufs.create(); - buffer.writeUUID(player.getUUID()); - buffer.writeItem(item); - - // Send packet. - ServerPlayNetworking.send(player, SEND_ITEM_ID, buffer); - } - } - - public static void handleItemPickupEvent(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) - { - Loader.LOGGER.info("receiving item pickup event message!"); - client.execute(() -> { - NewItemPickupCallback.EVENT.invoker().onItemPickup(buf.readUUID(), buf.readItem()); - }); - } - - public static void registerHandlers() - { - ClientPlayNetworking.registerGlobalReceiver(SEND_ITEM_ID, IcebergNetworkProtocol::handleItemPickupEvent); - } -} diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java index 26cdc14..6f8de4e 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java @@ -2,9 +2,43 @@ package com.anthonyhilyard.iceberg.util; import net.minecraft.world.item.ItemStack; import net.minecraft.network.chat.TextColor; +import net.minecraft.network.chat.Component; +import net.minecraft.ChatFormatting; public class ItemColor { + public static TextColor findFirstColorCode(Component textComponent) + { + // This function finds the first specified color code in the given text component. + // It is intended to skip non-color formatting codes. + String rawTitle = textComponent.getString(); + for (int i = 0; i < rawTitle.length(); i += 2) + { + // If we encounter a formatting code, check to see if it's a color. If so, return it. + if (rawTitle.charAt(i) == '\u00a7') + { + try + { + ChatFormatting format = ChatFormatting.getByCode(rawTitle.charAt(i + 1)); + if (format.isColor()) + { + return TextColor.fromLegacyFormat(format); + } + } + catch (StringIndexOutOfBoundsException e) + { + return null; + } + } + // Otherwise, if we encounter a non-formatting character, bail. + else + { + return null; + } + } + return null; + } + public static TextColor getColorForItem(ItemStack item, TextColor defaultColor) { TextColor result = null; @@ -21,12 +55,19 @@ public class ItemColor result = item.getItem().getName(item).getStyle().getColor(); } - // Finally, if the item has a special hover name TextColor (Stored in NBT), use that. + // If the item has a special hover name TextColor (Stored in NBT), use that. if (!item.getHoverName().getStyle().isEmpty() && item.getHoverName().getStyle().getColor() != null) { result = item.getHoverName().getStyle().getColor(); } + // Finally if there is a color code specified for the item name, use that. + TextColor formattingColor = findFirstColorCode(item.getItem().getName(item)); + if (formattingColor != null) + { + result = formattingColor; + } + // Fallback to the default TextColor if we somehow haven't found a single valid TextColor. if (result == null) { diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java index ec1dfc4..6d48c1a 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java @@ -1,35 +1,26 @@ package com.anthonyhilyard.iceberg.util; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import com.anthonyhilyard.iceberg.events.RenderTooltipEvents; -import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferUploader; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorExtResult; +import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.PreExtResult; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.screens.inventory.tooltip.ClientTextTooltip; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.Rect2i; +import net.minecraft.client.renderer.MultiBufferSource.BufferSource; import net.minecraft.client.renderer.entity.ItemRenderer; import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import com.mojang.math.Matrix4f; -import net.minecraft.network.chat.FormattedText; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.Style; public class Tooltips { @@ -41,82 +32,33 @@ public class Tooltips private int tooltipWidth = 0; private int titleLines = 1; private Font font; - private List<ClientTooltipComponent> lines = new ArrayList<>(); + private List<ClientTooltipComponent> components = new ArrayList<>(); - public TooltipInfo(List<ClientTooltipComponent> lines, Font font) + public TooltipInfo(List<ClientTooltipComponent> components, Font font) { - this.lines = lines; + this.components = components; this.font = font; } public int getTooltipWidth() { return tooltipWidth; } public int getTitleLines() { return titleLines; } public Font getFont() { return font; } - public List<ClientTooltipComponent> getLines() { return lines; } + public List<ClientTooltipComponent> getComponents() { return components; } public void setFont(Font font) { this.font = font; } public int getMaxLineWidth() { - int textWidth = 0; - for (ClientTooltipComponent component : lines) + int width = 0; + for (ClientTooltipComponent component : components) { int textLineWidth = component.getWidth(font); - if (textLineWidth > textWidth) + if (textLineWidth > width) { - textWidth = textLineWidth; + width = textLineWidth; } } - return textWidth; - } - - private List<ClientTextTooltip> splitComponent(ClientTextTooltip component, int maxWidth, Font font) - { - FormattedText text = FormattedText.composite(StringRecomposer.recompose(Arrays.asList(component))); - List<FormattedText> wrappedLines = font.getSplitter().splitLines(text, maxWidth, Style.EMPTY); - List<ClientTextTooltip> result = new ArrayList<>(); - - for (FormattedText wrappedLine : wrappedLines) - { - result.add(new ClientTextTooltip(Language.getInstance().getVisualOrder(wrappedLine))); - } - - return result; - } - - public void wrap(int maxWidth) - { - tooltipWidth = 0; - List<ClientTooltipComponent> wrappedLines = new ArrayList<>(); - for (int i = 0; i < lines.size(); i++) - { - ClientTooltipComponent textLine = lines.get(i); - - // Only wrap text lines. - // TODO: What to do with images that are too big? - if (!(textLine instanceof ClientTextTooltip)) - { - continue; - } - - List<ClientTextTooltip> wrappedLine = splitComponent((ClientTextTooltip)textLine, maxWidth, font); - if (i == 0) - { - titleLines = wrappedLine.size(); - } - - for (ClientTooltipComponent line : wrappedLine) - { - int lineWidth = line.getWidth(font); - if (lineWidth > tooltipWidth) - { - tooltipWidth = lineWidth; - } - wrappedLines.add(line); - } - } - - lines = wrappedLines; + return width; } } @@ -127,12 +69,11 @@ public class Tooltips } public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, - Rect2i rect, int screenWidth, int screenHeight, - int backgroundColor, int borderColorStart, int borderColorEnd) + Rect2i rect, int screenWidth, int screenHeight, + int backgroundColor, int borderColorStart, int borderColorEnd) { renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, false); } - public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, Rect2i rect, int screenWidth, int screenHeight, int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison) @@ -144,237 +85,138 @@ public class Tooltips Rect2i rect, int screenWidth, int screenHeight, int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain) { - // Initialize if needed. - if (!initialized) + renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, backgroundColor, borderColorStart, borderColorEnd, comparison, constrain); + } + + public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, + Rect2i rect, int screenWidth, int screenHeight, + int backgroundColorStart, int backgroundColorEnd, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain) + { + if (info.components.isEmpty()) { - init(Minecraft.getInstance()); + return; } - if (info.lines.isEmpty()) + // Initialize if needed. + if (!initialized) { - return; + init(Minecraft.getInstance()); } int rectX = rect.getX() - 8; int rectY = rect.getY() + 18; - int maxTextWidth = rect.getWidth() - 8; - InteractionResult result = RenderTooltipEvents.PRE.invoker().onPre(stack, info.getLines(), poseStack, rectX, rectY, screenWidth, screenHeight, maxTextWidth, info.getFont(), comparison); - if (result != InteractionResult.PASS) + PreExtResult preResult = RenderTooltipEvents.PREEXT.invoker().onPre(stack, info.getComponents(), poseStack, rectX, rectY, screenWidth, screenHeight, info.getFont(), comparison); + if (preResult.result() != InteractionResult.PASS) { return; } - boolean needsWrap = false; + rectX = preResult.x(); + rectY = preResult.y(); + screenWidth = preResult.screenWidth(); + screenHeight = preResult.screenHeight(); + info.setFont(preResult.font()); - int tooltipX = rectX + 12; - int tooltipTextWidth = info.getMaxLineWidth(); - - // Constrain the minimum width to the rect. - if (constrain) - { - tooltipTextWidth = Math.max(info.getMaxLineWidth(), rect.getWidth() - 8); - } - - if (tooltipX + tooltipTextWidth + 4 > screenWidth) - { - tooltipX = rectX - 16 - tooltipTextWidth; - if (tooltipX < 4) - { - if (rectX > screenWidth / 2) - { - tooltipTextWidth = rectX - 20; - } - else - { - tooltipTextWidth = screenWidth - 16 - rectX; - } - needsWrap = true; - } - } + poseStack.pushPose(); - if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth) - { - tooltipTextWidth = maxTextWidth; - needsWrap = true; - } + final int zLevel = 400; - if (needsWrap) - { - info.wrap(tooltipTextWidth); - tooltipTextWidth = info.getTooltipWidth(); - tooltipX = rectX + 12; - } + float f = itemRenderer.blitOffset; + itemRenderer.blitOffset = zLevel; + Matrix4f mat = poseStack.last().pose(); - int tooltipY = rectY - 12; - int tooltipHeight = 8; + ColorExtResult colors = RenderTooltipEvents.COLOREXT.invoker().onColor(stack, info.components, poseStack, rectX, rectY, info.getFont(), backgroundColorStart, backgroundColorEnd, borderColorStart, borderColorEnd, comparison); - if (info.getLines().size() > 1) - { - tooltipHeight += (info.getLines().size() - 1) * 10; - if (info.getLines().size() > info.getTitleLines()) - { - tooltipHeight += 2; // gap between title lines and next lines - } - } + backgroundColorStart = colors.backgroundStart(); + backgroundColorEnd = colors.backgroundEnd(); + borderColorStart = colors.borderStart(); + borderColorEnd = colors.borderEnd(); - if (tooltipY < 4) - { - tooltipY = 4; - } - else if (tooltipY + tooltipHeight + 4 > screenHeight) - { - tooltipY = screenHeight - tooltipHeight - 4; - } - - poseStack.pushPose(); - int bgColor = 0xF0100010; - int borderStart = 0x505000FF; - int borderEnd = 0x5028007F; + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 4, rectX + rect.getWidth() + 3, rectY - 3, backgroundColorStart, backgroundColorStart); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 4, backgroundColorEnd, backgroundColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 4, rectY - 3, rectX - 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 3, rectY - 3, rectX + rect.getWidth() + 4, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3 + 1, rectX - 3 + 1, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 2, rectY - 3 + 1, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY - 3 + 1, borderColorStart, borderColorStart); + GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 2, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, borderColorEnd, borderColorEnd); - ColorResult colors = RenderTooltipEvents.COLOR.invoker().onColor(stack, info.lines, poseStack, tooltipX, tooltipY, info.getFont(), bgColor, borderStart, borderEnd, comparison); + BufferSource renderType = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + poseStack.translate(0.0D, 0.0D, zLevel); - bgColor = colors.background(); - borderStart = colors.borderStart(); - borderEnd = colors.borderEnd(); + int tooltipTop = rectY; - float f = itemRenderer.blitOffset; - itemRenderer.blitOffset = 400.0F; - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder bufferBuilder = tesselator.getBuilder(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - Matrix4f mat = poseStack.last().pose(); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, 400, bgColor, bgColor); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, 400, bgColor, bgColor); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX + tooltipTextWidth + 3, tooltipY - 3, tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, 400, borderStart, borderEnd); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, 400, borderStart, borderEnd); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, 400, borderStart, borderStart); - GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, 400, borderEnd, borderEnd); - RenderSystem.enableDepthTest(); - RenderSystem.disableTexture(); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - bufferBuilder.end(); - BufferUploader.end(bufferBuilder); - RenderSystem.disableBlend(); - RenderSystem.enableTexture(); - - MultiBufferSource.BufferSource bufferSource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); - poseStack.translate(0.0D, 0.0D, 400.0D); - int v = tooltipY; - - ClientTooltipComponent clientTooltipComponent3; - for (int i = 0; i < info.getLines().size(); ++i) + for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber) { - clientTooltipComponent3 = (ClientTooltipComponent)info.getLines().get(i); - clientTooltipComponent3.renderText(info.getFont(), tooltipX, v, mat, bufferSource); - v += clientTooltipComponent3.getHeight() + (i == 0 ? 2 : 0); + ClientTooltipComponent textComponent = (ClientTooltipComponent)info.getComponents().get(componentNumber); + textComponent.renderText(info.getFont(), rectX, tooltipTop, mat, renderType); + tooltipTop += textComponent.getHeight() + (componentNumber == 0 ? 2 : 0); } - bufferSource.endBatch(); + renderType.endBatch(); poseStack.popPose(); - v = tooltipY; + tooltipTop = rectY; - for (int i = 0; i < info.getLines().size(); ++i) + for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber) { - clientTooltipComponent3 = (ClientTooltipComponent)info.getLines().get(i); - clientTooltipComponent3.renderImage(info.getFont(), tooltipX, v, poseStack, itemRenderer, 400); - v += clientTooltipComponent3.getHeight() + (i == 0 ? 2 : 0); + ClientTooltipComponent imageComponent = (ClientTooltipComponent)info.getComponents().get(componentNumber); + imageComponent.renderImage(info.getFont(), rectX, tooltipTop, poseStack, itemRenderer, 400); + tooltipTop += imageComponent.getHeight() + (componentNumber == 0 ? 2 : 0); } itemRenderer.blitOffset = f; - RenderTooltipEvents.POST.invoker().onPost(stack, info.getLines(), poseStack, tooltipX, tooltipY, info.getFont(), tooltipTextWidth, tooltipHeight, comparison); + RenderTooltipEvents.POST.invoker().onPost(stack, info.getComponents(), poseStack, rectX, rectY, info.getFont(), rect.getWidth(), rect.getHeight(), comparison); } - public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> textLines, int mouseX, int mouseY, + public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> components, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, Font font) { Rect2i rect = new Rect2i(0, 0, 0, 0); - if (textLines == null || textLines.isEmpty() || stack == null) + if (components == null || components.isEmpty() || stack == null) { return rect; } - int tooltipTextWidth = 0; - - for (ClientTooltipComponent textLine : textLines) + // Generate a tooltip event even though we aren't rendering anything in case event handlers are modifying the input values. + PreExtResult preResult = RenderTooltipEvents.PREEXT.invoker().onPre(stack, components, poseStack, mouseX, mouseY, screenWidth, screenHeight, font, false); + if (preResult.result() != InteractionResult.PASS) { - int textLineWidth = textLine.getWidth(font); - if (textLineWidth > tooltipTextWidth) - { - tooltipTextWidth = textLineWidth; - } + return rect; } - boolean needsWrap = false; - - int titleLinesCount = 1; - int tooltipX = mouseX + 14; - if (tooltipX + tooltipTextWidth + 4 > screenWidth) - { - tooltipX = mouseX - 16 - tooltipTextWidth; - if (tooltipX < 4) // if the tooltip doesn't fit on the screen - { - if (mouseX > screenWidth / 2) - { - tooltipTextWidth = mouseX - 14 - 8; - } - else - { - tooltipTextWidth = screenWidth - 16 - mouseX; - } - needsWrap = true; - } - } + mouseX = preResult.x(); + mouseY = preResult.y(); + screenWidth = preResult.screenWidth(); + screenHeight = preResult.screenHeight(); + font = preResult.font(); - if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth) - { - tooltipTextWidth = maxTextWidth; - needsWrap = true; - } + int tooltipTextWidth = 0; + int tooltipHeight = components.size() == 1 ? -2 : 0; - if (needsWrap) + for (ClientTooltipComponent component : components) { - TooltipInfo info = new TooltipInfo(textLines, font); - info.wrap(tooltipTextWidth); - - tooltipTextWidth = info.tooltipWidth; - textLines = info.lines; - - if (mouseX > screenWidth / 2) + int componentWidth = component.getWidth(font); + if (componentWidth > tooltipTextWidth) { - tooltipX = mouseX - 16 - tooltipTextWidth; + tooltipTextWidth = componentWidth; } - else - { - tooltipX = mouseX + 14; - } - } - int tooltipY = mouseY - 14; - int tooltipHeight = 8; - - if (textLines.size() > 1) - { - tooltipHeight += (textLines.size() - 1) * 10; - if (textLines.size() > titleLinesCount) - { - tooltipHeight += 2; // gap between title lines and next lines - } + tooltipHeight += component.getHeight(); } - if (tooltipY < 4) + int tooltipX = mouseX + 12; + int tooltipY = mouseY - 12; + if (tooltipX + tooltipTextWidth > screenWidth) { - tooltipY = 4; + tooltipX -= 28 + tooltipTextWidth; } - else if (tooltipY + tooltipHeight + 4 > screenHeight) + + if (tooltipY + tooltipHeight + 6 > screenHeight) { - tooltipY = screenHeight - tooltipHeight - 4; + tooltipY = screenHeight - tooltipHeight - 6; } rect = new Rect2i(tooltipX - 4, tooltipY - 4, tooltipTextWidth + 8, tooltipHeight + 8); diff --git a/src/main/resources/iceberg.mixins.json b/src/main/resources/iceberg.mixins.json index 758fce2..ed2f38f 100644 --- a/src/main/resources/iceberg.mixins.json +++ b/src/main/resources/iceberg.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "com.anthonyhilyard.iceberg.mixin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_17", "verbose": true, "mixins": [ "EntityMixin", @@ -16,6 +16,6 @@ "injectors": { "defaultRequire": 1 }, - "minVersion": "0.8.2", + "minVersion": "0.8.4", "target": "@env(DEFAULT)" } |