diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Explosion.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Explosion.java index 634ffab3..0e391e21 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Explosion.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Explosion.java @@ -195,7 +195,7 @@ public class Explosion { int oZ = sZ > dZ ? -1 : 1; while (true) { Material material = simulatorData.getBlockType(floor(x), floor(y), floor(z)); - if (material != Material.LAVA && material != Material.WATER && !material.isAir()) { + if (material != Material.LAVA && material != Material.WATER && material != Material.AIR) { return true; } diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Simulator19.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Simulator19.java index 3b5d5db1..b65cc135 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Simulator19.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/Simulator19.java @@ -29,10 +29,7 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @@ -48,7 +45,7 @@ public class Simulator19 implements Simulator { private SimulatorData simulatorData = new SimulatorData(); private PreviewRecord previewRecord = new PreviewRecord(); private int currentTick = 0; - private Map recordMap = new HashMap<>(); + private Map recordMap = new IdentityHashMap<>(); @Override public void run() { @@ -85,6 +82,7 @@ public class Simulator19 implements Simulator { List remove = new ArrayList<>(); for (TNT tnt : simulatorData.tntList) { + // System.out.println("CALC: " + simulatorData.blockTypesMap.size() + "/" + simulatorData.blockDataMap.size() + "/" + simulatorData.collisionDataMap.size() + "/" + simulatorData.airBlocks.size() + " " + recordMap.size()); if (tnt.tick(simulatorData)) { remove.add(tnt); recordMap.remove(tnt).explode(new Vector(tnt.getX(), tnt.getY(), tnt.getZ()), new Vector(tnt.getVx(), tnt.getVy(), tnt.getVz()), tnt.getFuse()); @@ -95,9 +93,10 @@ public class Simulator19 implements Simulator { simulatorData.tntList.removeAll(remove); } - System.out.println("Time: " + (System.currentTimeMillis() - time) + "ms " + simulatorData.cacheMisses + "/" + simulatorData.accessed + "/" + simulatorData.aired); + System.out.println("Time: " + (System.currentTimeMillis() - time) + "ms " + simulatorData.blockTypesMap.size() + "/" + simulatorData.blockDataMap.size() + "/" + simulatorData.collisionDataMap.size() + "/" + simulatorData.airBlocks.size() + " " + recordMap.size()); if (simulatorData.tntList.isEmpty() && currentTick > toCalculate.getKey()) { - simulatorData.airBlocks.forEach(pos -> previewRecord.addAir(new Vector(pos.x, pos.y, pos.z))); + previewRecord.setDestroyedBlocks(simulatorData.airBlocks()); + previewRecord.setAccessedBlocks(vector -> true); consumer.accept(previewRecord); cancel(); } diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/SimulatorData.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/SimulatorData.java index bc6b41c3..342c4466 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/SimulatorData.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/SimulatorData.java @@ -22,9 +22,11 @@ package de.steamwar.bausystem.features.simulator.preview; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; import org.bukkit.util.VoxelShape; import java.util.*; +import java.util.stream.Collectors; public class SimulatorData { @@ -64,7 +66,11 @@ public class SimulatorData { public BlockData getBlockData(int x, int y, int z) { accessed++; - return blockDataMap.computeIfAbsent(new Pos(x, y, z), v -> { + Pos pos = new Pos(x, y, z); + if (airBlocks.contains(pos)) { + return AIR_BLOCK_DATA; + } + return blockDataMap.computeIfAbsent(pos, v -> { cacheMisses++; return Simulator19.WORLD.getBlockAt(x, y, z).getBlockData(); }); @@ -84,10 +90,16 @@ public class SimulatorData { public void clearBlock(Pos pos) { aired++; airBlocks.add(pos); - blockDataMap.put(pos, AIR_BLOCK_DATA); + blockTypesMap.remove(pos); + blockDataMap.remove(pos); + collisionDataMap.remove(pos); } public void clearBlocks(Set poss) { // TODO: Optimize poss.forEach(this::clearBlock); } + + public Set airBlocks() { + return airBlocks.stream().map(pos -> new Vector(pos.x, pos.y, pos.z)).collect(Collectors.toSet()); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java index 59914193..071a9aff 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java @@ -41,6 +41,7 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.scheduler.BukkitTask; +import org.bukkit.util.Vector; import yapion.hierarchy.types.YAPIONArray; import yapion.hierarchy.types.YAPIONObject; import yapion.hierarchy.types.YAPIONType; @@ -138,6 +139,12 @@ public class TNTSimulator { return previewRecord != null && previewRecord.has(player); } + public void calcPreview(boolean force, Vector changedBlock) { + if (previewRecord == null || previewRecord.getAccessedBlocks().test(changedBlock)) { + calcPreview(force); + } + } + public void calcPreview(boolean force) { if (!force && previewRecord == null) { return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java index f18af23c..25205d00 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java @@ -194,17 +194,17 @@ public class TNTSimulatorListener implements Listener { } @EventHandler - public void onBlockPlace(BlockPlaceEvent event) { // TODO: Optimize this + public void onBlockPlace(BlockPlaceEvent event) { currentSimulator.values().forEach(simulator -> { - simulator.calcPreview(false); + simulator.calcPreview(false, event.getBlock().getLocation().toVector()); }); } @EventHandler - public void onBlockBreak(BlockBreakEvent event) { // TODO: Optimize this + public void onBlockBreak(BlockBreakEvent event) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { currentSimulator.values().forEach(simulator -> { - simulator.calcPreview(false); + simulator.calcPreview(false, event.getBlock().getLocation().toVector()); }); }, 0); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/PreviewRecord.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/PreviewRecord.java index 0075ee05..609de031 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/PreviewRecord.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/PreviewRecord.java @@ -23,6 +23,7 @@ import de.steamwar.bausystem.features.tracer.show.EntityShowMode; import de.steamwar.bausystem.features.tracer.show.Record; import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; import lombok.Getter; +import lombok.Setter; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -33,12 +34,18 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.function.Predicate; public class PreviewRecord { private static final BlockData AIR_BLOCK_DATA = Material.AIR.createBlockData(); - private Set destroyedBlocks = new HashSet<>(); + @Setter + private Set destroyedBlocks; + + @Setter + @Getter + private Predicate accessedBlocks; @Getter private Record record = new Record(null, (region, tntPosition) -> {}); @@ -49,10 +56,6 @@ public class PreviewRecord { return new HashSet<>(showModeMap.keySet()); } - public void addAir(Vector destroyed) { - destroyedBlocks.add(destroyed); - } - public void show(Player player) { destroyedBlocks.forEach(vector -> { player.sendBlockChange(vector.toLocation(player.getWorld()), AIR_BLOCK_DATA);