/* * 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 sparkDirections; private int sparkIndex = 0; public PhysicsBasedExplosionEffect(Vec3 position, float power) { this.position = position; this.power = power; this.random = new Random(); this.level = Minecraft.m_91087_().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(); 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(); 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; } }