generated from MrSphay/codex-agent-repository-kit
246 lines
16 KiB
Java
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);
|
|
}
|
|
}
|
|
}
|
|
|