fix(hud): rewrite PotionEffectsHud.EffectEntry to match obfuscated semantics
The previous EffectEntry had two render-killing inversions: show() animated heightAnim to the target row height and widthAnim to 100, but the render loop uses heightAnim as the 0..1 alpha factor (multiplied by 80/140/160/185) and widthAnim as the actual row height. That made every entry render with massively saturated alpha and a 100-pixel-tall pill. getTotalWidth() also returned the height animation value, so the sort order was wrong too. Rewrite to mirror Recaf's PotionEffectsHud$EffectEntry: - show(h): heightAnim -> 1.0 (alpha), widthAnim -> h (row height). - startRemove() animates both back to 0; isRemoveDone() checks anim isDone() instead of a hand-rolled alpha field. - tick() drops the custom alpha decay and keeps the duration text fresh for non-instantaneous effects. - getTotalWidth() actually measures the text (icon + name + duration + padding) so sort-by-width works. - updateEffect() bumps originalDuration when the new instance has a longer remaining duration (stacked refresh). - refreshDisplayText() delegates to the outer HUD for the infinity symbol and roman-numeral amplifier formatting. - Rename instance -> effectInstance and update render-site reads. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -23,68 +23,80 @@ import shit.zen.event.EventTarget;
|
||||
public class PotionEffectsHud
|
||||
extends HudElement {
|
||||
public static final class EffectEntry {
|
||||
public final PotionEffectsHud parent;
|
||||
public MobEffectInstance instance;
|
||||
public String effectName = "";
|
||||
public String durationText = "";
|
||||
public String amplifierText = "";
|
||||
public int originalDuration = 1;
|
||||
public final PotionEffectsHud outer;
|
||||
public MobEffectInstance effectInstance;
|
||||
public long originalDuration;
|
||||
public String effectName;
|
||||
public String durationText;
|
||||
public String amplifierText;
|
||||
public final shit.zen.utils.animation.SmoothAnimationTimer fadeAnim = new shit.zen.utils.animation.SmoothAnimationTimer();
|
||||
public final shit.zen.utils.animation.SmoothAnimationTimer heightAnim = new shit.zen.utils.animation.SmoothAnimationTimer();
|
||||
public final shit.zen.utils.animation.SmoothAnimationTimer widthAnim = new shit.zen.utils.animation.SmoothAnimationTimer();
|
||||
public float alpha = 1.0f;
|
||||
public float targetY;
|
||||
public float currentY;
|
||||
public boolean removing = false;
|
||||
public boolean visible = true;
|
||||
|
||||
public EffectEntry(PotionEffectsHud parent, MobEffectInstance instance) {
|
||||
this.parent = parent;
|
||||
this.instance = instance;
|
||||
this.originalDuration = Math.max(1, instance.getDuration());
|
||||
this.updateText();
|
||||
public EffectEntry(PotionEffectsHud outer, MobEffectInstance instance) {
|
||||
this.outer = outer;
|
||||
this.effectInstance = instance;
|
||||
this.originalDuration = instance.getDuration();
|
||||
this.refreshDisplayText();
|
||||
this.heightAnim.setCurrentValue(0.0);
|
||||
this.widthAnim.setCurrentValue(0.0);
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return this.effectInstance.getDuration();
|
||||
}
|
||||
|
||||
public net.minecraft.world.effect.MobEffect getEffect() {
|
||||
return this.instance.getEffect();
|
||||
return this.effectInstance.getEffect();
|
||||
}
|
||||
|
||||
public void updateEffect(MobEffectInstance instance) {
|
||||
this.instance = instance;
|
||||
this.updateText();
|
||||
if (instance.getDuration() > this.effectInstance.getDuration()) {
|
||||
this.originalDuration = instance.getDuration();
|
||||
}
|
||||
this.effectInstance = instance;
|
||||
this.refreshDisplayText();
|
||||
}
|
||||
|
||||
private void updateText() {
|
||||
this.effectName = this.instance.getEffect().getDisplayName().getString();
|
||||
this.durationText = net.minecraft.world.effect.MobEffectUtil.formatDuration(this.instance, 1.0f).getString();
|
||||
int amp = this.instance.getAmplifier();
|
||||
this.amplifierText = amp > 0 ? String.valueOf(amp + 1) : "";
|
||||
}
|
||||
|
||||
public void show(float targetHeight) {
|
||||
this.visible = false;
|
||||
this.heightAnim.animate(targetHeight, 0.2, shit.zen.utils.math.Easings.EASE_OUT_POW3);
|
||||
this.widthAnim.animate(100.0, 0.2, shit.zen.utils.math.Easings.EASE_OUT_POW3);
|
||||
public void refreshDisplayText() {
|
||||
this.effectName = this.effectInstance.getEffect().getDisplayName().getString();
|
||||
this.durationText = this.outer.formatDuration(this.effectInstance);
|
||||
this.amplifierText = this.outer.formatAmplifier(this.effectInstance.getAmplifier() + 1);
|
||||
}
|
||||
|
||||
public float getTotalWidth() {
|
||||
return this.widthAnim.getValueF();
|
||||
float iconBoxWidth = 22.0f;
|
||||
float padding = 5.0f;
|
||||
float nameWidth = GlHelper.getStringWidth(this.effectName, this.outer.effectNameFont);
|
||||
float durationWidth = GlHelper.getStringWidth(this.durationText, this.outer.amplifierFont);
|
||||
return iconBoxWidth + nameWidth + durationWidth + padding * 3.0f;
|
||||
}
|
||||
|
||||
public void show(float targetHeight) {
|
||||
this.heightAnim.animate(1.0, 0.3, shit.zen.utils.math.Easings.EASE_OUT_POW3);
|
||||
this.widthAnim.animate(targetHeight, 0.3, shit.zen.utils.math.Easings.EASE_OUT_POW3);
|
||||
}
|
||||
|
||||
public void startRemove() {
|
||||
if (this.removing) return;
|
||||
this.removing = true;
|
||||
this.heightAnim.animate(0.0, 0.2, shit.zen.utils.math.Easings.EASE_IN_POW3);
|
||||
this.widthAnim.animate(0.0, 0.2, shit.zen.utils.math.Easings.EASE_IN_POW3);
|
||||
}
|
||||
|
||||
public boolean isRemoveDone() {
|
||||
return this.removing && this.alpha <= 0.01f;
|
||||
return this.removing && this.heightAnim.isDone() && this.widthAnim.isDone();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
float target = this.removing ? 0.0f : 1.0f;
|
||||
this.alpha += (target - this.alpha) * 0.18f;
|
||||
this.fadeAnim.tick();
|
||||
this.heightAnim.tick();
|
||||
this.widthAnim.tick();
|
||||
if (!this.effectInstance.getEffect().isInstantenous()) {
|
||||
this.refreshDisplayText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,12 +196,12 @@ extends HudElement {
|
||||
currentY += animWidth + (animWidth > 0.0f ? spacing : 0.0f);
|
||||
continue;
|
||||
}
|
||||
int effectColor = this.getEffectColor(entry.instance.getEffect());
|
||||
int effectColor = this.getEffectColor(entry.effectInstance.getEffect());
|
||||
float barWidth = totalWidth - iconBoxWidth;
|
||||
float barX = x + iconBoxWidth;
|
||||
this.iconBgPaint.setColor(ColorUtil.fromARGB(30, 30, 35, (int)(80.0f * animHeight)));
|
||||
drawContext.drawRoundedRect(RoundedRectangle.ofXYWHRadii(barX, entryY, barWidth, animWidth, new float[]{0.0f, 0.0f, 4.5f, 4.5f, 4.5f, 4.5f, 0.0f, 0.0f}), this.iconBgPaint);
|
||||
float durationPct = entry.instance.isInfiniteDuration() ? 1.0f : (float)entry.instance.getDuration() / (float)entry.originalDuration;
|
||||
float durationPct = entry.effectInstance.isInfiniteDuration() ? 1.0f : (float)entry.effectInstance.getDuration() / (float)entry.originalDuration;
|
||||
this.effectIconPaint.setColor(ColorUtil.fromARGB(effectColor >> 16 & 0xFF, effectColor >> 8 & 0xFF, effectColor & 0xFF, (int)(140.0f * animHeight)));
|
||||
if (durationPct > 0.0f) {
|
||||
drawContext.drawRoundedRect(RoundedRectangle.ofXYWHRadii(barX, entryY, barWidth * durationPct, animWidth, new float[]{0.0f, 0.0f, cornerRadius * durationPct, cornerRadius * durationPct, cornerRadius * durationPct, cornerRadius * durationPct, 0.0f, 0.0f}), this.effectIconPaint);
|
||||
|
||||
Reference in New Issue
Block a user