/* * Decompiled with CFR 0.152. */ package com.vinlanx.explosionoverhaul.client; import com.vinlanx.explosionoverhaul.Config; import com.vinlanx.explosionoverhaul.ModSounds; import com.vinlanx.explosionoverhaul.client.Blur; import com.vinlanx.explosionoverhaul.client.CameraShakeConcussionEffect; import com.vinlanx.explosionoverhaul.client.DeafnessConcussionEffect; import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect; import java.util.concurrent.ThreadLocalRandom; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.loading.FMLEnvironment; @Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT}) public class ConcussionAudioEffect { public static boolean debugSendDebugMessage = false; public static boolean TestingHudHeart = true; public static float currentBPM = 23.3f; private static double heartbeatCycleTimer = 0.0; private static float heartbeatVisualPulse = 0.0f; private static float explosionBPMMod = 0.0f; private static float jumpBPMMod = 0.0f; private static boolean wasOnGround = true; private static int idleTicks = 0; private static boolean lubTriggered = false; private static boolean dubTriggered = false; @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { if (event.phase == TickEvent.Phase.END) { Minecraft mc = Minecraft.m_91087_(); if (mc.f_91074_ != null && !mc.f_91074_.m_6084_()) { ConcussionAudioEffect.stopAll(); } } } public static void stopAll() { Blur.stop(); DeafnessConcussionEffect.stop(); LowPassConcussionEffect.stop(); CameraShakeConcussionEffect.stop(); } public static void start(float power, double distance, boolean hasDirectLineOfSight, boolean explosionInCave) { LocalPlayer player; LocalPlayer player2; LocalPlayer player3; if (!FMLEnvironment.dist.isClient()) { return; } if (!((Boolean)Config.CLIENT.enableConcussion.get()).booleanValue()) { return; } Minecraft mc = Minecraft.m_91087_(); if (mc == null || mc.f_91073_ == null || mc.f_91074_ == null) { return; } double rawPercent = ConcussionAudioEffect.computePercent(power, distance, explosionInCave); if (explosionInCave) { rawPercent = Math.min(100.0, rawPercent * 1.5); } double effectivePercent = hasDirectLineOfSight ? rawPercent : ConcussionAudioEffect.applyOcclusion(rawPercent); double maxDistance = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave); if (rawPercent <= 0.0) { LocalPlayer player4 = mc.f_91074_; if (player4 != null && debugSendDebugMessage) { double metersToExplosion = distance; double onePercentDistance = maxDistance * 0.99; String outMessage = String.format("\u041f\u043e\u0437\u0430 \u0437\u043e\u043d\u043e\u044e \u043f\u043e\u0440\u0430\u0437\u043a\u0438. \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c. 1%% \u043f\u043e\u0447\u0438\u043d\u0430\u0454\u0442\u044c\u0441\u044f \u0437: %.1f \u043c.", metersToExplosion, onePercentDistance); player4.m_5661_((Component)Component.m_237113_((String)outMessage).m_130940_(ChatFormatting.GRAY), false); } return; } double normalized = Math.max(0.0, Math.min(1.0, effectivePercent / 100.0)); float intensity = (float)normalized; if (intensity < 0.01f) { return; } double baseSilentSeconds = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, explosionInCave); double intensityPercent = ConcussionAudioEffect.computeBaseIntensityPercent(effectivePercent); double multiplier = ConcussionAudioEffect.computePowerMultiplier(power); double finalSilentSeconds = baseSilentSeconds * multiplier * (Double)Config.CLIENT.concussionDurationMultiplier.get(); double lowpassChance = ConcussionAudioEffect.computeLowpassPowerChance(power, explosionInCave) * (Double)Config.CLIENT.concussionChanceMultiplier.get() * (Double)Config.CLIENT.lowPassChanceMultiplier.get(); boolean lowpassRoll = ThreadLocalRandom.current().nextDouble() <= lowpassChance; double chance = ConcussionAudioEffect.computePowerChance(power, explosionInCave) * (Double)Config.CLIENT.concussionChanceMultiplier.get() * (Double)Config.CLIENT.deafnessChanceMultiplier.get(); boolean roll = ThreadLocalRandom.current().nextDouble() <= chance; boolean anyAudioEffectActive = roll || lowpassRoll; double baseBlurSeconds = ConcussionAudioEffect.computeBaseBlurSilentSeconds(effectivePercent, explosionInCave); double blurMultiplier = ConcussionAudioEffect.computeBlurPowerMultiplier(power); double finalBlurSeconds = baseBlurSeconds * blurMultiplier * (Double)Config.CLIENT.concussionDurationMultiplier.get(); boolean lowpassReduced = false; if (!lowpassRoll) { finalBlurSeconds = roll ? finalSilentSeconds : (finalBlurSeconds /= 3.0); lowpassReduced = true; } int blurSeconds = Math.max(1, (int)Math.round(finalBlurSeconds)); double blurIntensityPercent = ConcussionAudioEffect.computeBaseBlurIntensityPercent(effectivePercent); float blurIntensity = (float)(blurIntensityPercent / 100.0); double swayIntensityPercent = ConcussionAudioEffect.computeBaseSwayIntensityPercent(effectivePercent) * (Double)Config.CLIENT.cameraSwayIntensity.get(); float swayIntensity = (float)(swayIntensityPercent / 100.0); if (rawPercent > 0.0 && blurIntensity >= 0.01f && anyAudioEffectActive) { float addedBPM = 0.0f; if (rawPercent > 80.0) { addedBPM = 60.0f; } else if (rawPercent > 60.0) { addedBPM = 40.0f; } else if (rawPercent > 30.0) { addedBPM = 20.0f; } explosionBPMMod = Math.min(200.0f, explosionBPMMod + addedBPM); try { LocalPlayer player5; Blur.start(blurSeconds, blurIntensity); if (((Boolean)Config.CLIENT.enableCameraSway.get()).booleanValue()) { CameraShakeConcussionEffect.start(blurSeconds, swayIntensity); } if (debugSendDebugMessage && (player5 = mc.f_91074_) != null) { String reductionInfo = lowpassReduced ? " [LowPass reduced /3]" : ""; String blurMsg = String.format("Blur & Sway %.1f m \u2014 activated (Blur: %.2f, Sway: %.2f, Time: %ds%s)", distance, Float.valueOf(blurIntensity), Float.valueOf(swayIntensity), blurSeconds, reductionInfo); player5.m_5661_((Component)Component.m_237113_((String)blurMsg).m_130940_(ChatFormatting.BLUE), false); } } catch (Throwable player5) {} } else if (debugSendDebugMessage && (player3 = mc.f_91074_) != null) { String reason = !anyAudioEffectActive ? "no audio effects" : "out of range"; String blurMsg = String.format("Blur %.1f m \u2014 not activated (%s)", distance, reason); player3.m_5661_((Component)Component.m_237113_((String)blurMsg).m_130940_(ChatFormatting.GRAY), false); } int lowpassSeconds = blurSeconds; double lowpassIntensityPercent = ConcussionAudioEffect.computeBaseLowpassIntensityPercent(effectivePercent); float lowpassIntensity = (float)(lowpassIntensityPercent / 100.0); if (lowpassIntensity < 0.01f) { lowpassIntensity = 0.01f; } String lpVisibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430"; int lowpassIntensityRound = (int)Math.round(lowpassIntensityPercent); if (((Boolean)Config.CLIENT.enableLowPass.get()).booleanValue() && rawPercent > 0.0 && lowpassIntensity >= 0.01f && (lowpassRoll || LowPassConcussionEffect.isActive())) { try { LocalPlayer player6; float finalLpIntensity = lowpassRoll ? lowpassIntensity : 0.0f; int finalLpRound = lowpassRoll ? lowpassIntensityRound : 0; LowPassConcussionEffect.start(lowpassSeconds, finalLpIntensity, effectivePercent, lpVisibility, finalLpRound); if (debugSendDebugMessage && (player6 = mc.f_91074_) != null) { String status = lowpassRoll ? "activated" : "refreshed"; String lpMsg = String.format("Low pass %.1f m \u2014 %s (intensity=%.2f chance=%.1f%%)", distance, status, Float.valueOf(finalLpIntensity), lowpassChance * 100.0); player6.m_5661_((Component)Component.m_237113_((String)lpMsg).m_130940_(ChatFormatting.DARK_GREEN), false); } } catch (Throwable finalLpIntensity) {} } else if (debugSendDebugMessage && (player2 = mc.f_91074_) != null) { String reason = rawPercent <= 0.0 || lowpassIntensity < 0.01f ? "out of range" : "chance fail"; String lpMsg = String.format("Low pass %.1f m \u2014 not activated (%s)", distance, reason); player2.m_5661_((Component)Component.m_237113_((String)lpMsg).m_130940_(ChatFormatting.GRAY), false); } if (debugSendDebugMessage) { ConcussionAudioEffect.sendDebugMessage(mc, effectivePercent, rawPercent, hasDirectLineOfSight, distance, maxDistance); } if (debugSendDebugMessage && (player = mc.f_91074_) != null) { Object visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430"; visibility = (String)visibility + (explosionInCave ? " | \u0432\u0438\u0431\u0443\u0445 \u0443 \u043f\u0435\u0447\u0435\u0440\u0456" : " | \u0432\u0438\u0431\u0443\u0445 \u043d\u0435 \u0432 \u043f\u0435\u0447\u0435\u0440\u0456"); visibility = (String)visibility + String.format(" | \u0444\u0456\u043d\u0430\u043b\u044c\u043d\u0438\u0439 %%: %.1f%%", effectivePercent); player.m_5661_((Component)Component.m_237113_((String)visibility).m_130940_(ChatFormatting.GRAY), false); String chanceMsg = String.format("\u0428\u0430\u043d\u0441 \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457: %.1f%%", chance * 100.0); player.m_5661_((Component)Component.m_237113_((String)chanceMsg).m_130940_(ChatFormatting.YELLOW), false); double maxDistanceNormal = ConcussionAudioEffect.computeMaxDistance(power, false); double maxDistanceUsed = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave); String distMsg = String.format("\u041c\u0430\u043a\u0441 \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0456\u044f (\u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0430): %.1f \u043c | (\u0432 \u043f\u0435\u0447\u0435\u0440\u0456): %.1f \u043c | \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c", maxDistanceNormal, maxDistanceUsed, distance); player.m_5661_((Component)Component.m_237113_((String)distMsg).m_130940_(ChatFormatting.GRAY), false); double baseSilentNormal = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, false); double baseSilentCave = ConcussionAudioEffect.computeBaseSilentSeconds(effectivePercent, true); String silentMsg = String.format("\u0427\u0430\u0441 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f (\u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0438\u0439): %.1fs | (\u0432 \u043f\u0435\u0447\u0435\u0440\u0456): %.1fs | \u0412\u0418\u041a\u041e\u0420\u0418\u0421\u0422\u0410\u041d\u041e: %.1fs", baseSilentNormal, baseSilentCave, baseSilentSeconds * multiplier); player.m_5661_((Component)Component.m_237113_((String)silentMsg).m_130940_(ChatFormatting.GRAY), false); if (roll) { String deafnessMsg = String.format("Deafness %.1f m \u2014 activated (intensity=%.1f%% chance=%.1f%%)", distance, intensityPercent, chance * 100.0); player.m_5661_((Component)Component.m_237113_((String)deafnessMsg).m_130940_(ChatFormatting.RED), false); } else { String deafnessMsg = String.format("Deafness %.1f m \u2014 not activated (chance)", distance); player.m_5661_((Component)Component.m_237113_((String)deafnessMsg).m_130940_(ChatFormatting.GRAY), false); } } if (!roll) { return; } if (!((Boolean)Config.CLIENT.enableDeafness.get()).booleanValue()) { return; } int intensityRound = (int)Math.round(intensityPercent); String visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430"; float intensityFromIntensityPercent = (float)(intensityPercent / 100.0); DeafnessConcussionEffect.start(intensityFromIntensityPercent, (float)finalSilentSeconds, effectivePercent, visibility, intensityRound); } private static double computePercent(float power, double distance, boolean explosionInCave) { double maxDistance = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave); if (maxDistance <= 0.0) { return 0.0; } double normalized = 1.0 - Math.max(0.0, distance) / maxDistance; return Math.max(0.0, Math.min(1.0, normalized)) * 100.0; } private static double computeMaxDistance(float power, boolean explosionInCave) { double[][] points = explosionInCave ? new double[][]{{1.0, 5.0}, {3.0, 10.0}, {10.0, 50.0}, {25.0, 90.0}, {50.0, 150.0}, {80.0, 200.0}, {120.0, 200.0}} : new double[][]{{1.0, 2.0}, {3.0, 5.0}, {10.0, 30.0}, {25.0, 70.0}, {50.0, 100.0}, {80.0, 150.0}, {120.0, 200.0}}; double clampedPower = Math.max(points[0][0], Math.min(points[points.length - 1][0], (double)power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clampedPower <= upperP)) continue; double lowerD = points[i - 1][1]; double upperD = points[i][1]; double t = (clampedPower - lowerP) / (upperP - lowerP); return lowerD + (upperD - lowerD) * t; } return points[points.length - 1][1]; } private static double applyOcclusion(double percent) { if (percent >= 80.0) { return percent / 1.2; } if (percent >= 60.0) { return percent / 1.4; } if (percent >= 40.0) { return percent / 1.6; } if (percent >= 20.0) { return percent / 3.0; } if (percent >= 1.0) { return 0.0; } return 0.0; } private static void sendDebugMessage(Minecraft mc, double effectivePercent, double rawPercent, boolean hasDirectLineOfSight, double distance, double maxDistance) { LocalPlayer player = mc.f_91074_; if (player == null) { return; } double clamped = Math.max(0.0, Math.min(100.0, effectivePercent)); if (rawPercent <= 0.0) { double metersToExplosion = distance; double onePercentDistance = maxDistance * 0.99; String outMessage = String.format("\u041f\u043e\u0437\u0430 \u0437\u043e\u043d\u043e\u044e \u043f\u043e\u0440\u0430\u0437\u043a\u0438. \u0412\u0456\u0434\u0441\u0442\u0430\u043d\u044c \u0434\u043e \u0432\u0438\u0431\u0443\u0445\u0443: %.1f \u043c. 1%% \u043f\u043e\u0447\u0438\u043d\u0430\u0454\u0442\u044c\u0441\u044f \u0437: %.1f \u043c.", metersToExplosion, onePercentDistance); player.m_5661_((Component)Component.m_237113_((String)outMessage).m_130940_(ChatFormatting.GRAY), false); return; } ChatFormatting color = ConcussionAudioEffect.pickColor(clamped); String visibility = hasDirectLineOfSight ? "\u043f\u0440\u044f\u043c\u0430 \u0432\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c" : "\u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0430"; String message = String.format("\u041f\u043e\u0442\u0443\u0436\u043d\u0456\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457 %.1f%% (%s)", clamped, visibility); player.m_5661_((Component)Component.m_237113_((String)message).m_130940_(color), false); if (!hasDirectLineOfSight && rawPercent > 0.0) { String rawMessage = String.format("(\u0434\u043e \u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0438: %.1f%%)", Math.max(0.0, Math.min(100.0, rawPercent))); player.m_5661_((Component)Component.m_237113_((String)rawMessage).m_130940_(ChatFormatting.GRAY), false); } } private static ChatFormatting pickColor(double percent) { if (percent >= 80.0) { return ChatFormatting.RED; } if (percent >= 60.0) { return ChatFormatting.GOLD; } if (percent >= 40.0) { return ChatFormatting.YELLOW; } if (percent >= 20.0) { return ChatFormatting.AQUA; } if (percent > 0.0) { return ChatFormatting.BLUE; } return ChatFormatting.GRAY; } private static double computeBaseSilentSeconds(double effectivePercent, boolean explosionInCave) { if (!explosionInCave) { if (effectivePercent <= 40.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 4.0 + 1.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 2.0 + 2.0 * t; } double t = (effectivePercent - 40.0) / 20.0; return 1.0 + 1.0 * t; } if (effectivePercent <= 20.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 7.0 + 3.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 4.0 + 1.0 * t; } double t = (effectivePercent - 20.0) / 40.0; if (effectivePercent <= 40.0) { double tt = (effectivePercent - 20.0) / 20.0; return 2.0 + 1.0 * tt; } double tt = (effectivePercent - 40.0) / 20.0; return 2.0 + 1.0 * tt; } private static double computeBaseIntensityPercent(double effectivePercent) { if (effectivePercent <= 60.0) { return 0.0; } if (effectivePercent <= 70.0) { double t = (effectivePercent - 60.0) / 10.0; return 0.0 + 60.0 * t; } if (effectivePercent <= 85.0) { double t = (effectivePercent - 70.0) / 15.0; return 60.0 + 20.0 * t; } if (effectivePercent <= 90.0) { double t = (effectivePercent - 85.0) / 5.0; return 80.0 + 20.0 * t; } return 100.0; } private static double computePowerMultiplier(double power) { double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}}; double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clamped <= upperP)) continue; double lowerM = points[i - 1][1]; double upperM = points[i][1]; double t = (clamped - lowerP) / (upperP - lowerP); return lowerM + (upperM - lowerM) * t; } return points[points.length - 1][1]; } private static double computePowerChance(double power, boolean explosionInCave) { double[][] points = explosionInCave ? new double[][]{{1.0, 0.25}, {2.0, 0.3}, {3.0, 0.35}, {5.0, 0.4}, {6.0, 0.5}, {10.0, 0.75}, {15.0, 0.9}, {20.0, 1.0}, {120.0, 1.0}} : new double[][]{{1.0, 0.15}, {2.0, 0.15}, {3.0, 0.175}, {5.0, 0.215}, {6.0, 0.225}, {10.0, 0.225}, {11.0, 0.35}, {25.0, 0.4}, {26.0, 0.5}, {34.0, 0.75}, {42.0, 0.9}, {50.0, 1.0}, {120.0, 1.0}}; double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clamped <= upperP)) continue; double lowerC = points[i - 1][1]; double upperC = points[i][1]; double t = (clamped - lowerP) / (upperP - lowerP); return lowerC + (upperC - lowerC) * t; } return 1.0; } private static double computeBaseBlurSilentSeconds(double effectivePercent, boolean explosionInCave) { if (!explosionInCave) { if (effectivePercent <= 40.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 6.0 + 2.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 2.0 + 4.0 * t; } double t = (effectivePercent - 40.0) / 20.0; return 0.0 + 2.0 * t; } if (effectivePercent <= 20.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 12.0 + 6.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 6.0 + 2.0 * t; } if (effectivePercent <= 40.0) { double tt = (effectivePercent - 20.0) / 20.0; return 2.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt)); } double tt = (effectivePercent - 40.0) / 20.0; return 2.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt)); } private static double computeBaseBlurIntensityPercent(double effectivePercent) { if (effectivePercent < 60.0) { return 0.0; } double t = (effectivePercent - 60.0) / 40.0; return 1.0 + 49.0 * t; } private static double computeBaseSwayIntensityPercent(double effectivePercent) { if (effectivePercent < 50.0) { return 0.0; } double t = (effectivePercent - 50.0) / 50.0; return 100.0 * t; } private static double computeBlurPowerMultiplier(double power) { double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}}; double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clamped <= upperP)) continue; double lowerM = points[i - 1][1]; double upperM = points[i][1]; double t = (clamped - lowerP) / (upperP - lowerP); return lowerM + (upperM - lowerM) * t; } return points[points.length - 1][1]; } public static void renderHeartbeatHUD(GuiGraphics ctx) { if (!((Boolean)Config.CLIENT.showHeartbeatHUD.get()).booleanValue() || !Blur.isActive()) { return; } Minecraft mc = Minecraft.m_91087_(); if (mc.f_91074_ == null) { return; } float bps = currentBPM / 60.0f; String text = String.format("%.2f bps (%.1f BPM)", Float.valueOf(bps), Float.valueOf(currentBPM)); int x = ctx.m_280182_() - 10; int y = 10; int color = -65536; if (currentBPM < 30.0f) { color = -11141291; } else if (currentBPM < 50.0f) { color = -171; } ctx.m_280056_(mc.f_91062_, text, x - mc.f_91062_.m_92895_(text), y, color, false); } public static float getCurrentHeartbeatVisual() { return heartbeatVisualPulse; } public static void updateHeartbeat(LocalPlayer player, float blurIntensity) { float healthPercent; boolean isMoving; if (player == null) { return; } if (!Blur.isActive()) { explosionBPMMod *= 0.98f; jumpBPMMod *= 0.98f; if ((currentBPM += (23.3f - currentBPM) * 0.05f) < 24.0f && explosionBPMMod < 0.1f && jumpBPMMod < 0.1f) { currentBPM = 23.3f; explosionBPMMod = 0.0f; jumpBPMMod = 0.0f; heartbeatVisualPulse = 0.0f; return; } } float baseBPM = 23.3f; boolean bl = isMoving = player.m_20184_().m_165925_() > 0.001; if (isMoving) { if (player.m_20142_()) { baseBPM = 50.0f; if (!player.m_20096_()) { baseBPM = 60.0f; } } else { baseBPM = 35.0f; } } if ((healthPercent = player.m_21223_() / player.m_21233_()) < 0.1f) { baseBPM += 63.3f; } else if (healthPercent < 0.3f) { baseBPM += 43.3f; } if (!player.m_20096_() && wasOnGround && isMoving) { jumpBPMMod = Math.min(13.3f, jumpBPMMod + 3.3f); } wasOnGround = player.m_20096_(); jumpBPMMod *= 0.99f; explosionBPMMod *= 0.995f; if (player.f_19789_ > 3.0f) { baseBPM += Math.min(16.6f, player.f_19789_ * 1.6f); } if (player.m_20146_() <= 0) { baseBPM += 5.0f; } if (player.m_6047_()) { baseBPM -= 3.3f; } if (!isMoving) { if (++idleTicks >= 60) { baseBPM -= 1.6f; idleTicks = 0; } } else { idleTicks = 0; } float finalTarget = baseBPM + jumpBPMMod + explosionBPMMod; if ((finalTarget = Math.max(20.0f, Math.min(130.0f, finalTarget))) > currentBPM) { float rampSpeed = explosionBPMMod > 5.0f || Blur.isActive() ? 0.4f : 0.15f; currentBPM += (finalTarget - currentBPM) * rampSpeed; } else { currentBPM += (finalTarget - currentBPM) * 0.04f; } double cycleSeconds = 60.0 / (double)Math.max(5.0f, currentBPM); heartbeatCycleTimer += 0.05; if (heartbeatCycleTimer >= cycleSeconds) { heartbeatCycleTimer -= cycleSeconds; lubTriggered = false; dubTriggered = false; } double t = heartbeatCycleTimer; float pulse = 0.0f; double lubEnd = cycleSeconds * 0.35; double pause1End = cycleSeconds * 0.45; double dubEnd = cycleSeconds * 0.7; if (t < lubEnd) { s = (float)Math.sin(t / lubEnd * Math.PI); pulse = (float)Math.pow(s, 1.2); if (!lubTriggered) { lubTriggered = true; if (blurIntensity >= 0.1f && ((Boolean)Config.CLIENT.enableHeartbeatPulse.get()).booleanValue()) { try { Minecraft mc = Minecraft.m_91087_(); if (mc != null) { mc.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.HEART_LAB.get()), (float)1.0f, (float)100.0f)); } } catch (Throwable mc) {} } } } else if (t > pause1End && t < dubEnd) { s = (float)Math.sin((t - pause1End) / (dubEnd - pause1End) * Math.PI); pulse = (float)Math.pow(s, 1.2) * 0.7f; if (!dubTriggered) { dubTriggered = true; if (blurIntensity >= 0.1f && ((Boolean)Config.CLIENT.enableHeartbeatPulse.get()).booleanValue()) { try { Minecraft mc = Minecraft.m_91087_(); if (mc != null) { mc.m_91106_().m_120367_((SoundInstance)SimpleSoundInstance.m_119755_((SoundEvent)((SoundEvent)ModSounds.HEART_DAB.get()), (float)1.0f, (float)100.0f)); } } catch (Throwable throwable) { // empty catch block } } } } if ((healthPercent < 0.05f || explosionBPMMod > 80.0f && t < 2.0) && ThreadLocalRandom.current().nextDouble() < 0.03) { heartbeatCycleTimer += 0.08; } float pulseScale = 0.3f + blurIntensity * 1.5f; heartbeatVisualPulse = pulse * pulseScale; } private static double computeBaseLowpassSilentSeconds(double effectivePercent, boolean explosionInCave) { if (!explosionInCave) { if (effectivePercent <= 40.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 8.0 + 2.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 4.0 + 4.0 * t; } double t = (effectivePercent - 40.0) / 20.0; return 2.0 + 2.0 * t; } if (effectivePercent <= 20.0) { return 0.0; } if (effectivePercent > 80.0) { double t = (effectivePercent - 80.0) / 20.0; return 14.0 + 6.0 * t; } if (effectivePercent > 60.0) { double t = (effectivePercent - 60.0) / 20.0; return 8.0 + 2.0 * t; } if (effectivePercent <= 40.0) { double tt = (effectivePercent - 20.0) / 20.0; return 4.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt)); } double tt = (effectivePercent - 40.0) / 20.0; return 4.0 + 2.0 * Math.max(0.0, Math.min(1.0, tt)); } private static double computeBaseLowpassIntensityPercent(double effectivePercent) { if (effectivePercent <= 40.0) { return 0.0; } if (effectivePercent <= 50.0) { double t = (effectivePercent - 40.0) / 10.0; return 0.0 + 70.0 * t; } if (effectivePercent <= 70.0) { double t = (effectivePercent - 50.0) / 20.0; return 70.0 + 30.0 * t; } return 100.0; } private static double computeLowpassPowerMultiplier(double power) { double[][] points = new double[][]{{2.0, 1.0}, {5.0, 1.2}, {6.0, 1.4}, {12.0, 1.8}, {13.0, 2.0}, {22.0, 2.3}, {23.0, 2.7}, {50.0, 3.0}, {51.0, 3.2}, {80.0, 5.0}, {120.0, 7.0}}; double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clamped <= upperP)) continue; double lowerM = points[i - 1][1]; double upperM = points[i][1]; double t = (clamped - lowerP) / (upperP - lowerP); return lowerM + (upperM - lowerM) * t; } return points[points.length - 1][1]; } private static double computeLowpassPowerChance(double power, boolean explosionInCave) { double[][] points = explosionInCave ? new double[][]{{1.0, 0.5}, {2.0, 0.6}, {3.0, 0.7}, {5.0, 0.8}, {6.0, 0.95}, {120.0, 1.0}} : new double[][]{{1.0, 0.3}, {2.0, 0.3}, {3.0, 0.35}, {5.0, 0.43}, {6.0, 0.45}, {10.0, 0.45}, {11.0, 0.7}, {25.0, 0.8}, {26.0, 1.0}, {120.0, 1.0}}; double clamped = Math.max(points[0][0], Math.min(points[points.length - 1][0], power)); for (int i = 1; i < points.length; ++i) { double lowerP = points[i - 1][0]; double upperP = points[i][0]; if (!(clamped <= upperP)) continue; double lowerC = points[i - 1][1]; double upperC = points[i][1]; double t = (clamped - lowerP) / (upperP - lowerP); return lowerC + (upperC - lowerC) * t; } return 1.0; } }