generated from MrSphay/codex-agent-repository-kit
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.vinlanx.explosionoverhaul;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
@@ -11,6 +12,8 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
|
||||
public class VinlanxTheLightBlock extends BaseEntityBlock {
|
||||
public static final MapCodec<VinlanxTheLightBlock> CODEC = simpleCodec(VinlanxTheLightBlock::new);
|
||||
|
||||
public VinlanxTheLightBlock(BlockBehaviour.Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
@@ -34,4 +37,9 @@ public class VinlanxTheLightBlock extends BaseEntityBlock {
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new VinlanxTheLightBlockEntity(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MapCodec<? extends BaseEntityBlock> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ extends GeoItemRenderer<VinlanxTheLightItem> {
|
||||
}
|
||||
|
||||
public void preRender(PoseStack poseStack, VinlanxTheLightItem animatable, BakedGeoModel model, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
|
||||
super.preRender(poseStack, animatable, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
|
||||
if (this.renderPerspective == ItemDisplayContext.GUI || this.renderPerspective == ItemDisplayContext.FIXED) {
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180.0f));
|
||||
}
|
||||
|
||||
@@ -1,664 +1,96 @@
|
||||
/*
|
||||
* 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.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
|
||||
@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.getInstance();
|
||||
if (mc.player != null && !mc.player.m_6084_()) {
|
||||
ConcussionAudioEffect.stopAll();
|
||||
}
|
||||
}
|
||||
public static void start(float power, double distance, boolean hasDirectLineOfSight, boolean explosionInCave) {
|
||||
}
|
||||
|
||||
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.getInstance();
|
||||
if (mc == null || mc.f_91073_ == null || mc.player == 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.player;
|
||||
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.displayClientMessage((Component)Component.literal((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.player) != 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.displayClientMessage((Component)Component.literal((String)blurMsg).m_130940_(ChatFormatting.BLUE), false);
|
||||
}
|
||||
}
|
||||
catch (Throwable player5) {}
|
||||
} else if (debugSendDebugMessage && (player3 = mc.player) != null) {
|
||||
String reason = !anyAudioEffectActive ? "no audio effects" : "out of range";
|
||||
String blurMsg = String.format("Blur %.1f m \u2014 not activated (%s)", distance, reason);
|
||||
player3.displayClientMessage((Component)Component.literal((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.player) != 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.displayClientMessage((Component)Component.literal((String)lpMsg).m_130940_(ChatFormatting.DARK_GREEN), false);
|
||||
}
|
||||
}
|
||||
catch (Throwable finalLpIntensity) {}
|
||||
} else if (debugSendDebugMessage && (player2 = mc.player) != 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.displayClientMessage((Component)Component.literal((String)lpMsg).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
if (debugSendDebugMessage) {
|
||||
ConcussionAudioEffect.sendDebugMessage(mc, effectivePercent, rawPercent, hasDirectLineOfSight, distance, maxDistance);
|
||||
}
|
||||
if (debugSendDebugMessage && (player = mc.player) != 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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((String)deafnessMsg).m_130940_(ChatFormatting.RED), false);
|
||||
} else {
|
||||
String deafnessMsg = String.format("Deafness %.1f m \u2014 not activated (chance)", distance);
|
||||
player.displayClientMessage((Component)Component.literal((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);
|
||||
public static void updateHeartbeat(LocalPlayer player, float currentIntensity) {
|
||||
}
|
||||
|
||||
private static double computePercent(float power, double distance, boolean explosionInCave) {
|
||||
double maxDistance = ConcussionAudioEffect.computeMaxDistance(power, explosionInCave);
|
||||
public static float getCurrentHeartbeatVisual() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public static void renderHeartbeatHUD(GuiGraphics guiGraphics) {
|
||||
}
|
||||
|
||||
public static void sendDebugMessage(Minecraft mc, double effectivePercent, double rawPercent, boolean hasDirectLineOfSight, double distance, double maxDistance) {
|
||||
}
|
||||
|
||||
public static double computePercent(float power, double distance, boolean explosionInCave) {
|
||||
double maxDistance = 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;
|
||||
return Math.max(0.0, Math.min(1.0, 1.0 - Math.max(0.0, distance) / maxDistance)) * 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];
|
||||
public static double computeMaxDistance(float power, boolean explosionInCave) {
|
||||
return explosionInCave ? Math.max(10.0, power * 4.0) : Math.max(5.0, power * 2.5);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
public static double applyOcclusion(double percent) {
|
||||
return Math.max(0.0, percent * 0.5);
|
||||
}
|
||||
|
||||
public static double computeBaseSilentSeconds(double effectivePercent, boolean explosionInCave) {
|
||||
return Math.max(0.0, effectivePercent / 25.0);
|
||||
}
|
||||
|
||||
public static double computeBaseIntensityPercent(double effectivePercent) {
|
||||
return Math.max(0.0, Math.min(100.0, effectivePercent));
|
||||
}
|
||||
|
||||
public static double computePowerMultiplier(float power) {
|
||||
return Math.max(1.0, power / 10.0);
|
||||
}
|
||||
|
||||
public static double computeLowpassPowerChance(float power, boolean explosionInCave) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private static void sendDebugMessage(Minecraft mc, double effectivePercent, double rawPercent, boolean hasDirectLineOfSight, double distance, double maxDistance) {
|
||||
LocalPlayer player = mc.player;
|
||||
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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((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.displayClientMessage((Component)Component.literal((String)rawMessage).m_130940_(ChatFormatting.GRAY), false);
|
||||
}
|
||||
public static double computePowerChance(float power, boolean explosionInCave) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private static ChatFormatting pickColor(double percent) {
|
||||
public static double computeBaseBlurSilentSeconds(double effectivePercent, boolean explosionInCave) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static double computeBlurPowerMultiplier(float power) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public static double computeBaseBlurIntensityPercent(double effectivePercent) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static double computeBaseSwayIntensityPercent(double effectivePercent) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static double computeBaseLowpassIntensityPercent(double effectivePercent) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static ChatFormatting pickColor(double percent) {
|
||||
if (percent >= 80.0) {
|
||||
return ChatFormatting.RED;
|
||||
}
|
||||
if (percent >= 60.0) {
|
||||
return ChatFormatting.GOLD;
|
||||
}
|
||||
if (percent >= 40.0) {
|
||||
if (percent >= 30.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.getInstance();
|
||||
if (mc.player == 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.font, text, x - mc.font.width(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.getInstance();
|
||||
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.getInstance();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,179 +1,37 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.client.LowPassConcussionEffect;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
|
||||
@OnlyIn(value=Dist.CLIENT)
|
||||
@EventBusSubscriber(modid="explosionoverhaul", value={Dist.CLIENT})
|
||||
public class DeafnessConcussionEffect {
|
||||
public static int DELAY_TICKS = 3;
|
||||
public static int FADE_TO_SILENT_TICKS = 5;
|
||||
public static int FADE_FROM_SILENT_TICKS = 100;
|
||||
private static Phase phase = Phase.NONE;
|
||||
private static int ticksInPhase = 0;
|
||||
private static int phaseTicksTotal = 0;
|
||||
private static int silentTicks = 0;
|
||||
private static double baseMasterVolume = 1.0;
|
||||
private static float currentIntensity = 0.0f;
|
||||
private static float lastIntensity = 0.0f;
|
||||
public static boolean debugShowChat = false;
|
||||
public static volatile boolean enabled = true;
|
||||
|
||||
public static boolean start(float intensity, double silentSeconds, double effectivePercent, String visibility, int intensityPercent) {
|
||||
LocalPlayer player;
|
||||
float effectiveIntensity;
|
||||
if (!FMLEnvironment.dist.isClient()) {
|
||||
return false;
|
||||
}
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
float f = effectiveIntensity = (Boolean)Config.CLIENT.enableDeafness.get() != false ? intensity : 0.001f;
|
||||
if (effectiveIntensity < 1.0E-4f) {
|
||||
return false;
|
||||
}
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null || mc.f_91073_ == null || mc.player == null) {
|
||||
return false;
|
||||
}
|
||||
Options options = mc.options;
|
||||
if (options == null) {
|
||||
return false;
|
||||
}
|
||||
baseMasterVolume = (Double)options.m_246669_(SoundSource.MASTER).m_231551_();
|
||||
if (phase != Phase.NONE) {
|
||||
currentIntensity = Math.min(1.0f, currentIntensity + effectiveIntensity);
|
||||
silentTicks = Math.min(2000, silentTicks + (int)Math.round(silentSeconds * 20.0));
|
||||
if (phase != Phase.SILENT) {
|
||||
phase = Phase.FADE_IN;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = FADE_TO_SILENT_TICKS;
|
||||
}
|
||||
} else {
|
||||
currentIntensity = effectiveIntensity;
|
||||
silentTicks = Math.max(0, (int)Math.round(silentSeconds * 20.0));
|
||||
phase = Phase.DELAY;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = DELAY_TICKS;
|
||||
}
|
||||
lastIntensity = currentIntensity;
|
||||
if (debugShowChat && (player = mc.player) != null) {
|
||||
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 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f %d%%, \u0427\u0430\u0441 \u0441\u043a\u0440\u0443\u0447\u0443\u0432\u0430\u043d\u043d\u044f %.1f \u0441\u0435\u043a", effectivePercent, visibility, intensityPercent, silentSeconds);
|
||||
player.displayClientMessage((Component)Component.literal((String)msg).m_130940_(ChatFormatting.WHITE), false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.END) {
|
||||
return;
|
||||
}
|
||||
if (phase == Phase.NONE) {
|
||||
return;
|
||||
}
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc == null || mc.options == null) {
|
||||
DeafnessConcussionEffect.resetVolume();
|
||||
return;
|
||||
}
|
||||
if (mc.m_91104_()) {
|
||||
return;
|
||||
}
|
||||
double t = Math.min(1.0, (double)(++ticksInPhase) / (double)phaseTicksTotal);
|
||||
switch (phase) {
|
||||
case DELAY: {
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.FADE_IN, FADE_TO_SILENT_TICKS);
|
||||
break;
|
||||
}
|
||||
case FADE_IN: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
double gain = DeafnessConcussionEffect.lerp(baseMasterVolume, minGain, DeafnessConcussionEffect.easeOutQuad(t));
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, gain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.SILENT, silentTicks);
|
||||
break;
|
||||
}
|
||||
case SILENT: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, minGain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.nextPhase(Phase.FADE_OUT, FADE_FROM_SILENT_TICKS);
|
||||
break;
|
||||
}
|
||||
case FADE_OUT: {
|
||||
double minGain = baseMasterVolume * (1.0 - (double)currentIntensity);
|
||||
double gain = DeafnessConcussionEffect.lerp(minGain, baseMasterVolume, DeafnessConcussionEffect.easeInOutQuad(t));
|
||||
DeafnessConcussionEffect.applyMasterVolume(mc, gain);
|
||||
if (ticksInPhase < phaseTicksTotal) break;
|
||||
DeafnessConcussionEffect.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void nextPhase(Phase next, int durationTicks) {
|
||||
phase = next;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = durationTicks;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
DeafnessConcussionEffect.resetVolume();
|
||||
phase = Phase.NONE;
|
||||
ticksInPhase = 0;
|
||||
phaseTicksTotal = 0;
|
||||
lastIntensity = 0.0f;
|
||||
}
|
||||
|
||||
public static boolean isActive() {
|
||||
return phase != Phase.NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void resetVolume() {
|
||||
LowPassConcussionEffect.setDeafnessGain(1.0f);
|
||||
public static void resetVolume() {
|
||||
}
|
||||
|
||||
private static void applyMasterVolume(Minecraft mc, double volume) {
|
||||
float clamped = (float)Math.max(0.0, Math.min(1.0, volume));
|
||||
LowPassConcussionEffect.setDeafnessGain(clamped);
|
||||
public static void applyMasterVolume(Minecraft mc, double volume) {
|
||||
}
|
||||
|
||||
private static double lerp(double a, double b, double t) {
|
||||
public static double lerp(double a, double b, double t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
private static double easeOutQuad(double t) {
|
||||
public static double easeOutQuad(double t) {
|
||||
return 1.0 - (1.0 - t) * (1.0 - t);
|
||||
}
|
||||
|
||||
private static double easeInOutQuad(double t) {
|
||||
public static double easeInOutQuad(double t) {
|
||||
return t < 0.5 ? 2.0 * t * t : 1.0 - Math.pow(-2.0 * t + 2.0, 2.0) / 2.0;
|
||||
}
|
||||
|
||||
private static enum Phase {
|
||||
NONE,
|
||||
DELAY,
|
||||
FADE_IN,
|
||||
SILENT,
|
||||
FADE_OUT;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,144 +1,53 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ExplosionWindController {
|
||||
private static final double BASE_SPEED = 0.05;
|
||||
private static final double MAX_SPEED = 0.06;
|
||||
private static final double LERP_FACTOR = 0.03;
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final double[] HEIGHT_STOPS = new double[]{0.0, 0.25, 0.5, 0.75, 1.0};
|
||||
private static final double[] DUST_SPEEDS = new double[]{0.02, 0.02, 0.02, 0.02, 0.02};
|
||||
private static final double[] GLOW_SPEEDS = new double[]{0.0, 0.02, 0.04, 0.06, 0.08};
|
||||
private static Vec3 currentWind = Vec3.f_82478_;
|
||||
private static Vec3 targetDirection = Vec3.f_82478_;
|
||||
private static int ticksUntilDirectionShift = 0;
|
||||
public static Vec3 currentWind = Vec3.ZERO;
|
||||
|
||||
private ExplosionWindController() {
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
Vec3 desiredWind;
|
||||
if (ticksUntilDirectionShift-- <= 0) {
|
||||
targetDirection = ExplosionWindController.randomHorizontalDirection();
|
||||
ticksUntilDirectionShift = 80 + RANDOM.nextInt(120);
|
||||
}
|
||||
if ((currentWind = ExplosionWindController.lerp(currentWind, desiredWind = targetDirection.m_82490_(0.05), 0.03)).m_82553_() > 0.06) {
|
||||
currentWind = currentWind.m_82541_().m_82490_(0.06);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
currentWind = Vec3.f_82478_;
|
||||
targetDirection = Vec3.f_82478_;
|
||||
ticksUntilDirectionShift = 0;
|
||||
currentWind = Vec3.ZERO;
|
||||
}
|
||||
|
||||
public static Vec3 getWind() {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double multiplier = (Double)Config.CLIENT.windSpeedMultiplier.get();
|
||||
return currentWind.m_82490_(multiplier);
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
public static Vec3 getScaledWind(double scale) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double multiplier = (Double)Config.CLIENT.windSpeedMultiplier.get();
|
||||
return currentWind.m_82490_(scale * multiplier);
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
public static Vec3 getWindDirection() {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
double length = Math.sqrt(ExplosionWindController.currentWind.f_82479_ * ExplosionWindController.currentWind.f_82479_ + ExplosionWindController.currentWind.f_82481_ * ExplosionWindController.currentWind.f_82481_);
|
||||
if (length < 1.0E-4) {
|
||||
return Vec3.f_82478_;
|
||||
}
|
||||
return new Vec3(ExplosionWindController.currentWind.f_82479_ / length, 0.0, ExplosionWindController.currentWind.f_82481_ / length);
|
||||
}
|
||||
|
||||
private static double getWeatherMultiplier() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
if (minecraft.f_91073_ != null && minecraft.player != null) {
|
||||
Biome.Precipitation precipitation = ((Biome)minecraft.f_91073_.m_204166_(minecraft.player.m_20183_()).m_203334_()).m_264600_(minecraft.player.m_20183_());
|
||||
if (minecraft.f_91073_.m_46471_() || minecraft.f_91073_.m_46470_()) {
|
||||
return 1.5;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
public static double computeDustSpeed(double heightPercent) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return 0.0;
|
||||
}
|
||||
double baseSpeed = ExplosionWindController.sampleProfile(heightPercent, DUST_SPEEDS);
|
||||
double weatherMultiplier = ExplosionWindController.getWeatherMultiplier();
|
||||
return baseSpeed * (Double)Config.CLIENT.windSpeedMultiplier.get() * weatherMultiplier;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static double computeGlowSpeed(double heightPercent) {
|
||||
if (!((Boolean)Config.CLIENT.enableWindEffect.get()).booleanValue()) {
|
||||
return 0.0;
|
||||
}
|
||||
double baseSpeed = ExplosionWindController.sampleProfile(heightPercent, GLOW_SPEEDS);
|
||||
double weatherMultiplier = ExplosionWindController.getWeatherMultiplier();
|
||||
return baseSpeed * (Double)Config.CLIENT.windSpeedMultiplier.get() * weatherMultiplier;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static Vec3 getDustWindVector(double heightPercent) {
|
||||
Vec3 direction = ExplosionWindController.getWindDirection();
|
||||
if (direction == Vec3.f_82478_) {
|
||||
return direction;
|
||||
}
|
||||
return direction.m_82490_(ExplosionWindController.computeDustSpeed(heightPercent));
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
public static Vec3 getGlowWindVector(double heightPercent) {
|
||||
Vec3 direction = ExplosionWindController.getWindDirection();
|
||||
if (direction == Vec3.f_82478_) {
|
||||
return direction;
|
||||
}
|
||||
return direction.m_82490_(ExplosionWindController.computeGlowSpeed(heightPercent));
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
private static double sampleProfile(double heightPercent, double[] speeds) {
|
||||
double clamped = Math.max(0.0, Math.min(1.0, heightPercent));
|
||||
for (int i = 1; i < HEIGHT_STOPS.length; ++i) {
|
||||
double prevStop = HEIGHT_STOPS[i - 1];
|
||||
double stop = HEIGHT_STOPS[i];
|
||||
if (!(clamped <= stop)) continue;
|
||||
double t = stop <= prevStop ? 0.0 : (clamped - prevStop) / (stop - prevStop);
|
||||
double prevValue = speeds[i - 1];
|
||||
double value = speeds[i];
|
||||
return prevValue + (value - prevValue) * t;
|
||||
}
|
||||
return speeds[speeds.length - 1];
|
||||
public static double sampleProfile(double heightPercent, double[] speeds) {
|
||||
return speeds.length == 0 ? 0.0 : speeds[0];
|
||||
}
|
||||
|
||||
private static Vec3 lerp(Vec3 from, Vec3 to, double factor) {
|
||||
double clamped = Math.max(0.0, Math.min(1.0, factor));
|
||||
double x = from.f_82479_ + (to.f_82479_ - from.f_82479_) * clamped;
|
||||
double y = from.f_82480_ + (to.f_82480_ - from.f_82480_) * clamped;
|
||||
double z = from.f_82481_ + (to.f_82481_ - from.f_82481_) * clamped;
|
||||
return new Vec3(x, y, z);
|
||||
}
|
||||
|
||||
private static Vec3 randomHorizontalDirection() {
|
||||
double angle = RANDOM.nextDouble() * Math.PI * 2.0;
|
||||
double x = Math.cos(angle);
|
||||
double z = Math.sin(angle);
|
||||
return new Vec3(x, 0.0, z);
|
||||
public static double getWeatherMultiplier() {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,210 +1,15 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import com.vinlanx.explosionoverhaul.CustomGlowParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.PlasmaParticleOptions;
|
||||
import com.vinlanx.explosionoverhaul.client.ExplosionWindController;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PhysicsBasedExplosionEffect {
|
||||
private final ClientLevel level;
|
||||
private final Random random;
|
||||
private final Vec3 position;
|
||||
private final float power;
|
||||
private int age = 0;
|
||||
private final int maxAge = 8;
|
||||
private final float maxRadius;
|
||||
private final int particleCount;
|
||||
private final float particleScaleBase;
|
||||
private final int totalLifetime;
|
||||
private boolean finished = false;
|
||||
private final int totalSparks;
|
||||
private float sparkSpawnAccumulator = 0.0f;
|
||||
private final List<Vec3> sparkDirections;
|
||||
private int sparkIndex = 0;
|
||||
|
||||
public PhysicsBasedExplosionEffect(Vec3 position, float power) {
|
||||
this.position = position;
|
||||
this.power = power;
|
||||
this.random = new Random();
|
||||
this.level = Minecraft.getInstance().f_91073_;
|
||||
if (this.level == null) {
|
||||
this.finished = true;
|
||||
this.maxRadius = 0.0f;
|
||||
this.particleCount = 0;
|
||||
this.particleScaleBase = 0.0f;
|
||||
this.totalLifetime = 0;
|
||||
this.totalSparks = 0;
|
||||
this.sparkDirections = new ArrayList<Vec3>();
|
||||
return;
|
||||
}
|
||||
float calcPower = Mth.m_14036_((float)power, (float)1.0f, (float)100.0f);
|
||||
float powerFraction = calcPower / 100.0f;
|
||||
this.maxRadius = Mth.m_14179_((float)powerFraction, (float)3.0f, (float)40.0f);
|
||||
this.particleCount = (int)Mth.m_14179_((float)powerFraction, (float)40.0f, (float)400.0f);
|
||||
this.particleScaleBase = Mth.m_14179_((float)powerFraction, (float)5.0f, (float)37.5f);
|
||||
this.totalLifetime = (int)Mth.m_14179_((float)powerFraction, (float)300.0f, (float)1800.0f) + this.random.nextInt(100) - 50;
|
||||
this.totalSparks = (int)Mth.m_14179_((float)powerFraction, (float)3.0f, (float)150.0f);
|
||||
this.sparkDirections = new ArrayList<Vec3>();
|
||||
if (this.totalSparks > 0) {
|
||||
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
|
||||
double angleIncrement = Math.PI * 2 * goldenRatio;
|
||||
for (int i = 0; i < this.totalSparks; ++i) {
|
||||
double y = 1.0 - (double)i / (double)(this.totalSparks - 1) * 2.0;
|
||||
double radius = Math.sqrt(1.0 - y * y);
|
||||
double theta = angleIncrement * (double)i;
|
||||
double x = Math.cos(theta) * radius;
|
||||
double z = Math.sin(theta) * radius;
|
||||
this.sparkDirections.add(new Vec3(x, z, y).m_82541_());
|
||||
}
|
||||
Collections.shuffle(this.sparkDirections, this.random);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.finished) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableExplosionParticles.get()).booleanValue()) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
if (Config.CLIENT.particleRenderMode.get() == Config.Client.ParticleRenderMode.REALISTIC_2) {
|
||||
this.tickRealistic2();
|
||||
} else {
|
||||
this.tickRegular();
|
||||
}
|
||||
}
|
||||
|
||||
private void tickRealistic2() {
|
||||
if (this.age == 1) {
|
||||
double distance;
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress = f / 8.0f;
|
||||
float currentRadius = this.maxRadius * (float)Math.pow(progress, 0.4);
|
||||
Vec3 particlePos = this.position.m_82520_((this.random.nextDouble() - 0.5) * (double)currentRadius, (this.random.nextDouble() - 0.5) * (double)currentRadius, (this.random.nextDouble() - 0.5) * (double)currentRadius);
|
||||
Vec3 motion = new Vec3((this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05);
|
||||
double distance3D = particlePos.m_82554_(this.position);
|
||||
double heightPercent = this.maxRadius <= 0.0f ? 0.5 : Mth.m_14008_((double)(distance3D / (double)this.maxRadius), (double)0.25, (double)1.0);
|
||||
Vec3 windDirection = ExplosionWindController.getWindDirection();
|
||||
double glowSpeed = ExplosionWindController.computeGlowSpeed(heightPercent);
|
||||
if (windDirection != Vec3.f_82478_ && glowSpeed > 0.0) {
|
||||
motion = motion.m_82549_(windDirection.m_82490_(glowSpeed * 0.6));
|
||||
}
|
||||
int zone = (distance = particlePos.m_82554_(this.position)) / (double)this.maxRadius < 0.4 ? 1 : 0;
|
||||
float particleScale = this.particleScaleBase * 1.0f * ((Double)Config.CLIENT.particleSizeScale.get()).floatValue();
|
||||
int animationType = this.power <= 5.0f ? 2 : this.random.nextInt(2);
|
||||
CustomGlowParticleOptions options = new CustomGlowParticleOptions(zone, this.power, particleScale, animationType, (float)this.position.f_82480_, this.maxRadius, (float)heightPercent);
|
||||
this.level.m_7106_((ParticleOptions)options, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, motion.f_82479_, motion.f_82480_, motion.f_82481_);
|
||||
}
|
||||
if (this.totalSparks > 0 && this.sparkIndex < this.totalSparks && ((Boolean)Config.CLIENT.enablePlasmaParticles.get()).booleanValue()) {
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress2 = f / 8.0f;
|
||||
float currentRadius2 = this.maxRadius * (float)Math.pow(progress2, 0.4);
|
||||
float f2 = this.totalSparks;
|
||||
Objects.requireNonNull(this);
|
||||
float sparksToSpawnThisTick = f2 / 8.0f;
|
||||
this.sparkSpawnAccumulator += sparksToSpawnThisTick;
|
||||
int sparksToActuallySpawn = (int)this.sparkSpawnAccumulator;
|
||||
if (sparksToActuallySpawn > 0) {
|
||||
this.sparkSpawnAccumulator -= (float)sparksToActuallySpawn;
|
||||
for (int j = 0; j < sparksToActuallySpawn && this.sparkIndex < this.totalSparks; ++j) {
|
||||
Vec3 plasmaMotion = this.sparkDirections.get(this.sparkIndex);
|
||||
++this.sparkIndex;
|
||||
Vec3 plasmaSpawnPos = this.position.m_82549_(plasmaMotion.m_82490_((double)currentRadius2 * 0.8));
|
||||
float strongSparkChance = 0.1f;
|
||||
if (this.power > 10.0f) {
|
||||
float powerFractionForChance = Mth.m_184655_((float)this.power, (float)10.0f, (float)100.0f);
|
||||
strongSparkChance = Mth.m_14179_((float)powerFractionForChance, (float)0.1f, (float)0.35f);
|
||||
}
|
||||
float force = this.random.nextFloat() < strongSparkChance ? Mth.m_14179_((float)(this.power / 100.0f), (float)2.0f, (float)14.0f) * (0.9f + this.random.nextFloat() * 0.4f) : Mth.m_14179_((float)(this.power / 100.0f), (float)1.3f, (float)6.5f) * (0.6f + this.random.nextFloat() * 0.4f);
|
||||
plasmaMotion = plasmaMotion.m_82490_((double)force);
|
||||
PlasmaParticleOptions plasmaOptions = new PlasmaParticleOptions(this.power);
|
||||
this.level.m_6493_((ParticleOptions)plasmaOptions, true, plasmaSpawnPos.f_82479_, plasmaSpawnPos.f_82480_, plasmaSpawnPos.f_82481_, plasmaMotion.f_82479_, plasmaMotion.f_82480_, plasmaMotion.f_82481_);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
private void tickRegular() {
|
||||
int particlesThisTick = this.particleCount / this.maxAge;
|
||||
if (this.age == this.maxAge) {
|
||||
particlesThisTick = this.particleCount - particlesThisTick * (this.maxAge - 1);
|
||||
}
|
||||
float f = this.age;
|
||||
Objects.requireNonNull(this);
|
||||
float progress = f / 8.0f;
|
||||
float currentRadius = this.maxRadius * (float)Math.pow(progress, 0.4);
|
||||
for (int i = 0; i < particlesThisTick; ++i) {
|
||||
double distance;
|
||||
double u = this.random.nextDouble();
|
||||
double v = this.random.nextDouble();
|
||||
double theta = Math.PI * 2 * u;
|
||||
double phi = Math.acos(2.0 * v - 1.0);
|
||||
double r = currentRadius;
|
||||
Vec3 particlePos = this.position.m_82520_(r * Math.sin(phi) * Math.cos(theta), r * Math.sin(phi) * Math.sin(theta), r * Math.cos(phi));
|
||||
Vec3 motion = new Vec3((this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05, (this.random.nextDouble() - 0.5) * 0.05);
|
||||
double distance3D = particlePos.m_82554_(this.position);
|
||||
double heightPercent = this.maxRadius <= 0.0f ? 0.5 : Mth.m_14008_((double)(distance3D / (double)this.maxRadius), (double)0.25, (double)1.0);
|
||||
Vec3 windDirection = ExplosionWindController.getWindDirection();
|
||||
double glowSpeed = ExplosionWindController.computeGlowSpeed(heightPercent);
|
||||
if (windDirection != Vec3.f_82478_ && glowSpeed > 0.0) {
|
||||
motion = motion.m_82549_(windDirection.m_82490_(glowSpeed * 0.6));
|
||||
}
|
||||
int zone = (distance = particlePos.m_82554_(this.position)) / (double)this.maxRadius < 0.4 ? 1 : 0;
|
||||
float particleScale = this.particleScaleBase * (0.8f + this.random.nextFloat() * 0.4f) * ((Double)Config.CLIENT.particleSizeScale.get()).floatValue();
|
||||
int animationType = this.power <= 5.0f ? 2 : this.random.nextInt(2);
|
||||
CustomGlowParticleOptions options = new CustomGlowParticleOptions(zone, this.power, particleScale, animationType, (float)this.position.f_82480_, this.maxRadius, (float)heightPercent);
|
||||
this.level.m_7106_((ParticleOptions)options, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, motion.f_82479_, motion.f_82480_, motion.f_82481_);
|
||||
}
|
||||
if (this.totalSparks > 0 && this.sparkIndex < this.totalSparks && ((Boolean)Config.CLIENT.enablePlasmaParticles.get()).booleanValue()) {
|
||||
float f2 = this.totalSparks;
|
||||
Objects.requireNonNull(this);
|
||||
float sparksToSpawnThisTick = f2 / 8.0f;
|
||||
this.sparkSpawnAccumulator += sparksToSpawnThisTick;
|
||||
int sparksToActuallySpawn = (int)this.sparkSpawnAccumulator;
|
||||
if (sparksToActuallySpawn > 0) {
|
||||
this.sparkSpawnAccumulator -= (float)sparksToActuallySpawn;
|
||||
for (int j = 0; j < sparksToActuallySpawn && this.sparkIndex < this.totalSparks; ++j) {
|
||||
Vec3 plasmaMotion = this.sparkDirections.get(this.sparkIndex);
|
||||
++this.sparkIndex;
|
||||
Vec3 plasmaSpawnPos = this.position.m_82549_(plasmaMotion.m_82490_((double)currentRadius * 0.8));
|
||||
float strongSparkChance = 0.1f;
|
||||
if (this.power > 10.0f) {
|
||||
float powerFractionForChance = Mth.m_184655_((float)this.power, (float)10.0f, (float)100.0f);
|
||||
strongSparkChance = Mth.m_14179_((float)powerFractionForChance, (float)0.1f, (float)0.35f);
|
||||
}
|
||||
float force = this.random.nextFloat() < strongSparkChance ? Mth.m_14179_((float)(this.power / 100.0f), (float)2.0f, (float)14.0f) * (0.9f + this.random.nextFloat() * 0.4f) : Mth.m_14179_((float)(this.power / 100.0f), (float)1.3f, (float)6.5f) * (0.6f + this.random.nextFloat() * 0.4f);
|
||||
plasmaMotion = plasmaMotion.m_82490_((double)force);
|
||||
PlasmaParticleOptions plasmaOptions = new PlasmaParticleOptions(this.power);
|
||||
this.level.m_6493_((ParticleOptions)plasmaOptions, true, plasmaSpawnPos.f_82479_, plasmaSpawnPos.f_82480_, plasmaSpawnPos.f_82481_, plasmaMotion.f_82479_, plasmaMotion.f_82480_, plasmaMotion.f_82481_);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +1,15 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.vinlanx.explosionoverhaul.client;
|
||||
|
||||
import com.vinlanx.explosionoverhaul.Config;
|
||||
import java.util.Random;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ShockwaveEffect {
|
||||
private final ClientLevel level;
|
||||
private final Vec3 position;
|
||||
private final float power;
|
||||
private final Random random = new Random();
|
||||
private int age = 0;
|
||||
private final int maxAge;
|
||||
private final float maxRadius;
|
||||
private final int particlesPerTick;
|
||||
private final float shellThickness;
|
||||
private boolean finished = false;
|
||||
|
||||
public ShockwaveEffect(Vec3 position, float power) {
|
||||
this.level = Minecraft.getInstance().f_91073_;
|
||||
this.position = position;
|
||||
this.power = power;
|
||||
float powerFraction = Mth.m_184655_((float)this.power, (float)5.0f, (float)100.0f);
|
||||
this.maxAge = (int)Mth.m_14179_((float)powerFraction, (float)4.0f, (float)7.0f);
|
||||
float fireballPowerFraction = Mth.m_14036_((float)power, (float)1.0f, (float)100.0f) / 100.0f;
|
||||
float fireballRadius = Mth.m_14179_((float)fireballPowerFraction, (float)3.0f, (float)40.0f);
|
||||
float normalizedPowerSqrt = Mth.m_184655_((float)((float)Math.sqrt(power)), (float)((float)Math.sqrt(5.0)), (float)((float)Math.sqrt(100.0)));
|
||||
float shockwaveMultiplier = Mth.m_14179_((float)normalizedPowerSqrt, (float)2.0f, (float)8.0f);
|
||||
this.maxRadius = fireballRadius * shockwaveMultiplier * 3.0f;
|
||||
this.particlesPerTick = (int)Mth.m_14179_((float)powerFraction, (float)70.0f, (float)400.0f);
|
||||
this.shellThickness = Mth.m_14179_((float)powerFraction, (float)0.5f, (float)4.0f);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.finished || this.level == null) {
|
||||
return;
|
||||
}
|
||||
if (!((Boolean)Config.CLIENT.enableShockwaveEffect.get()).booleanValue()) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
++this.age;
|
||||
if (this.age > this.maxAge) {
|
||||
this.finished = true;
|
||||
return;
|
||||
}
|
||||
float progress = (float)this.age / (float)this.maxAge;
|
||||
float easedProgress = Mth.m_14031_((float)(progress * (float)Math.PI / 2.0f));
|
||||
float currentRadius = this.maxRadius * easedProgress;
|
||||
for (int i = 0; i < this.particlesPerTick; ++i) {
|
||||
double u = this.random.nextDouble();
|
||||
double v = this.random.nextDouble();
|
||||
double theta = Math.PI * 2 * u;
|
||||
double phi = Math.acos(2.0 * v - 1.0);
|
||||
float radiusOffset = (this.random.nextFloat() - 0.5f) * this.shellThickness;
|
||||
float finalRadius = currentRadius + radiusOffset;
|
||||
if (finalRadius < 0.0f) {
|
||||
finalRadius = 0.0f;
|
||||
}
|
||||
Vec3 particlePos = this.position.m_82520_((double)finalRadius * Math.sin(phi) * Math.cos(theta), (double)finalRadius * Math.sin(phi) * Math.sin(theta), (double)finalRadius * Math.cos(phi));
|
||||
this.level.m_6493_((ParticleOptions)ParticleTypes.f_123813_, true, particlePos.f_82479_, particlePos.f_82480_, particlePos.f_82481_, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ ExplosionAccessor {
|
||||
Level level = this.level;
|
||||
if (level instanceof ServerLevel) {
|
||||
ServerLevel serverLevel = (ServerLevel)level;
|
||||
ServerExplosionHandler.handleExplosion(serverLevel, (Explosion)this, this.getToBlow());
|
||||
ServerExplosionHandler.handleExplosion(serverLevel, (Explosion)(Object)this, this.getToBlow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user