From 05dc42355df752d88e7fc3140f6b47f8f12b5015 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 19 Apr 2025 23:04:19 +0200 Subject: [PATCH] Update and improve SimulatorStabGenerator --- .../features/cannon/depth/Depth.java | 19 +- .../execute/SimulatorStabGenerator.java | 227 ++++++++++-------- 2 files changed, 127 insertions(+), 119 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java index 3a48d136..22ce7fde 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java @@ -32,22 +32,13 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.*; -import java.util.function.BiConsumer; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; public class Depth { - private static final Map>> callbacks = new HashMap<>(); - - public static void addCallback(Region region, BiConsumer callback) { - callbacks.computeIfAbsent(region, k -> new ArrayList<>()).add(callback); - } - - public static void removeCallback(Region region, BiConsumer callback) { - callbacks.computeIfAbsent(region, k -> new ArrayList<>()).remove(callback); - } - private Region region; private Vector minVector = null; private Vector maxVector = null; @@ -79,10 +70,6 @@ public class Depth { player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount)); } }); - - new ArrayList<>(callbacks.getOrDefault(region, Collections.emptyList())).forEach(consumer -> { - consumer.accept(dimensions, tntCount); - }); } private void internalUpdate(Block block) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java index 5d700ddd..b874280f 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java @@ -27,7 +27,6 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.cannon.depth.Depth; import de.steamwar.bausystem.features.simulator.SimulatorWatcher; import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; @@ -50,28 +49,57 @@ import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.util.Vector; import java.util.*; -import java.util.function.BiConsumer; import java.util.function.Function; import java.util.logging.Level; +import java.util.stream.Collectors; -public class SimulatorStabGenerator { +public class SimulatorStabGenerator implements Listener { - private static final int MAX_RECORDINGS = 10; + // Lupfstichs sind noch nicht perfekt + // Schwenkstichs sidn noch nicht perfekt + + private static final int MAX_RECORDINGS = 5; + private static final Level LEVEL = Level.INFO; + private static final int TNT_INCREASE = 10; + private static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20; + + private final Map> destroyedBlocksPerSlice = new HashMap<>(); + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (direction == null) return; + if (Region.getRegion(event.getEntity().getLocation()) == region) { + event.blockList().forEach(block -> { + if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return; + int component = direction.component.apply(block.getLocation().toVector()); + destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>()) + .add(block.getLocation()); + }); + } + } private final Region region; private final Simulator simulator; private final TNTElement tntElement; private final List phases; private final int depthLimit; + private Clipboard clipboard; private boolean cancel = false; + private Direction direction = null; + public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) { this.region = region; this.simulator = simulator; @@ -111,77 +139,31 @@ public class SimulatorStabGenerator { TraceRecorder.instance.removeAutoTraceRegion(region); } clipboard = FlatteningWrapper.impl.copy(region.getMinPointTestblockExtension(), region.getMaxPointTestblockExtension(), region.getTestBlockPoint()); - run(); + + getDirection(); } private BlockVector3 toBlockVector3(Point point) { return BlockVector3.at(point.getX(), point.getY(), point.getZ()); } - private Direction direction = null; - - private void removeTestblock() { + private void getDirection() { try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(toBlockVector3(region.getMinPointTestblockExtension()), toBlockVector3(region.getMaxPointTestblockExtension())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); } - } - private void setTestblock() { - try { - PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); - PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) - .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); - region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); - } catch (SecurityException e) { - stop(); - throw e; - } - } - - private void run() { - if (cancel) return; showBossbar(false); - Trace trace; - if (direction == null) { - removeTestblock(); - trace = TraceRecorder.instance.startRecording(region); - } else { - setTestblock(); - trace = null; - } - - if (trace == null && currentDepth > 0) { - TNTPhase lastPhase = phases.getLast(); - TNTPhase nextPhase = new TNTPhase(); - nextPhase.setCount(1); - nextPhase.setTickOffset(lastPhase.getTickOffset()); - nextPhase.setOrder(100); - nextPhase.setXJump(lastPhase.isXJump()); - nextPhase.setYJump(lastPhase.isYJump()); - nextPhase.setZJump(lastPhase.isZJump()); - phases.add(nextPhase); - } - + Trace trace = TraceRecorder.instance.startRecording(region); SimulatorExecutor.run(simulator, () -> { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - if (trace != null) TraceRecorder.instance.stopRecording(region); - if (trace == null && currentDepth > 0) phases.removeLast(); - next(trace); + TraceRecorder.instance.stopRecording(region); + calculateDirection(trace); }, 20); }); } - @AllArgsConstructor - private enum Direction { - X(Vector::getBlockX), - Y(Vector::getBlockY), - Z(Vector::getBlockZ); - - private final Function extractVelocity; - } - - private void calcDirection(Trace trace) { + private void calculateDirection(Trace trace) { long tickSinceStart = -1; List points = null; for (List current : trace.getHistories()) { @@ -193,6 +175,7 @@ public class SimulatorStabGenerator { points = current; } } + TraceManager.instance.remove(trace); if (points == null) { stop(); return; @@ -214,33 +197,64 @@ public class SimulatorStabGenerator { return; } - Bukkit.getLogger().log(Level.FINEST, "Direction: {}", direction); - TraceManager.instance.remove(trace); + Bukkit.getLogger().log(LEVEL, "Direction: {0}", direction); phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT); - phases.getFirst().setCount(10); - Depth.addCallback(region, callback); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + phases.getFirst().setCount(TNT_INCREASE); + destroyedBlocksPerSlice.clear(); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + getStab(); + }, 20); + } + + private void getStab() { + try { + PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); + PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) + .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); + region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); + } catch (SecurityException e) { + stop(); + throw e; + } + if (cancel) return; + + showBossbar(false); + + SimulatorExecutor.run(simulator, () -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::calculateStep, 20); + }); } private int recordings = 0; - private List depths = new ArrayList<>(); + private List currentDepths = new ArrayList<>(); private int lastDepth = 0; private int currentDepth = 0; - private void next(Trace trace) { - if (direction == null) { - calcDirection(trace); - return; + private void calculateStep() { + List>> locations = destroyedBlocksPerSlice.entrySet() + .stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)) + .collect(Collectors.toList()); + int depth = 0; + for (int i = 0; i < locations.size(); i++) { + if (i == 0 || i == locations.size() - 1) { + if (locations.get(i).getValue().size() > MIN_BLOCK_TO_COUNT_AS_DEPTH) { + depth++; + } + } else { + depth++; + } } - List depths = new ArrayList<>(); - for (Vector vector : this.depths) { - depths.add(direction.extractVelocity.apply(vector)); + if (depth > 0) { + Bukkit.getLogger().log(LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())}); + currentDepths.add(depth); } - // System.out.println(depths); + destroyedBlocksPerSlice.clear(); - int depth = depths.stream().max(Integer::compareTo).orElse(0); - currentDepth = depth; + int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0); + currentDepth = maxDepth; int countWithoutLast = 0; for (int i = 0; i < phases.size() - 1; i++) { @@ -248,61 +262,74 @@ public class SimulatorStabGenerator { } TNTPhase lastPhase = phases.getLast(); - boolean moreTNTNeeded = depth - countWithoutLast >= lastPhase.getCount() - 5; - if (!depths.isEmpty() && moreTNTNeeded) { - Bukkit.getLogger().log(Level.FINEST, "Increasing tnt count by 10"); - lastPhase.setCount(lastPhase.getCount() + 10); + boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5; + if (!currentDepths.isEmpty() && moreTNTNeeded) { + Bukkit.getLogger().log(LEVEL, "Increasing tnt count by {0}", TNT_INCREASE); + lastPhase.setCount(lastPhase.getCount() + TNT_INCREASE); recordings = 0; - depths.clear(); + currentDepths.clear(); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); return; } if (recordings++ < MAX_RECORDINGS) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); return; } recordings = 0; - if (depths.isEmpty()) { - Bukkit.getLogger().log(Level.FINEST, "No dimension - Increasing tickOffset to: {}", phases.getFirst().getTickOffset() + 1); + if (currentDepths.isEmpty()) { + Bukkit.getLogger().log(LEVEL, "No dimension - Increasing tickOffset to: {0}", phases.getFirst().getTickOffset() + 1); phases.getFirst().setTickOffset(phases.getFirst().getTickOffset() + 1); phases.getFirst().setOrder(0); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + if (phases.getFirst().getTickOffset() > 80) { + stop(); + } else { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); + } return; } - depths.clear(); + currentDepths.clear(); - Bukkit.getLogger().log(Level.FINEST, "No more TNT needed on phase adjusting - {} new depth; {} current count", new Object[]{depth - countWithoutLast, lastPhase.getCount()}); - lastPhase.setCount(depth - countWithoutLast); + Bukkit.getLogger().log(LEVEL, "No more TNT needed on phase adjusting - {0} new depth; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()}); + lastPhase.setCount(maxDepth - countWithoutLast); if (lastPhase.getCount() <= 0) { - Bukkit.getLogger().log(Level.FINEST, "Count was 0 or negative - removing last phase"); + Bukkit.getLogger().log(LEVEL, "Count was 0 or negative - removing last phase"); phases.removeLast(); } - if (depth > depthLimit) { - Bukkit.getLogger().log(Level.FINEST, "Depth is greater than {} - finished", depthLimit); + if (maxDepth > depthLimit) { + Bukkit.getLogger().log(LEVEL, "Depth is greater than {0} - finished", depthLimit); stop(); return; } - if (depth <= lastDepth) { - Bukkit.getLogger().log(Level.FINEST, "Depth is equal to last depth recorded {} - finished", depth); + if (maxDepth <= lastDepth) { + Bukkit.getLogger().log(LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth); stop(); return; } - lastDepth = depth; + lastDepth = maxDepth; - Bukkit.getLogger().log(Level.FINEST, "Adding new phase in next tick"); + Bukkit.getLogger().log(LEVEL, "Adding new phase in next tick"); TNTPhase nextPhase = new TNTPhase(); - nextPhase.setCount(10); + nextPhase.setCount(TNT_INCREASE); nextPhase.setTickOffset(lastPhase.getTickOffset() + 1); nextPhase.setXJump(lastPhase.isXJump()); nextPhase.setYJump(lastPhase.isYJump()); nextPhase.setZJump(lastPhase.isZJump()); phases.add(nextPhase); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); + } + + @AllArgsConstructor + private enum Direction { + X(Vector::getBlockX), + Y(Vector::getBlockY), + Z(Vector::getBlockZ); + + private final Function component; } private void showBossbar(boolean finished) { @@ -331,8 +358,8 @@ public class SimulatorStabGenerator { private void stop() { simulator.setStabGenerator(null); - Depth.removeCallback(region, callback); SimulatorWatcher.update(simulator); + HandlerList.unregisterAll(this); showBossbar(true); new Thread(() -> { @@ -348,18 +375,12 @@ public class SimulatorStabGenerator { }).start(); } - private BiConsumer callback = this::depth; - - private void depth(Vector dimension, int tntCount) { - depths.add(dimension.clone().add(new Vector(1, 1, 1))); - } - public void cancel() { cancel = true; simulator.setStabGenerator(null); - Depth.removeCallback(region, callback); for (Player player : Bukkit.getOnlinePlayers()) { BossBarService.instance.remove(player, region, "simulator_stab_generator"); } + HandlerList.unregisterAll(this); } }