package com.vinlanx.explosionoverhaul.client; import com.vinlanx.explosionoverhaul.Config; import com.vinlanx.explosionoverhaul.ModParticles; import com.vinlanx.explosionoverhaul.SmokeParticleOptions; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; public class ShockwaveEffect { private final Vec3 position; private final float power; private final int lifetime; private final float maxRadius; private int age; public ShockwaveEffect(Vec3 position, float power) { this.position = position; this.power = power; this.lifetime = Mth.clamp(18 + Math.round(power * 0.9f), 24, 72); this.maxRadius = Mth.clamp(8.0f + power * 2.9f, 10.0f, 96.0f); } public void tick() { ++this.age; ClientLevel level = Minecraft.getInstance().level; if (level == null || !((Boolean)Config.CLIENT.enableShockwaveEffect.get()).booleanValue()) { return; } float progress = this.age / (float)this.lifetime; float radius = this.maxRadius * easeOutCubic(progress); float fade = Mth.clamp(1.0f - progress, 0.0f, 1.0f); int points = Mth.clamp(Math.round(8.0f + this.power * 1.15f), 12, 44); for (int i = 0; i < points; ++i) { double angle = (Math.PI * 2.0 * i / points) + level.random.nextDouble() * 0.22; double x = this.position.x + Math.cos(angle) * radius; double z = this.position.z + Math.sin(angle) * radius; double y = this.position.y + 0.08 + level.random.nextDouble() * 0.35; double outwardSpeed = 0.18 + Math.min(0.9, this.power * 0.025); if (progress < 0.72f) { level.addParticle(ModParticles.LINE_SPARK.get(), x, y + 0.16, z, Math.cos(angle) * outwardSpeed, 0.015 + level.random.nextDouble() * 0.04, Math.sin(angle) * outwardSpeed); } if (((Boolean)Config.CLIENT.enableGroundDustEffect.get()).booleanValue()) { float scale = Mth.clamp(0.8f + this.power * 0.055f + level.random.nextFloat() * 0.8f, 0.8f, 4.2f); level.addParticle(new SmokeParticleOptions(scale, 42 + level.random.nextInt(36), 0.28f, 0.25f, 0.21f, 0.34f * fade, true, 0.0f, 0.05f, null), x, y, z, Math.cos(angle) * 0.055, 0.012, Math.sin(angle) * 0.055); } } } public boolean isFinished() { return this.age >= this.lifetime; } private static float easeOutCubic(float t) { float clamped = Mth.clamp(t, 0.0f, 1.0f); float inv = 1.0f - clamped; return 1.0f - inv * inv * inv; } }