From f5d35697f524cda1736740e739f8afd902651c53 Mon Sep 17 00:00:00 2001 From: Anthony Hilyard Date: Sat, 4 Dec 2021 21:27:28 -0800 Subject: Initial 1.18 port. Overhauled tooltip handling, added color code item color support. --- build.gradle | 2 +- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew.bat | 45 +-- .../com/anthonyhilyard/iceberg/IcebergClient.java | 29 +- .../java/com/anthonyhilyard/iceberg/Loader.java | 27 +- .../iceberg/events/RenderTooltipExtEvent.java | 49 ++-- .../anthonyhilyard/iceberg/mixin/ScreenMixin.java | 7 +- .../iceberg/network/IcebergNetworkProtocol.java | 30 -- .../iceberg/network/NewItemPickupEventPacket.java | 45 --- .../com/anthonyhilyard/iceberg/util/ItemColor.java | 43 ++- .../com/anthonyhilyard/iceberg/util/Tooltips.java | 325 ++++++--------------- src/main/resources/META-INF/mods.toml | 6 +- src/main/resources/iceberg.mixins.json | 4 +- src/main/resources/pack.mcmeta | 3 +- 15 files changed, 214 insertions(+), 409 deletions(-) delete mode 100644 src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java delete mode 100644 src/main/java/com/anthonyhilyard/iceberg/network/NewItemPickupEventPacket.java diff --git a/build.gradle b/build.gradle index beb2d59..32990d9 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ apply plugin: 'eclipse' archivesBaseName = project.name + '-' + project.mcVersion -java.toolchain.languageVersion = JavaLanguageVersion.of(16) +java.toolchain.languageVersion = JavaLanguageVersion.of(17) mixin { add sourceSets.main, "${project.name.toLowerCase()}.refmap.json" diff --git a/gradle.properties b/gradle.properties index 9c4f785..1fcdaec 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ org.gradle.daemon=false name=${rootProject.name} group=com.anthonyhilyard.${name.toLowerCase()} author=anthonyhilyard -version=1.0.27 -mcVersion=1.17.1 -forgeVersion=37.0.90 +version=1.0.29 +mcVersion=1.18 +forgeVersion=38.0.12 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a2..e750102 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew.bat b/gradlew.bat index dee787c..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell @@ -81,4 +86,4 @@ exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega \ No newline at end of file +:omega diff --git a/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java b/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java index 3a860a2..edbfc1b 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java +++ b/src/main/java/com/anthonyhilyard/iceberg/IcebergClient.java @@ -5,7 +5,7 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -@Mod.EventBusSubscriber(modid = Loader.MODID, bus = Bus.MOD, value = Dist.CLIENT) +@Mod.EventBusSubscriber(modid = Loader.MODID, bus = Bus.FORGE, value = Dist.CLIENT) public class IcebergClient { public IcebergClient() @@ -14,13 +14,24 @@ public class IcebergClient public void onClientSetup(FMLClientSetupEvent event) { - event.enqueueWork(new Runnable() - { - @Override - public void run() - { - - } - }); + } + + // @SubscribeEvent + // public static void onTooltipPre(RenderTooltipEvent.Pre event) + // { + // Loader.LOGGER.info("tooltip pre"); + // } + + // @SubscribeEvent + // public static void onTooltipColor(RenderTooltipEvent.Color event) + // { + // Loader.LOGGER.info("tooltip color"); + // } + + // @SubscribeEvent + // public static void onTooltipPost(RenderTooltipExtEvent.Post event) + // { + // Loader.LOGGER.info("tooltip post"); + // } } diff --git a/src/main/java/com/anthonyhilyard/iceberg/Loader.java b/src/main/java/com/anthonyhilyard/iceberg/Loader.java index 7b7911b..ae7db63 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/Loader.java +++ b/src/main/java/com/anthonyhilyard/iceberg/Loader.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModLoadingContext; @@ -23,6 +24,7 @@ public class Loader if (FMLEnvironment.dist == Dist.CLIENT) { IcebergClient mod = new IcebergClient(); + MinecraftForge.EVENT_BUS.register(IcebergClient.class); FMLJavaModLoadingContext.get().getModEventBus().addListener(mod::onClientSetup); } else @@ -38,29 +40,4 @@ public class Loader { } - - // Event testing. - // - // @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.FORGE) - // public static class AdvancementEvents - // { - // @SubscribeEvent - // public static void onCriterion(final CriterionEvent event) - // { - // LOGGER.info("{} gained {} for {}!", event.getPlayer().getName().getString(), event.getCriterionKey(), event.getAdvancement().getId().toString()); - // } - - // @SubscribeEvent - // public static void onFluidEntered(final EntityFluidEvent.Entered event) - // { - // LOGGER.info("{} entered {}!", event.getEntity().getName().getString(), event.getFluid().getRegistryName().toString()); - // } - - // @SubscribeEvent - // public static void onFluidExited(final EntityFluidEvent.Exited event) - // { - // LOGGER.info("{} exited {}!", event.getEntity().getName().getString(), event.getFluid().getRegistryName().toString()); - // } - // } - } diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipExtEvent.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipExtEvent.java index 3ca2d37..98f01a6 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipExtEvent.java +++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipExtEvent.java @@ -5,61 +5,58 @@ import java.util.List; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.world.item.ItemStack; -import net.minecraft.network.chat.FormattedText; import net.minecraftforge.client.event.RenderTooltipEvent; public class RenderTooltipExtEvent { public static class Pre extends RenderTooltipEvent.Pre { - private boolean comparisonTooltip = false; + private final boolean comparisonTooltip; - @SuppressWarnings("removal") - public Pre(ItemStack stack, List lines, PoseStack PoseStack, int x, int y, int screenWidth, int screenHeight, int maxWidth, Font font, boolean comparison) + public Pre(ItemStack stack, PoseStack PoseStack, int x, int y, int screenWidth, int screenHeight, Font font, List components, boolean comparison) { - super(stack, lines, PoseStack, x, y, screenWidth, screenHeight, maxWidth, font); + super(stack, PoseStack, x, y, screenWidth, screenHeight, font, components); comparisonTooltip = comparison; } public boolean isComparison() { return comparisonTooltip; } } - @SuppressWarnings("removal") - public static class PostBackground extends RenderTooltipEvent.PostBackground + public static class Post extends RenderTooltipEvent { - private boolean comparisonTooltip = false; + private final boolean comparisonTooltip; + private final int width; + private final int height; - public PostBackground(ItemStack stack, List textLines, PoseStack PoseStack, int x, int y, Font font, int width, int height, boolean comparison) + public Post(ItemStack stack, PoseStack PoseStack, int x, int y, Font font, int width, int height, List components, boolean comparison) { - super(stack, textLines, PoseStack, x, y, font, width, height); - comparisonTooltip = comparison; - } - public boolean isComparison() { return comparisonTooltip; } - } + super(stack, PoseStack, x, y, font, components); + this.width = width; + this.height = height; - @SuppressWarnings("removal") - public static class PostText extends RenderTooltipEvent.PostText - { - private boolean comparisonTooltip = false; - - public PostText(ItemStack stack, List textLines, PoseStack PoseStack, int x, int y, Font font, int width, int height, boolean comparison) - { - super(stack, textLines, PoseStack, x, y, font, width, height); comparisonTooltip = comparison; } public boolean isComparison() { return comparisonTooltip; } + public int getWidth() { return width; } + public int getHeight() { return height; } } public static class Color extends RenderTooltipEvent.Color { - private boolean comparisonTooltip = false; + private final boolean comparisonTooltip; - @SuppressWarnings("removal") - public Color(ItemStack stack, List textLines, PoseStack PoseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, boolean comparison) + public Color(ItemStack stack, PoseStack PoseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, List components, boolean comparison) { - super(stack, textLines, PoseStack, x, y, font, background, borderStart, borderEnd); + super(stack, PoseStack, x, y, font, background, borderStart, borderEnd, components); comparisonTooltip = comparison; } + public Color(ItemStack stack, PoseStack PoseStack, int x, int y, Font font, int backgroundStart, int backgroundEnd, int borderStart, int borderEnd, List components, boolean comparison) + { + this(stack, PoseStack, x, y, font, backgroundStart, borderStart, borderEnd, components, comparison); + setBackgroundStart(backgroundStart); + setBackgroundEnd(backgroundEnd); + } public boolean isComparison() { return comparisonTooltip; } } } diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java index bbd2d6b..4c7e0c8 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java +++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java @@ -2,11 +2,10 @@ package com.anthonyhilyard.iceberg.mixin; import java.util.List; -import com.anthonyhilyard.iceberg.util.StringRecomposer; +import com.anthonyhilyard.iceberg.events.RenderTooltipExtEvent; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; -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 +36,9 @@ public class ScreenMixin extends AbstractContainerEventHandler @Shadow(remap = false) private ItemStack tooltipStack = ItemStack.EMPTY; - @Final @Shadow private final List children = Lists.newArrayList(); - @SuppressWarnings("removal") @Inject(method = "renderTooltipInternal", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;blitOffset:F", ordinal = 2, shift = Shift.AFTER), locals = LocalCapture.CAPTURE_FAILEXCEPTION) @@ -49,7 +46,7 @@ public class ScreenMixin extends AbstractContainerEventHandler { if (!components.isEmpty()) { - MinecraftForge.EVENT_BUS.post(new RenderTooltipEvent.PostText(tooltipStack, StringRecomposer.recompose(components), poseStack, postX, postY, ForgeHooksClient.getTooltipFont(tooltipFont, tooltipStack, font), tooltipWidth, tooltipHeight)); + MinecraftForge.EVENT_BUS.post(new RenderTooltipExtEvent.Post(tooltipStack, poseStack, postX, postY, ForgeHooksClient.getTooltipFont(tooltipFont, tooltipStack, font), tooltipWidth, tooltipHeight, components, false)); } } 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 4b5db06..0000000 --- a/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.anthonyhilyard.iceberg.network; - -import com.anthonyhilyard.iceberg.Loader; - -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.fmllegacy.network.NetworkRegistry; -import net.minecraftforge.fmllegacy.network.simple.SimpleChannel; - -public class IcebergNetworkProtocol -{ - private static final String NETWORK_PROTOCOL_VERSION = "1"; - - public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( - new ResourceLocation(Loader.MODID, "main"), () -> NETWORK_PROTOCOL_VERSION, - NETWORK_PROTOCOL_VERSION::equals, NETWORK_PROTOCOL_VERSION::equals - ); - - public static final void register() - { - int messageID = 0; - - CHANNEL.registerMessage( - messageID++, - NewItemPickupEventPacket.class, - NewItemPickupEventPacket::encode, - NewItemPickupEventPacket::decode, - NewItemPickupEventPacket::handle - ); - } -} diff --git a/src/main/java/com/anthonyhilyard/iceberg/network/NewItemPickupEventPacket.java b/src/main/java/com/anthonyhilyard/iceberg/network/NewItemPickupEventPacket.java deleted file mode 100644 index b99a36d..0000000 --- a/src/main/java/com/anthonyhilyard/iceberg/network/NewItemPickupEventPacket.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.anthonyhilyard.iceberg.network; - -import net.minecraft.world.item.ItemStack; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fmllegacy.network.NetworkEvent; - -import java.util.UUID; -import java.util.function.Supplier; - -import com.anthonyhilyard.iceberg.events.NewItemPickupEvent; - - -public final class NewItemPickupEventPacket -{ - private final UUID playerUUID; - private final ItemStack item; - - public NewItemPickupEventPacket(final UUID playerUUID, final ItemStack item) - { - this.playerUUID = playerUUID; - this.item = item; - } - - public static void encode(final NewItemPickupEventPacket msg, final FriendlyByteBuf packetBuffer) - { - packetBuffer.writeUUID(msg.playerUUID); - packetBuffer.writeItem(msg.item); - } - - public static NewItemPickupEventPacket decode(final FriendlyByteBuf packetBuffer) - { - return new NewItemPickupEventPacket(packetBuffer.readUUID(), packetBuffer.readItem()); - } - - public static void handle(final NewItemPickupEventPacket msg, final Supplier contextSupplier) - { - final NetworkEvent.Context context = contextSupplier.get(); - context.enqueueWork(() -> { - MinecraftForge.EVENT_BUS.post(new NewItemPickupEvent(msg.playerUUID, msg.item)); - }); - context.setPacketHandled(true); - } - -} \ No newline at end of file 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 bea4b5a..b3ab741 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java @@ -7,84 +7,58 @@ import javax.annotation.Nonnull; import com.anthonyhilyard.iceberg.events.RenderTooltipExtEvent; 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.ClientTooltipComponent; 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 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; import net.minecraftforge.client.event.RenderTooltipEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fmlclient.gui.GuiUtils; +import net.minecraftforge.client.gui.GuiUtils; public class Tooltips { + private static ItemRenderer itemRenderer = null; + public static class TooltipInfo { private int tooltipWidth = 0; private int titleLines = 1; private Font font; - private List lines = new ArrayList<>(); + private List components = new ArrayList<>(); - public TooltipInfo(List lines, Font font) + public TooltipInfo(List 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 getLines() { return lines; } + public List getComponents() { return components; } public void setFont(Font font) { this.font = font; } public int getMaxLineWidth() { - int textWidth = 0; - for (FormattedText textLine : lines) + int width = 0; + for (ClientTooltipComponent component : components) { - int textLineWidth = font.width(textLine); - if (textLineWidth > textWidth) + int componentWidth = component.getWidth(font); + if (componentWidth > width) { - textWidth = textLineWidth; + width = componentWidth; } } - return textWidth; - } - - public void wrap(int maxWidth) - { - tooltipWidth = 0; - List wrappedLines = new ArrayList<>(); - for (int i = 0; i < lines.size(); i++) - { - FormattedText textLine = lines.get(i); - List wrappedLine = font.getSplitter().splitLines(textLine, maxWidth, Style.EMPTY); - if (i == 0) - { - titleLines = wrappedLine.size(); - } - - for (FormattedText line : wrappedLine) - { - int lineWidth = font.width(line); - if (lineWidth > tooltipWidth) - { - tooltipWidth = lineWidth; - } - wrappedLines.add(line); - } - } - - lines = wrappedLines; + return width; } } @@ -102,159 +76,108 @@ public class Tooltips renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, comparison, false); } - @SuppressWarnings("removal") public static void renderItemTooltip(@Nonnull final ItemStack stack, PoseStack poseStack, TooltipInfo info, Rect2i rect, int screenWidth, int screenHeight, int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain) { - if (info.getLines().isEmpty()) - { - return; - } - - int rectX = rect.getX() - 8; - int rectY = rect.getY() + 18; - int maxTextWidth = rect.getWidth() - 8; + renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, backgroundColor, borderColorStart, borderColorEnd, comparison, constrain); + } - RenderTooltipExtEvent.Pre event = new RenderTooltipExtEvent.Pre(stack, info.getLines(), poseStack, rectX, rectY, screenWidth, screenHeight, maxTextWidth, info.getFont(), comparison); - if (MinecraftForge.EVENT_BUS.post(event)) + public static void renderItemTooltip(@Nonnull 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.getComponents().isEmpty()) { return; } - rectX = event.getX(); - rectY = event.getY(); - screenWidth = event.getScreenWidth(); - screenHeight = event.getScreenHeight(); - maxTextWidth = event.getMaxWidth(); - info.setFont(event.getFontRenderer()); - - RenderSystem.disableDepthTest(); - int tooltipTextWidth = info.getMaxLineWidth(); - - // Constrain the minimum width to the rect. - if (constrain) - { - tooltipTextWidth = Math.max(info.getMaxLineWidth(), rect.getWidth() - 8); - } - - boolean needsWrap = false; - - int tooltipX = rectX + 12; - if (tooltipX + tooltipTextWidth + 4 > screenWidth) + // Grab the itemRenderer now if needed. + if (itemRenderer == null) { - tooltipX = rectX - 16 - tooltipTextWidth; - if (tooltipX < 4) // if the tooltip doesn't fit on the screen - { - if (rectX > screenWidth / 2) - { - tooltipTextWidth = rectX - 12 - 8; - } - else - { - tooltipTextWidth = screenWidth - 16 - rectX; - } - needsWrap = true; - } + itemRenderer = Minecraft.getInstance().getItemRenderer(); } - if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth) - { - tooltipTextWidth = maxTextWidth; - needsWrap = true; - } - - if (needsWrap) + int rectX = rect.getX() - 8; + int rectY = rect.getY() + 18; + + RenderTooltipExtEvent.Pre preEvent = new RenderTooltipExtEvent.Pre(stack, poseStack, rectX, rectY, screenWidth, screenHeight, info.getFont(), info.getComponents(), comparison); + if (MinecraftForge.EVENT_BUS.post(preEvent)) { - info.wrap(tooltipTextWidth); - tooltipTextWidth = info.getTooltipWidth(); - tooltipX = rectX + 12; + return; } - int tooltipY = rectY - 12; - int tooltipHeight = 8; - - 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 - } - } + rectX = preEvent.getX(); + rectY = preEvent.getY(); + screenWidth = preEvent.getScreenWidth(); + screenHeight = preEvent.getScreenHeight(); + info.setFont(preEvent.getFont()); - if (tooltipY < 4) - { - tooltipY = 4; - } - else if (tooltipY + tooltipHeight + 4 > screenHeight) - { - tooltipY = screenHeight - tooltipHeight - 4; - } + poseStack.pushPose(); final int zLevel = 400; - RenderTooltipExtEvent.Color colorEvent = new RenderTooltipExtEvent.Color(stack, info.getLines(), poseStack, tooltipX, tooltipY, info.getFont(), backgroundColor, borderColorStart, borderColorEnd, comparison); + float f = itemRenderer.blitOffset; + itemRenderer.blitOffset = zLevel; + Matrix4f mat = poseStack.last().pose(); + + RenderTooltipExtEvent.Color colorEvent = new RenderTooltipExtEvent.Color(stack, poseStack, rectX, rectY, info.getFont(), backgroundColorStart, backgroundColorEnd, borderColorStart, borderColorEnd, info.getComponents(), comparison); MinecraftForge.EVENT_BUS.post(colorEvent); - backgroundColor = colorEvent.getBackground(); + + backgroundColorStart = colorEvent.getBackgroundStart(); + backgroundColorEnd = colorEvent.getBackgroundEnd(); borderColorStart = colorEvent.getBorderStart(); borderColorEnd = colorEvent.getBorderEnd(); - poseStack.pushPose(); - Matrix4f mat = poseStack.last().pose(); - - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX + tooltipTextWidth + 3, tooltipY - 3, tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, borderColorStart, borderColorStart); - GuiUtils.drawGradientRect(mat, zLevel, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColorEnd, borderColorEnd); - - MinecraftForge.EVENT_BUS.post(new RenderTooltipEvent.PostBackground(stack, info.getLines(), poseStack, tooltipX, tooltipY, info.getFont(), tooltipTextWidth, tooltipHeight)); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY - 4, rectX + rect.getWidth() + 3, rectY - 3, backgroundColorStart, backgroundColorStart); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 4, backgroundColorEnd, backgroundColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 4, rectY - 3, rectX - 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 3, rectY - 3, rectX + rect.getWidth() + 4, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3 + 1, rectX - 3 + 1, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 2, rectY - 3 + 1, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY - 3 + 1, borderColorStart, borderColorStart); + GuiUtils.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 2, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, borderColorEnd, borderColorEnd); BufferSource renderType = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); poseStack.translate(0.0D, 0.0D, zLevel); - int tooltipTop = tooltipY; + int tooltipTop = rectY; - for (int lineNumber = 0; lineNumber < info.getLines().size(); ++lineNumber) + for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber) { - FormattedText line = info.getLines().get(lineNumber); - if (line != null) - { - info.getFont().drawInBatch(Language.getInstance().getVisualOrder(line), (float)tooltipX, (float)tooltipY, -1, true, mat, renderType, false, 0, 15728880); - } - - if (lineNumber + 1 == info.getTitleLines()) - { - tooltipY += 2; - } - - tooltipY += 10; + ClientTooltipComponent textComponent = info.getComponents().get(componentNumber); + textComponent.renderText(preEvent.getFont(), rectX, tooltipTop, mat, renderType); + tooltipTop += textComponent.getHeight() + (componentNumber == 0 ? 2 : 0); } renderType.endBatch(); poseStack.popPose(); + tooltipTop = rectY; + + for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber) + { + ClientTooltipComponent imageComponent = info.getComponents().get(componentNumber); + imageComponent.renderImage(preEvent.getFont(), rectX, tooltipTop, poseStack, itemRenderer, 400); + tooltipTop += imageComponent.getHeight() + (componentNumber == 0 ? 2 : 0); + } - MinecraftForge.EVENT_BUS.post(new RenderTooltipExtEvent.PostText(stack, info.getLines(), poseStack, tooltipX, tooltipTop, info.getFont(), tooltipTextWidth, tooltipHeight, comparison)); + itemRenderer.blitOffset = f; - RenderSystem.enableDepthTest(); + RenderTooltipExtEvent.Post postEvent = new RenderTooltipExtEvent.Post(stack, poseStack, rectX, rectY, info.getFont(), rect.getWidth(), rect.getHeight(), info.getComponents(), comparison); + MinecraftForge.EVENT_BUS.post(postEvent); } - @SuppressWarnings("removal") - public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List textLines, int mouseX, int mouseY, - int screenWidth, int screenHeight, int maxTextWidth, Font font) + public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List 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; } - // Generate a tooltip event even though we aren't rendering anything in case the event handlers are modifying the input values. - RenderTooltipEvent.Pre event = new RenderTooltipEvent.Pre(stack, textLines, poseStack, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, font); + // Generate a tooltip event even though we aren't rendering anything in case event handlers are modifying the input values. + RenderTooltipEvent.Pre event = new RenderTooltipEvent.Pre(stack, poseStack, mouseX, mouseY, screenWidth, screenHeight, font, components); if (MinecraftForge.EVENT_BUS.post(event)) { return rect; @@ -264,102 +187,32 @@ public class Tooltips mouseY = event.getY(); screenWidth = event.getScreenWidth(); screenHeight = event.getScreenHeight(); - maxTextWidth = event.getMaxWidth(); - font = event.getFontRenderer(); + font = event.getFont(); int tooltipTextWidth = 0; + int tooltipHeight = components.size() == 1 ? -2 : 0; - for (FormattedText textLine : textLines) - { - int textLineWidth = font.width(textLine); - if (textLineWidth > tooltipTextWidth) - { - tooltipTextWidth = textLineWidth; - } - } - - 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; - } - } - - if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth) - { - tooltipTextWidth = maxTextWidth; - needsWrap = true; - } - - if (needsWrap) + for (ClientTooltipComponent component : components) { - int wrappedTooltipWidth = 0; - List wrappedTextLines = new ArrayList<>(); - for (int i = 0; i < textLines.size(); i++) + int componentWidth = component.getWidth(event.getFont()); + if (componentWidth > tooltipTextWidth) { - FormattedText textLine = textLines.get(i); - List wrappedLine = font.getSplitter().splitLines(textLine, tooltipTextWidth, Style.EMPTY); - if (i == 0) - { - titleLinesCount = wrappedLine.size(); - } - - for (FormattedText line : wrappedLine) - { - int lineWidth = font.width(line); - if (lineWidth > wrappedTooltipWidth) - { - wrappedTooltipWidth = lineWidth; - } - wrappedTextLines.add(line); - } + tooltipTextWidth = componentWidth; } - tooltipTextWidth = wrappedTooltipWidth; - textLines = wrappedTextLines; - if (mouseX > screenWidth / 2) - { - tooltipX = mouseX - 16 - tooltipTextWidth; - } - else - { - tooltipX = mouseX + 14; - } + tooltipHeight += component.getHeight(); } - int tooltipY = mouseY - 14; - int tooltipHeight = 8; - - if (textLines.size() > 1) + int tooltipX = mouseX + 12; + int tooltipY = mouseY - 12; + if (tooltipX + tooltipTextWidth > screenWidth) { - tooltipHeight += (textLines.size() - 1) * 10; - if (textLines.size() > titleLinesCount) - { - tooltipHeight += 2; // gap between title lines and next lines - } + tooltipX -= 28 + tooltipTextWidth; } - if (tooltipY < 4) - { - tooltipY = 4; - } - 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/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 7623938..256313d 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,5 +1,5 @@ modLoader="javafml" -loaderVersion="[37,)" +loaderVersion="[38,)" license="CC BY-NC-ND 4.0" [[mods]] @@ -15,13 +15,13 @@ description="A library containing events, helpers, and utilities to make modding [[dependencies.iceberg]] modId="forge" mandatory=true - versionRange="[37,)" + versionRange="[38,)" ordering="NONE" side="BOTH" [[dependencies.iceberg]] modId="minecraft" mandatory=true - versionRange="[1.17.1]" + versionRange="[1.18]" ordering="NONE" side="BOTH" \ No newline at end of file diff --git a/src/main/resources/iceberg.mixins.json b/src/main/resources/iceberg.mixins.json index 927fd30..93984a4 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_8", + "compatibilityLevel": "JAVA_16", "refmap": "iceberg.refmap.json", "mixins": [ "EntityMixin", @@ -14,6 +14,6 @@ "injectors": { "defaultRequire": 1 }, - "minVersion": "0.8.4", + "minVersion": "0.8.5", "target": "@env(DEFAULT)" } diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 709504e..f8afc50 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,6 @@ { "pack": { "description": "iceberg resources", - "pack_format": 6, - "_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods." + "pack_format": 8 } } -- cgit