diff --git a/changelog.md b/changelog.md
index eaf1142..19633ee 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1 +1,2 @@
- Add Ukrainian translation (Tarteroycc)
+- Improve GUI mixin
diff --git a/common/src/main/java/dev/terminalmc/effecttimerplus/gui/screen/YaclScreenProvider.java b/common/src/main/java/dev/terminalmc/effecttimerplus/gui/screen/YaclScreenProvider.java
index 8c59748..bc29a41 100644
--- a/common/src/main/java/dev/terminalmc/effecttimerplus/gui/screen/YaclScreenProvider.java
+++ b/common/src/main/java/dev/terminalmc/effecttimerplus/gui/screen/YaclScreenProvider.java
@@ -341,20 +341,23 @@ public int render(GuiGraphics graphics, int x, int y, int width, float delta) {
int targetHeight = space;
int maxX = (int)(x + width / scale);
+ int spriteSize = 24;
+ int iconSize = 18;
+
for (MobEffectInstance effect : DEMO_EFFECTS) {
if (effect.isAmbient()) {
- graphics.blitSprite(GuiAccessor.getEffectBackgroundAmbientSprite(), movingX, movingY, 24, 24);
+ graphics.blitSprite(GuiAccessor.getEffectBackgroundAmbientSprite(), movingX, movingY, spriteSize, spriteSize);
} else {
- graphics.blitSprite(GuiAccessor.getEffectBackgroundSprite(), movingX, movingY, 24, 24);
+ graphics.blitSprite(GuiAccessor.getEffectBackgroundSprite(), movingX, movingY, spriteSize, spriteSize);
}
- graphics.blit(movingX + 3, movingY + 3, 0, 18, 18, mc.getMobEffectTextures().get(effect.getEffect()));
+ graphics.blit(movingX + 3, movingY + 3, 0, iconSize, iconSize, mc.getMobEffectTextures().get(effect.getEffect()));
// Render potency overlay
if (potencyEnabled && effect.getAmplifier() > 0) {
String label = IndicatorUtil.getAmplifierAsString(effect.getAmplifier());
int labelWidth = mc.font.width(label);
- int pX = movingX + IndicatorUtil.getTextOffsetX(potencyLocation, labelWidth);
- int pY = movingY + IndicatorUtil.getTextOffsetY(potencyLocation, mc.font.lineHeight);
+ int pX = movingX + IndicatorUtil.getTextOffsetX(potencyLocation, labelWidth, spriteSize);
+ int pY = movingY + IndicatorUtil.getTextOffsetY(potencyLocation, mc.font.lineHeight, spriteSize);
graphics.pose().pushPose();
graphics.pose().translate(pX * (1 - potencyScale), pY * (1 - potencyScale), 0.0F);
@@ -371,8 +374,8 @@ public int render(GuiGraphics graphics, int x, int y, int width, float delta) {
if (timerEnabled && (timerEnabledAmbient || !effect.isAmbient())) {
String label = IndicatorUtil.getDurationAsString(effect.getDuration());
int labelWidth = mc.font.width(label);
- int pX = movingX + IndicatorUtil.getTextOffsetX(timerLocation, labelWidth);
- int pY = movingY + IndicatorUtil.getTextOffsetY(timerLocation, mc.font.lineHeight);
+ int pX = movingX + IndicatorUtil.getTextOffsetX(timerLocation, labelWidth, spriteSize);
+ int pY = movingY + IndicatorUtil.getTextOffsetY(timerLocation, mc.font.lineHeight, spriteSize);
graphics.pose().pushPose();
graphics.pose().translate(pX * (1 - timerScale), pY * (1 - timerScale), 0.0F);
diff --git a/common/src/main/java/dev/terminalmc/effecttimerplus/mixin/MixinGui.java b/common/src/main/java/dev/terminalmc/effecttimerplus/mixin/MixinGui.java
index 7db0315..4471531 100644
--- a/common/src/main/java/dev/terminalmc/effecttimerplus/mixin/MixinGui.java
+++ b/common/src/main/java/dev/terminalmc/effecttimerplus/mixin/MixinGui.java
@@ -1,30 +1,26 @@
package dev.terminalmc.effecttimerplus.mixin;
-import com.google.common.collect.Ordering;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
import dev.terminalmc.effecttimerplus.config.Config;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen;
-import net.minecraft.core.Holder;
-import net.minecraft.world.effect.MobEffect;
+import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffectInstance;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import java.util.Collection;
+import java.util.List;
import static dev.terminalmc.effecttimerplus.util.IndicatorUtil.*;
-/**
- * Includes derivative work of code used by
- * Status Effect Timer
- */
@Mixin(value = Gui.class, priority = 500)
public class MixinGui {
@@ -32,91 +28,101 @@ public class MixinGui {
@Shadow
private Minecraft minecraft;
- @Inject(method = "renderEffects", at = @At("HEAD"))
- private void scaleGraphics(GuiGraphics graphics, DeltaTracker delta, CallbackInfo ci) {
+ @Unique
+ @Nullable
+ private Runnable effectTimerPlus$runnable;
+
+ @Inject(
+ method = "renderEffects",
+ at = @At("HEAD")
+ )
+ private void scale(GuiGraphics graphics, DeltaTracker delta, CallbackInfo ci) {
float scale = (float) Config.get().scale;
graphics.pose().pushPose();
graphics.pose().translate(graphics.guiWidth() * (1 - scale), 0.0F, 0.0F);
graphics.pose().scale(scale, scale, 0.0F);
}
- @Inject(method = "renderEffects", at = @At("RETURN"))
- private void descaleGraphicsAndOverlay(GuiGraphics graphics, DeltaTracker delta, CallbackInfo ci) {
- // Replicate vanilla placement algorithm to place labels correctly
- Collection effects = this.minecraft.player.getActiveEffects();
-
- if (effects.isEmpty() || this.minecraft.screen instanceof EffectRenderingInventoryScreen) {
- graphics.pose().popPose();
- return;
- }
-
- int beneficialCount = 0;
- int nonBeneficialCount = 0;
-
- for (MobEffectInstance effectInstance : Ordering.natural().reverse().sortedCopy(effects)) {
- Holder effect = effectInstance.getEffect();
- if (effectInstance.showIcon()) {
- int x = graphics.guiWidth();
- int y = 1;
- if (this.minecraft.isDemo()) {
- y += 15;
- }
+ @Inject(
+ method = "renderEffects",
+ at = @At("RETURN")
+ )
+ private void descale(GuiGraphics graphics, DeltaTracker delta, CallbackInfo ci) {
+ graphics.pose().popPose();
+ }
- if (effect.value().isBeneficial()) {
- ++beneficialCount;
- x -= 25 * beneficialCount;
- } else {
- ++nonBeneficialCount;
- x -= 25 * nonBeneficialCount;
- y += 26;
- }
+ @WrapOperation(
+ method = "renderEffects",
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/client/gui/GuiGraphics;blitSprite(Lnet/minecraft/resources/ResourceLocation;IIII)V"
+ )
+ )
+ private void CreateOverlayRunnable(GuiGraphics graphics, ResourceLocation sprite, int x, int y,
+ int width, int height, Operation original,
+ @Local MobEffectInstance effectInstance) {
+ original.call(graphics, sprite, x, y, width, height);
- Config options = Config.get();
- // Render potency overlay
- if (options.potencyEnabled && effectInstance.getAmplifier() > 0) {
- String label = getAmplifierAsString(effectInstance.getAmplifier());
- int labelWidth = minecraft.font.width(label);
- int posX = x + getTextOffsetX(options.potencyLocation, labelWidth);
- int posY = y + getTextOffsetY(options.potencyLocation, minecraft.font.lineHeight);
+ Config options = Config.get();
+ effectTimerPlus$runnable = () -> {
+ // Render potency overlay
+ if (options.potencyEnabled && effectInstance.getAmplifier() > 0) {
+ String label = getAmplifierAsString(effectInstance.getAmplifier());
+ int labelWidth = minecraft.font.width(label);
+ int posX = x + getTextOffsetX(options.potencyLocation, labelWidth, width);
+ int posY = y + getTextOffsetY(options.potencyLocation, minecraft.font.lineHeight, height);
- float scale = (float)Config.get().potencyScale;
- graphics.pose().pushPose();
- graphics.pose().translate(posX * (1 - scale), posY * (1 - scale), 0.0F);
- graphics.pose().translate(getScaleTranslateX(options.potencyLocation, labelWidth, scale),
- getScaleTranslateY(options.potencyLocation, minecraft.font.lineHeight, scale), 0.0F);
- graphics.pose().scale(scale, scale, 0.0F);
- if (options.potencyBack) {
- graphics.fill(posX - 1, posY - 1, posX + labelWidth,
- posY + minecraft.font.lineHeight - 1, options.potencyBackColor);
- }
- graphics.drawString(minecraft.font, label, posX, posY, options.potencyColor, options.potencyShadow);
- graphics.pose().popPose();
+ float scale = (float)Config.get().potencyScale;
+ graphics.pose().pushPose();
+ graphics.pose().translate(posX * (1 - scale), posY * (1 - scale), 0.0F);
+ graphics.pose().translate(getScaleTranslateX(options.potencyLocation, labelWidth, scale),
+ getScaleTranslateY(options.potencyLocation, minecraft.font.lineHeight, scale), 0.0F);
+ graphics.pose().scale(scale, scale, 0.0F);
+ if (options.potencyBack) {
+ graphics.fill(posX - 1, posY - 1, posX + labelWidth,
+ posY + minecraft.font.lineHeight - 1, options.potencyBackColor);
}
- // Render timer overlay
- if (options.timerEnabled && (options.timerEnabledAmbient || !effectInstance.isAmbient())) {
- String label = getDurationAsString(effectInstance.getDuration());
- int labelWidth = minecraft.font.width(label);
- int posX = x + getTextOffsetX(options.timerLocation, labelWidth);
- int posY = y + getTextOffsetY(options.timerLocation, minecraft.font.lineHeight);
+ graphics.drawString(minecraft.font, label, posX, posY, options.potencyColor, options.potencyShadow);
+ graphics.pose().popPose();
+ }
+ // Render timer overlay
+ if (options.timerEnabled && (options.timerEnabledAmbient || !effectInstance.isAmbient())) {
+ String label = getDurationAsString(effectInstance.getDuration());
+ int labelWidth = minecraft.font.width(label);
+ int posX = x + getTextOffsetX(options.timerLocation, labelWidth, width);
+ int posY = y + getTextOffsetY(options.timerLocation, minecraft.font.lineHeight, height);
- int color = getTimerColor(effectInstance, options.timerColor,
- options.timerWarnEnabled, options.timerWarnTime,
- options.timerWarnColor, options.timerFlashEnabled);
- float scale = (float)Config.get().timerScale;
- graphics.pose().pushPose();
- graphics.pose().translate(posX * (1 - scale), posY * (1 - scale), 0.0F);
- graphics.pose().translate(getScaleTranslateX(options.timerLocation, labelWidth, scale),
- getScaleTranslateY(options.timerLocation, minecraft.font.lineHeight, scale), 0.0F);
- graphics.pose().scale(scale, scale, 0.0F);
- if (options.timerBack) {
- graphics.fill(posX - 1, posY - 1, posX + labelWidth,
- posY + minecraft.font.lineHeight - 1, options.timerBackColor);
- }
- graphics.drawString(minecraft.font, label, posX, posY, color, options.timerShadow);
- graphics.pose().popPose();
+ int color = getTimerColor(effectInstance, options.timerColor,
+ options.timerWarnEnabled, options.timerWarnTime,
+ options.timerWarnColor, options.timerFlashEnabled);
+ float scale = (float)Config.get().timerScale;
+ graphics.pose().pushPose();
+ graphics.pose().translate(posX * (1 - scale), posY * (1 - scale), 0.0F);
+ graphics.pose().translate(getScaleTranslateX(options.timerLocation, labelWidth, scale),
+ getScaleTranslateY(options.timerLocation, minecraft.font.lineHeight, scale), 0.0F);
+ graphics.pose().scale(scale, scale, 0.0F);
+ if (options.timerBack) {
+ graphics.fill(posX - 1, posY - 1, posX + labelWidth,
+ posY + minecraft.font.lineHeight - 1, options.timerBackColor);
}
+ graphics.drawString(minecraft.font, label, posX, posY, color, options.timerShadow);
+ graphics.pose().popPose();
}
+ };
+ }
+
+ @ModifyExpressionValue(
+ method = "renderEffects",
+ at = @At(
+ value = "INVOKE",
+ target = "Ljava/util/List;add(Ljava/lang/Object;)Z"
+ )
+ )
+ private boolean AddOverlayRunnable(boolean original, @Local List runnables) {
+ if (effectTimerPlus$runnable != null) {
+ runnables.add(effectTimerPlus$runnable);
+ effectTimerPlus$runnable = null;
}
- graphics.pose().popPose();
+ return original;
}
}
diff --git a/common/src/main/java/dev/terminalmc/effecttimerplus/util/IndicatorUtil.java b/common/src/main/java/dev/terminalmc/effecttimerplus/util/IndicatorUtil.java
index 277b362..4c3fc9b 100644
--- a/common/src/main/java/dev/terminalmc/effecttimerplus/util/IndicatorUtil.java
+++ b/common/src/main/java/dev/terminalmc/effecttimerplus/util/IndicatorUtil.java
@@ -4,7 +4,6 @@
import net.minecraft.world.effect.MobEffectInstance;
public class IndicatorUtil {
- public static final int SPRITE_SIZE = 24;
public static final int SPRITE_BORDER = 3;
/**
@@ -78,11 +77,11 @@ else if (seconds >= 60) {
* @return the X-axis offset.
* @throws IllegalStateException if the given index is invalid.
*/
- public static int getTextOffsetX(int locIndex, int labelWidth) {
+ public static int getTextOffsetX(int locIndex, int labelWidth, int spriteWidth) {
return switch (locIndex) {
case 0, 6, 7 -> SPRITE_BORDER; // Left
- case 1, 5 -> (SPRITE_SIZE / 2) - (labelWidth / 2); // Center
- case 2, 3, 4 -> SPRITE_SIZE - SPRITE_BORDER - (labelWidth - 1); // Right
+ case 1, 5 -> (spriteWidth / 2) - (labelWidth / 2); // Center
+ case 2, 3, 4 -> spriteWidth - SPRITE_BORDER - (labelWidth - 1); // Right
default -> throw new IllegalStateException(
"Unexpected positional index outside of allowed range (0-7): " + locIndex);
};
@@ -95,11 +94,11 @@ public static int getTextOffsetX(int locIndex, int labelWidth) {
* @return the Y-axis offset.
* @throws IllegalStateException if the given index is invalid.
*/
- public static int getTextOffsetY(int locIndex, int labelHeight) {
+ public static int getTextOffsetY(int locIndex, int labelHeight, int spriteHeight) {
return switch (locIndex) {
case 0, 1, 2 -> SPRITE_BORDER; // Top
- case 3, 7 -> (SPRITE_SIZE / 2) - (labelHeight / 2); // Center
- case 4, 5, 6 -> SPRITE_SIZE - SPRITE_BORDER - (labelHeight - 2); // Bottom
+ case 3, 7 -> (spriteHeight / 2) - (labelHeight / 2); // Center
+ case 4, 5, 6 -> spriteHeight - SPRITE_BORDER - (labelHeight - 2); // Bottom
default -> throw new IllegalStateException(
"Unexpected positional index outside of allowed range (0-7): " + locIndex);
};