Files
Explosion-Overhaul/com/vinlanx/explosionoverhaul/CraterDeformer.java
2026-05-04 10:03:58 +00:00

246 lines
16 KiB
Java

/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.Config;
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.item.FallingBlockEntity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class CraterDeformer {
public static Set<BlockPos> getCraterBlocks(ServerLevel level, Vec3 explosionPos, float power) {
double multiplier = (Double)Config.COMMON.craterSizeMultiplier.get();
double baseRadius = CraterDeformer.calculateRadius(power);
double finalRadius = baseRadius * multiplier;
if (finalRadius <= 0.0) {
return new HashSet<BlockPos>();
}
HashSet<BlockPos> blocksToDestroy = new HashSet<BlockPos>();
if (power >= 40.0f) {
double coreRatio = (Double)Config.COMMON.craterCoreRatio.get();
double coreRadius = finalRadius * coreRatio;
int searchRadius = (int)Math.ceil(finalRadius);
BlockPos centerPos = BlockPos.m_274446_((Position)explosionPos);
RandomSource random = level.m_213780_();
for (int x = -searchRadius; x <= searchRadius; ++x) {
for (int y = -searchRadius; y <= searchRadius; ++y) {
for (int z = -searchRadius; z <= searchRadius; ++z) {
double noise;
BlockPos currentPos = centerPos.m_7918_(x, y, z);
double distanceToCenter = Math.sqrt(currentPos.m_123331_((Vec3i)centerPos));
if (!(distanceToCenter <= coreRadius * (noise = 1.0 - random.m_188500_() * 0.3)) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (state.m_60795_() || resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
blocksToDestroy.add(currentPos);
}
}
}
int numberOfRays = (int)Math.max(200.0, Math.min(25000.0, finalRadius * 75.0));
float rayEnergy = (float)((double)(power * 4.0f) * multiplier);
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
double angleIncrement = Math.PI * 2 * goldenRatio;
double stepIncrement = 0.4;
block3: for (int i = 0; i < numberOfRays; ++i) {
double t = (double)i / (double)numberOfRays;
double inclination = Math.acos(1.0 - 2.0 * t);
double azimuth = angleIncrement * (double)i;
Vec3 rayDirection = new Vec3(Math.cos(azimuth) * Math.sin(inclination), Math.sin(azimuth) * Math.sin(inclination), Math.cos(inclination)).m_82541_();
float currentEnergy = rayEnergy * (0.75f + level.m_213780_().m_188501_() * 0.5f);
BlockPos lastPos = null;
for (double step = coreRadius * 0.8; step < finalRadius; step += 0.4) {
BlockPos currentPos = BlockPos.m_274446_((Position)explosionPos.m_82549_(rayDirection.m_82490_(step)));
if (currentPos.equals(lastPos) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
lastPos = currentPos;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
if (state.m_60795_() || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block) || !((currentEnergy -= resistance + 0.3f) > 0.0f)) continue block3;
blocksToDestroy.add(currentPos);
}
}
} else {
int numberOfRays = (int)Math.max(200.0, Math.min(75000.0, finalRadius * 150.0));
float rayEnergy = (float)((double)(power * 7.5f) * multiplier);
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
double angleIncrement = Math.PI * 2 * goldenRatio;
double stepIncrement = 0.4;
RandomSource random = level.m_213780_();
block5: for (int i = 0; i < numberOfRays; ++i) {
double t = (double)i / (double)numberOfRays;
double inclination = Math.acos(1.0 - 2.0 * t);
double azimuth = angleIncrement * (double)i;
Vec3 rayDirection = new Vec3(Math.cos(azimuth) * Math.sin(inclination), Math.sin(azimuth) * Math.sin(inclination), Math.cos(inclination)).m_82541_();
float currentEnergy = rayEnergy * (0.75f + random.m_188501_() * 0.5f);
BlockPos lastPos = null;
for (double step = 0.0; step < finalRadius; step += 0.4) {
BlockPos currentPos = BlockPos.m_274446_((Position)explosionPos.m_82549_(rayDirection.m_82490_(step)));
if (currentPos.equals(lastPos) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
lastPos = currentPos;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
if (state.m_60795_() || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block) || !((currentEnergy -= resistance + 0.3f) > 0.0f)) continue block5;
blocksToDestroy.add(currentPos);
}
}
}
return blocksToDestroy;
}
public static float calculateRadius(float power) {
float baseRadius = power <= 4.0f ? Mth.m_14179_((float)(power / 4.0f), (float)2.0f, (float)6.0f) : (power <= 50.0f ? Mth.m_14179_((float)((power - 4.0f) / 46.0f), (float)6.0f, (float)60.0f) : 60.0f + (power - 50.0f) * 1.5f);
return baseRadius * 0.5f;
}
private static float calculateMaxResistance(float power) {
float maxRes = power <= 4.0f ? 10.0f : (power <= 10.0f ? 10.0f + (power - 4.0f) * 10.0f / 6.0f : (power <= 25.0f ? 20.0f + (power - 10.0f) * 10.0f / 15.0f : (power <= 40.0f ? 30.0f + (power - 25.0f) * 10.0f / 15.0f : (power <= 70.0f ? 40.0f + (power - 40.0f) * 10.0f / 30.0f : Float.MAX_VALUE))));
return maxRes;
}
public static void apply(ServerLevel level, Vec3 explosionPos, float power) {
if (power >= 40.0f) {
CraterDeformer.applyLargeExplosionLogic(level, explosionPos, power);
} else {
CraterDeformer.applySmallExplosionLogic(level, explosionPos, power);
}
}
private static void applyLargeExplosionLogic(ServerLevel level, Vec3 explosionPos, float power) {
RandomSource random = level.m_213780_();
double multiplier = (Double)Config.COMMON.craterSizeMultiplier.get();
double baseRadius = CraterDeformer.calculateRadius(power);
double finalRadius = baseRadius * multiplier;
if (finalRadius <= 0.0) {
return;
}
HashSet<BlockPos> blocksToDestroy = new HashSet<BlockPos>();
HashSet<BlockPos> blocksToLaunch = new HashSet<BlockPos>();
double coreRatio = (Double)Config.COMMON.craterCoreRatio.get();
double coreRadius = finalRadius * coreRatio;
int searchRadius = (int)Math.ceil(finalRadius);
BlockPos centerPos = BlockPos.m_274446_((Position)explosionPos);
for (int x = -searchRadius; x <= searchRadius; ++x) {
for (int y = -searchRadius; y <= searchRadius; ++y) {
for (int z = -searchRadius; z <= searchRadius; ++z) {
double noise;
BlockPos currentPos = centerPos.m_7918_(x, y, z);
double distanceToCenter = Math.sqrt(currentPos.m_123331_((Vec3i)centerPos));
if (!(distanceToCenter <= coreRadius * (noise = 1.0 - random.m_188500_() * 0.3)) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (state.m_60795_() || resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
blocksToDestroy.add(currentPos);
if (!(distanceToCenter < coreRadius * 0.4)) continue;
blocksToLaunch.add(currentPos);
}
}
}
int numberOfRays = (int)Math.max(200.0, Math.min(25000.0, finalRadius * 75.0));
float rayEnergy = (float)((double)(power * 4.0f) * multiplier);
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
double angleIncrement = Math.PI * 2 * goldenRatio;
double stepIncrement = 0.4;
block3: for (int i = 0; i < numberOfRays; ++i) {
double t = (double)i / (double)numberOfRays;
double inclination = Math.acos(1.0 - 2.0 * t);
double azimuth = angleIncrement * (double)i;
Vec3 rayDirection = new Vec3(Math.cos(azimuth) * Math.sin(inclination), Math.sin(azimuth) * Math.sin(inclination), Math.cos(inclination)).m_82541_();
float currentEnergy = rayEnergy * (0.75f + random.m_188501_() * 0.5f);
BlockPos lastPos = null;
for (double step = coreRadius * 0.8; step < finalRadius; step += 0.4) {
BlockPos currentPos = BlockPos.m_274446_((Position)explosionPos.m_82549_(rayDirection.m_82490_(step)));
if (currentPos.equals(lastPos) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
lastPos = currentPos;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
if (state.m_60795_() || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block) || !((currentEnergy -= resistance + 0.3f) > 0.0f)) continue block3;
blocksToDestroy.add(currentPos);
}
}
CraterDeformer.finalizeExplosion(level, explosionPos, power, blocksToDestroy, blocksToLaunch);
}
private static void applySmallExplosionLogic(ServerLevel level, Vec3 explosionPos, float power) {
RandomSource random = level.m_213780_();
double multiplier = (Double)Config.COMMON.craterSizeMultiplier.get();
double baseRadius = CraterDeformer.calculateRadius(power);
double finalRadius = baseRadius * multiplier;
if (finalRadius <= 0.0) {
return;
}
int numberOfRays = (int)Math.max(200.0, Math.min(75000.0, finalRadius * 150.0));
float rayEnergy = (float)((double)(power * 7.5f) * multiplier);
HashSet<BlockPos> blocksToDestroy = new HashSet<BlockPos>();
HashSet<BlockPos> blocksToLaunch = new HashSet<BlockPos>();
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
double angleIncrement = Math.PI * 2 * goldenRatio;
double stepIncrement = 0.4;
block0: for (int i = 0; i < numberOfRays; ++i) {
double t = (double)i / (double)numberOfRays;
double inclination = Math.acos(1.0 - 2.0 * t);
double azimuth = angleIncrement * (double)i;
Vec3 rayDirection = new Vec3(Math.cos(azimuth) * Math.sin(inclination), Math.sin(azimuth) * Math.sin(inclination), Math.cos(inclination)).m_82541_();
float currentEnergy = rayEnergy * (0.75f + random.m_188501_() * 0.5f);
BlockPos lastPos = null;
for (double step = 0.0; step < finalRadius; step += 0.4) {
BlockPos currentPos = BlockPos.m_274446_((Position)explosionPos.m_82549_(rayDirection.m_82490_(step)));
if (currentPos.equals(lastPos) || !level.m_46749_(currentPos) || level.m_151570_(currentPos)) continue;
lastPos = currentPos;
BlockState state = level.m_8055_(currentPos);
Block block = state.m_60734_();
if (state.m_60795_() || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block)) continue;
float resistance = state.m_60800_((BlockGetter)level, currentPos);
if (resistance < 0.0f || resistance > CraterDeformer.calculateMaxResistance(power) || block == Blocks.f_50722_ || ExplosionOverhaul.isBlockBlacklisted(block) || !((currentEnergy -= resistance + 0.3f) > 0.0f)) continue block0;
blocksToDestroy.add(currentPos);
if (!(step < finalRadius * 0.3)) continue;
blocksToLaunch.add(currentPos);
}
}
CraterDeformer.finalizeExplosion(level, explosionPos, power, blocksToDestroy, blocksToLaunch);
}
private static void finalizeExplosion(ServerLevel level, Vec3 explosionPos, float power, Set<BlockPos> blocksToDestroy, Set<BlockPos> blocksToLaunch) {
boolean allowFallingBlocks;
RandomSource random = level.m_213780_();
level.m_8767_((ParticleOptions)ParticleTypes.f_123812_, explosionPos.f_82479_, explosionPos.f_82480_, explosionPos.f_82481_, 1, 0.0, 0.0, 0.0, 0.0);
boolean bl = allowFallingBlocks = power <= 20.0f && (Boolean)Config.COMMON.enableFallingBlocks.get() != false;
if (allowFallingBlocks) {
for (BlockPos posToLaunch : blocksToLaunch) {
if (!(random.m_188500_() < 0.35)) continue;
FallingBlockEntity falling = FallingBlockEntity.m_201971_((Level)level, (BlockPos)posToLaunch, (BlockState)level.m_8055_(posToLaunch));
falling.m_6034_((double)posToLaunch.m_123341_() + 0.5, (double)posToLaunch.m_123342_() + 0.5, (double)posToLaunch.m_123343_() + 0.5);
Vec3 motionDir = Vec3.m_82512_((Vec3i)posToLaunch).m_82546_(explosionPos).m_82541_();
double powerMul = 0.5 + random.m_188500_() * 0.8;
falling.m_20334_(motionDir.f_82479_ * powerMul + (random.m_188500_() - 0.5) * 0.4, motionDir.f_82480_ * powerMul + 0.5 + random.m_188500_() * 0.4, motionDir.f_82481_ * powerMul + (random.m_188500_() - 0.5) * 0.4);
}
}
for (BlockPos posToDestroy : blocksToDestroy) {
level.m_7731_(posToDestroy, Blocks.f_50016_.m_49966_(), 3);
}
}
}