generated from MrSphay/codex-agent-repository-kit
312 lines
12 KiB
Java
312 lines
12 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
package com.vinlanx.explosionoverhaul.client;
|
|
|
|
import com.vinlanx.explosionoverhaul.Config;
|
|
import com.vinlanx.explosionoverhaul.client.SoundEngineAudioQueue;
|
|
import com.vinlanx.explosionoverhaul.client.SoundPhysicsCompatibility;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
import net.minecraftforge.event.TickEvent;
|
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
import net.minecraftforge.fml.common.Mod;
|
|
import org.lwjgl.openal.AL10;
|
|
import org.lwjgl.openal.ALC10;
|
|
import org.lwjgl.openal.EXTEfx;
|
|
|
|
@OnlyIn(value=Dist.CLIENT)
|
|
@Mod.EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
|
public class LowPassConcussionEffect {
|
|
private static final float HF_MIN = 0.01f;
|
|
private static final float HF_MAX = 1.0f;
|
|
private static final float GAIN_MIN = 0.1f;
|
|
private static final int FADE_IN_TICKS = 40;
|
|
private static final int FADE_OUT_TICKS = 100;
|
|
private static volatile Phase phase = Phase.IDLE;
|
|
private static volatile int holdTicks = 0;
|
|
private static volatile int ticksInPhase = 0;
|
|
private static final AtomicBoolean efxAvailable = new AtomicBoolean(false);
|
|
private static volatile int filterId = 0;
|
|
private static volatile float targetHfMin = 1.0f;
|
|
private static volatile float targetGainMin = 1.0f;
|
|
private static volatile float currentDeafnessGain = 1.0f;
|
|
public static volatile boolean enabled = true;
|
|
public static volatile boolean debugShowChat = false;
|
|
private static volatile boolean compatibilityMode = false;
|
|
private static volatile float lastAppliedHf = 1.0f;
|
|
private static volatile float lastAppliedGain = 1.0f;
|
|
|
|
public static void setDeafnessGain(float gain) {
|
|
currentDeafnessGain = Math.max(0.0f, Math.min(1.0f, gain));
|
|
if (phase == Phase.IDLE && currentDeafnessGain < 0.99f && !compatibilityMode) {
|
|
SoundEngineAudioQueue.enqueueAudio(() -> LowPassConcussionEffect.ensureFilterExists());
|
|
}
|
|
}
|
|
|
|
private static void ensureFilterExists() {
|
|
if (!efxAvailable.get()) {
|
|
long ctx = ALC10.alcGetCurrentContext();
|
|
long dev = ALC10.alcGetContextsDevice((long)ctx);
|
|
if (!ALC10.alcIsExtensionPresent((long)dev, (CharSequence)"ALC_EXT_EFX")) {
|
|
efxAvailable.set(false);
|
|
return;
|
|
}
|
|
efxAvailable.set(true);
|
|
}
|
|
if (filterId == 0) {
|
|
filterId = EXTEfx.alGenFilters();
|
|
EXTEfx.alFilteri((int)filterId, (int)32769, (int)1);
|
|
EXTEfx.alFilterf((int)filterId, (int)1, (float)1.0f);
|
|
EXTEfx.alFilterf((int)filterId, (int)2, (float)1.0f);
|
|
}
|
|
}
|
|
|
|
public static void start(int seconds, float intensity) {
|
|
Minecraft mc;
|
|
if (!enabled) {
|
|
return;
|
|
}
|
|
if (seconds < 1) {
|
|
seconds = 1;
|
|
}
|
|
if (seconds > 600) {
|
|
seconds = 600;
|
|
}
|
|
float effectiveIntensity = (Boolean)Config.CLIENT.enableLowPass.get() != false ? intensity : 0.001f;
|
|
float addedStrength = Math.max(0.0f, Math.min(1.0f, effectiveIntensity));
|
|
if (phase != Phase.IDLE) {
|
|
float currentStrength = (1.0f - targetHfMin) / 0.99f;
|
|
float totalStrength = Math.min(1.0f, currentStrength + addedStrength);
|
|
targetHfMin = 1.0f - totalStrength * 0.99f;
|
|
holdTicks = Math.min(2000, holdTicks + seconds * 20);
|
|
if (phase == Phase.FADE_OUT) {
|
|
phase = Phase.HOLD;
|
|
ticksInPhase = 0;
|
|
}
|
|
} else {
|
|
float totalStrength = addedStrength;
|
|
targetHfMin = 1.0f - totalStrength * 0.99f;
|
|
targetGainMin = 0.1f;
|
|
holdTicks = seconds * 20;
|
|
ticksInPhase = 0;
|
|
phase = Phase.FADE_IN;
|
|
}
|
|
if (!compatibilityMode) {
|
|
SoundEngineAudioQueue.enqueueAudio(() -> {
|
|
try {
|
|
LowPassConcussionEffect.ensureFilterExists();
|
|
}
|
|
catch (Throwable ex) {
|
|
efxAvailable.set(false);
|
|
}
|
|
});
|
|
SoundEngineAudioQueue.drainNow();
|
|
}
|
|
if (debugShowChat && (mc = Minecraft.m_91087_()) != null && mc.f_91074_ != null) {
|
|
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)("Low pass test queued for " + seconds + "s (strength=" + addedStrength + ")")), false);
|
|
}
|
|
}
|
|
|
|
public static void start(int seconds, float intensity, double effectivePercent, String visibility, int intensityPercent) {
|
|
Minecraft mc;
|
|
if (debugShowChat && (mc = Minecraft.m_91087_()) != null && mc.f_91074_ != null) {
|
|
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)"__________________________________________"), false);
|
|
String msg = String.format("\u041f\u043e\u0442\u0443\u0436\u043d\u0456\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0443\u0437\u0456\u0457 %.1f%% (%s) \u2014 \u0421\u0438\u043b\u0430 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %d%%, \u0427\u0430\u0441 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %.1f \u0441\u0435\u043a", effectivePercent, visibility, intensityPercent, (double)seconds);
|
|
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)msg).m_130940_(ChatFormatting.WHITE), false);
|
|
mc.f_91074_.m_5661_((Component)Component.m_237113_((String)"__________________________________________"), false);
|
|
}
|
|
LowPassConcussionEffect.start(seconds, intensity);
|
|
}
|
|
|
|
public static void stop() {
|
|
phase = Phase.IDLE;
|
|
ticksInPhase = 0;
|
|
lastAppliedHf = 1.0f;
|
|
lastAppliedGain = 1.0f;
|
|
targetGainMin = 1.0f;
|
|
if (compatibilityMode) {
|
|
SoundEngineAudioQueue.enqueueAudio(SoundPhysicsCompatibility::reapplyDirectFilterParameters);
|
|
}
|
|
SoundEngineAudioQueue.enqueueAudio(() -> {
|
|
if (filterId != 0) {
|
|
try {
|
|
EXTEfx.alFilterf((int)filterId, (int)2, (float)1.0f);
|
|
EXTEfx.alFilterf((int)filterId, (int)1, (float)1.0f);
|
|
}
|
|
catch (Throwable throwable) {
|
|
// empty catch block
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public static boolean isActive() {
|
|
return phase != Phase.IDLE || currentDeafnessGain < 0.99f;
|
|
}
|
|
|
|
public static int getFilterId() {
|
|
return filterId;
|
|
}
|
|
|
|
@SubscribeEvent
|
|
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
|
if (event.phase == TickEvent.Phase.END) {
|
|
LowPassConcussionEffect.onClientTick();
|
|
}
|
|
}
|
|
|
|
public static void onClientTick() {
|
|
Minecraft mc = Minecraft.m_91087_();
|
|
if (mc != null && mc.m_91104_()) {
|
|
return;
|
|
}
|
|
if (currentDeafnessGain < 0.99f || phase != Phase.IDLE) {
|
|
float hf = 1.0f;
|
|
float gainInterp = 1.0f;
|
|
if (phase != Phase.IDLE) {
|
|
++ticksInPhase;
|
|
switch (phase) {
|
|
case FADE_IN: {
|
|
float t = Math.min(1.0f, (float)ticksInPhase / 40.0f);
|
|
hf = LowPassConcussionEffect.lerp(1.0f, targetHfMin, LowPassConcussionEffect.easeOutQuad(t));
|
|
gainInterp = LowPassConcussionEffect.lerp(1.0f, targetGainMin, LowPassConcussionEffect.easeOutQuad(t));
|
|
if (ticksInPhase < 40) break;
|
|
phase = Phase.HOLD;
|
|
ticksInPhase = 0;
|
|
hf = targetHfMin;
|
|
gainInterp = targetGainMin;
|
|
break;
|
|
}
|
|
case HOLD: {
|
|
hf = targetHfMin;
|
|
gainInterp = targetGainMin;
|
|
if (ticksInPhase < holdTicks) break;
|
|
phase = Phase.FADE_OUT;
|
|
ticksInPhase = 0;
|
|
break;
|
|
}
|
|
case FADE_OUT: {
|
|
float t = Math.min(1.0f, (float)ticksInPhase / 100.0f);
|
|
hf = LowPassConcussionEffect.lerp(targetHfMin, 1.0f, LowPassConcussionEffect.easeInQuad(t));
|
|
gainInterp = LowPassConcussionEffect.lerp(targetGainMin, 1.0f, LowPassConcussionEffect.easeInQuad(t));
|
|
if (ticksInPhase < 100) break;
|
|
LowPassConcussionEffect.stop();
|
|
hf = 1.0f;
|
|
gainInterp = 1.0f;
|
|
}
|
|
}
|
|
}
|
|
float combinedGain = Math.max(0.0f, Math.min(1.0f, gainInterp * currentDeafnessGain));
|
|
LowPassConcussionEffect.applyFilterParamsOnAudioThread(hf, combinedGain);
|
|
}
|
|
}
|
|
|
|
private static void applyFilterParamsOnAudioThread(float hf, float gain) {
|
|
float clampedHf = Math.max(0.01f, Math.min(1.0f, hf));
|
|
float clampedGain = Math.max(0.0f, Math.min(1.0f, gain));
|
|
lastAppliedHf = clampedHf;
|
|
lastAppliedGain = clampedGain;
|
|
if (compatibilityMode) {
|
|
SoundEngineAudioQueue.enqueueAudio(SoundPhysicsCompatibility::reapplyDirectFilterParameters);
|
|
}
|
|
if (!efxAvailable.get()) {
|
|
return;
|
|
}
|
|
int fid = filterId;
|
|
if (fid == 0) {
|
|
return;
|
|
}
|
|
SoundEngineAudioQueue.enqueueAudio(() -> {
|
|
try {
|
|
EXTEfx.alFilterf((int)fid, (int)2, (float)clampedHf);
|
|
EXTEfx.alFilterf((int)fid, (int)1, (float)clampedGain);
|
|
}
|
|
catch (Throwable throwable) {
|
|
// empty catch block
|
|
}
|
|
});
|
|
}
|
|
|
|
private static float lerp(float a, float b, float t) {
|
|
return a + (b - a) * t;
|
|
}
|
|
|
|
private static float easeOutQuad(float t) {
|
|
return 1.0f - (1.0f - t) * (1.0f - t);
|
|
}
|
|
|
|
private static float easeInQuad(float t) {
|
|
return t * t;
|
|
}
|
|
|
|
private static String alErrorName(int err) {
|
|
return switch (err) {
|
|
case 0 -> "AL_NO_ERROR";
|
|
case 40961 -> "AL_INVALID_NAME";
|
|
case 40962 -> "AL_INVALID_ENUM";
|
|
case 40963 -> "AL_INVALID_VALUE";
|
|
case 40964 -> "AL_INVALID_OPERATION";
|
|
case 40965 -> "AL_OUT_OF_MEMORY";
|
|
default -> "AL_UNKNOWN_ERROR";
|
|
};
|
|
}
|
|
|
|
public static void setCompatibilityMode(boolean compatibilityActive) {
|
|
compatibilityMode = compatibilityActive;
|
|
}
|
|
|
|
public static float getCurrentHfMultiplier() {
|
|
return Math.max(0.01f, Math.min(1.0f, lastAppliedHf));
|
|
}
|
|
|
|
public static float getCurrentGainMultiplier() {
|
|
return Math.max(0.0f, Math.min(1.0f, lastAppliedGain));
|
|
}
|
|
|
|
public static void attachFilterToSource(int sourceId) {
|
|
if (sourceId <= 0) {
|
|
return;
|
|
}
|
|
if (!efxAvailable.get() || filterId == 0) {
|
|
return;
|
|
}
|
|
try {
|
|
if (!AL10.alIsSource((int)sourceId)) {
|
|
return;
|
|
}
|
|
if (AL10.alGetSourcei((int)sourceId, (int)514) == 1) {
|
|
return;
|
|
}
|
|
AL10.alSourcei((int)sourceId, (int)131077, (int)filterId);
|
|
}
|
|
catch (Throwable throwable) {
|
|
// empty catch block
|
|
}
|
|
}
|
|
|
|
public static void detachFilterFromSource(int sourceId) {
|
|
try {
|
|
if (AL10.alIsSource((int)sourceId)) {
|
|
AL10.alSourcei((int)sourceId, (int)131077, (int)0);
|
|
}
|
|
}
|
|
catch (Throwable throwable) {
|
|
// empty catch block
|
|
}
|
|
}
|
|
|
|
private static enum Phase {
|
|
IDLE,
|
|
FADE_IN,
|
|
HOLD,
|
|
FADE_OUT;
|
|
|
|
}
|
|
}
|
|
|