Initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package net.fretux.mindmotion.client;
|
||||
|
||||
public class ClientData {
|
||||
public static float SANITY = 80f;
|
||||
public static float INSANITY = 0f;
|
||||
public static int TEMPO = 0;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.fretux.mindmotion.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RenderGuiOverlayEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = "mindmotion", value = Dist.CLIENT)
|
||||
public class SanityTempoOverlay {
|
||||
|
||||
private static final int BAR_WIDTH = 102;
|
||||
private static final int BAR_HEIGHT = 9;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderOverlay(RenderGuiOverlayEvent.Post event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.player == null || mc.options.hideGui) return;
|
||||
|
||||
GuiGraphics gui = event.getGuiGraphics();
|
||||
int width = event.getWindow().getGuiScaledWidth();
|
||||
int height = event.getWindow().getGuiScaledHeight();
|
||||
|
||||
int y = height - 48;
|
||||
int xTempo = 8;
|
||||
int xSanity = width - BAR_WIDTH - 8;
|
||||
|
||||
float sanity = ClientData.SANITY;
|
||||
float insanity = ClientData.INSANITY;
|
||||
float tempo = ClientData.TEMPO;
|
||||
|
||||
float sanityPercent = sanity / 80f;
|
||||
float insanityPercent = insanity / 80f; // same max as sanity (80)
|
||||
float tempoPercent = tempo / 120f;
|
||||
|
||||
int sanityFill = (int) (BAR_WIDTH * sanityPercent);
|
||||
int tempoFill = (int) (BAR_WIDTH * tempoPercent);
|
||||
int insanityFill = (int) (BAR_WIDTH * insanityPercent);
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
|
||||
// --- TEMPO BAR ---
|
||||
drawRoundedBar(gui, xTempo, y, BAR_WIDTH, BAR_HEIGHT, 0xFF33AFFF, tempoFill);
|
||||
gui.drawString(mc.font, Component.literal("Tempo"), xTempo, y - 10, 0x66CCFF, false);
|
||||
|
||||
// --- SANITY OR INSANITY BAR ---
|
||||
boolean insaneMode = sanity <= 0;
|
||||
|
||||
if (!insaneMode) {
|
||||
// Normal sanity bar
|
||||
drawRoundedBar(gui, xSanity, y, BAR_WIDTH, BAR_HEIGHT, 0xFFFFFFFF, sanityFill);
|
||||
gui.drawString(mc.font, Component.literal("Sanity"), xSanity + BAR_WIDTH - 30, y - 10, 0xFFFFFF, false);
|
||||
} else {
|
||||
int purple = 0xFFAA33FF;
|
||||
int darkPurple = 0xFF6611AA;
|
||||
drawRoundedRect(gui, xSanity, y, BAR_WIDTH, BAR_HEIGHT, 0xDD000000);
|
||||
drawRoundedRect(gui, xSanity, y, insanityFill, BAR_HEIGHT, purple, darkPurple);
|
||||
gui.drawString(mc.font, Component.literal("Insanity"), xSanity + BAR_WIDTH - 42, y - 10, 0xCC66FF, false);
|
||||
}
|
||||
double mouseX = mc.mouseHandler.xpos() * width / (double) event.getWindow().getScreenWidth();
|
||||
double mouseY = mc.mouseHandler.ypos() * height / (double) event.getWindow().getScreenHeight();
|
||||
if (isMouseOver(mouseX, mouseY, xTempo, y, BAR_WIDTH, BAR_HEIGHT)) {
|
||||
String text = String.format("%.0f%%", tempoPercent * 100f);
|
||||
gui.drawCenteredString(mc.font, text, xTempo + BAR_WIDTH / 2, y - 12, 0x66CCFF);
|
||||
}
|
||||
if (isMouseOver(mouseX, mouseY, xSanity, y, BAR_WIDTH, BAR_HEIGHT)) {
|
||||
if (!insaneMode) {
|
||||
String text = String.format("%.0f%%", sanityPercent * 100f);
|
||||
gui.drawCenteredString(mc.font, text, xSanity + BAR_WIDTH / 2, y - 12, 0xFFFFFF);
|
||||
} else {
|
||||
String text = String.format("%.0f%%", insanityPercent * 100f);
|
||||
gui.drawCenteredString(mc.font, text, xSanity + BAR_WIDTH / 2, y - 12, 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);
|
||||
int top = color;
|
||||
int bottom = (color & 0x00FFFFFF) | 0xFF000000;
|
||||
drawRoundedRect(gui, x, y, fillWidth, height, top, bottom);
|
||||
}
|
||||
|
||||
private static 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); // 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) {
|
||||
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) {
|
||||
return mx >= x && mx <= x + w && my >= y && my <= y + h;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package net.fretux.mindmotion.client.effects;
|
||||
|
||||
import net.fretux.mindmotion.client.ClientData;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.PostChain;
|
||||
import net.minecraft.client.renderer.PostPass;
|
||||
import net.minecraft.client.renderer.EffectInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = "mindmotion", value = Dist.CLIENT)
|
||||
public class SanityShaderHandler {
|
||||
|
||||
private static final ResourceLocation DESAT_EFFECT =
|
||||
new ResourceLocation("mindmotion", "shaders/post/desaturate.json");
|
||||
|
||||
private static float currentStrength = 0f;
|
||||
|
||||
// cache reflection so we don't look it up every frame
|
||||
private static Field passesField;
|
||||
|
||||
private static List<PostPass> getPasses(PostChain chain) throws IllegalAccessException, NoSuchFieldException {
|
||||
if (passesField == null) {
|
||||
passesField = PostChain.class.getDeclaredField("passes");
|
||||
passesField.setAccessible(true);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<PostPass> passes = (List<PostPass>) passesField.get(chain);
|
||||
return passes;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderWorld(RenderLevelStageEvent event) {
|
||||
// AFTER_LEVEL is the point where the full world image is ready
|
||||
if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL) return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.player == null || mc.level == null) return;
|
||||
|
||||
float sanity = ClientData.SANITY;
|
||||
float insanity = ClientData.INSANITY;
|
||||
float maxSanity = 80f;
|
||||
|
||||
float sanityPct = sanity / maxSanity;
|
||||
float insanityPct = insanity / maxSanity;
|
||||
|
||||
float baseDesat = 0f;
|
||||
if (sanityPct < 0.70f) {
|
||||
baseDesat = 1f - (sanityPct / 0.70f);
|
||||
}
|
||||
|
||||
float insanityBoost = 0.75f * insanityPct;
|
||||
float target = Math.max(baseDesat, insanityBoost);
|
||||
if (sanity <= 0f) target = 1f;
|
||||
|
||||
// smooth to avoid popping
|
||||
currentStrength += (target - currentStrength) * 0.08f;
|
||||
|
||||
// if essentially zero, shut the effect off completely
|
||||
if (currentStrength < 0.005f) {
|
||||
if (mc.gameRenderer.currentEffect() != null) {
|
||||
mc.gameRenderer.shutdownEffect();
|
||||
}
|
||||
currentStrength = 0f;
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure our effect is loaded
|
||||
if (mc.gameRenderer.currentEffect() == null) {
|
||||
try {
|
||||
mc.gameRenderer.loadEffect(DESAT_EFFECT);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PostChain chain = mc.gameRenderer.currentEffect();
|
||||
if (chain == null) return; // failed to load
|
||||
|
||||
// update the Desat uniform on all passes
|
||||
try {
|
||||
for (PostPass pass : getPasses(chain)) {
|
||||
EffectInstance effect = pass.getEffect();
|
||||
if (effect == null) continue;
|
||||
var uniform = effect.getUniform("Desat");
|
||||
if (uniform != null) {
|
||||
uniform.set(currentStrength);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
|
||||
if (!event.getEntity().level().isClientSide()) return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
currentStrength = 0f;
|
||||
|
||||
mc.execute(() -> {
|
||||
if (mc.gameRenderer.currentEffect() != null) {
|
||||
mc.gameRenderer.shutdownEffect();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user