-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
107 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
- Add Ukrainian translation (Tarteroycc) | ||
- Improve GUI mixin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
174 changes: 90 additions & 84 deletions
174
common/src/main/java/dev/terminalmc/effecttimerplus/mixin/MixinGui.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,128 @@ | ||
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 | ||
* <a href="https://github.com/magicus/statuseffecttimer/">Status Effect Timer</a> | ||
*/ | ||
@Mixin(value = Gui.class, priority = 500) | ||
public class MixinGui { | ||
|
||
@Final | ||
@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<MobEffectInstance> 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<MobEffect> 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<Void> 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<Runnable> runnables) { | ||
if (effectTimerPlus$runnable != null) { | ||
runnables.add(effectTimerPlus$runnable); | ||
effectTimerPlus$runnable = null; | ||
} | ||
graphics.pose().popPose(); | ||
return original; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters