/* * 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 dripstoneQueue = new ConcurrentLinkedQueue(); private static final int MAX_DRIPSTONE_TASKS_PER_LEVEL_PER_TICK = 25; 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 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 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 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; } } }