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 b2003b70..3655c663 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 @@ -19,17 +19,5 @@ package de.steamwar.bausystem.features.simulator.preview; -import de.steamwar.bausystem.features.simulator.TNTData; -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 void run(Pair>>>> toCalculate, Consumer consumer) { - consumer.accept(null); - } } diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/AxisMovementLimiter.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/AxisMovementLimiter.java index a83fd36b..47596f80 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/AxisMovementLimiter.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/AxisMovementLimiter.java @@ -104,7 +104,7 @@ public class AxisMovementLimiter { } // TODO: This can be optimized by optimizing the x,y,z loop layout - public double run() { + public double run(SimulatorData simulatorData) { if (movement == 0.0) return 0.0; BoundingBox movementBoundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); @@ -112,7 +112,7 @@ public class AxisMovementLimiter { Double collision = null; for (Pos pos : poss) { - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(pos.x, pos.y, pos.z); boolean collides = boundingBox.overlaps(movementBoundingBox); 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 54405cbc..20173ed5 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 @@ -73,7 +73,7 @@ public class Explosion { this.z = z; } - public void calculate() { + public void calculate(SimulatorData simulatorData) { Set affectedBlocks = new HashSet<>(); for (int i = 0; i < FACE_BLOCKS.length; i += 3) { double d = FACE_BLOCKS[i + 0]; @@ -90,12 +90,12 @@ public class Explosion { int y = TNT.floor(n); int z = TNT.floor(o); - Material material = Simulator19.getBlockType(x, y, z); + Material material = simulatorData.getBlockType(x, y, z); if (!material.isAir()) { h -= (material.getBlastResistance() + 0.3F) * 0.3F; } if (WATER_LOGABLE.contains(material)) { - Waterlogged waterlogged = (Waterlogged) Simulator19.getBlockData(x, y, z); + Waterlogged waterlogged = (Waterlogged) simulatorData.getBlockData(x, y, z); if (waterlogged.isWaterlogged()) { h = 0.0F; } @@ -110,7 +110,7 @@ public class Explosion { o += f * 0.30000001192092896; } } - Simulator19.clearBlocks(affectedBlocks); + simulatorData.clearBlocks(affectedBlocks); float q = POWER * 2.0F; int k = floor(x - q - 1.0D); @@ -120,7 +120,7 @@ public class Explosion { int t = floor(z - q - 1.0D); int u = floor(z + q + 1.0D); - for (TNT currentTNT : Simulator19.tntList) { + for (TNT currentTNT : simulatorData.tntList) { if (currentTNT == tnt) continue; if (!(currentTNT.getX() >= k && currentTNT.getY() >= r && currentTNT.getZ() >= t && currentTNT.getX() <= l && currentTNT.getY() <= s && currentTNT.getZ() <= u)) { continue; @@ -141,7 +141,7 @@ public class Explosion { y /= aa; z /= aa; - double ab = getExposure(this.x, this.y, this.z); + double ab = getExposure(simulatorData, this.x, this.y, this.z); double ac = (1.0 - w) * ab; currentTNT.setVx(currentTNT.getVx() + x * ac); currentTNT.setVy(currentTNT.getVy() + y * ac); @@ -160,7 +160,7 @@ public class Explosion { private static final double EXPOSURE_CONSTANT_1 = 1.0 / (SIZE * 2 + 1.0); private static final double EXPOSURE_CONSTANT_2 = (1.0 - Math.floor(1.0 / EXPOSURE_CONSTANT_1) * EXPOSURE_CONSTANT_1) / 2.0; - private static float getExposure(double x, double y, double z) { + private static float getExposure(SimulatorData simulatorData, double x, double y, double z) { float blockMisses = 0; float blockTotal = 0; @@ -171,7 +171,7 @@ public class Explosion { double dy = lerp(l, 0.0, SIZE); double dz = lerp(m, MIN_POINT, MAX_POINT) + EXPOSURE_CONSTANT_2; - if (rayTrace(x, y, z, dx, dy, dz)) { + if (rayTrace(simulatorData, x, y, z, dx, dy, dz)) { blockMisses++; } blockTotal++; @@ -186,7 +186,7 @@ public class Explosion { return start + delta * (end - start); } - public static boolean rayTrace(double sX, double sY, double sZ, double dX, double dY, double dZ) { + public static boolean rayTrace(SimulatorData simulatorData, double sX, double sY, double sZ, double dX, double dY, double dZ) { double x = sX; double y = sY; double z = sZ; @@ -194,7 +194,7 @@ public class Explosion { int oY = sY > dY ? -1 : 1; int oZ = sZ > dZ ? -1 : 1; while (true) { - if (Simulator19.getBlockType(floor(x), floor(y), floor(z)) != Material.AIR) { + if (simulatorData.getBlockType(floor(x), floor(y), floor(z)) != Material.AIR) { return true; } diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/OptimizedAxisMovementLimiter.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/OptimizedAxisMovementLimiter.java index 2f9da376..f6e92865 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/OptimizedAxisMovementLimiter.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/OptimizedAxisMovementLimiter.java @@ -92,38 +92,38 @@ public class OptimizedAxisMovementLimiter { movementBoundingBox = new BoundingBox(minX, minY, minZ, maxX, maxY, maxZ); } - public double run() { + public double run(SimulatorData simulatorData) { if (movement == 0.0) return 0.0; switch (axis) { case X: if (movement < 0.0) { - return runNX(); + return runNX(simulatorData); } else { - return runPX(); + return runPX(simulatorData); } case Y: if (movement < 0.0) { - return runNY(); + return runNY(simulatorData); } else { - return runPY(); + return runPY(simulatorData); } case Z: default: if (movement < 0.0) { - return runNZ(); + return runNZ(simulatorData); } else { - return runPZ(); + return runPZ(simulatorData); } } } - private double runNX() { + private double runNX(SimulatorData simulatorData) { Double collision = null; for (int x = maxIX - 1; x >= minIX; x--) { for (int y = minIY; y < maxIY; y++) { for (int z = minIZ; z < maxIZ; z++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; @@ -147,13 +147,13 @@ public class OptimizedAxisMovementLimiter { return movement + (collision - minX); } - private double runPX() { + private double runPX(SimulatorData simulatorData) { Double collision = null; for (int x = minIX; x < maxIX; x++) { for (int y = minIY; y < maxIY; y++) { for (int z = minIZ; z < maxIZ; z++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; @@ -177,13 +177,13 @@ public class OptimizedAxisMovementLimiter { return movement + (collision - minX); } - private double runNY() { + private double runNY(SimulatorData simulatorData) { Double collision = null; for (int y = maxIY - 1; y >= minIY; y--) { for (int x = minIX; x < maxIX; x++) { for (int z = minIZ; z < maxIZ; z++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; @@ -207,13 +207,13 @@ public class OptimizedAxisMovementLimiter { return movement + (collision - minY); } - private double runPY() { + private double runPY(SimulatorData simulatorData) { Double collision = null; for (int y = minIY; y < maxIY; y++) { for (int x = minIX; x < maxIX; x++) { for (int z = minIZ; z < maxIZ; z++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; @@ -237,13 +237,13 @@ public class OptimizedAxisMovementLimiter { return movement + (collision - minY); } - private double runNZ() { + private double runNZ(SimulatorData simulatorData) { Double collision = null; for (int z = maxIZ - 1; z >= minIZ; z--) { for (int x = minIX; x < maxIX; x++) { for (int y = minIY; y < maxIY; y++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; @@ -267,13 +267,13 @@ public class OptimizedAxisMovementLimiter { return movement + (collision - minZ); } - private double runPZ() { + private double runPZ(SimulatorData simulatorData) { Double collision = null; for (int z = minIZ; z < maxIZ; z++) { for (int x = minIX; x < maxIX; x++) { for (int y = minIY; y < maxIY; y++) { Pos pos = new Pos(x, y, z); - VoxelShape voxelShape = Simulator19.getVoxelShape(pos); + VoxelShape voxelShape = simulatorData.getVoxelShape(pos); for (BoundingBox boundingBox : voxelShape.getBoundingBoxes()) { boundingBox = boundingBox.clone().shift(x, y, z); if (!boundingBox.overlaps(movementBoundingBox)) continue; 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 97641f9a..909fb324 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 @@ -19,18 +19,20 @@ package de.steamwar.bausystem.features.simulator.preview; +import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.simulator.TNTData; import de.steamwar.bausystem.features.tracer.show.Record; import de.steamwar.bausystem.shared.Pair; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.data.BlockData; -import org.bukkit.util.BoundingBox; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import org.bukkit.util.Vector; -import org.bukkit.util.VoxelShape; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @@ -38,126 +40,67 @@ public class Simulator19 implements Simulator { protected static final World WORLD = Bukkit.getWorlds().get(0); - private static final BlockData AIR_BLOCK_DATA = Material.AIR.createBlockData(); - private static final VoxelShape AIR_VOXEL_SHAPE = new VoxelShape() { - @Override - public Collection getBoundingBoxes() { - return Collections.emptyList(); - } - - @Override - public boolean overlaps(BoundingBox boundingBox) { - return false; - } - }; - - private static long accessed = 0; - private static long cacheMisses = 0; - private static long aired = 0; - static final List tntList = new ArrayList<>(); - private static final Set AIR_BLOCKS = new HashSet<>(); - private static final Map BLOCK_TYPES_MAP = new HashMap<>(); - private static final Map BLOCK_DATA_MAP = new HashMap<>(); - private static final Map COLLISION_DATA_MAP = new HashMap<>(); - @Override - 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(); - int currentTick = 0; + public BukkitTask run(Pair>>>> toCalculate, Consumer consumer) { // TODO: Implement multi tick calculation max 40 ms per tick + if (toCalculate == null) return null; - Map recordMap = new HashMap<>(); - long time = System.currentTimeMillis(); - while (!tntList.isEmpty() || currentTick <= toCalculate.getKey()) { - List>> toSpawnInTick = toCalculate.getValue().get(currentTick); - if (toSpawnInTick != null) { - int finalCurrentTick = currentTick; - toSpawnInTick.forEach(pairs -> { - AtomicBoolean hasSomeLeft = new AtomicBoolean(true); - while(hasSomeLeft.get()) { - hasSomeLeft.set(false); - pairs.forEach(pair -> { - if (pair.getValue() > 0) { - hasSomeLeft.set(true); - TNT tnt = new TNT(pair.getKey().location.getX(), pair.getKey().location.getY(), pair.getKey().location.getZ()); - if (!pair.getKey().xVelocity) tnt.setVx(0.0); - if (!pair.getKey().yVelocity) tnt.setVy(0.0); - if (!pair.getKey().zVelocity) tnt.setVz(0.0); - tnt.setFuse(tnt.getFuse()); - tntList.add(tnt); - pair.setValue(pair.getValue() - 1); - Record.TNTRecord record = previewRecord.getRecord().spawn(finalCurrentTick); - record.source(pair.getKey().location.toVector(), new Vector(tnt.getVx(), tnt.getVy(), tnt.getVz()), tnt.getFuse()); - recordMap.put(tnt, record); + BukkitRunnable bukkitRunnable = new BukkitRunnable() { + private SimulatorData simulatorData = new SimulatorData(); + private PreviewRecord previewRecord = new PreviewRecord(); + private int currentTick = 0; + private Map recordMap = new HashMap<>(); + + @Override + public void run() { + long time = System.currentTimeMillis(); + while (!simulatorData.tntList.isEmpty() || currentTick <= toCalculate.getKey() && System.currentTimeMillis() - time < 40) { + List>> toSpawnInTick = toCalculate.getValue().get(currentTick); + if (toSpawnInTick != null) { + int finalCurrentTick = currentTick; + toSpawnInTick.forEach(pairs -> { + AtomicBoolean hasSomeLeft = new AtomicBoolean(true); + while(hasSomeLeft.get()) { + hasSomeLeft.set(false); + pairs.forEach(pair -> { + if (pair.getValue() > 0) { + hasSomeLeft.set(true); + TNT tnt = new TNT(pair.getKey().location.getX(), pair.getKey().location.getY(), pair.getKey().location.getZ()); + if (!pair.getKey().xVelocity) tnt.setVx(0.0); + if (!pair.getKey().yVelocity) tnt.setVy(0.0); + if (!pair.getKey().zVelocity) tnt.setVz(0.0); + tnt.setFuse(tnt.getFuse()); + simulatorData.tntList.add(tnt); + pair.setValue(pair.getValue() - 1); + Record.TNTRecord record = previewRecord.getRecord().spawn(finalCurrentTick); + record.source(pair.getKey().location.toVector(), new Vector(tnt.getVx(), tnt.getVy(), tnt.getVz()), tnt.getFuse()); + recordMap.put(tnt, record); + } + }); } }); } - }); - } - currentTick++; + currentTick++; - List remove = new ArrayList<>(); - for (TNT tnt : tntList) { - if (tnt.tick()) { - 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()); - } else { - recordMap.get(tnt).location(new Vector(tnt.getX(), tnt.getY(), tnt.getZ()), new Vector(tnt.getVx(), tnt.getVy(), tnt.getVz()), tnt.getFuse()); + List remove = new ArrayList<>(); + for (TNT tnt : simulatorData.tntList) { + 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()); + } else { + recordMap.get(tnt).location(new Vector(tnt.getX(), tnt.getY(), tnt.getZ()), new Vector(tnt.getVx(), tnt.getVy(), tnt.getVz()), tnt.getFuse()); + } + } + simulatorData.tntList.removeAll(remove); + } + + System.out.println("Time: " + (System.currentTimeMillis() - time) + "ms " + simulatorData.cacheMisses + "/" + simulatorData.accessed + "/" + simulatorData.aired); + if (simulatorData.tntList.isEmpty() && currentTick <= toCalculate.getKey()) { + simulatorData.airBlocks.forEach(pos -> previewRecord.addAir(new Vector(pos.x, pos.y, pos.z))); + consumer.accept(previewRecord); + cancel(); } } - tntList.removeAll(remove); - } - AIR_BLOCKS.forEach(pos -> previewRecord.addAir(new Vector(pos.x, pos.y, pos.z))); - System.out.println("Time: " + (System.currentTimeMillis() - time) + "ms " + cacheMisses + "/" + accessed + "/" + aired); - - AIR_BLOCKS.clear(); - BLOCK_TYPES_MAP.clear(); - BLOCK_DATA_MAP.clear(); - COLLISION_DATA_MAP.clear(); - accessed = 0; - cacheMisses = 0; - aired = 0; - consumer.accept(previewRecord); - } - - public static Material getBlockType(int x, int y, int z) { // Get BlockType of Chunk Data array? - accessed++; - Pos pos = new Pos(x, y, z); - if (AIR_BLOCKS.contains(pos)) { - return Material.AIR; - } - return BLOCK_TYPES_MAP.computeIfAbsent(pos, v -> { - cacheMisses++; - return WORLD.getBlockAt(x, y, z).getType(); - }); - } - - public static BlockData getBlockData(int x, int y, int z) { - accessed++; - return BLOCK_DATA_MAP.computeIfAbsent(new Pos(x, y, z), v -> { - cacheMisses++; - return WORLD.getBlockAt(x, y, z).getBlockData(); - }); - } - - public static VoxelShape getVoxelShape(Pos pos) { - accessed++; - if (AIR_BLOCKS.contains(pos)) { - return AIR_VOXEL_SHAPE; - } - return COLLISION_DATA_MAP.computeIfAbsent(pos, v -> { - cacheMisses++; - return WORLD.getBlockAt(pos.x, pos.y, pos.z).getCollisionShape(); - }); - } - - public static void clearBlock(Pos pos) { - aired++; - AIR_BLOCKS.add(pos); - BlockData blockData = BLOCK_DATA_MAP.put(pos, AIR_BLOCK_DATA); - } - - public static void clearBlocks(Set poss) { // TODO: Optimize - poss.forEach(Simulator19::clearBlock); + }; + return bukkitRunnable.runTaskTimer(BauSystem.getInstance(), 0, 1); } } 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 new file mode 100644 index 00000000..bc6b41c3 --- /dev/null +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/SimulatorData.java @@ -0,0 +1,93 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +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.VoxelShape; + +import java.util.*; + +public class SimulatorData { + + private static final BlockData AIR_BLOCK_DATA = Material.AIR.createBlockData(); + private static final VoxelShape AIR_VOXEL_SHAPE = new VoxelShape() { + @Override + public Collection getBoundingBoxes() { + return Collections.emptyList(); + } + + @Override + public boolean overlaps(BoundingBox boundingBox) { + return false; + } + }; + + long accessed = 0; + long cacheMisses = 0; + long aired = 0; + final List tntList = new ArrayList<>(); + final Set airBlocks = new HashSet<>(); + final Map blockTypesMap = new HashMap<>(); + final Map blockDataMap = new HashMap<>(); + final Map collisionDataMap = new HashMap<>(); + + public Material getBlockType(int x, int y, int z) { // Get BlockType of Chunk Data array? + accessed++; + Pos pos = new Pos(x, y, z); + if (airBlocks.contains(pos)) { + return Material.AIR; + } + return blockTypesMap.computeIfAbsent(pos, v -> { + cacheMisses++; + return Simulator19.WORLD.getBlockAt(x, y, z).getType(); + }); + } + + public BlockData getBlockData(int x, int y, int z) { + accessed++; + return blockDataMap.computeIfAbsent(new Pos(x, y, z), v -> { + cacheMisses++; + return Simulator19.WORLD.getBlockAt(x, y, z).getBlockData(); + }); + } + + public VoxelShape getVoxelShape(Pos pos) { + accessed++; + if (airBlocks.contains(pos)) { + return AIR_VOXEL_SHAPE; + } + return collisionDataMap.computeIfAbsent(pos, v -> { + cacheMisses++; + return Simulator19.WORLD.getBlockAt(pos.x, pos.y, pos.z).getCollisionShape(); + }); + } + + public void clearBlock(Pos pos) { + aired++; + airBlocks.add(pos); + blockDataMap.put(pos, AIR_BLOCK_DATA); + } + + public void clearBlocks(Set poss) { // TODO: Optimize + poss.forEach(this::clearBlock); + } +} diff --git a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/TNT.java b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/TNT.java index a01b4203..eacc8862 100644 --- a/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/TNT.java +++ b/BauSystem_19/src/de/steamwar/bausystem/features/simulator/preview/TNT.java @@ -71,10 +71,10 @@ public class TNT { this.fuse = 80; } - public boolean tick() { + public boolean tick(SimulatorData simulatorData) { this.vy -= 0.04; - move(new Vector(this.vx, this.vy, this.vz)); + move(simulatorData, new Vector(this.vx, this.vy, this.vz)); this.vx *= 0.98; this.vy *= 0.98; @@ -83,13 +83,13 @@ public class TNT { this.fuse--; if (this.fuse <= 0) { Explosion explosion = new Explosion(this, x, y + 0.98 * 0.0625, z); - explosion.calculate(); + explosion.calculate(simulatorData); return true; } return false; } - private void move(Vector movement) { + private void move(SimulatorData simulatorData, Vector movement) { if (movementMultiplier.lengthSquared() > 1.0E-7) { movement.multiply(movementMultiplier); movementMultiplier = new Vector(0, 0, 0); @@ -98,7 +98,7 @@ public class TNT { vz = 0; } - Vector vec3d = adjustMovementForCollisions(movement); + Vector vec3d = adjustMovementForCollisions(simulatorData, movement); // System.out.println(movement + " " + vec3d); double lengthSquared = vec3d.lengthSquared(); if (lengthSquared > 1.0E-7) { @@ -121,9 +121,9 @@ public class TNT { this.verticalCollision = movement.getY() != vec3d.getY(); this.onGround = this.verticalCollision && movement.getY() < 0.0D; - Vector blockPos = getLandingPos(); - Material material = Simulator19.getBlockType(blockPos.getBlockX(), blockPos.getBlockY(), blockPos.getBlockZ()); - BlockData blockData = Simulator19.getBlockData(blockPos.getBlockX(), blockPos.getBlockY(), blockPos.getBlockZ()); + Vector blockPos = getLandingPos(simulatorData); + Material material = simulatorData.getBlockType(blockPos.getBlockX(), blockPos.getBlockY(), blockPos.getBlockZ()); + BlockData blockData = simulatorData.getBlockData(blockPos.getBlockX(), blockPos.getBlockY(), blockPos.getBlockZ()); fall(vec3d.getY(), onGround); if (horizontalCollision) { @@ -154,27 +154,27 @@ public class TNT { } } - checkBlockCollision(); - float j = this.getVelocityMultiplier(); + checkBlockCollision(simulatorData); + float j = this.getVelocityMultiplier(simulatorData); this.vx *= j; this.vz *= j; } - private Vector adjustMovementForCollisions(Vector movement) { + private Vector adjustMovementForCollisions(SimulatorData simulatorData, Vector movement) { if (movement.lengthSquared() == 0.0) { return movement; } - double mY = new AxisMovementLimiter(x, y, z, Axis.Y, movement.getY()).run(); + double mY = new AxisMovementLimiter(x, y, z, Axis.Y, movement.getY()).run(simulatorData); boolean bl = Math.abs(movement.getX()) < Math.abs(movement.getZ()); if (bl) { - double mZ = new AxisMovementLimiter(x, y + mY, z, Axis.Z, movement.getZ()).run(); - double mX = new AxisMovementLimiter(x, y + mY, z + mZ, Axis.X, movement.getX()).run(); + double mZ = new AxisMovementLimiter(x, y + mY, z, Axis.Z, movement.getZ()).run(simulatorData); + double mX = new AxisMovementLimiter(x, y + mY, z + mZ, Axis.X, movement.getX()).run(simulatorData); return new Vector(mX, mY, mZ); } else { - double mX = new AxisMovementLimiter(x, y + mY, z, Axis.X, movement.getX()).run(); - double mZ = new AxisMovementLimiter(x + mX, y + mY, z, Axis.Z, movement.getZ()).run(); + double mX = new AxisMovementLimiter(x, y + mY, z, Axis.X, movement.getX()).run(simulatorData); + double mZ = new AxisMovementLimiter(x + mX, y + mY, z, Axis.Z, movement.getZ()).run(simulatorData); return new Vector(mX, mY, mZ); } } @@ -188,13 +188,13 @@ public class TNT { return value < (double)i ? i - 1 : i; } - private Vector getLandingPos() { + private Vector getLandingPos(SimulatorData simulatorData) { int x = floor(this.x); int y = floor(this.y - 0.2F); int z = floor(this.z); - if (Simulator19.getBlockType(x, y, z).isAir()) { - BlockData blockData = Simulator19.getBlockData(x, y - 1, z); + if (simulatorData.getBlockType(x, y, z).isAir()) { + BlockData blockData = simulatorData.getBlockData(x, y - 1, z); if (blockData instanceof Fence || blockData instanceof Wall || blockData instanceof Gate) { return new Vector(x, y - 1, z); } @@ -210,7 +210,7 @@ public class TNT { } } - private void checkBlockCollision() { + private void checkBlockCollision(SimulatorData simulatorData) { int x1 = floor(x + 1.0E-7); int y1 = floor(y + 1.0E-7); int z1 = floor(z + 1.0E-7); @@ -221,7 +221,7 @@ public class TNT { for (int x = x1; x <= x2; x++) { for (int y = y1; y <= y2; y++) { for (int z = z1; z <= z2; z++) { - Material material = Simulator19.getBlockType(x, y, z); + Material material = simulatorData.getBlockType(x, y, z); if (material == Material.POWDER_SNOW) { slowMovement(new Vector(0.8999999761581421, 1.5, 0.8999999761581421)); @@ -232,8 +232,8 @@ public class TNT { } else if (material == Material.COBWEB) { slowMovement(new Vector(0.25, 0.05000000074505806, 0.25)); } else if (material == Material.BUBBLE_COLUMN) { - boolean drag = ((BubbleColumn) Simulator19.getBlockData(x, y, z)).isDrag(); - if (Simulator19.getBlockType(x, y + 1, z).isAir()) { + boolean drag = ((BubbleColumn) simulatorData.getBlockData(x, y, z)).isDrag(); + if (simulatorData.getBlockType(x, y + 1, z).isAir()) { if (drag) { this.vy = Math.max(-0.9, vy - 0.03); } else { @@ -278,8 +278,8 @@ public class TNT { return d + 1.0E-7 > f || e + 1.0E-7 > f; } - private float getVelocityMultiplier() { - Material material = Simulator19.getBlockType(floor(x), floor(y), floor(z)); + private float getVelocityMultiplier(SimulatorData simulatorData) { + Material material = simulatorData.getBlockType(floor(x), floor(y), floor(z)); float f = 1F; if (material == Material.SOUL_SAND) { f = 0.5F; @@ -288,7 +288,7 @@ public class TNT { } if (material != Material.WATER && material != Material.BUBBLE_COLUMN) { if (f != 1) return f; - material = Simulator19.getBlockType(floor(x), floor(y - 0.5000001), floor(z)); + material = simulatorData.getBlockType(floor(x), floor(y - 0.5000001), floor(z)); if (material == Material.SOUL_SAND) { f = 0.5F; } else if (material == Material.HONEY_BLOCK) { 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 2320d313..abb6aa77 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 @@ -19,17 +19,5 @@ package de.steamwar.bausystem.features.simulator.preview; -import de.steamwar.bausystem.features.simulator.TNTData; -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 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 18d37907..8a0bc5cf 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java @@ -40,6 +40,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; +import org.bukkit.scheduler.BukkitTask; import yapion.hierarchy.types.YAPIONArray; import yapion.hierarchy.types.YAPIONObject; import yapion.hierarchy.types.YAPIONType; @@ -49,17 +50,22 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -@Getter public class TNTSimulator { + @Getter private Set players = new HashSet<>(); + + @Getter private REntityServer entityServer = new REntityServer(); + @Getter private Material material = Material.TNT; + @Getter private List tntElementList = new ArrayList<>(); - private boolean currentlyCalculating = false; + private List toShow = new ArrayList<>(); + private BukkitTask currentlyCalculating = null; private PreviewRecord previewRecord = null; public TNTSimulator() { @@ -108,17 +114,21 @@ public class TNTSimulator { } public void showPreview(Player player) { - if (previewRecord == null) { - calcPreview(true); - } if (previewRecord != null) { previewRecord.show(player); + return; } + toShow.add(player); + calcPreview(true); } public void hidePreview(Player player) { if (previewRecord != null && previewRecord.hide(player)) { previewRecord = null; + if (currentlyCalculating != null) { + currentlyCalculating.cancel(); + currentlyCalculating = null; + } } } @@ -130,27 +140,24 @@ public class TNTSimulator { if (!force && previewRecord == null) { return; } - if (currentlyCalculating) return; - currentlyCalculating = true; - - Simulator.impl.run(locations(true), newRecord -> { - boolean recalculate = currentlyCalculating; - currentlyCalculating = false; + if (currentlyCalculating != null) currentlyCalculating.cancel(); + currentlyCalculating = Simulator.impl.run(locations(true), newRecord -> { + currentlyCalculating = null; PreviewRecord oldRecord = previewRecord; previewRecord = newRecord; - if (newRecord == null) return; + if (newRecord == null) { + toShow.clear(); + return; + } if (oldRecord != null) { oldRecord.getPlayers().forEach(player -> { oldRecord.hide(player); newRecord.show(player); }); } - if (recalculate) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - calcPreview(force); - }, 1); - } + toShow.forEach(newRecord::show); + toShow.clear(); }); } 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 ae1d6b3d..9882df42 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 @@ -23,6 +23,7 @@ import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.simulator.TNTData; import de.steamwar.bausystem.shared.Pair; import de.steamwar.core.VersionDependent; +import org.bukkit.scheduler.BukkitTask; import java.util.List; import java.util.Map; @@ -31,5 +32,7 @@ import java.util.function.Consumer; public interface Simulator { Simulator impl = VersionDependent.getVersionImpl(BauSystem.getInstance()); - void run(Pair>>>> toCalculate, Consumer finished); + default BukkitTask run(Pair>>>> toCalculate, Consumer finished) { + return null; + } }