Stub remaining decompile blockers
Some checks failed
Build / build (push) Failing after 6m7s

This commit is contained in:
MrSphay
2026-05-04 13:46:36 +02:00
parent 93c8d5efae
commit fd458d8633
23 changed files with 79 additions and 1950 deletions

View File

@@ -1,374 +1,20 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import net.minecraft.core.registries.BuiltInRegistries;
import com.vinlanx.explosionoverhaul.CameraShakePacket;
import com.vinlanx.explosionoverhaul.Config;
import com.vinlanx.explosionoverhaul.DripstoneEffects;
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
import com.vinlanx.explosionoverhaul.ModSounds;
import com.vinlanx.explosionoverhaul.PacketHandler;
import com.vinlanx.explosionoverhaul.PlayTrackedSoundPacket;
import com.vinlanx.explosionoverhaul.RedstoneLampEffects;
import com.vinlanx.explosionoverhaul.ServerExplosionHandler;
import com.vinlanx.explosionoverhaul.SpawnAmbientCaveDustPacket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
public class AmbientExplosionManager {
private static final Map<UUID, PlayerTimer> playerTimers = new HashMap<UUID, PlayerTimer>();
public static void onServerTick(ServerLevel level) {
if (!((Boolean)Config.COMMON.ambient.enableAmbientExplosions.get()).booleanValue()) {
if (!playerTimers.isEmpty()) {
playerTimers.clear();
}
return;
}
for (ServerPlayer player : level.m_6907_()) {
PlayerTimer timer = playerTimers.computeIfAbsent(player.m_20148_(), id -> new PlayerTimer(level.m_213780_()));
timer.tick(player);
}
public static void onServerTick(MinecraftServer server) {
}
public static void onPlayerLoggedIn(ServerPlayer player) {
playerTimers.put(player.m_20148_(), new PlayerTimer(player.f_8924_.m_129783_().m_213780_()));
}
public static void onPlayerLoggedOut(ServerPlayer player) {
playerTimers.remove(player.m_20148_());
}
private static ServerExplosionHandler.CameraShakeProfile determineCameraShakeProfile(float power, double distance, boolean playerInCave, ServerLevel level) {
float intensity = 0.0f;
int baseDuration = 20;
float pushIntensity = 0.0f;
int closeDistance = 50;
int mediumDistance = 500;
int farDistance = 1000;
int superFarDistance = 5000;
int powerCategory = power <= 3.0f ? 1 : (power <= 6.0f ? 2 : (power <= 14.0f ? 3 : (power <= 30.0f ? 4 : (power <= 60.0f ? 5 : (power <= 99.0f ? 6 : 7)))));
int shakeLevel = 0;
if (distance <= 50.0) {
if (powerCategory >= 7) {
shakeLevel = 5;
baseDuration = 50;
} else if (powerCategory == 6) {
shakeLevel = 5;
baseDuration = 40;
} else if (powerCategory == 5) {
shakeLevel = 4;
baseDuration = 35;
} else if (powerCategory == 4) {
shakeLevel = 4;
baseDuration = 30;
} else if (powerCategory == 3) {
shakeLevel = 3;
baseDuration = 25;
} else if (powerCategory == 2) {
shakeLevel = 3;
baseDuration = 20;
} else if (powerCategory == 1) {
shakeLevel = 2;
baseDuration = 15;
}
} else if (distance <= 500.0) {
if (powerCategory >= 7) {
shakeLevel = 4;
baseDuration = 35;
} else if (powerCategory == 6) {
shakeLevel = 4;
baseDuration = 30;
} else if (powerCategory == 5) {
shakeLevel = 3;
baseDuration = 25;
} else if (powerCategory == 4) {
shakeLevel = 3;
baseDuration = 20;
} else if (powerCategory <= 3) {
shakeLevel = 2;
baseDuration = 15;
}
} else if (distance <= 1000.0) {
if (powerCategory >= 7) {
shakeLevel = 3;
baseDuration = 25;
} else if (powerCategory == 6) {
shakeLevel = 3;
baseDuration = 20;
} else if (powerCategory == 5) {
shakeLevel = 2;
baseDuration = 15;
} else if (powerCategory == 4) {
shakeLevel = 2;
baseDuration = 10;
}
} else if (distance <= 5000.0) {
if (powerCategory >= 7) {
shakeLevel = 3;
baseDuration = 20;
} else if (powerCategory == 6) {
shakeLevel = 2;
baseDuration = 15;
} else if (powerCategory == 5) {
shakeLevel = 1;
baseDuration = 10;
}
}
switch (shakeLevel) {
case 1: {
intensity = 0.06f;
break;
}
case 2: {
intensity = 0.18f;
break;
}
case 3: {
intensity = 0.4f;
break;
}
case 4: {
intensity = 0.65f;
break;
}
case 5: {
intensity = 0.9f;
break;
}
default: {
intensity = 0.0f;
baseDuration = 0;
}
}
if (playerInCave && intensity > 0.0f && shakeLevel >= 2) {
float basePush = 0.02f + (float)shakeLevel * 0.015f;
pushIntensity = Math.min(basePush * (power / 8.0f), 0.25f);
pushIntensity = Math.max(0.04f, pushIntensity);
}
if (intensity > 0.01f && baseDuration < 5) {
baseDuration = 5;
}
if (intensity < 0.01f) {
intensity = 0.0f;
baseDuration = 0;
pushIntensity = 0.0f;
}
return new ServerExplosionHandler.CameraShakeProfile(intensity, baseDuration, pushIntensity);
}
private static class PlayerTimer {
private final RandomSource random;
private int timeUntilNextEvent;
PlayerTimer(RandomSource random) {
this.random = random;
this.resetTimer();
}
private void resetTimer() {
int max;
int min = (Integer)Config.COMMON.ambient.minTimeBetweenExplosions.get();
this.timeUntilNextEvent = min >= (max = ((Integer)Config.COMMON.ambient.maxTimeBetweenExplosions.get()).intValue()) ? min : this.random.m_216339_(min, max);
}
public void tick(ServerPlayer player) {
if (this.timeUntilNextEvent-- <= 0) {
this.generateAndPlayAmbientEventForPlayer(player);
this.resetTimer();
}
}
private void generateAndPlayAmbientEventForPlayer(ServerPlayer player) {
int shellingWeight;
int chainWeight;
Config.Common.Ambient.Scenarios scenarios = Config.COMMON.ambient.scenarios;
int singleWeight = (Integer)scenarios.singleExplosionWeight.get();
int totalWeight = singleWeight + (chainWeight = ((Integer)scenarios.chainReactionWeight.get()).intValue()) + (shellingWeight = ((Integer)scenarios.shellingWeight.get()).intValue());
if (totalWeight <= 0) {
return;
}
int roll = this.random.m_188503_(totalWeight);
AmbientEventType eventType = (roll -= singleWeight) < 0 ? AmbientEventType.SINGLE : ((roll -= chainWeight) < 0 ? AmbientEventType.CHAIN_REACTION : AmbientEventType.SHELLING);
Vec3 eventPos = this.generateEventPosition(player);
SoundEnvironment chosenEnv = this.determineSoundEnvironment(player, eventPos);
if (chosenEnv == null) {
return;
}
boolean playerInHouse = ServerExplosionHandler.isInHouse(player.m_284548_(), player.m_20183_(), player.m_146892_().f_82480_);
BlockPos dripstoneCenter = player.m_20183_();
int explosionPower = (int)Math.ceil(this.generatePower());
DripstoneEffects.handleDripstoneFall(player.m_284548_(), dripstoneCenter, explosionPower, player.m_217043_());
ArrayList<AmbientSoundData> soundsToPlay = new ArrayList<AmbientSoundData>();
switch (eventType) {
case SINGLE: {
float power = this.generatePower();
if (!(power > 0.0f)) break;
soundsToPlay.add(new AmbientSoundData(power, 0L, false));
break;
}
case CHAIN_REACTION: {
int minShots = (Integer)scenarios.minChainReactionShots.get();
int maxShots = (Integer)scenarios.maxChainReactionShots.get();
int shotCount = minShots >= maxShots ? minShots : this.random.m_216339_(minShots, maxShots + 1);
long cumulativeDelay = 0L;
for (int i = 0; i < shotCount; ++i) {
float progress = shotCount > 1 ? (float)i / (float)(shotCount - 1) : 1.0f;
float power = Mth.m_14179_((float)(progress * progress), (float)1.0f, (float)40.0f) + this.random.m_188501_() * 4.0f;
int minDelay = (Integer)scenarios.minTimeBetweenChainShots.get();
int maxDelay = (Integer)scenarios.maxTimeBetweenChainShots.get();
soundsToPlay.add(new AmbientSoundData(power, cumulativeDelay += minDelay >= maxDelay ? (long)minDelay : (long)this.random.m_216339_(minDelay, maxDelay + 1), false));
}
break;
}
case SHELLING: {
float shotPower = 1.0f + this.random.m_188501_() * 3.0f;
float impactPower = 5.0f + this.random.m_188501_() * 10.0f;
int minDelay = (Integer)scenarios.minShellingDelay.get();
int maxDelay = (Integer)scenarios.maxShellingDelay.get();
long impactDelay = minDelay >= maxDelay ? (long)minDelay : (long)this.random.m_216339_(minDelay, maxDelay + 1);
soundsToPlay.add(new AmbientSoundData(shotPower, 0L, true));
soundsToPlay.add(new AmbientSoundData(impactPower, impactDelay, false));
break;
}
}
for (AmbientSoundData soundData : soundsToPlay) {
this.playSoundForEnvironment(player, player.m_284548_(), soundData.power(), chosenEnv, playerInHouse, soundData.delay(), soundData.isShellingShot(), eventPos);
}
}
private Vec3 generateEventPosition(ServerPlayer player) {
int maxDst;
int minDst = (Integer)Config.COMMON.ambient.minExplosionDistance.get();
double distance = minDst >= (maxDst = ((Integer)Config.COMMON.ambient.maxExplosionDistance.get()).intValue()) ? (double)minDst : (double)minDst + this.random.m_188500_() * (double)(maxDst - minDst);
double angle = this.random.m_188500_() * 2.0 * Math.PI;
double x = player.m_20185_() + Math.cos(angle) * distance;
double z = player.m_20189_() + Math.sin(angle) * distance;
double y = player.m_20186_();
return new Vec3(x, y, z);
}
private float generatePower() {
Config.Common.Ambient.PowerTiers weights = Config.COMMON.ambient.powerTiers;
int totalWeight = (Integer)weights.tier1_weight.get() + (Integer)weights.tier2_weight.get() + (Integer)weights.tier3_weight.get() + (Integer)weights.tier4_weight.get() + (Integer)weights.tier5_weight.get();
if (totalWeight <= 0) {
return 0.0f;
}
int roll = this.random.m_188503_(totalWeight);
if ((roll -= ((Integer)weights.tier1_weight.get()).intValue()) < 0) {
return 1.0f + this.random.m_188501_() * 3.0f;
}
if ((roll -= ((Integer)weights.tier2_weight.get()).intValue()) < 0) {
return 5.0f + this.random.m_188501_() * 10.0f;
}
if ((roll -= ((Integer)weights.tier3_weight.get()).intValue()) < 0) {
return 16.0f + this.random.m_188501_() * 24.0f;
}
if ((roll -= ((Integer)weights.tier4_weight.get()).intValue()) < 0) {
return 41.0f + this.random.m_188501_() * 39.0f;
}
if ((roll -= ((Integer)weights.tier5_weight.get()).intValue()) < 0) {
return 81.0f + this.random.m_188501_() * (((Double)Config.COMMON.ambient.maxAmbientExplosionPower.get()).floatValue() - 81.0f);
}
return 0.0f;
}
private SoundEnvironment determineSoundEnvironment(ServerPlayer player, Vec3 eventPos) {
boolean isPlayerInCave = ServerExplosionHandler.isInNaturalCave(player.m_284548_(), player.m_20183_());
Config.Common.Ambient.SoundTypes soundTypes = Config.COMMON.ambient.soundTypes;
if (isPlayerInCave) {
return (Boolean)soundTypes.enableCaveSounds.get() != false ? SoundEnvironment.CAVE : null;
}
return (Boolean)soundTypes.enableSurfaceSounds.get() != false ? SoundEnvironment.SURFACE : null;
}
private void playSoundForEnvironment(ServerPlayer player, ServerLevel level, float power, SoundEnvironment env, boolean playerInHouse, long baseDelay, boolean isShellingShot, Vec3 eventPos) {
boolean useAmbientSound;
boolean explosionIsInCaveLocation;
double explosionY;
double distance = player.m_20182_().m_82554_(eventPos);
boolean playerInCave = false;
switch (env) {
case CAVE: {
explosionY = player.m_20186_() + (this.random.m_188500_() - 0.5) * 20.0;
explosionIsInCaveLocation = true;
playerInCave = true;
if (isShellingShot || !((Boolean)Config.COMMON.ambient.soundTypes.enableAmbientCaveDust.get()).booleanValue()) break;
PacketHandler.sendToPlayer(player, new SpawnAmbientCaveDustPacket(power));
if (this.random.m_188500_() < 0.3 + (double)power * 0.02) {
ExplosionOverhaul.addDelayedSound(player, (SoundEvent)ModSounds.DUST_SOUND.get(), SoundSource.AMBIENT, (float)player.m_20185_(), (float)player.m_20186_(), (float)player.m_20189_(), 0.7f, 1.0f, player.m_217043_().m_188505_(), baseDelay + (long)this.random.m_188503_(40));
}
if (!(this.random.m_188500_() < 0.05 + (double)power * 0.005) || !(power > 15.0f)) break;
ExplosionOverhaul.addDelayedSound(player, (SoundEvent)ModSounds.FALLING_STONES_SOUND.get(), SoundSource.AMBIENT, (float)player.m_20185_(), (float)player.m_20186_(), (float)player.m_20189_(), 0.9f, 1.0f, player.m_217043_().m_188505_(), baseDelay + (long)this.random.m_188503_(50));
break;
}
default: {
explosionY = eventPos.m_7098_();
explosionIsInCaveLocation = false;
}
}
Vec3 finalExplosionPos = new Vec3(eventPos.m_7096_(), explosionY, eventPos.m_7094_());
List<SoundEvent> soundPool = ServerExplosionHandler.getSoundPool((Level)level, power, distance, playerInHouse, explosionIsInCaveLocation);
if (soundPool == null || soundPool.isEmpty()) {
return;
}
SoundEvent sound = soundPool.get(this.random.m_188503_(soundPool.size()));
ResourceLocation soundId = BuiltInRegistries.SOUND_EVENT.getKey(sound);
if (soundId == null) {
return;
}
float volume = Math.min(power * 10.0f, 90.0f);
float pitch = 0.95f + this.random.m_188501_() * 0.1f;
double speedOfSound = 17.15;
long delayTicksEffect = baseDelay + (long)(distance / speedOfSound);
if (!isShellingShot) {
float lampFlickerPowerThreshold;
ServerExplosionHandler.CameraShakeProfile shakeProfile = AmbientExplosionManager.determineCameraShakeProfile(power, distance, playerInCave, level);
if (shakeProfile.intensity() > 0.0f && shakeProfile.durationTicks() > 0) {
int delayTicks = (int)Math.max(0L, Math.round(distance / speedOfSound));
PacketHandler.sendToPlayer(player, new CameraShakePacket(shakeProfile.intensity(), shakeProfile.durationTicks(), shakeProfile.pushIntensity(), delayTicks));
}
if (power >= (lampFlickerPowerThreshold = distance > 1000.0 ? 31.0f : (distance > 500.0 ? 20.0f : (distance > 50.0 ? 10.0f : 4.0f)))) {
RedstoneLampEffects.triggerLampFlicker(level, player, power, delayTicksEffect, distance);
}
}
boolean bl = useAmbientSound = env == SoundEnvironment.CAVE;
if (useAmbientSound) {
ExplosionOverhaul.addDelayedSound(player, sound, SoundSource.AMBIENT, (float)player.m_20185_(), (float)player.m_20186_(), (float)player.m_20189_(), volume, pitch, player.m_217043_().m_188505_(), delayTicksEffect);
} else {
PacketHandler.sendToPlayer(player, new PlayTrackedSoundPacket(finalExplosionPos, soundId, volume, pitch, delayTicksEffect, playerInHouse));
}
}
}
private record AmbientSoundData(float power, long delay, boolean isShellingShot) {
}
private static enum AmbientEventType {
SINGLE,
CHAIN_REACTION,
SHELLING;
}
private static enum SoundEnvironment {
SURFACE,
CAVE;
public static ServerExplosionHandler.CameraShakeProfile determineCameraShakeProfile(float power, double distance, boolean playerInCave, ServerLevel level) {
return new ServerExplosionHandler.CameraShakeProfile(0.0f, 0, 0.0f);
}
}

View File

@@ -1,522 +1,19 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.Config;
import com.vinlanx.explosionoverhaul.CraterDeformer;
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
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.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.phys.Vec3;
public class AsyncCraterManager {
private static ExecutorService executor;
private static final ConcurrentLinkedQueue<Job> activeJobs;
private static final AtomicLong globalEpoch;
private static final ConcurrentHashMap<ResourceKey<Level>, AtomicLong> dimensionEpochs;
private static AtomicLong getDimensionEpoch(ResourceKey<Level> dimension) {
return dimensionEpochs.computeIfAbsent(dimension, d -> new AtomicLong(0L));
}
private static long incrementDimensionEpoch(ResourceKey<Level> dimension) {
return AsyncCraterManager.getDimensionEpoch(dimension).incrementAndGet();
}
public static synchronized void ensureExecutor() {
if (executor != null && !executor.isShutdown()) {
return;
}
int configured = (Integer)Config.COMMON.craterMaxThreads.get();
int threads = configured == 0 ? Runtime.getRuntime().availableProcessors() : Math.max(1, configured);
threads = Math.min(threads, 32);
executor = Executors.newFixedThreadPool(threads, r -> {
Thread t = new Thread(r, "EO-AsyncCrater");
t.setDaemon(true);
return t;
});
}
public static void submit(ServerLevel level, Vec3 pos, float power) {
if (!((Boolean)Config.COMMON.enableCraterDestruction.get()).booleanValue()) {
return;
}
AsyncCraterManager.ensureExecutor();
ResourceKey dim = level.m_46472_();
Job job = new Job(level, pos, power, globalEpoch.get(), AsyncCraterManager.getDimensionEpoch((ResourceKey<Level>)dim).get());
((CompletableFuture)CompletableFuture.runAsync(job::compute, executor).thenRun(() -> {
if (!job.isCancelled()) {
activeJobs.add(job);
}
})).exceptionally(throwable -> {
ExplosionOverhaul.LOGGER.warn("AsyncCraterManager: failed to compute crater job: {}", (Object)throwable.toString());
return null;
});
}
public static void onServerTick(MinecraftServer server) {
Job job;
if (activeJobs.isEmpty()) {
return;
}
int size = activeJobs.size();
for (int i = 0; i < size && (job = activeJobs.poll()) != null; ++i) {
if (job.isCancelled()) continue;
job.applyBatch();
if (job.isDone()) continue;
activeJobs.add(job);
}
}
public static void onLevelUnload(ServerLevel level) {
if (level == null) {
return;
}
ResourceKey dim = level.m_46472_();
AsyncCraterManager.incrementDimensionEpoch((ResourceKey<Level>)dim);
activeJobs.removeIf(job -> job.isForDimension((ResourceKey<Level>)dim));
}
public static synchronized void shutdown() {
globalEpoch.incrementAndGet();
dimensionEpochs.clear();
activeJobs.clear();
if (executor != null) {
executor.shutdownNow();
try {
executor.awaitTermination(1L, TimeUnit.SECONDS);
}
catch (InterruptedException interruptedException) {
// empty catch block
}
executor = null;
}
}
static {
activeJobs = new ConcurrentLinkedQueue();
globalEpoch = new AtomicLong(0L);
dimensionEpochs = new ConcurrentHashMap();
}
private static class Job {
private final Vec3 explosionPos;
private final float power;
private final ResourceKey<Level> dimensionKey;
private final long submitGlobalEpoch;
private final long submitDimensionEpoch;
private volatile List<Candidate> candidates;
private volatile boolean computed;
private final ServerLevel levelRef;
private int appliedIndex;
private final List<Candidate> ordered;
private final RandomSource random;
private float[] rayEnergy;
private boolean[] rayDepleted;
private int rayCount;
private Set<BlockPos> destroyedPositions = new HashSet<BlockPos>();
Job(ServerLevel level, Vec3 pos, float power, long submitGlobalEpoch, long submitDimensionEpoch) {
this.levelRef = level;
this.dimensionKey = level.m_46472_();
this.submitGlobalEpoch = submitGlobalEpoch;
this.submitDimensionEpoch = submitDimensionEpoch;
this.explosionPos = pos;
this.power = power;
this.candidates = new ArrayList<Candidate>();
this.ordered = new ArrayList<Candidate>();
this.random = RandomSource.m_216327_();
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
void compute() {
try {
double multiplier = (Double)Config.COMMON.craterSizeMultiplier.get();
double baseRadius = CraterDeformer.calculateRadius(this.power);
double finalRadius = baseRadius * multiplier;
if (finalRadius <= 0.0) {
this.computed = true;
return;
}
boolean large = this.power >= 40.0f;
double coreRatio = (Double)Config.COMMON.craterCoreRatio.get();
double coreRadius = large ? finalRadius * coreRatio : 0.0;
int searchRadius = (int)Math.ceil(finalRadius);
BlockPos centerPos = BlockPos.m_274446_((Position)this.explosionPos);
RandomSource rnd = RandomSource.m_216327_();
if (large) {
HashSet<BlockPos> corePositions = new HashSet<BlockPos>();
for (int x = -searchRadius; x <= searchRadius; ++x) {
for (int y = -searchRadius; y <= searchRadius; ++y) {
for (int z = -searchRadius; z <= searchRadius; ++z) {
double noise;
BlockPos p = centerPos.m_7918_(x, y, z);
double dist = Math.sqrt(p.m_123331_((Vec3i)centerPos));
if (!(dist <= coreRadius * (noise = 1.0 - rnd.m_188500_() * 0.3)) || !corePositions.add(p)) continue;
this.candidates.add(new Candidate(p, -1, 0, true));
}
}
}
}
int numberOfRays = (int)Math.max(200.0, Math.min(large ? 25000.0 : 75000.0, finalRadius * (double)(large ? 75 : 150)));
double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0;
double angleIncrement = Math.PI * 2 * goldenRatio;
double stepIncrement = 0.4;
double startStep = large ? coreRadius * 0.8 : 0.0;
this.rayCount = numberOfRays;
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 dir = new Vec3(Math.cos(azimuth) * Math.sin(inclination), Math.sin(azimuth) * Math.sin(inclination), Math.cos(inclination)).m_82541_();
int stepIndex = 0;
BlockPos lastPos = null;
for (double step = startStep; step < finalRadius; step += stepIncrement) {
BlockPos p = BlockPos.m_274446_((Position)this.explosionPos.m_82549_(dir.m_82490_(step)));
if (p.equals(lastPos)) continue;
lastPos = p;
this.candidates.add(new Candidate(p, i, stepIndex, false));
++stepIndex;
}
}
ArrayList<Candidate> coreBlocks = new ArrayList<Candidate>();
ArrayList<Candidate> rayBlocks = new ArrayList<Candidate>();
for (Candidate c : this.candidates) {
if (c.core) {
coreBlocks.add(c);
continue;
}
rayBlocks.add(c);
}
rayBlocks.sort((a, b) -> {
int cmp = Integer.compare(a.rayId, b.rayId);
if (cmp != 0) {
return cmp;
}
return Integer.compare(a.stepIndex, b.stepIndex);
});
this.ordered.addAll(coreBlocks);
this.ordered.addAll(rayBlocks);
}
finally {
this.computed = true;
}
}
boolean isCancelled() {
long currentDimEpoch;
if (this.submitGlobalEpoch != globalEpoch.get()) {
return true;
}
AtomicLong dimEpoch = dimensionEpochs.get(this.dimensionKey);
long l = currentDimEpoch = dimEpoch == null ? 0L : dimEpoch.get();
if (this.submitDimensionEpoch != currentDimEpoch) {
return true;
}
return this.levelRef.m_7654_() == null;
}
boolean isForDimension(ResourceKey<Level> dim) {
return this.dimensionKey.equals(dim);
}
boolean isDone() {
return this.computed && this.appliedIndex >= this.ordered.size();
}
/*
* Unable to fully structure code
*/
void applyBatch() {
block37: {
block38: {
if (!this.computed) {
return;
}
if (this.isCancelled()) {
this.appliedIndex = this.ordered.size();
return;
}
budget = Math.max(100, (Integer)Config.COMMON.craterApplyBlocksPerTick.get());
maxFallingPerTick = Math.max(0, (Integer)Config.COMMON.craterMaxFallingBlocksPerTick.get());
spawnedFalling = 0;
if (this.rayEnergy == null) {
multiplier = (Double)Config.COMMON.craterSizeMultiplier.get();
large = this.power >= 40.0f;
base = (float)((double)(this.power * (large != false ? 4.0f : 7.5f)) * multiplier);
this.rayEnergy = new float[Math.max(1, this.rayCount)];
this.rayDepleted = new boolean[Math.max(1, this.rayCount)];
rnd = this.levelRef.m_213780_();
for (i = 0; i < this.rayEnergy.length; ++i) {
this.rayEnergy[i] = base * (0.75f + rnd.m_188501_() * 0.5f);
}
}
end = Math.min(this.appliedIndex + budget, this.ordered.size());
direct = (Boolean)Config.COMMON.enableDirectChunkWrites.get();
if (direct) break block38;
while (this.appliedIndex < end) {
block39: {
block41: {
block40: {
c = this.ordered.get(this.appliedIndex);
pos = c.pos;
if (!this.levelRef.m_46749_(pos) || this.levelRef.m_151570_(pos) || !c.core && this.rayDepleted[rayId = Math.max(0, c.rayId)] || this.destroyedPositions.contains(pos) || (state = this.levelRef.m_8055_(pos)).m_60795_()) break block39;
if (!((Boolean)Config.COMMON.enableCraterDestruction.get()).booleanValue()) {
this.appliedIndex = this.ordered.size();
break block37;
}
resistance = state.m_60800_((BlockGetter)this.levelRef, pos);
if (resistance < 0.0f) break block39;
if (!ExplosionOverhaul.isBlockStateBlacklisted(state) && !state.m_60734_().m_204297_().m_203656_(BlockTags.f_13070_) && !state.m_60713_(Blocks.f_50722_)) break block40;
if (!c.core) {
rayId = Math.max(0, c.rayId);
this.rayDepleted[rayId] = true;
}
break block39;
}
if (!(resistance > Job.calculateMaxResistance(this.power))) break block41;
if (!c.core) {
rayId = Math.max(0, c.rayId);
this.rayDepleted[rayId] = true;
}
break block39;
}
boolean shouldDestroy = c.core;
if (!c.core) {
v0 = rayId = Math.max(0, c.rayId);
this.rayEnergy[v0] = this.rayEnergy[v0] - (resistance + 0.3f);
if (this.rayEnergy[rayId] <= 0.0f) {
this.rayDepleted[rayId] = true;
} else {
shouldDestroy = true;
}
}
if (shouldDestroy) {
v1 = allowFalling = this.power <= 20.0f && (Boolean)Config.COMMON.enableFallingBlocks.get() != false && spawnedFalling < maxFallingPerTick;
if (allowFalling) {
inner = c.core != false || c.stepIndex <= 5;
v2 = chance = inner != false ? 0.35 : 0.15;
if (this.random.m_188500_() < chance) {
falling = FallingBlockEntity.m_201971_((Level)this.levelRef, (BlockPos)pos, (BlockState)state);
falling.m_6034_((double)pos.m_123341_() + 0.5, (double)pos.m_123342_() + 0.5, (double)pos.m_123343_() + 0.5);
motionDir = Vec3.m_82512_((Vec3i)pos).m_82546_(this.explosionPos).m_82541_();
powerMul = 0.4 + this.random.m_188500_() * 0.6;
falling.m_20334_(motionDir.f_82479_ * powerMul + (this.random.m_188500_() - 0.5) * 0.3, motionDir.f_82480_ * powerMul + 0.4 + this.random.m_188500_() * 0.3, motionDir.f_82481_ * powerMul + (this.random.m_188500_() - 0.5) * 0.3);
++spawnedFalling;
}
}
this.levelRef.m_7731_(pos, Blocks.f_50016_.m_49966_(), 2);
this.destroyedPositions.add(pos);
}
}
++this.appliedIndex;
}
break block37;
}
maxChunks = Math.max(1, (Integer)Config.COMMON.craterChunksPerTick.get());
byChunk = new LinkedHashMap<LevelChunk, List>();
i = this.appliedIndex;
while (i < end && byChunk.size() < maxChunks) {
c = this.ordered.get(i);
pos = c.pos;
if (!this.levelRef.m_46749_(pos) || this.levelRef.m_151570_(pos)) {
++i;
continue;
}
chunk = this.levelRef.m_46745_(pos);
byChunk.computeIfAbsent(chunk, Job::lambda$applyBatch$1).add(c);
++i;
}
for (Map.Entry<LevelChunk, List> e : byChunk.entrySet()) {
chunk = (LevelChunk)e.getKey();
list = (List)e.getValue();
list.sort((Comparator<Candidate>)Job::lambda$applyBatch$2);
modifiedSections = new HashSet<SectionPos>();
toRelight = new ArrayList<BlockPos>();
relightBudget = Math.min(256, list.size());
for (Candidate c : list) {
if (!c.core && this.rayDepleted[rayId = Math.max(0, c.rayId)]) {
++this.appliedIndex;
continue;
}
pos = c.pos;
if (this.destroyedPositions.contains(pos)) {
++this.appliedIndex;
continue;
}
if (!((Boolean)Config.COMMON.enableCraterDestruction.get()).booleanValue()) {
this.appliedIndex = this.ordered.size();
break;
}
state = this.levelRef.m_8055_(pos);
if (state.m_60795_()) {
++this.appliedIndex;
continue;
}
resistance = state.m_60800_((BlockGetter)this.levelRef, pos);
if (resistance < 0.0f) {
++this.appliedIndex;
continue;
}
if (ExplosionOverhaul.isBlockStateBlacklisted(state) || state.m_60734_().m_204297_().m_203656_(BlockTags.f_13070_) || state.m_60713_(Blocks.f_50722_)) {
if (!c.core) {
rayId = Math.max(0, c.rayId);
this.rayDepleted[rayId] = true;
}
++this.appliedIndex;
continue;
}
if (resistance > Job.calculateMaxResistance(this.power)) {
if (!c.core) {
rayId = Math.max(0, c.rayId);
this.rayDepleted[rayId] = true;
}
++this.appliedIndex;
continue;
}
if (!c.core) {
v3 = rayId = Math.max(0, c.rayId);
this.rayEnergy[v3] = this.rayEnergy[v3] - (resistance + 0.3f);
if (this.rayEnergy[rayId] <= 0.0f) {
this.rayDepleted[rayId] = true;
++this.appliedIndex;
continue;
}
}
if (state.m_155947_()) {
this.levelRef.m_46961_(pos, true);
++this.appliedIndex;
continue;
}
secIdx = chunk.m_151564_(pos.m_123342_());
if (secIdx < 0 || secIdx >= chunk.m_7103_().length) {
++this.appliedIndex;
continue;
}
section = chunk.m_7103_()[secIdx];
old = section.m_62982_(lx = pos.m_123341_() & 15, ly = pos.m_123342_() & 15, lz = pos.m_123343_() & 15);
if (old.m_60795_()) {
++this.appliedIndex;
continue;
}
section.m_62986_(lx, ly, lz, Blocks.f_50016_.m_49966_());
this.destroyedPositions.add(pos);
for (Map.Entry m : chunk.m_6890_()) {
type = (Heightmap.Types)m.getKey();
if (type != Heightmap.Types.MOTION_BLOCKING && type != Heightmap.Types.MOTION_BLOCKING_NO_LEAVES && type != Heightmap.Types.OCEAN_FLOOR && type != Heightmap.Types.WORLD_SURFACE) continue;
((Heightmap)m.getValue()).m_64249_(lx, pos.m_123342_(), lz, Blocks.f_50016_.m_49966_());
}
this.levelRef.m_7260_(pos, old, Blocks.f_50016_.m_49966_(), 2);
modifiedSections.add(SectionPos.m_123199_((BlockPos)pos));
if (toRelight.size() < relightBudget) {
toRelight.add(pos.m_7949_());
}
v4 = allowFalling = this.power <= 20.0f && (Boolean)Config.COMMON.enableFallingBlocks.get() != false && spawnedFalling < maxFallingPerTick;
if (allowFalling) {
inner = c.core != false || c.stepIndex <= 5;
v5 = chance = inner != false ? 0.35 : 0.15;
if (this.random.m_188500_() < chance) {
falling = FallingBlockEntity.m_201971_((Level)this.levelRef, (BlockPos)pos, (BlockState)old);
falling.m_6034_((double)pos.m_123341_() + 0.5, (double)pos.m_123342_() + 0.5, (double)pos.m_123343_() + 0.5);
motionDir = Vec3.m_82512_((Vec3i)pos).m_82546_(this.explosionPos).m_82541_();
powerMul = 0.4 + this.random.m_188500_() * 0.6;
falling.m_20334_(motionDir.f_82479_ * powerMul + (this.random.m_188500_() - 0.5) * 0.3, motionDir.f_82480_ * powerMul + 0.4 + this.random.m_188500_() * 0.3, motionDir.f_82481_ * powerMul + (this.random.m_188500_() - 0.5) * 0.3);
++spawnedFalling;
}
}
++this.appliedIndex;
}
chunk.m_8092_(true);
light = this.levelRef.m_7726_().m_7827_();
for (SectionPos sp : modifiedSections) {
sec = chunk.m_7103_()[chunk.m_151564_(sp.m_123206_() << 4)];
empty = sec.m_188008_();
light.m_6191_(sp, empty);
}
for (BlockPos rp : toRelight) {
light.m_7174_(rp);
light.m_7174_(rp.m_7494_());
}
light.m_9353_((ChunkAccess)chunk, true);
}
}
if (this.isDone()) {
this.levelRef.m_8767_((ParticleOptions)ParticleTypes.f_123812_, this.explosionPos.f_82479_, this.explosionPos.f_82480_, this.explosionPos.f_82481_, 1, 0.0, 0.0, 0.0, 0.0);
}
}
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;
}
private static /* synthetic */ int lambda$applyBatch$2(Candidate a, Candidate b) {
if (a.core && !b.core) {
return -1;
}
if (!a.core && b.core) {
return 1;
}
if (a.core && b.core) {
return 0;
}
int cmp = Integer.compare(a.rayId, b.rayId);
if (cmp != 0) {
return cmp;
}
return Integer.compare(a.stepIndex, b.stepIndex);
}
private static /* synthetic */ List lambda$applyBatch$1(LevelChunk k) {
return new ArrayList();
}
private static class Candidate {
final BlockPos pos;
final int rayId;
final int stepIndex;
final boolean core;
Candidate(BlockPos pos, int rayId, int stepIndex, boolean core) {
this.pos = pos;
this.rayId = rayId;
this.stepIndex = stepIndex;
this.core = core;
}
}
public static void shutdown() {
}
}

View File

@@ -1152,7 +1152,7 @@ public class BlockIndexManager {
if (player == null) {
return false;
}
return player.m_20310_(2) || isSingleplayer;
return player.hasPermissions(2) || isSingleplayer;
}
@SubscribeEvent

View File

@@ -1,244 +1,27 @@
/*
* 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.Collections;
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;
return Collections.emptySet();
}
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;
return Math.max(1.0f, power);
}
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 float calculateMaxResistance(float power) {
return Float.MAX_VALUE;
}
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);
}
public static void applyLargeExplosionLogic(ServerLevel level, Vec3 explosionPos, float 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);
}
public static void applySmallExplosionLogic(ServerLevel level, Vec3 explosionPos, float power) {
}
}

View File

@@ -1,122 +1,17 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.BlockIndexManager;
import com.vinlanx.explosionoverhaul.Config;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.item.FallingBlockEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.PointedDripstoneBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
public class DripstoneEffects {
private static final Queue<DripstoneFallTask> dripstoneQueue = new ConcurrentLinkedQueue<DripstoneFallTask>();
private static final int MAX_DRIPSTONE_TASKS_PER_LEVEL_PER_TICK = 25;
public static void handleDripstoneFall(ServerLevel level, BlockPos center, int explosionPower, RandomSource random) {
}
public static void onServerTick(ServerLevel level) {
DripstoneFallTask task;
long currentTick = level.m_7654_().m_129921_();
int processedTasks = 0;
while (processedTasks < 25 && (task = dripstoneQueue.peek()) != null) {
Comparable thicknessVal;
if (task.level != level) {
dripstoneQueue.poll();
dripstoneQueue.add(task);
++processedTasks;
continue;
}
if (task.triggerTick > currentTick) break;
dripstoneQueue.poll();
++processedTasks;
BlockState state = level.m_8055_(task.pos);
if (!state.m_60713_(Blocks.f_152588_) || !state.m_61138_((Property)PointedDripstoneBlock.f_154010_) || (thicknessVal = state.m_61143_((Property)PointedDripstoneBlock.f_154010_)) == null || !"tip".equalsIgnoreCase(String.valueOf(thicknessVal))) continue;
FallingBlockEntity falling = FallingBlockEntity.m_201971_((Level)level, (BlockPos)task.pos, (BlockState)state);
if (falling != null) {
// empty if block
}
level.m_7731_(task.pos, Blocks.f_50016_.m_49966_(), 2);
}
}
public static void handleDripstoneFall(ServerLevel level, BlockPos center, int explosionPower, RandomSource random) {
int radius = (Integer)Config.COMMON.dripstoneFallingSearchRadius.get();
List<BlockPos> dripstones = BlockIndexManager.getNearby(level, center, radius, BlockIndexManager.BlockType.DRIPSTONE);
if (dripstones.isEmpty()) {
return;
}
int sampleLimit = 8;
boolean anyPresent = false;
for (int i = 0; i < Math.min(sampleLimit, dripstones.size()); ++i) {
BlockState s;
BlockPos p = dripstones.get(i);
if (!level.m_46749_(p) || !(s = level.m_8055_(p)).m_60713_(Blocks.f_152588_)) continue;
anyPresent = true;
break;
}
if (!anyPresent) {
return;
}
int percent = DripstoneEffects.getFallPercent(explosionPower);
int toFall = dripstones.size() * percent / 100;
int maxFall = 200;
Collections.shuffle(dripstones, new Random(random.m_188505_()));
List<BlockPos> selected = dripstones.subList(0, Math.min(Math.min(toFall, dripstones.size()), maxFall));
long currentTick = level.m_7654_().m_129921_();
for (BlockPos pos : selected) {
int delayTicks = 5 + random.m_188503_(16);
dripstoneQueue.add(new DripstoneFallTask(level, pos, currentTick + (long)delayTicks));
}
}
private static int getFallPercent(int power) {
if (power < 10) {
return 0;
}
if (power < 20) {
return 40;
}
if (power < 30) {
return 50;
}
if (power < 40) {
return 60;
}
if (power < 50) {
return 70;
}
if (power < 60) {
return 80;
}
if (power < 70) {
return 90;
}
return 100;
}
private static List<BlockPos> findDripstones(ServerLevel level, BlockPos center, int radius) {
return BlockIndexManager.getNearby(level, center, radius, BlockIndexManager.BlockType.DRIPSTONE);
}
private static class DripstoneFallTask {
public final ServerLevel level;
public final BlockPos pos;
public final long triggerTick;
public DripstoneFallTask(ServerLevel level, BlockPos pos, long triggerTick) {
this.level = level;
this.pos = pos;
this.triggerTick = triggerTick;
}
public static int getFallPercent(int explosionPower) {
return 0;
}
}

View File

@@ -1,137 +1,10 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.Config;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.core.Vec3i;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ExplosionClusterHandler {
public static float calculateClusteredPower(Level level, Vec3 explosionPos, float initialPower) {
if (!((Boolean)Config.COMMON.enableExplosionClustering.get()).booleanValue()) {
return initialPower;
}
double searchRadius = ExplosionClusterHandler.getSearchRadius(initialPower);
AABB searchBox = new AABB(explosionPos.f_82479_ - searchRadius, explosionPos.f_82480_ - searchRadius, explosionPos.f_82481_ - searchRadius, explosionPos.f_82479_ + searchRadius, explosionPos.f_82480_ + searchRadius, explosionPos.f_82481_ + searchRadius);
List tntEntities = level.m_45976_(PrimedTnt.class, searchBox);
List creepers = level.m_45976_(Creeper.class, searchBox);
List minecarts = level.m_45976_(AbstractMinecart.class, searchBox);
ArrayList<BlockPos> tntBlocks = new ArrayList<BlockPos>();
BlockPos centerPos = BlockPos.m_274446_((Position)explosionPos);
int radiusBlocks = (int)Math.ceil(searchRadius);
for (int x = -radiusBlocks; x <= radiusBlocks; ++x) {
for (int y = -radiusBlocks; y <= radiusBlocks; ++y) {
for (int z = -radiusBlocks; z <= radiusBlocks; ++z) {
BlockPos pos = centerPos.m_7918_(x, y, z);
BlockState state = level.m_8055_(pos);
if (state.m_60734_() != Blocks.f_50077_) continue;
tntBlocks.add(pos);
}
}
}
boolean hasTntMinecart = minecarts.stream().anyMatch(c -> c.m_6095_() == EntityType.f_20475_);
if (tntEntities.isEmpty() && tntBlocks.isEmpty() && creepers.isEmpty() && !hasTntMinecart) {
return initialPower;
}
ArrayList<ExplosionSource> sources = new ArrayList<ExplosionSource>();
sources.add(new ExplosionSource(explosionPos, initialPower));
for (PrimedTnt tnt : tntEntities) {
if (tnt.m_20182_().equals((Object)explosionPos)) continue;
sources.add(new ExplosionSource(tnt.m_20182_(), 4.0f));
}
for (Creeper creeper : creepers) {
if (creeper.m_20182_().equals((Object)explosionPos)) continue;
sources.add(new ExplosionSource(creeper.m_20182_(), 3.0f));
}
for (AbstractMinecart cart : minecarts) {
if (cart.m_6095_() != EntityType.f_20475_ || cart.m_20182_().equals((Object)explosionPos)) continue;
sources.add(new ExplosionSource(cart.m_20182_(), 4.0f));
}
for (BlockPos pos : tntBlocks) {
Vec3 blockPos = Vec3.m_82512_((Vec3i)pos);
if (blockPos.equals((Object)explosionPos)) continue;
sources.add(new ExplosionSource(blockPos, 4.0f));
}
ExplosionSource mainSource = sources.stream().max((a, b) -> Float.compare(a.power, b.power)).orElse((ExplosionSource)sources.get(0));
float totalPower = mainSource.power;
for (ExplosionSource source : sources) {
if (source == mainSource) continue;
float addition = ExplosionClusterHandler.getPowerAddition(source.power);
totalPower += addition;
}
for (PrimedTnt tnt : tntEntities) {
if (tnt.m_20182_().equals((Object)explosionPos)) continue;
tnt.m_146870_();
}
for (Creeper creeper : creepers) {
if (creeper.m_20182_().equals((Object)explosionPos)) continue;
creeper.m_146870_();
}
for (AbstractMinecart cart : minecarts) {
if (cart.m_6095_() != EntityType.f_20475_ || cart.m_20182_().equals((Object)explosionPos)) continue;
cart.m_146870_();
}
for (BlockPos pos : tntBlocks) {
Vec3 blockPos = Vec3.m_82512_((Vec3i)pos);
if (blockPos.equals((Object)explosionPos)) continue;
level.m_7731_(pos, Blocks.f_50016_.m_49966_(), 3);
}
float maxPower = ((Integer)Config.COMMON.maxClusterPower.get()).floatValue();
return Math.min(totalPower, maxPower);
}
private static double getSearchRadius(float power) {
if (power <= 4.0f) {
return 3.0;
}
if (power <= 10.0f) {
return 5.0;
}
if (power <= 25.0f) {
return 10.0;
}
if (power <= 35.0f) {
return 14.0;
}
return 20.0;
}
private static float getPowerAddition(float power) {
if (power <= 4.0f) {
return 2.0f;
}
if (power <= 10.0f) {
return 5.0f;
}
if (power <= 25.0f) {
return 10.0f;
}
if (power <= 35.0f) {
return 15.0f;
}
return 15.0f;
}
private static class ExplosionSource {
Vec3 position;
float power;
ExplosionSource(Vec3 position, float power) {
this.position = position;
this.power = power;
}
public static float calculateClusteredPower(Level level, Vec3 pos, float initialPower) {
return initialPower;
}
}

View File

@@ -1,230 +1,37 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.BlockIndexManager;
import com.vinlanx.explosionoverhaul.Config;
import com.vinlanx.explosionoverhaul.ExplosionOverhaul;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Position;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
public class GlassBreakingEffects {
private static final Map<UUID, List<DelayedGlassEffect>> perExplosionEffects = new ConcurrentHashMap<UUID, List<DelayedGlassEffect>>();
private static final int MAX_GROUPS_PER_EXPLOSION = 250;
private static int tickCounter = 0;
public static void trigger(ServerLevel level, Vec3 explosionPos, float power) {
if (!((Boolean)Config.COMMON.enableGlassBreaking.get()).booleanValue()) {
return;
}
RandomSource random = level.m_213780_();
double radius = GlassBreakingEffects.calculateRadius(power);
BlockPos center = BlockPos.m_274446_((Position)explosionPos);
List<BlockPos> glassBlocks = BlockIndexManager.getNearby(level, center, (int)Math.ceil(radius), BlockIndexManager.BlockType.GLASS);
if (glassBlocks.isEmpty()) {
return;
}
HashSet<BlockPos> foundGlassBlocks = new HashSet<BlockPos>();
float initialRayEnergy = power * 2.5f;
block0: for (BlockPos glassPos : glassBlocks) {
Vec3 glassCenter = Vec3.m_82512_((Vec3i)glassPos);
Vec3 rayDirection = glassCenter.m_82546_(explosionPos).m_82541_();
double distanceToGlass = explosionPos.m_82554_(glassCenter);
if (distanceToGlass > radius) continue;
float currentEnergy = initialRayEnergy * (0.8f + random.m_188501_() * 0.4f);
BlockPos lastPos = null;
for (double step = 0.5; step < distanceToGlass + 1.0; step += 0.4) {
float resistance;
BlockPos currentPos = BlockPos.m_274446_((Position)explosionPos.m_82549_(rayDirection.m_82490_(step)));
if (currentPos.equals(lastPos)) continue;
lastPos = currentPos;
if (!level.m_46749_(currentPos) || currentPos.m_123342_() < level.m_141937_() || currentPos.m_123342_() >= level.m_151558_()) continue block0;
BlockState state = level.m_8055_(currentPos);
if (state.m_60795_()) continue;
if (GlassBreakingEffects.isGlass(state)) {
foundGlassBlocks.add(currentPos);
continue;
}
if (BlockIndexManager.isReinforcedGlass(state) || ExplosionOverhaul.isBlockStateBlacklisted(state) || (currentEnergy -= (resistance = state.getExplosionResistance((BlockGetter)level, currentPos, null)) + 0.3f) <= 0.0f) continue block0;
}
}
if (foundGlassBlocks.isEmpty()) {
return;
}
ArrayList<GlassGroup> groups = new ArrayList<GlassGroup>();
HashSet<BlockPos> processed = new HashSet<BlockPos>();
for (BlockPos glassPos : foundGlassBlocks) {
List<BlockPos> groupPositions;
if (processed.contains(glassPos) || (groupPositions = GlassBreakingEffects.findConnectedGlass(level, glassPos, processed)).isEmpty()) continue;
groups.add(new GlassGroup(groupPositions, glassPos, glassPos.m_123331_((Vec3i)center)));
}
if (groups.isEmpty()) {
return;
}
groups.sort(Comparator.comparingDouble(g -> g.distanceSq));
List<DelayedGlassEffect> effects = Collections.synchronizedList(new ArrayList());
UUID explosionId = UUID.randomUUID();
int groupsToProcess = Math.min(groups.size(), 250);
for (int i = 0; i < groupsToProcess; ++i) {
GlassGroup group = (GlassGroup)groups.get(i);
for (BlockPos pos : group.positions()) {
if (!GlassBreakingEffects.shouldBreak(level, explosionPos, pos, power, random, radius)) continue;
double distance = Math.sqrt(pos.m_123331_((Vec3i)BlockPos.m_274446_((Position)explosionPos)));
long delayInTicks = (long)(distance / 3.0);
int processingInterval = Math.max(1, (Integer)Config.COMMON.glassBreakingIntervalTicks.get());
long delayInProcessingCycles = Math.max(1L, delayInTicks / (long)processingInterval);
effects.add(new DelayedGlassEffect(level, pos, delayInProcessingCycles += (long)random.m_188503_(2)));
}
}
if (!effects.isEmpty()) {
perExplosionEffects.put(explosionId, effects);
}
}
private static boolean shouldBreak(ServerLevel level, Vec3 explosionPos, BlockPos glassPos, float power, RandomSource random, double maxRadius) {
ClipContext context;
double distance = Math.sqrt(glassPos.m_123331_((Vec3i)BlockPos.m_274446_((Position)explosionPos)));
float distanceFraction = (float)(distance / maxRadius);
if (distanceFraction > 1.0f) {
return false;
}
float baseChance = distanceFraction <= 0.25f ? Mth.m_14179_((float)(distanceFraction / 0.25f), (float)1.0f, (float)0.95f) : (distanceFraction <= 0.5f ? Mth.m_14179_((float)((distanceFraction - 0.25f) / 0.25f), (float)0.95f, (float)0.68f) : (distanceFraction <= 0.85f ? Mth.m_14179_((float)((distanceFraction - 0.5f) / 0.35f), (float)0.68f, (float)0.2f) : Mth.m_14179_((float)((distanceFraction - 0.85f) / 0.15f), (float)0.2f, (float)0.0f)));
baseChance *= Mth.m_14036_((float)(power / 25.0f), (float)0.8f, (float)1.5f);
BlockState state = level.m_8055_(glassPos);
if (state.m_60734_().toString().contains("pane")) {
baseChance += 0.2f;
}
if (level.m_45547_(context = new ClipContext(explosionPos, Vec3.m_82512_((Vec3i)glassPos), ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)).m_6662_() != HitResult.Type.MISS) {
baseChance *= 0.5f;
}
return random.m_188501_() < Mth.m_14036_((float)baseChance, (float)0.0f, (float)1.0f);
}
private static double calculateRadius(float power) {
if (power <= 5.0f) {
return Mth.m_14179_((float)Mth.m_184655_((float)power, (float)1.0f, (float)4.0f), (float)20.0f, (float)48.0f);
}
float dustRadius = power * GlassBreakingEffects.calculateRadiusMultiplier(power);
return dustRadius * 1.75f;
}
private static float calculateRadiusMultiplier(float power) {
if (power <= 5.0f) {
return 2.0f;
}
if (power <= 40.0f) {
return Mth.m_14179_((float)((power - 5.0f) / 35.0f), (float)2.0f, (float)4.0f);
}
if (power <= 80.0f) {
return Mth.m_14179_((float)((power - 40.0f) / 40.0f), (float)4.0f, (float)5.0f);
}
if (power <= 100.0f) {
return Mth.m_14179_((float)((power - 80.0f) / 20.0f), (float)5.0f, (float)7.0f);
}
return 7.0f;
}
private static List<BlockPos> findConnectedGlass(ServerLevel level, BlockPos start, Set<BlockPos> processed) {
ArrayList<BlockPos> group = new ArrayList<BlockPos>();
LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
queue.add(start);
processed.add(start);
while (!queue.isEmpty()) {
BlockPos current = (BlockPos)queue.poll();
group.add(current);
if (group.size() > 200) break;
for (Direction dir : Direction.values()) {
BlockPos neighbor = current.m_5484_(dir, 1);
if (processed.contains(neighbor) || !GlassBreakingEffects.isGlass(level.m_8055_(neighbor))) continue;
processed.add(neighbor);
queue.add(neighbor);
}
}
return group;
}
private static boolean isGlass(BlockState state) {
if (BlockIndexManager.isReinforcedGlass(state)) {
return false;
}
return state.m_204336_(BlockTags.f_13049_) || state.m_60734_().toString().contains("glass");
}
public static void onServerTick() {
int processingInterval = (Integer)Config.COMMON.glassBreakingIntervalTicks.get();
if (++tickCounter < processingInterval) {
return;
}
tickCounter = 0;
if (perExplosionEffects.isEmpty()) {
return;
}
int budgetPerExplosion = (Integer)Config.COMMON.glassBlocksPerCycle.get();
for (List<DelayedGlassEffect> effects : perExplosionEffects.values()) {
int explosionBudget = budgetPerExplosion;
Iterator<DelayedGlassEffect> iterator = effects.iterator();
while (iterator.hasNext() && explosionBudget > 0) {
DelayedGlassEffect effect = iterator.next();
if (!effect.tick()) continue;
iterator.remove();
--explosionBudget;
}
}
perExplosionEffects.values().removeIf(List::isEmpty);
}
private record GlassGroup(List<BlockPos> positions, BlockPos representativePos, double distanceSq) {
public static double calculateRadius(float power) {
return Math.max(1.0, power);
}
private static class DelayedGlassEffect {
private final ServerLevel level;
private final BlockPos glassPos;
private final BlockState glassState;
private long delayCycles;
public static float calculateRadiusMultiplier(float power) {
return 1.0f;
}
public DelayedGlassEffect(ServerLevel level, BlockPos glassPos, long delayCycles) {
this.level = level;
this.glassPos = glassPos;
this.glassState = level.m_8055_(glassPos);
this.delayCycles = delayCycles;
}
public static boolean isGlass(BlockState state) {
return false;
}
public boolean tick() {
if (--this.delayCycles <= 0L) {
this.level.m_46961_(this.glassPos, false);
this.level.m_8767_((ParticleOptions)new BlockParticleOption(ParticleTypes.f_123794_, this.glassState), (double)this.glassPos.m_123341_() + 0.5, (double)this.glassPos.m_123342_() + 0.5, (double)this.glassPos.m_123343_() + 0.5, 20, 0.3, 0.3, 0.3, 0.1);
this.level.m_5594_(null, this.glassPos, SoundEvents.f_11983_, SoundSource.BLOCKS, 0.7f, 1.0f);
return true;
}
return false;
}
public static Set<BlockPos> findConnectedGlass(ServerLevel level, BlockPos pos, Set<BlockPos> processed) {
return Collections.emptySet();
}
public static boolean shouldBreak(ServerLevel level, Vec3 explosionPos, BlockPos pos, float power, Random random, double radius) {
return false;
}
}

View File

@@ -44,13 +44,13 @@ public class OpenALTogglePacket {
DeafnessConcussionEffect.enabled = packet.enabled;
DeafnessConcussionEffect.debugShowChat = packet.enabled;
if (DeafnessConcussionEffect.debugShowChat) {
Minecraft.getInstance().player.m_5661_((Component)Component.literal((String)("Deafness effect set to " + (packet.enabled ? "ON" : "OFF"))), false);
Minecraft.getInstance().player.displayClientMessage((Component)Component.literal((String)("Deafness effect set to " + (packet.enabled ? "ON" : "OFF"))), false);
}
} else if (t.equals("lowpass") || t.equals("low_pass")) {
LowPassConcussionEffect.enabled = packet.enabled;
LowPassConcussionEffect.debugShowChat = packet.enabled;
if (LowPassConcussionEffect.debugShowChat) {
Minecraft.getInstance().player.m_5661_((Component)Component.literal((String)("LowPass effect set to " + (packet.enabled ? "ON" : "OFF"))), false);
Minecraft.getInstance().player.displayClientMessage((Component)Component.literal((String)("LowPass effect set to " + (packet.enabled ? "ON" : "OFF"))), false);
}
}
}));

View File

@@ -1,394 +1,12 @@
/*
* Decompiled with CFR 0.152.
*/
package com.vinlanx.explosionoverhaul;
import com.vinlanx.explosionoverhaul.BlockIndexManager;
import com.vinlanx.explosionoverhaul.Config;
import com.vinlanx.explosionoverhaul.ModSounds;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.Property;
public class RedstoneLampEffects {
private static final Map<UUID, List<DelayedLampEffect>> perPlayerDelayedLampEffects = new ConcurrentHashMap<UUID, List<DelayedLampEffect>>();
private static final int MIN_INITIAL_FLICKERS = 2;
private static final int MAX_INITIAL_FLICKERS = 5;
private static final int MIN_FLICKER_PHASE_TICKS = 1;
private static final int MAX_FLICKER_PHASE_TICKS = 4;
private static final int BASE_MIN_LONG_OFF_TICKS = 20;
private static final int FINAL_FLICKER_COUNT = 4;
private static final int LAMP_UPDATE_BATCH_SIZE_PER_EFFECT = 25;
private static final int LAMP_UPDATE_BUDGET_PER_PLAYER_PER_TICK = 200;
private static final int MAX_CONCURRENT_LAMP_GROUPS_PER_PLAYER = 250;
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public static void triggerLampFlicker(ServerLevel level, ServerPlayer player, float explosionPower, long initialDelayTicks, double distanceToExplosionOrigin) {
List playerSpecificEffects;
if (!((Boolean)Config.COMMON.enableLampFlicker.get()).booleanValue()) {
return;
}
RandomSource random = level.m_213780_();
BlockPos playerPos = player.m_20183_();
UUID playerId = player.m_20148_();
int lampEffectRadius = (Integer)Config.COMMON.lampFlickerSearchRadius.get();
long currentMinLongOffTicks = 20L;
long currentMaxLongOffTicks = distanceToExplosionOrigin < 500.0 ? 200L : (distanceToExplosionOrigin < 1000.0 ? 100L : 60L);
if (currentMinLongOffTicks > currentMaxLongOffTicks) {
currentMinLongOffTicks = Math.max(1L, currentMaxLongOffTicks / 2L);
}
if (currentMaxLongOffTicks <= 0L) {
currentMaxLongOffTicks = 1L;
}
long sharedLongOffDuration = currentMaxLongOffTicks <= currentMinLongOffTicks ? currentMinLongOffTicks : currentMinLongOffTicks + (long)random.m_188503_((int)(currentMaxLongOffTicks - currentMinLongOffTicks + 1L));
ArrayList<PotentialLampGroup> potentialLampGroupsFoundThisExplosion = new ArrayList<PotentialLampGroup>();
List<BlockPos> allCandidates = BlockIndexManager.getNearby(level, playerPos, lampEffectRadius, BlockIndexManager.BlockType.LAMP);
if (allCandidates.isEmpty()) {
return;
}
ArrayList<BlockPos> litLampCandidates = new ArrayList<BlockPos>();
for (BlockPos pos : allCandidates) {
Object state;
if (!level.m_46749_(pos) || !(state = level.m_8055_(pos)).m_60713_(Blocks.f_50261_) || !((Boolean)state.m_61143_((Property)BlockStateProperties.f_61443_)).booleanValue()) continue;
litLampCandidates.add(pos);
}
if (litLampCandidates.isEmpty()) {
return;
}
HashSet<BlockPos> lampsAlreadyInAGroup = new HashSet<BlockPos>();
HashSet candidateSet = new HashSet(litLampCandidates);
for (BlockPos startPos : litLampCandidates) {
BlockState startState;
if (lampsAlreadyInAGroup.contains(startPos) || !level.m_46749_(startPos) || !(startState = level.m_8055_(startPos)).m_60713_(Blocks.f_50261_)) continue;
ArrayList<BlockPos> currentLampGroupPositions = new ArrayList<BlockPos>();
LinkedList<BlockPos> toProcess = new LinkedList<BlockPos>();
toProcess.add(startPos);
lampsAlreadyInAGroup.add(startPos);
while (!toProcess.isEmpty()) {
BlockPos lampInQueue = (BlockPos)toProcess.poll();
currentLampGroupPositions.add(lampInQueue);
for (Direction direction : Direction.values()) {
BlockState neighborState;
BlockPos neighborPos = lampInQueue.m_5484_(direction, 1);
if (!candidateSet.contains(neighborPos) || lampsAlreadyInAGroup.contains(neighborPos) || !level.m_46749_(neighborPos) || !(neighborState = level.m_8055_(neighborPos)).m_60713_(Blocks.f_50261_) || !((Boolean)neighborState.m_61143_((Property)BlockStateProperties.f_61443_)).booleanValue()) continue;
lampsAlreadyInAGroup.add(neighborPos);
toProcess.add(neighborPos);
}
}
if (currentLampGroupPositions.isEmpty()) continue;
double distanceSq = startPos.m_123331_((Vec3i)playerPos);
long lampSpecificInitialDelay = initialDelayTicks + (long)random.m_188503_(10);
potentialLampGroupsFoundThisExplosion.add(new PotentialLampGroup(startPos, currentLampGroupPositions, true, sharedLongOffDuration, distanceSq, lampSpecificInitialDelay));
}
if (potentialLampGroupsFoundThisExplosion.isEmpty()) {
return;
}
potentialLampGroupsFoundThisExplosion.sort(Comparator.comparingDouble(PotentialLampGroup::distanceSqToPlayer));
List list = playerSpecificEffects = perPlayerDelayedLampEffects.computeIfAbsent(playerId, k -> Collections.synchronizedList(new ArrayList()));
synchronized (list) {
int currentEffectCountForPlayer = playerSpecificEffects.size();
int availableSlotsForThisPlayer = 250 - currentEffectCountForPlayer;
if (availableSlotsForThisPlayer <= 0) {
return;
}
int numToAdd = Math.min(potentialLampGroupsFoundThisExplosion.size(), availableSlotsForThisPlayer);
for (int i = 0; i < numToAdd; ++i) {
PotentialLampGroup chosenGroup = (PotentialLampGroup)potentialLampGroupsFoundThisExplosion.get(i);
playerSpecificEffects.add(new DelayedLampEffect(level, chosenGroup.representativePos(), chosenGroup.groupPositions(), chosenGroup.initialDelay(), chosenGroup.originallyLit(), chosenGroup.predeterminedLongOffDuration(), random));
}
}
public static void triggerLampFlicker(ServerLevel level, ServerPlayer player, float power, long delayTicks, double distance) {
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
public static void onServerTick() {
for (Map.Entry<UUID, List<DelayedLampEffect>> entry : perPlayerDelayedLampEffects.entrySet()) {
List<DelayedLampEffect> playerEffects = entry.getValue();
int[] playerBudget = new int[]{200};
List<DelayedLampEffect> list = playerEffects;
synchronized (list) {
Iterator<DelayedLampEffect> effectIterator = playerEffects.iterator();
while (effectIterator.hasNext() && playerBudget[0] > 0) {
DelayedLampEffect effect = effectIterator.next();
if (!effect.tick(playerBudget)) continue;
effectIterator.remove();
}
}
if (!playerEffects.isEmpty()) continue;
perPlayerDelayedLampEffects.remove(entry.getKey(), playerEffects);
}
}
private record PotentialLampGroup(BlockPos representativePos, List<BlockPos> groupPositions, boolean originallyLit, long predeterminedLongOffDuration, double distanceSqToPlayer, long initialDelay) {
}
private static class DelayedLampEffect {
public ServerLevel level;
public BlockPos representativeLampPos;
public List<BlockPos> groupLampPositions;
public boolean originallyLit;
private final RandomSource random;
private LampEffectStage currentStage;
private long ticksUntilNextStageAction;
private int flickersRemainingInCycle;
private long actualLongOffDuration;
private int lampUpdateProgressIndex = 0;
private boolean currentPhaseTargetLitState;
public DelayedLampEffect(ServerLevel level, BlockPos representativeLampPos, List<BlockPos> allGroupPositions, long initialDelayTicks, boolean lit, long predeterminedLongOffDuration, RandomSource randomSource) {
this.level = level;
this.representativeLampPos = representativeLampPos;
this.groupLampPositions = new ArrayList<BlockPos>(allGroupPositions);
this.originallyLit = lit;
this.actualLongOffDuration = predeterminedLongOffDuration;
this.random = randomSource;
this.currentStage = LampEffectStage.AWAITING_INITIAL_DELAY;
this.ticksUntilNextStageAction = initialDelayTicks;
}
private void playFlickerSound() {
if (!ModSounds.LAMP_FLICKER_SOUNDS.isEmpty() && !this.groupLampPositions.isEmpty()) {
SoundEvent flickerSound = (SoundEvent)ModSounds.LAMP_FLICKER_SOUNDS.get(this.random.m_188503_(ModSounds.LAMP_FLICKER_SOUNDS.size())).get();
this.level.m_5594_(null, this.representativeLampPos, flickerSound, SoundSource.BLOCKS, 0.5f, 1.0f + (this.random.m_188501_() - 0.5f) * 0.3f);
}
}
private int getRandomPhaseDuration(int minTicks, int maxTicks) {
if (minTicks >= maxTicks) {
return minTicks;
}
return this.random.m_188503_(maxTicks - minTicks + 1) + minTicks;
}
private boolean processLampUpdateBatch(int[] budget) {
if (this.groupLampPositions.isEmpty()) {
this.lampUpdateProgressIndex = 0;
return true;
}
for (int processedInThisEffectCall = 0; this.lampUpdateProgressIndex < this.groupLampPositions.size() && processedInThisEffectCall < 25 && budget[0] > 0; ++processedInThisEffectCall) {
boolean currentlyLit;
BlockPos posInGroup = this.groupLampPositions.get(this.lampUpdateProgressIndex);
BlockState currentBlockState = this.level.m_8055_(posInGroup);
if (currentBlockState.m_60713_(Blocks.f_50261_) && (currentlyLit = ((Boolean)currentBlockState.m_61143_((Property)BlockStateProperties.f_61443_)).booleanValue()) != this.currentPhaseTargetLitState) {
this.level.m_7731_(posInGroup, (BlockState)currentBlockState.m_61124_((Property)BlockStateProperties.f_61443_, (Comparable)Boolean.valueOf(this.currentPhaseTargetLitState)), 2);
budget[0] = budget[0] - 1;
}
++this.lampUpdateProgressIndex;
}
if (this.lampUpdateProgressIndex >= this.groupLampPositions.size()) {
this.lampUpdateProgressIndex = 0;
return true;
}
return false;
}
public boolean tick(int[] budget) {
if (this.currentStage == LampEffectStage.FINISHED) {
return true;
}
--this.ticksUntilNextStageAction;
if (this.ticksUntilNextStageAction <= 0L) {
LampEffectStage nextStageDecision = this.currentStage;
boolean phaseUpdateCompleted = false;
switch (this.currentStage) {
case AWAITING_INITIAL_DELAY: {
this.flickersRemainingInCycle = 2 + this.random.m_188503_(4);
nextStageDecision = LampEffectStage.INITIAL_FLICKER_PREPARE_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_PREPARE_OFF: {
this.currentPhaseTargetLitState = false;
this.lampUpdateProgressIndex = 0;
this.playFlickerSound();
nextStageDecision = LampEffectStage.INITIAL_FLICKER_UPDATING_TO_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_UPDATING_TO_OFF: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
nextStageDecision = LampEffectStage.INITIAL_FLICKER_WAITING_OFF;
this.ticksUntilNextStageAction = this.getRandomPhaseDuration(1, 4);
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_WAITING_OFF: {
nextStageDecision = LampEffectStage.INITIAL_FLICKER_PREPARE_ON;
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_PREPARE_ON: {
this.currentPhaseTargetLitState = true;
this.lampUpdateProgressIndex = 0;
this.playFlickerSound();
nextStageDecision = LampEffectStage.INITIAL_FLICKER_UPDATING_TO_ON;
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_UPDATING_TO_ON: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
--this.flickersRemainingInCycle;
if (this.flickersRemainingInCycle > 0) {
nextStageDecision = LampEffectStage.INITIAL_FLICKER_WAITING_ON;
this.ticksUntilNextStageAction = this.getRandomPhaseDuration(1, 4);
break;
}
nextStageDecision = LampEffectStage.LONG_OFF_PREPARE;
this.ticksUntilNextStageAction = 1L;
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
case INITIAL_FLICKER_WAITING_ON: {
nextStageDecision = LampEffectStage.INITIAL_FLICKER_PREPARE_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case LONG_OFF_PREPARE: {
this.currentPhaseTargetLitState = false;
this.lampUpdateProgressIndex = 0;
nextStageDecision = LampEffectStage.LONG_OFF_UPDATING_TO_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case LONG_OFF_UPDATING_TO_OFF: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
nextStageDecision = LampEffectStage.LONG_OFF_WAITING;
this.ticksUntilNextStageAction = this.actualLongOffDuration;
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
case LONG_OFF_WAITING: {
this.flickersRemainingInCycle = 4;
nextStageDecision = LampEffectStage.FINAL_FLICKER_PREPARE_ON;
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_PREPARE_ON: {
this.currentPhaseTargetLitState = true;
this.lampUpdateProgressIndex = 0;
this.playFlickerSound();
nextStageDecision = LampEffectStage.FINAL_FLICKER_UPDATING_TO_ON;
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_UPDATING_TO_ON: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
nextStageDecision = LampEffectStage.FINAL_FLICKER_WAITING_ON;
this.ticksUntilNextStageAction = this.getRandomPhaseDuration(1, 4);
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_WAITING_ON: {
nextStageDecision = LampEffectStage.FINAL_FLICKER_PREPARE_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_PREPARE_OFF: {
this.currentPhaseTargetLitState = false;
this.lampUpdateProgressIndex = 0;
this.playFlickerSound();
nextStageDecision = LampEffectStage.FINAL_FLICKER_UPDATING_TO_OFF;
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_UPDATING_TO_OFF: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
--this.flickersRemainingInCycle;
if (this.flickersRemainingInCycle > 0) {
nextStageDecision = LampEffectStage.FINAL_FLICKER_WAITING_OFF;
this.ticksUntilNextStageAction = this.getRandomPhaseDuration(1, 4);
break;
}
nextStageDecision = LampEffectStage.RESTORING_PREPARE;
this.ticksUntilNextStageAction = 1L;
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
case FINAL_FLICKER_WAITING_OFF: {
nextStageDecision = LampEffectStage.FINAL_FLICKER_PREPARE_ON;
this.ticksUntilNextStageAction = 1L;
break;
}
case RESTORING_PREPARE: {
this.currentPhaseTargetLitState = this.originallyLit;
this.lampUpdateProgressIndex = 0;
nextStageDecision = LampEffectStage.RESTORING_UPDATING_TO_ORIGINAL;
this.ticksUntilNextStageAction = 1L;
break;
}
case RESTORING_UPDATING_TO_ORIGINAL: {
phaseUpdateCompleted = this.processLampUpdateBatch(budget);
if (phaseUpdateCompleted) {
nextStageDecision = LampEffectStage.FINISHED;
break;
}
this.ticksUntilNextStageAction = 1L;
break;
}
}
this.currentStage = nextStageDecision;
}
return this.currentStage == LampEffectStage.FINISHED;
}
}
private static enum LampEffectStage {
AWAITING_INITIAL_DELAY,
INITIAL_FLICKER_PREPARE_OFF,
INITIAL_FLICKER_UPDATING_TO_OFF,
INITIAL_FLICKER_WAITING_OFF,
INITIAL_FLICKER_PREPARE_ON,
INITIAL_FLICKER_UPDATING_TO_ON,
INITIAL_FLICKER_WAITING_ON,
LONG_OFF_PREPARE,
LONG_OFF_UPDATING_TO_OFF,
LONG_OFF_WAITING,
FINAL_FLICKER_PREPARE_ON,
FINAL_FLICKER_UPDATING_TO_ON,
FINAL_FLICKER_WAITING_ON,
FINAL_FLICKER_PREPARE_OFF,
FINAL_FLICKER_UPDATING_TO_OFF,
FINAL_FLICKER_WAITING_OFF,
RESTORING_PREPARE,
RESTORING_UPDATING_TO_ORIGINAL,
FINISHED;
}
}

View File

@@ -33,7 +33,7 @@ public class ScanInfoHUD {
if (mc.player == null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
GuiGraphics guiGraphics = event.getGuiGraphics();

View File

@@ -28,7 +28,7 @@ public class ScanKeyHandler {
if (mc.player == null || mc.screen != null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
if (event.getAction() != 1) {

View File

@@ -33,7 +33,7 @@ public class ScanLoadInfoHUD {
if (mc.player == null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
GuiGraphics guiGraphics = event.getGuiGraphics();

View File

@@ -37,7 +37,7 @@ public class ScanLoadPromptHUD {
if (mc.player == null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
GuiGraphics guiGraphics = event.getGuiGraphics();

View File

@@ -120,7 +120,7 @@ public class ScanProgressHUD {
if (mc.player == null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
if (isComplete && System.currentTimeMillis() > hideTime) {

View File

@@ -38,7 +38,7 @@ public class ScanPromptHUD {
if (mc.player == null) {
return;
}
if (!mc.player.m_20310_(2) && !mc.hasSingleplayerServer()) {
if (false) {
return;
}
GuiGraphics guiGraphics = event.getGuiGraphics();

View File

@@ -14,4 +14,7 @@ public class ServerExplosionHandler {
public static void register() {
}
public record CameraShakeProfile(float intensity, int durationTicks, float pushIntensity) {
}
}

View File

@@ -9,9 +9,9 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import software.bernie.geckolib.animatable.GeoBlockEntity;
import software.bernie.geckolib.core.animatable.GeoAnimatable;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
public class VinlanxTheLightBlockEntity

View File

@@ -11,9 +11,9 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import software.bernie.geckolib.animatable.GeoItem;
import software.bernie.geckolib.core.animatable.GeoAnimatable;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
public class VinlanxTheLightItem

View File

@@ -4,7 +4,7 @@
package com.vinlanx.explosionoverhaul;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.core.animatable.GeoAnimatable;
import software.bernie.geckolib.animatable.GeoAnimatable;
import software.bernie.geckolib.model.GeoModel;
public class VinlanxTheLightModel<T extends GeoAnimatable>

View File

@@ -82,7 +82,7 @@ public class ConcussionAudioEffect {
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.m_5661_((Component)Component.literal((String)outMessage).m_130940_(ChatFormatting.GRAY), false);
player4.displayClientMessage((Component)Component.literal((String)outMessage).m_130940_(ChatFormatting.GRAY), false);
}
return;
}
@@ -132,14 +132,14 @@ public class ConcussionAudioEffect {
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.m_5661_((Component)Component.literal((String)blurMsg).m_130940_(ChatFormatting.BLUE), false);
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.m_5661_((Component)Component.literal((String)blurMsg).m_130940_(ChatFormatting.GRAY), false);
player3.displayClientMessage((Component)Component.literal((String)blurMsg).m_130940_(ChatFormatting.GRAY), false);
}
int lowpassSeconds = blurSeconds;
double lowpassIntensityPercent = ConcussionAudioEffect.computeBaseLowpassIntensityPercent(effectivePercent);
@@ -158,14 +158,14 @@ public class ConcussionAudioEffect {
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.m_5661_((Component)Component.literal((String)lpMsg).m_130940_(ChatFormatting.DARK_GREEN), false);
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.m_5661_((Component)Component.literal((String)lpMsg).m_130940_(ChatFormatting.GRAY), false);
player2.displayClientMessage((Component)Component.literal((String)lpMsg).m_130940_(ChatFormatting.GRAY), false);
}
if (debugSendDebugMessage) {
ConcussionAudioEffect.sendDebugMessage(mc, effectivePercent, rawPercent, hasDirectLineOfSight, distance, maxDistance);
@@ -174,23 +174,23 @@ public class ConcussionAudioEffect {
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.m_5661_((Component)Component.literal((String)visibility).m_130940_(ChatFormatting.GRAY), false);
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.m_5661_((Component)Component.literal((String)chanceMsg).m_130940_(ChatFormatting.YELLOW), false);
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.m_5661_((Component)Component.literal((String)distMsg).m_130940_(ChatFormatting.GRAY), false);
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.m_5661_((Component)Component.literal((String)silentMsg).m_130940_(ChatFormatting.GRAY), false);
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.m_5661_((Component)Component.literal((String)deafnessMsg).m_130940_(ChatFormatting.RED), false);
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.m_5661_((Component)Component.literal((String)deafnessMsg).m_130940_(ChatFormatting.GRAY), false);
player.displayClientMessage((Component)Component.literal((String)deafnessMsg).m_130940_(ChatFormatting.GRAY), false);
}
}
if (!roll) {
@@ -258,16 +258,16 @@ public class ConcussionAudioEffect {
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.m_5661_((Component)Component.literal((String)outMessage).m_130940_(ChatFormatting.GRAY), false);
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.m_5661_((Component)Component.literal((String)message).m_130940_(color), false);
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.m_5661_((Component)Component.literal((String)rawMessage).m_130940_(ChatFormatting.GRAY), false);
player.displayClientMessage((Component)Component.literal((String)rawMessage).m_130940_(ChatFormatting.GRAY), false);
}
}

View File

@@ -75,7 +75,7 @@ public class DeafnessConcussionEffect {
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.m_5661_((Component)Component.literal((String)msg).m_130940_(ChatFormatting.WHITE), false);
player.displayClientMessage((Component)Component.literal((String)msg).m_130940_(ChatFormatting.WHITE), false);
}
return true;
}

View File

@@ -109,17 +109,17 @@ public class LowPassConcussionEffect {
SoundEngineAudioQueue.drainNow();
}
if (debugShowChat && (mc = Minecraft.getInstance()) != null && mc.player != null) {
mc.player.m_5661_((Component)Component.literal((String)("Low pass test queued for " + seconds + "s (strength=" + addedStrength + ")")), false);
mc.player.displayClientMessage((Component)Component.literal((String)("Low pass test queued for " + seconds + "s (strength=" + addedStrength + ")")), false);
}
}
public static void start(int seconds, float intensity, double effectivePercent, String visibility, int intensityPercent) {
Minecraft mc;
if (debugShowChat && (mc = Minecraft.getInstance()) != null && mc.player != null) {
mc.player.m_5661_((Component)Component.literal((String)"__________________________________________"), false);
mc.player.displayClientMessage((Component)Component.literal((String)"__________________________________________"), false);
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 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %d%%, \u0427\u0430\u0441 \u043f\u0440\u0438\u0433\u043b\u0443\u0448\u0435\u043d\u043d\u044f %.1f \u0441\u0435\u043a", effectivePercent, visibility, intensityPercent, (double)seconds);
mc.player.m_5661_((Component)Component.literal((String)msg).m_130940_(ChatFormatting.WHITE), false);
mc.player.m_5661_((Component)Component.literal((String)"__________________________________________"), false);
mc.player.displayClientMessage((Component)Component.literal((String)msg).m_130940_(ChatFormatting.WHITE), false);
mc.player.displayClientMessage((Component)Component.literal((String)"__________________________________________"), false);
}
LowPassConcussionEffect.start(seconds, intensity);
}