diff --git a/CHANGELOG.md b/CHANGELOG.md index 2980b00..8b82d53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2.0.0+1.20.5 - 2025-07-29 + +### Added + +- Internal refactoring to allow for interoperability with other mods + ## 1.2.0+1.20.5 - 2024-04-26 ### Added diff --git a/README.md b/README.md index 3a0baac..ee179a8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Status Effect Timer -[![Modrinth](https://img.shields.io/modrinth/dt/statuseffecttimer?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAHZklEQVRoge1afYxUVxV%2FW5aydEsspWrFUkM%2FUlOTes99M0OmUB0TXdhKUpSuf4itmrZUUChitNpz7uSK7dJ1k6VdpAaIxPrVhDYa77lvmKGr01CypUrTFrIx8Q%2FRkvpFC4IFKVt4%2FjEz5M3beW%2Fna7sx8ST3r3n33N%2F5uOfrjuP8n6LJ9%2F0O3%2Fc7phvHpJQp6i43R9dLj5aBpXWC1QAw7hSGfgpMPxZMPwBLCgzelWCdcllfpX19yXSD7oScvlka%2BjoweWDoNcF4Vhj0oxedB8Z%2FAdMrwPSE9Gh5Oq%2BvfPeBs0oD404w9LpgvBAPOnoB03%2BAaRQsrbm1oN835eCTVl8HjI8D07EYUOPAdBKY%2FiaYjpaEpDfjrANM42DwBTDZlb254VltB97n754hOfsZYDo0AQDjBWHoH8CYl0waTHZlgnUqsYduSlp9nczrG5KeFtJmlwKr9YLpZ8D0R2Aar%2BFi%2F5YWt6X54Q%2B2DXx6dGg2WHpQGDoR9mfBeFgaQrlH35Ip6q56lZEs4AJgdbdgKoDBMxMUwlQEVh9tGXxPYbBbsBqYYH6mo8LiQ61qKlPUl0tPfU4wHRCGzofc6hCwSjfNvDc3PEtYehgYz4W0UxBGJdsZ32Gvni8sDQnGt0LWOOyylk0xFUatDZoXmMYF046pihZ9Y%2FpSaej%2BcIAApn0u62sbYgYefgwY%2F3qRicF3gHHr4v0Dc6YCfIV83%2B%2BQjKvA4BvVQuDOeu%2BYkxrpnweMIyEt%2FDxT1Fc0A6o3Nzxrid08t16X832%2FAyytAabTAQWekYyr6joQWK0Hg%2B8ENv8%2BVaCFjYB2D26fKZhuBEv3CKZfAdM%2BYfHWevf35oZnAePWkBIPwl49P3ZjKbxVxfpTwsveUc%2BhmaLuTBVoIbC6G5ieAkOvVSmC8Q%2BuzX6iXiFc1tcC40vBAAKMG2M3SaavBksDYHqyb0xfOtlhyQIuEEw7hMEjtRNUxZr0i0YyrbD4RWHo7YASXooMIov3D8wRjL8NSHxcWnXbZIeUcgXtqqP2OdJoXE%2Fn9ZWC6flA8nwbmO6s%2BTGwSgezLTD9erKbX75w3whqKWKdAoN3NQK%2BQtKqDaEkuqtmKQ6MG4Wh86WQSeOS6b7JmIPJ9gLjP2MrzhK%2Ffvfg9pnNCCCMSgrG4wF%2BY0lPXz3hw6SnBZjsSmnps8LL3gG5%2FvfGMU7soZuA6ZW4ClMwvgyMG5sNwY7jOEvs5rmC8cWgNRM5tbhZfo7jOE6mqK8AxmdiwP9FsLp30cgj72%2FpoDJJi9uC%2FCXTl1sB3wlMm4IhMuzv0qov1MvPPbh9Znp0aHbcN4LVvVUKsuq7TQtQigxVJg31B2ogU9Sdk%2FHJFHVXuWT5kbRqMC68ujb76VA4%2FWHTAjiO4wimB8Ll78VkY2lN3N6ewmC3y7RCMP6yEvWA6aT0aHnUngRTJlRYPtlSNZz09NXA9LvaFsAXo5JNxf1qtpdMxajL3nYBHMdxwNI9Vb1CIGwKpgdqHeAyrZjY2V0E5UVVu9Kj5cGzWnYhx6lUrTQaAeYYWFpXSYQ9hcFu4WU%2FJRgPR9ydv7uMS6LOKltgrCIEMG1qCbzv%2Bx3So2XC0J9iEtgZYHwcLK0Bg3uB6WSEy12QTDrOJbSvLyl1bdgHTD8Bk1054SMw6uOS1deEUWulofsX5fQ1tZhlirpTeupLwYYnetH5mpe92vefbyRfZIq6s2ZWL5USwVhL68LfuKwvE0zfidRmw4tOCKbb6wUfS66nFlXVHIz5nsJgd%2BX31Ej%2FPDA0PPn4sP4lmR6rJ2fURZmivhwM%2FaY6o2aXOo7jgIcfAqanI93h4iyH9tUDHJiOCaZdyQIuaAv4Cgmj1gZBAmM%2BwZQBpufi%2FByYnoK9ev6inL6m1I3VKDNKjdIRYXALeDrRbHUaS2UAhwICnIufg%2BI5aXFbcMK8xG6eKwxuqbhaee75qrD4kGC6ccrH6uGmPsYNTgPTpuA9qVB6dGi2ZPomMD0rme5z8498oBEMi%2FcPzAFWX5EeLWu4FK81VqnhDseB1fq4fjlT1J0u68saOtyplBv47XL7eBqYRqVVG2opKpLCg63qBEWvS8ZVff7uGY2Cqwd86R7iqVCu2NHw2D08Wixr%2Fqy0anW7gTtOKceApQfDOQaY9jUVraKGu%2BUXlU%2B20wJujq4XTLvCOQaYDiVyCppm3FMY7AZDj05gbPANYWnIZf3hVqJKaqR%2FnrRqNRgcqxEkWhuvV6gUUfBbwSwdsMafhcEt0qrb3GcffU89NXqmqLsgp2%2BWVm0QTAdqluRMzyU9LVoGX6E%2Bf%2FcMl2kFGHw1IqSeLIPZKq1aLW12aYJ1qvS0pNwEU0aw%2Bjyw%2Bh4w5koBomZH9xYwPdHWJ6YgpQq0UDI9FpfcSmUFni0L9aYwdKI0aY6uSstN0AFgunNKHvmC1PZnVoMvvGvPrGFBknn1EWDcCIw5wXS0nofuUgmNL0uL26bloTtCmC6Z1zcIptvLT6nfD%2F7VABi3AiNJxlXCqGRqpH%2FetP%2FVoB76n%2Fijx3TTfwGWd%2FQ%2FPbYNFgAAAABJRU5ErkJggg%3D%3D)](https://modrinth.com/mod/statuseffecttimer) -[![CurseForge](https://cf.way2muchnoise.eu/short_status-effect-timer.svg)](https://www.curseforge.com/minecraft/mc-mods/status-effect-timer) +[![Modrinth](https://img.shields.io/modrinth/dt/statuseffecttimer?logo=modrinth)](https://modrinth.com/mod/statuseffecttimer) +[![CurseForge](https://img.shields.io/curseforge/dt/484738?logo=curseforge)](https://www.curseforge.com/minecraft/mc-mods/status-effect-timer) [![GitHub](https://img.shields.io/github/downloads/magicus/statuseffecttimer/total?logo=github)](https://github.com/magicus/statuseffecttimer/releases) +![Logo](docs/logo.png) + This is a Minecraft mod for Fabric that overlays a timer on the Vanilla status effect HUD icons. This mod overlays the time left of the status effect on the vanilla indicator. If the effect has an amplifier (as in "Haste II"), the amplifier is also overlaid. That's it. This is a very minimalistic mod. No settings are required nor provided. @@ -42,4 +44,4 @@ Do you have any problems with the mod? Please open an issue here on Github. This mod does not work if the mod ['Slight' Gui Modifications](https://github.com/shedaniel/slight-gui-modifications) is installed and the configuration `fluidStatusEffects` is enabled. -This mod conflicts with [Giselbaer's Durability Viewer](https://github.com/gbl/DurabilityViewer), since that mod also draws a timer on the status effect icon. You need to disable the effect time feature in Durability Viewer to avoid clutter. +This mod conflicts with [Giselbaer's Durability Viewer](https://github.com/gbl/DurabilityViewer), since that mod also draws a timer on the status effect icon. You need to disable the effect time feature in Durability Viewer to avoid clutter. diff --git a/build.gradle b/build.gradle index 3959ace..a13029f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'fabric-loom' version '1.6-SNAPSHOT' + id 'fabric-loom' version '1.11.4' } dependencies { diff --git a/gradle.properties b/gradle.properties index b7301ef..cd732c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Mod version -mod_version=1.2.0 +mod_version=2.0.0 # Minecraft/Java version # Also hardcoded in fabric.mod.json and *.mixin.json diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23..ca025c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 6689b85..7101f8e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/se/icus/mag/statuseffecttimer/StatusEffectTimerRenderer.java b/src/main/java/se/icus/mag/statuseffecttimer/StatusEffectTimerRenderer.java new file mode 100644 index 0000000..0eae279 --- /dev/null +++ b/src/main/java/se/icus/mag/statuseffecttimer/StatusEffectTimerRenderer.java @@ -0,0 +1,40 @@ +package se.icus.mag.statuseffecttimer; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.util.math.MathHelper; + +public class StatusEffectTimerRenderer { + public void drawStatusEffectOverlay(MinecraftClient client, DrawContext context, StatusEffectInstance statusEffectInstance, int x, int y) { + String duration = getDurationAsString(statusEffectInstance); + int durationLength = client.textRenderer.getWidth(duration); + context.drawTextWithShadow(client.textRenderer, duration, x + 13 - (durationLength / 2), y + 14, 0x99FFFFFF); + + int amplifier = statusEffectInstance.getAmplifier(); + if (amplifier > 0) { + // Convert to roman numerals if possible + String amplifierString = (amplifier < 10) ? I18n.translate("enchantment.level." + (amplifier + 1)) : "**"; + int amplifierLength = client.textRenderer.getWidth(amplifierString); + context.drawTextWithShadow(client.textRenderer, amplifierString, x + 22 - amplifierLength, y + 3, 0x99FFFFFF); + } + } + + private String getDurationAsString(StatusEffectInstance statusEffectInstance) { + if (statusEffectInstance.isInfinite()) { + return I18n.translate("effect.duration.infinite"); + } + + int ticks = MathHelper.floor((float) statusEffectInstance.getDuration()); + int seconds = ticks / 20; + + if (seconds >= 3600) { + return seconds / 3600 + "h"; + } else if (seconds >= 60) { + return seconds / 60 + "m"; + } else { + return String.valueOf(seconds); + } + } +} diff --git a/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java b/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java index 690f3af..6b12cec 100644 --- a/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java +++ b/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java @@ -6,15 +6,15 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.resource.language.I18n; import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.util.math.MathHelper; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import se.icus.mag.statuseffecttimer.StatusEffectTimerRenderer; import java.util.List; @@ -22,6 +22,9 @@ @Environment(EnvType.CLIENT) @Mixin(value = InGameHud.class, priority = 500) public abstract class StatusEffectTimerMixin { + @Unique + private StatusEffectTimerRenderer renderer = new StatusEffectTimerRenderer(); + @Shadow @Final private MinecraftClient client; @@ -31,38 +34,7 @@ private void appendOverlayDrawing(DrawContext context, float tickDelta, Callback @Local List list, @Local StatusEffectInstance statusEffectInstance, @Local(ordinal = 4) int x, @Local(ordinal = 3) int y) { list.add(() -> { - drawStatusEffectOverlay(context, statusEffectInstance, x, y); + renderer.drawStatusEffectOverlay(client, context, statusEffectInstance, x, y); }); } - - private void drawStatusEffectOverlay(DrawContext context, StatusEffectInstance statusEffectInstance, int x, int y) { - String duration = getDurationAsString(statusEffectInstance); - int durationLength = client.textRenderer.getWidth(duration); - context.drawTextWithShadow(client.textRenderer, duration, x + 13 - (durationLength / 2), y + 14, 0x99FFFFFF); - - int amplifier = statusEffectInstance.getAmplifier(); - if (amplifier > 0) { - // Convert to roman numerals if possible - String amplifierString = (amplifier < 10) ? I18n.translate("enchantment.level." + (amplifier + 1)) : "**"; - int amplifierLength = client.textRenderer.getWidth(amplifierString); - context.drawTextWithShadow(client.textRenderer, amplifierString, x + 22 - amplifierLength, y + 3, 0x99FFFFFF); - } - } - - private String getDurationAsString(StatusEffectInstance statusEffectInstance) { - if (statusEffectInstance.isInfinite()) { - return I18n.translate("effect.duration.infinite"); - } - - int ticks = MathHelper.floor((float) statusEffectInstance.getDuration()); - int seconds = ticks / 20; - - if (seconds >= 3600) { - return seconds / 3600 + "h"; - } else if (seconds >= 60) { - return seconds / 60 + "m"; - } else { - return String.valueOf(seconds); - } - } }