diff --git a/BauSystem_15/src/de/steamwar/bausystem/features/simulator/preview/Simulator15.java b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/preview/Simulator15.java index 0c33b6d8..b2003b70 100644 --- a/BauSystem_15/src/de/steamwar/bausystem/features/simulator/preview/Simulator15.java +++ b/BauSystem_15/src/de/steamwar/bausystem/features/simulator/preview/Simulator15.java @@ -20,16 +20,16 @@ package de.steamwar.bausystem.features.simulator.preview; import de.steamwar.bausystem.features.simulator.TNTData; -import de.steamwar.bausystem.features.simulator.preview.Simulator; import de.steamwar.bausystem.shared.Pair; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class Simulator15 implements Simulator { @Override - public PreviewRecord run(Pair>>>> toCalculate) { - return null; + public void run(Pair>>>> toCalculate, Consumer consumer) { + consumer.accept(null); } } 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 282464b1..54405cbc 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 @@ -91,7 +91,9 @@ public class Explosion { int z = TNT.floor(o); Material material = Simulator19.getBlockType(x, y, z); - h -= (material.getBlastResistance() + 0.3F) * 0.3F; + if (!material.isAir()) { + h -= (material.getBlastResistance() + 0.3F) * 0.3F; + } if (WATER_LOGABLE.contains(material)) { Waterlogged waterlogged = (Waterlogged) Simulator19.getBlockData(x, y, z); if (waterlogged.isWaterlogged()) { 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 4cc36085..97641f9a 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 @@ -32,6 +32,7 @@ import org.bukkit.util.VoxelShape; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; public class Simulator19 implements Simulator { @@ -60,11 +61,9 @@ public class Simulator19 implements Simulator { private static final Map COLLISION_DATA_MAP = new HashMap<>(); @Override - public synchronized PreviewRecord run(Pair>>>> toCalculate) { + public void run(Pair>>>> toCalculate, Consumer consumer) { // TODO: Implement multi tick calculation max 40 ms per tick + if (toCalculate == null) return; PreviewRecord previewRecord = new PreviewRecord(); - if (toCalculate == null) { - return previewRecord; - } int currentTick = 0; Map recordMap = new HashMap<>(); @@ -118,7 +117,7 @@ public class Simulator19 implements Simulator { accessed = 0; cacheMisses = 0; aired = 0; - return previewRecord; + consumer.accept(previewRecord); } public static Material getBlockType(int x, int y, int z) { // Get BlockType of Chunk Data array? diff --git a/BauSystem_20/src/de/steamwar/bausystem/features/simulator/preview/Simulator20.java b/BauSystem_20/src/de/steamwar/bausystem/features/simulator/preview/Simulator20.java index 089674fd..2320d313 100644 --- a/BauSystem_20/src/de/steamwar/bausystem/features/simulator/preview/Simulator20.java +++ b/BauSystem_20/src/de/steamwar/bausystem/features/simulator/preview/Simulator20.java @@ -24,11 +24,12 @@ import de.steamwar.bausystem.shared.Pair; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class Simulator20 implements Simulator { @Override - public PreviewRecord run(Pair>>>> toCalculate) { - return null; + public void run(Pair>>>> toCalculate, Consumer consumer) { + consumer.accept(null); } } 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 22078942..18d37907 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java @@ -36,6 +36,7 @@ import de.steamwar.bausystem.utils.RayTraceUtils; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; @@ -58,6 +59,7 @@ public class TNTSimulator { private List tntElementList = new ArrayList<>(); + private boolean currentlyCalculating = false; private PreviewRecord previewRecord = null; public TNTSimulator() { @@ -120,21 +122,36 @@ public class TNTSimulator { } } + public boolean hasPreview(Player player) { + return previewRecord != null && previewRecord.has(player); + } + public void calcPreview(boolean force) { if (!force && previewRecord == null) { return; } + if (currentlyCalculating) return; + currentlyCalculating = true; - PreviewRecord newRecord = Simulator.impl.run(locations()); - PreviewRecord oldRecord = previewRecord; - previewRecord = newRecord; - if (newRecord == null) return; - if (oldRecord != null) { - oldRecord.getPlayers().forEach(player -> { - oldRecord.hide(player); - newRecord.show(player); - }); - } + Simulator.impl.run(locations(true), newRecord -> { + boolean recalculate = currentlyCalculating; + currentlyCalculating = false; + + PreviewRecord oldRecord = previewRecord; + previewRecord = newRecord; + if (newRecord == null) return; + if (oldRecord != null) { + oldRecord.getPlayers().forEach(player -> { + oldRecord.hide(player); + newRecord.show(player); + }); + } + if (recalculate) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + calcPreview(force); + }, 1); + } + }); } public List getEntities() { @@ -239,10 +256,10 @@ public class TNTSimulator { TNTElementGUI.open(player, tntElement, null); } - public Pair>>>> locations() { + public Pair>>>> locations(boolean allowFrozen) { Map>>> result = new HashMap<>(); for (SimulatorElement element : tntElementList) { - if (element.locations(result)) { + if (element.locations(result) && !allowFrozen) { return null; } } @@ -267,7 +284,7 @@ public class TNTSimulator { public void start(Player p) { Region region = Region.getRegion(p.getLocation()); - Pair>>>> result = locations(); + Pair>>>> result = locations(false); if (result == null) { BauSystem.MESSAGE.send("SIMULATOR_REGION_FROZEN", p); 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 78d89545..995bf560 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java @@ -19,14 +19,19 @@ package de.steamwar.bausystem.features.simulator; +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI; +import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.shared.Pair; import de.steamwar.bausystem.utils.ItemUtils; +import de.steamwar.bausystem.utils.PlayerMovementWrapper; import de.steamwar.bausystem.utils.RayTraceUtils; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -39,6 +44,7 @@ import org.bukkit.inventory.ItemStack; import java.util.HashMap; import java.util.Map; +import java.util.function.BiFunction; @Linked public class TNTSimulatorListener implements Listener { @@ -71,6 +77,25 @@ public class TNTSimulatorListener implements Listener { return RayTraceUtils.traceREntity(player, to, simulator.getEntities()); } + private static final Class position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition"); + private static final Class positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook"); + + { + BiFunction positionSetter = (player, o) -> { + if (player.getGameMode() == GameMode.SPECTATOR) return o; + TNTSimulator tntSimulator = currentSimulator.get(player); + if (tntSimulator == null) return o; + if (!tntSimulator.hasPreview(player)) return o; + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + PlayerMovementWrapper.impl.setPosition(player, o); + }, 0L); + return null; + }; + + TinyProtocol.instance.addFilter(position, positionSetter); + TinyProtocol.instance.addFilter(positionLook, positionSetter); + } + private void hideShow(Player player, Pair simulatorPair) { TNTSimulator simulator = simulatorPair.getKey(); TNTSimulator tntSimulator = currentSimulator.remove(player); 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 6a8094f3..147a0119 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 @@ -59,14 +59,13 @@ public class PreviewRecord { p.sendBlockChange(vector.toLocation(player.getWorld()), AIR_BLOCK_DATA); }); ShowModeParameter showModeParameter = new ShowModeParameter(); - showModeParameter.enableInterpolateY(); - showModeParameter.enableInterpolateXZ(); showModeParameter.enableWater(); showModeParameter.enableCount(); - showModeParameter.setTntPositionMaterial(Material.RED_STAINED_GLASS); - showModeParameter.setUpdatePositionMaterial(Material.WHITE_STAINED_GLASS); - showModeParameter.setExplosePositionMaterial(Material.RED_WOOL); - return new EntityShowMode(p, showModeParameter, 10); + showModeParameter.setTntPositionMaterial(Material.WHITE_STAINED_GLASS); + showModeParameter.setExplosePositionMaterial(Material.RED_STAINED_GLASS); + EntityShowMode entityShowMode = new EntityShowMode(p, showModeParameter, 10); + record.getTnt().forEach(tntRecord -> tntRecord.getPositions().forEach(entityShowMode::show)); + return entityShowMode; }); } @@ -81,4 +80,8 @@ public class PreviewRecord { } return showModeMap.isEmpty(); } + + public boolean has(Player player) { + return showModeMap.containsKey(player); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/Simulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/Simulator.java index ca3fa2c8..ae1d6b3d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/Simulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/preview/Simulator.java @@ -26,9 +26,10 @@ import de.steamwar.core.VersionDependent; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public interface Simulator { Simulator impl = VersionDependent.getVersionImpl(BauSystem.getInstance()); - PreviewRecord run(Pair>>>> toCalculate); + void run(Pair>>>> toCalculate, Consumer finished); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java index 2033b868..805804fc 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java @@ -200,14 +200,11 @@ public class TNTElement implements SimulatorElement { if (disabled) return false; Location location = getPosition().toLocation(SimulatorStorage.WORLD); Region thisRegion = Region.getRegion(location); - if (thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE) { - return true; - } result.computeIfAbsent(getTickOffset(), ignore -> new HashMap<>()) .computeIfAbsent(OrderUtils.order(order), ignore -> new HashSet<>()) .add(new Pair<>(new TNTData(location, fuseTicks, xVelocity, yVelocity, zVelocity), count)); - return false; + return thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE; } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java index 3bfa0553..70eef4a3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java @@ -149,12 +149,13 @@ public class TNTGroup implements SimulatorElement { @Override public boolean locations(Map>>> result) { if (disabled) return false; + boolean frozen = false; for (TNTElement element : elements) { if (element.locations(result)) { - return true; + frozen = true; } } - return false; + return frozen; } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java index 1a9387c6..50e5f3ca 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java @@ -118,7 +118,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen if (hidden.containsKey(region) && hidden.get(region).contains(player)) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { PlayerMovementWrapper.impl.setPosition(player, o); - }, 1L); + }, 0L); return null; } return o;