Add some visual changes

This commit is contained in:
2026-07-26 14:36:54 +02:00
parent 442d3d8a24
commit f293f67f2d
6 changed files with 227 additions and 169 deletions
@@ -0,0 +1,122 @@
package net.fretux.mindmotion.client;
import net.minecraft.client.gui.GuiGraphics;
public final class BarRenderer {
private static final float CORNER_ALPHA = 0.42f;
private BarRenderer() {
}
public static void drawRoundedBar(GuiGraphics gui, int x, int y, int width, int height,
float progress, int topColor, int bottomColor) {
drawTrackAndFill(gui, x, y, width, height, progress,
HudTheme.BAR_BACKGROUND, topColor, bottomColor);
}
public static void drawBossStyleBar(GuiGraphics gui, int x, int y, int width, int height,
float progress, double animationTime) {
int fillColor = mixColor(
HudTheme.MADNESS_GRADIENT_START,
HudTheme.MADNESS_GRADIENT_END,
progress
);
if (progress >= HudTheme.MADNESS_URGENT_THRESHOLD) {
float pulse = 1f + 0.16f
* (0.5f + 0.5f * (float) Math.sin(animationTime * 13.0));
fillColor = scaleColor(fillColor, pulse);
}
drawTrackAndFill(gui, x, y, width, height, progress, HudTheme.MADNESS_TRACK,
lightenColor(fillColor, 0.16f), scaleColor(fillColor, 0.78f));
}
private static void drawTrackAndFill(GuiGraphics gui, int x, int y, int width, int height,
float progress, int trackColor, int topColor, int bottomColor) {
if (width <= 0 || height <= 0) return;
drawRoundedRect(gui, x, y, width, height, HudTheme.BORDER);
if (width <= 2 || height <= 2) return;
int innerX = x + 1;
int innerY = y + 1;
int innerWidth = width - 2;
int innerHeight = height - 2;
drawRoundedRect(gui, innerX, innerY, innerWidth, innerHeight, trackColor);
int fillWidth = Math.round(innerWidth * clamp01(progress));
if (fillWidth > 0) {
drawRoundedRect(gui, innerX, innerY, fillWidth, innerHeight, topColor, bottomColor);
}
}
public static void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height, int color) {
drawRoundedRect(gui, x, y, width, height, color, color);
}
public static void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height,
int topColor, int bottomColor) {
if (width <= 0 || height <= 0) return;
if (width <= 2 || height <= 2) {
gui.fillGradient(x, y, x + width, y + height, topColor, bottomColor);
return;
}
gui.fillGradient(x + 1, y, x + width - 1, y + height, topColor, bottomColor);
gui.fillGradient(x, y + 1, x + width, y + height - 1, topColor, bottomColor);
int topCorner = scaleAlpha(topColor, CORNER_ALPHA);
int bottomCorner = scaleAlpha(bottomColor, CORNER_ALPHA);
gui.fill(x, y, x + 1, y + 1, topCorner);
gui.fill(x + width - 1, y, x + width, y + 1, topCorner);
gui.fill(x, y + height - 1, x + 1, y + height, bottomCorner);
gui.fill(x + width - 1, y + height - 1, x + width, y + height, bottomCorner);
}
public static int mixColor(int from, int to, float amount) {
float t = clamp01(amount);
int a = mixChannel((from >>> 24) & 0xFF, (to >>> 24) & 0xFF, t);
int r = mixChannel((from >>> 16) & 0xFF, (to >>> 16) & 0xFF, t);
int g = mixChannel((from >>> 8) & 0xFF, (to >>> 8) & 0xFF, t);
int b = mixChannel(from & 0xFF, to & 0xFF, t);
return (a << 24) | (r << 16) | (g << 8) | b;
}
public static int scaleColor(int color, float factor) {
int a = (color >>> 24) & 0xFF;
int r = clampChannel(Math.round(((color >>> 16) & 0xFF) * factor));
int g = clampChannel(Math.round(((color >>> 8) & 0xFF) * factor));
int b = clampChannel(Math.round((color & 0xFF) * factor));
return (a << 24) | (r << 16) | (g << 8) | b;
}
public static int lightenColor(int color, float amount) {
return mixColor(color, (color & 0xFF000000) | 0x00FFFFFF, amount);
}
public static int withAlpha(int color, float alpha) {
int a = clampChannel(Math.round(255f * clamp01(alpha)));
return (color & 0x00FFFFFF) | (a << 24);
}
public static int urgentShake(double animationTime) {
long step = (long) (animationTime * 24.0);
return (int) Math.floorMod(step * 31L + 17L, 3L) - 1;
}
private static int scaleAlpha(int color, float factor) {
int alpha = clampChannel(Math.round(((color >>> 24) & 0xFF) * factor));
return (color & 0x00FFFFFF) | (alpha << 24);
}
private static int mixChannel(int from, int to, float amount) {
return Math.round(from + (to - from) * amount);
}
private static int clampChannel(int value) {
return Math.max(0, Math.min(255, value));
}
public static float clamp01(float value) {
return Math.max(0f, Math.min(1f, value));
}
}
@@ -13,6 +13,7 @@ public class ClientData {
private static float displayedInsanity = 0f; private static float displayedInsanity = 0f;
private static float displayedTempo = 0f; private static float displayedTempo = 0f;
private static float displayedMadness = 0f; private static float displayedMadness = 0f;
private static float displayedInsanityBlend = 0f;
private static float madnessRenderTarget = 0f; private static float madnessRenderTarget = 0f;
private static long lastMadnessRenderNanos = System.nanoTime(); private static long lastMadnessRenderNanos = System.nanoTime();
@@ -46,6 +47,10 @@ public class ClientData {
displayedInsanity += (INSANITY - displayedInsanity) * lerp; displayedInsanity += (INSANITY - displayedInsanity) * lerp;
displayedTempo += (TEMPO - displayedTempo) * lerp; displayedTempo += (TEMPO - displayedTempo) * lerp;
displayedMadness += (madnessRenderTarget - displayedMadness) * lerp; displayedMadness += (madnessRenderTarget - displayedMadness) * lerp;
float insanityTarget = SANITY <= 0f ? 1f : 0f;
float modeLerp = 1f - (float) Math.exp(-8f * elapsedSeconds);
displayedInsanityBlend += (insanityTarget - displayedInsanityBlend) * modeLerp;
} }
public static float getDisplayedSanity() { public static float getDisplayedSanity() {
@@ -63,4 +68,8 @@ public class ClientData {
public static float getDisplayedMadness() { public static float getDisplayedMadness() {
return displayedMadness; return displayedMadness;
} }
public static float getDisplayedInsanityBlend() {
return displayedInsanityBlend;
}
} }
@@ -284,25 +284,29 @@ public class HudEditorScreen extends Screen {
BarPosition sanityBar = getSanityBarPosition(); BarPosition sanityBar = getSanityBarPosition();
BarPosition madnessBar = getMadnessBarPosition(); BarPosition madnessBar = getMadnessBarPosition();
if (isTempoEnabled()) { if (isTempoEnabled()) {
drawRoundedBar(gui, tempoBar, 0xFF33AFFF, (int) (barWidth * 0.75f)); BarRenderer.drawRoundedBar(gui, tempoBar.x, tempoBar.y, tempoBar.width, tempoBar.height,
gui.drawString(this.font, Component.literal("Tempo"), tempoBar.x, tempoBar.y - 12, 0x66CCFF, false); 0.75f, HudTheme.TEMPO_TOP, HudTheme.TEMPO_BOTTOM);
gui.drawString(this.font, Component.literal("Tempo"), tempoBar.x, tempoBar.y - 12,
HudTheme.TEMPO_LABEL, false);
} }
if (isSanityEnabled()) { if (isSanityEnabled()) {
drawRoundedBar(gui, sanityBar, 0xFFE8E8E8, (int) (barWidth * 0.6f)); BarRenderer.drawRoundedBar(gui, sanityBar.x, sanityBar.y, sanityBar.width, sanityBar.height,
0.6f, HudTheme.SANITY_TOP, HudTheme.SANITY_BOTTOM);
int sanityLabelWidth = this.font.width("Sanity"); int sanityLabelWidth = this.font.width("Sanity");
gui.drawString( gui.drawString(
this.font, this.font,
Component.literal("Sanity"), Component.literal("Sanity"),
sanityBar.x + barWidth - sanityLabelWidth, sanityBar.x + barWidth - sanityLabelWidth,
sanityBar.y - 12, sanityBar.y - 12,
0xFFFFFF, HudTheme.SANITY_LABEL,
false false
); );
} }
if (isMadnessEnabled()) { if (isMadnessEnabled()) {
drawBossStyleBar(gui, madnessBar, 0.72f); BarRenderer.drawBossStyleBar(gui, madnessBar.x, madnessBar.y, madnessBar.width,
madnessBar.height, 0.72f, System.nanoTime() / 1_000_000_000.0);
gui.drawCenteredString(this.font, Component.literal("Madness"), gui.drawCenteredString(this.font, Component.literal("Madness"),
madnessBar.x + madnessBar.width / 2, madnessBar.y - 11, 0xFFFFFF55); madnessBar.x + madnessBar.width / 2, madnessBar.y - 11, HudTheme.MADNESS_LABEL);
} }
} }
@@ -431,50 +435,6 @@ public class HudEditorScreen extends Screen {
return Math.min(Math.max(value, min), max); return Math.min(Math.max(value, min), max);
} }
private void drawRoundedBar(GuiGraphics gui, BarPosition pos, int color, int fillWidth) {
int bg = 0xCC000000;
drawRoundedRect(gui, pos.x, pos.y, pos.width, pos.height, bg);
int top = color;
int bottom = (color & 0x00FFFFFF) | 0xFF000000;
drawRoundedRect(gui, pos.x, pos.y, fillWidth, pos.height, top, bottom);
if (fillWidth > 2) {
gui.fill(pos.x + 1, pos.y, pos.x + fillWidth - 1, pos.y + 1, lightenColor(color, 0.18f));
}
}
private void drawBossStyleBar(GuiGraphics gui, BarPosition pos, float progress) {
gui.fill(pos.x, pos.y, pos.x + pos.width, pos.y + pos.height, 0xFF000000);
gui.fill(pos.x + 1, pos.y + 1, pos.x + pos.width - 1, pos.y + pos.height - 1, 0xFF4A4000);
int fillWidth = Math.round((pos.width - 2) * progress);
int fillColor = mixColor(0xFFAD8D2C, 0xFFFFF4B0, progress);
gui.fillGradient(pos.x + 1, pos.y + 1, pos.x + 1 + fillWidth, pos.y + pos.height - 1,
lightenColor(fillColor, 0.16f), fillColor);
}
private static int mixColor(int from, int to, float amount) {
float t = Math.max(0f, Math.min(1f, amount));
int a = Math.round(((from >>> 24) & 0xFF) + (((to >>> 24) & 0xFF) - ((from >>> 24) & 0xFF)) * t);
int r = Math.round(((from >>> 16) & 0xFF) + (((to >>> 16) & 0xFF) - ((from >>> 16) & 0xFF)) * t);
int g = Math.round(((from >>> 8) & 0xFF) + (((to >>> 8) & 0xFF) - ((from >>> 8) & 0xFF)) * t);
int b = Math.round((from & 0xFF) + ((to & 0xFF) - (from & 0xFF)) * t);
return (a << 24) | (r << 16) | (g << 8) | b;
}
private static int lightenColor(int color, float amount) {
return mixColor(color, (color & 0xFF000000) | 0x00FFFFFF, amount);
}
private void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height, int color) {
gui.fill(x + 1, y, x + width - 1, y + height, color);
gui.fill(x, y + 1, x + width, y + height - 1, color);
gui.fill(x + 1, y + 1, x + width - 1, y + height - 1, color);
}
private void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height, int topColor, int bottomColor) {
gui.fillGradient(x + 1, y, x + width - 1, y + height, topColor, bottomColor);
gui.fillGradient(x, y + 1, x + width, y + height - 1, topColor, bottomColor);
}
private static boolean isMouseOver(double mouseX, double mouseY, BarPosition pos) { private static boolean isMouseOver(double mouseX, double mouseY, BarPosition pos) {
return mouseX >= pos.x return mouseX >= pos.x
&& mouseX <= pos.x + pos.width && mouseX <= pos.x + pos.width
@@ -0,0 +1,29 @@
package net.fretux.mindmotion.client;
public final class HudTheme {
public static final int BORDER = 0xFF000000;
public static final int BAR_BACKGROUND = 0xCC090B10;
public static final int TEMPO_TOP = 0xFF66CCFF;
public static final int TEMPO_BOTTOM = 0xFF2389D8;
public static final int TEMPO_LABEL = 0xFF66CCFF;
public static final int VENT_LABEL = 0xFF33AFFF;
public static final int SANITY_TOP = 0xFFFFFFFF;
public static final int SANITY_BOTTOM = 0xFFD8D8D8;
public static final int SANITY_LABEL = 0xFFFFFFFF;
public static final int INSANITY_TOP = 0xFFAA33FF;
public static final int INSANITY_BOTTOM = 0xFF6611AA;
public static final int INSANITY_LABEL = 0xFFCC66FF;
public static final int MADNESS_TRACK = 0xFF4A4000;
public static final int MADNESS_GRADIENT_START = 0xFFAD8D2C;
public static final int MADNESS_GRADIENT_END = 0xFFFFF4B0;
public static final int MADNESS_LABEL = 0xFFFFFF55;
public static final int MADNESS_TOOLTIP = 0xFFFFFF88;
public static final float MADNESS_URGENT_THRESHOLD = 0.85f;
private HudTheme() {
}
}
@@ -43,19 +43,20 @@ public class SanityTempoOverlay {
float insanity = ClientData.getDisplayedInsanity(); float insanity = ClientData.getDisplayedInsanity();
float madness = ClientData.getDisplayedMadness(); float madness = ClientData.getDisplayedMadness();
float tempo = ClientData.getDisplayedTempo(); float tempo = ClientData.getDisplayedTempo();
float sanityPercent = clamp01(sanity / ClientData.MAX_SANITY); float insanityBlend = ClientData.getDisplayedInsanityBlend();
float insanityPercent = clamp01(insanity / ClientData.MAX_SANITY); float sanityPercent = BarRenderer.clamp01(sanity / ClientData.MAX_SANITY);
float tempoPercent = clamp01(tempo / ClientData.MAX_TEMPO); float insanityPercent = BarRenderer.clamp01(insanity / ClientData.MAX_SANITY);
int sanityFill = Math.round(barWidth * sanityPercent); float tempoPercent = BarRenderer.clamp01(tempo / ClientData.MAX_TEMPO);
int tempoFill = Math.round(barWidth * tempoPercent); float mentalPercent = sanityPercent + (insanityPercent - sanityPercent) * insanityBlend;
int insanityFill = Math.round(barWidth * insanityPercent);
double animationTime = System.nanoTime() / 1_000_000_000.0; double animationTime = System.nanoTime() / 1_000_000_000.0;
double mouseX = mc.mouseHandler.xpos() * width / (double) event.getWindow().getScreenWidth(); double mouseX = mc.mouseHandler.xpos() * width / (double) event.getWindow().getScreenWidth();
double mouseY = mc.mouseHandler.ypos() * height / (double) event.getWindow().getScreenHeight(); double mouseY = mc.mouseHandler.ypos() * height / (double) event.getWindow().getScreenHeight();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
if (tempoEnabled) { if (tempoEnabled) {
drawRoundedBar(gui, xTempo, yTempo, barWidth, barHeight, 0xFF33AFFF, tempoFill); BarRenderer.drawRoundedBar(gui, xTempo, yTempo, barWidth, barHeight, tempoPercent,
gui.drawString(mc.font, Component.literal("Tempo"), xTempo, yTempo - labelOffset, 0x66CCFF, false); HudTheme.TEMPO_TOP, HudTheme.TEMPO_BOTTOM);
gui.drawString(mc.font, Component.literal("Tempo"), xTempo, yTempo - labelOffset,
HudTheme.TEMPO_LABEL, false);
} }
if (tempoEnabled && ClientData.VENT_COOLDOWN > 0) { if (tempoEnabled && ClientData.VENT_COOLDOWN > 0) {
int seconds = ClientData.VENT_COOLDOWN / 20; int seconds = ClientData.VENT_COOLDOWN / 20;
@@ -65,28 +66,33 @@ public class SanityTempoOverlay {
Component.literal(ventText), Component.literal(ventText),
xTempo, xTempo,
yTempo - ventOffset, yTempo - ventOffset,
0x33AFFF, HudTheme.VENT_LABEL,
false false
); );
} }
boolean insaneMode = ClientData.SANITY <= 0f;
boolean showMadness = ClientData.MADNESS > 0f; boolean showMadness = ClientData.MADNESS > 0f;
if (sanityEnabled) { if (sanityEnabled) {
if (!insaneMode) { float insanityPulse = 0.92f + 0.08f
drawRoundedBar(gui, xSanity, ySanity, barWidth, barHeight, 0xFFE8E8E8, sanityFill); * (0.5f + 0.5f * (float) Math.sin(animationTime * 3.5));
int pulsingInsanityTop = BarRenderer.scaleColor(HudTheme.INSANITY_TOP, insanityPulse);
int pulsingInsanityBottom = BarRenderer.scaleColor(HudTheme.INSANITY_BOTTOM, insanityPulse);
int mentalTop = BarRenderer.mixColor(HudTheme.SANITY_TOP, pulsingInsanityTop, insanityBlend);
int mentalBottom = BarRenderer.mixColor(HudTheme.SANITY_BOTTOM, pulsingInsanityBottom, insanityBlend);
BarRenderer.drawRoundedBar(gui, xSanity, ySanity, barWidth, barHeight, mentalPercent,
mentalTop, mentalBottom);
float sanityLabelAlpha = 1f - insanityBlend;
if (sanityLabelAlpha > 0.01f) {
int sanityLabelWidth = mc.font.width("Sanity"); int sanityLabelWidth = mc.font.width("Sanity");
int sanityLabelX = xSanity + barWidth - sanityLabelWidth; int sanityLabelX = xSanity + barWidth - sanityLabelWidth;
gui.drawString(mc.font, Component.literal("Sanity"), sanityLabelX, ySanity - labelOffset, 0xFFFFFF, false); gui.drawString(mc.font, Component.literal("Sanity"), sanityLabelX, ySanity - labelOffset,
} else { BarRenderer.withAlpha(HudTheme.SANITY_LABEL, sanityLabelAlpha), false);
float insanityPulse = 0.92f + 0.08f * (0.5f + 0.5f * (float) Math.sin(animationTime * 3.5)); }
int purple = scaleColor(0xFFAA33FF, insanityPulse); if (insanityBlend > 0.01f) {
int darkPurple = scaleColor(0xFF6611AA, insanityPulse);
drawRoundedRect(gui, xSanity, ySanity, barWidth, barHeight, 0xDD000000);
drawRoundedRect(gui, xSanity, ySanity, insanityFill, barHeight, purple, darkPurple);
drawTopHighlight(gui, xSanity, ySanity, insanityFill, lightenColor(purple, 0.18f));
int insanityLabelWidth = mc.font.width("Insanity"); int insanityLabelWidth = mc.font.width("Insanity");
int insanityLabelX = xSanity + barWidth - insanityLabelWidth; int insanityLabelX = xSanity + barWidth - insanityLabelWidth;
gui.drawString(mc.font, Component.literal("Insanity"), insanityLabelX, ySanity - labelOffset, 0xCC66FF, false); gui.drawString(mc.font, Component.literal("Insanity"), insanityLabelX, ySanity - labelOffset,
BarRenderer.withAlpha(HudTheme.INSANITY_LABEL, insanityBlend), false);
} }
} }
if (madnessEnabled && showMadness) { if (madnessEnabled && showMadness) {
@@ -96,119 +102,35 @@ public class SanityTempoOverlay {
int madnessY = 13 + ConfigMM.CLIENT.MADNESS_BAR_Y_OFFSET.get(); int madnessY = 13 + ConfigMM.CLIENT.MADNESS_BAR_Y_OFFSET.get();
float madnessPercent = ClientData.MAX_MADNESS <= 0f float madnessPercent = ClientData.MAX_MADNESS <= 0f
? 0f ? 0f
: clamp01(madness / ClientData.MAX_MADNESS); : BarRenderer.clamp01(madness / ClientData.MAX_MADNESS);
int shakeX = madnessPercent >= 0.85f ? urgentShake(animationTime) : 0; int shakeX = madnessPercent >= HudTheme.MADNESS_URGENT_THRESHOLD
? BarRenderer.urgentShake(animationTime)
: 0;
int renderedMadnessX = madnessX + shakeX; int renderedMadnessX = madnessX + shakeX;
drawBossStyleBar(gui, renderedMadnessX, madnessY, madnessBarWidth, madnessBarHeight, BarRenderer.drawBossStyleBar(gui, renderedMadnessX, madnessY, madnessBarWidth, madnessBarHeight,
madnessPercent, animationTime); madnessPercent, animationTime);
gui.drawCenteredString(mc.font, Component.literal("Madness"), gui.drawCenteredString(mc.font, Component.literal("Madness"),
madnessX + madnessBarWidth / 2, madnessY - 11, 0xFFFFFF55); madnessX + madnessBarWidth / 2, madnessY - 11, HudTheme.MADNESS_LABEL);
if (isMouseOver(mouseX, mouseY, renderedMadnessX, madnessY, madnessBarWidth, madnessBarHeight)) { if (isMouseOver(mouseX, mouseY, renderedMadnessX, madnessY, madnessBarWidth, madnessBarHeight)) {
String text = String.format("%.0f%%", madnessPercent * 100f); String text = String.format("%.0f%%", madnessPercent * 100f);
gui.drawCenteredString(mc.font, text, madnessX + madnessBarWidth / 2, gui.drawCenteredString(mc.font, text, madnessX + madnessBarWidth / 2,
madnessY + madnessBarHeight + 3, 0xFFFFFF88); madnessY + madnessBarHeight + 3, HudTheme.MADNESS_TOOLTIP);
} }
} }
if (tempoEnabled && isMouseOver(mouseX, mouseY, xTempo, yTempo, barWidth, barHeight)) { if (tempoEnabled && isMouseOver(mouseX, mouseY, xTempo, yTempo, barWidth, barHeight)) {
String text = String.format("%.0f%%", tempoPercent * 100f); String text = String.format("%.0f%%", tempoPercent * 100f);
gui.drawCenteredString(mc.font, text, xTempo + barWidth / 2, yTempo - (labelOffset + 2), 0x66CCFF); gui.drawCenteredString(mc.font, text, xTempo + barWidth / 2, yTempo - (labelOffset + 2),
HudTheme.TEMPO_LABEL);
} }
if (sanityEnabled && isMouseOver(mouseX, mouseY, xSanity, ySanity, barWidth, barHeight)) { if (sanityEnabled && isMouseOver(mouseX, mouseY, xSanity, ySanity, barWidth, barHeight)) {
if (!insaneMode) { String text = String.format("%.0f%%", mentalPercent * 100f);
String text = String.format("%.0f%%", sanityPercent * 100f); int tooltipColor = BarRenderer.mixColor(
gui.drawCenteredString(mc.font, text, xSanity + barWidth / 2, ySanity - (labelOffset + 2), 0xFFFFFF); HudTheme.SANITY_LABEL, HudTheme.INSANITY_LABEL, insanityBlend);
} else { gui.drawCenteredString(mc.font, text, xSanity + barWidth / 2,
String text = String.format("%.0f%%", insanityPercent * 100f); ySanity - (labelOffset + 2), tooltipColor);
gui.drawCenteredString(mc.font, text, xSanity + barWidth / 2, ySanity - (labelOffset + 2), 0xCC66FF);
} }
} }
}
private static void drawRoundedBar(GuiGraphics gui, int x, int y, int width, int height, int color, int fillWidth) {
int bg = 0xCC000000;
drawRoundedRect(gui, x, y, width, height, bg);
if (fillWidth <= 0) return;
int clampedFill = Math.min(width, fillWidth);
drawRoundedRect(gui, x, y, clampedFill, height, color, scaleColor(color, 0.78f));
drawTopHighlight(gui, x, y, clampedFill, lightenColor(color, 0.18f));
}
private static void drawBossStyleBar(GuiGraphics gui, int x, int y, int width, int height,
float progress, double animationTime) {
gui.fill(x, y, x + width, y + height, 0xFF000000);
gui.fill(x + 1, y + 1, x + width - 1, y + height - 1, 0xFF4A4000);
int innerWidth = width - 2;
int fillWidth = Math.round(innerWidth * progress);
if (fillWidth > 0) {
int fillColor = mixColor(0xFFAD8D2C, 0xFFFFF4B0, progress);
if (progress >= 0.85f) {
float urgentPulse = 1f + 0.16f
* (0.5f + 0.5f * (float) Math.sin(animationTime * 13.0));
fillColor = scaleColor(fillColor, urgentPulse);
}
gui.fillGradient(x + 1, y + 1, x + 1 + fillWidth, y + height - 1,
lightenColor(fillColor, 0.16f), scaleColor(fillColor, 0.78f));
}
}
private static void drawTopHighlight(GuiGraphics gui, int x, int y, int fillWidth, int color) {
if (fillWidth <= 2) return;
gui.fill(x + 1, y, x + fillWidth - 1, y + 1, color);
}
private static int urgentShake(double animationTime) {
long step = (long) (animationTime * 24.0);
return (int) Math.floorMod(step * 31L + 17L, 3L) - 1;
}
private static int mixColor(int from, int to, float amount) {
float t = clamp01(amount);
int a = Math.round(((from >>> 24) & 0xFF) + (((to >>> 24) & 0xFF) - ((from >>> 24) & 0xFF)) * t);
int r = Math.round(((from >>> 16) & 0xFF) + (((to >>> 16) & 0xFF) - ((from >>> 16) & 0xFF)) * t);
int g = Math.round(((from >>> 8) & 0xFF) + (((to >>> 8) & 0xFF) - ((from >>> 8) & 0xFF)) * t);
int b = Math.round((from & 0xFF) + ((to & 0xFF) - (from & 0xFF)) * t);
return (a << 24) | (r << 16) | (g << 8) | b;
}
private static int scaleColor(int color, float factor) {
int a = (color >>> 24) & 0xFF;
int r = Math.min(255, Math.max(0, Math.round(((color >>> 16) & 0xFF) * factor)));
int g = Math.min(255, Math.max(0, Math.round(((color >>> 8) & 0xFF) * factor)));
int b = Math.min(255, Math.max(0, Math.round((color & 0xFF) * factor)));
return (a << 24) | (r << 16) | (g << 8) | b;
}
private static int lightenColor(int color, float amount) {
return mixColor(color, (color & 0xFF000000) | 0x00FFFFFF, amount);
}
private static float clamp01(float value) {
return Math.max(0f, Math.min(1f, value));
}
private static void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height, int color) {
if (width <= 0 || height <= 0) return;
if (width <= 2 || height <= 2) {
gui.fill(x, y, x + width, y + height, color);
return;
}
gui.fill(x + 1, y, x + width - 1, y + height, color); // center
gui.fill(x, y + 1, x + width, y + height - 1, color); // sides
gui.fill(x + 1, y + 1, x + width - 1, y + height - 1, color);
}
private static void drawRoundedRect(GuiGraphics gui, int x, int y, int width, int height, int topColor, int bottomColor) {
if (width <= 0 || height <= 0) return;
if (width <= 2 || height <= 2) {
gui.fillGradient(x, y, x + width, y + height, topColor, bottomColor);
return;
}
gui.fillGradient(x + 1, y, x + width - 1, y + height, topColor, bottomColor);
gui.fillGradient(x, y + 1, x + width, y + height - 1, topColor, bottomColor);
}
private static boolean isMouseOver(double mx, double my, int x, int y, int w, int h) { private static boolean isMouseOver(double mx, double my, int x, int y, int w, int h) {
return mx >= x && mx <= x + w && my >= y && my <= y + h; return mx >= x && mx <= x + w && my >= y && my <= y + h;
@@ -0,0 +1,16 @@
package net.fretux.mindmotion.compat;
import io.redspace.ironsspellbooks.api.magic.MagicData;
import io.redspace.ironsspellbooks.api.util.UpdateClient;
import net.minecraft.server.level.ServerPlayer;
public final class IronsSpellbooksCompat {
private IronsSpellbooksCompat() {
}
public static void reduceMana(ServerPlayer player, float fraction) {
MagicData magicData = MagicData.getPlayerMagicData(player);
magicData.setMana(Math.max(0f, magicData.getMana() * (1f - fraction)));
UpdateClient.SendManaUpdate(player, magicData);
}
}