From 8f06dcfc857fb7b758642b712f4d924ce24557cd Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sat, 5 Feb 2022 15:44:24 +0100 Subject: [PATCH] Update Laufbau Signed-off-by: yoyosource --- BauSystem_Main/src/BauSystem.properties | 11 +- .../slaves/laufbau/BlockBoundingBox.java | 292 ++++++++++++++ .../features/slaves/laufbau/Cuboid.java | 80 ++++ .../features/slaves/laufbau/Laufbau.java | 364 ++++-------------- .../slaves/laufbau/LaufbauCommand.java | 27 +- .../states/CreatingInnerBlocksState.java | 120 ++++++ .../states/CreatingOuterBlocksState.java | 66 ++++ .../laufbau/states/ExpandingTracesState.java | 79 ++++ .../laufbau/states/FilteringTracesState.java | 89 +++++ .../slaves/laufbau/states/LaufbauState.java | 31 ++ .../laufbau/states/ProcessingTracesState.java | 75 ++++ .../states/ShrinkingOuterPointsState.java | 70 ++++ .../laufbau/states/SplittingPointsState.java | 80 ++++ 13 files changed, 1093 insertions(+), 291 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Cuboid.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingInnerBlocksState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingOuterBlocksState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ExpandingTracesState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ShrinkingOuterPointsState.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/SplittingPointsState.java diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index ad8d78a5..d6aabbc8 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -1122,8 +1122,15 @@ LAUFBAU_PREPARE1 = §71. Trace die Kanonen so oft wie nötig, in allen Modi. LAUFBAU_PREPARE2 = §72. Versuche alle Fails aus dem Trace zu löschen. LAUFBAU_NO_PERM = §cDu darfst hier nicht das Laufbau System verwenden LAUFBAU_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection -LAUFBAU_PROGRESS = §e{0} §7Blöcke übrig, §e{1} §7Blöcke pro Sekunde, §e{2} §7Block Delta -LAUFBAU_DONE = §aZuende gepanzert +LAUFBAU_STATE_FILTERING_TRACES = Traces filtern +LAUFBAU_STATE_PROCESSING_TRACES = Traces verbinden +LAUFBAU_STATE_EXPANDING_TRACES = Traces aufblähen +LAUFBAU_STATE_SPLITTING_POINTS = Punkte aufteilen +LAUFBAU_STATE_SHRINKING_POINTS = Punkte ausdünnen +LAUFBAU_STATE_CREATING_INNER_BLOCKS = Innenraum füllen +LAUFBAU_STATE_CREATING_OUTER_BLOCKS = Mantel bauen +LAUFBAU_SIMPLE_PROGRESS = §e{0}§8: §e{1}§8/§7{2} +LAUFBAU_DONE = §aZuende gebaut # UTILS SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java new file mode 100644 index 00000000..f939d857 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java @@ -0,0 +1,292 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.*; +import org.bukkit.block.data.type.*; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@ToString +@Getter +public class BlockBoundingBox { + + public static List elements = new ArrayList<>(); + + public BlockData blockData; + public Cuboid cuboid; + + static { + addPixel(Material.AIR.createBlockData(), 0, 0, 0, 0, 0, 0); + addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16); + + addPixel(Material.GRASS_PATH.createBlockData(), 0, 0, 0, 16, 15, 16); + addPixel(Material.SOUL_SAND.createBlockData(), 0, 0, 0, 16, 14, 16); + addPixel(Material.HONEY_BLOCK.createBlockData(), 1, 0, 1, 14, 15, 14); + + Grindstone floorGrindstone = (Grindstone) Material.GRINDSTONE.createBlockData(); + floorGrindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR); + addPixel(floorGrindstone, 2, 0, 2, 12, 16, 12); + + Grindstone northSouthGrindstone = (Grindstone) Material.GRINDSTONE.createBlockData(); + northSouthGrindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL); + northSouthGrindstone.setFacing(BlockFace.NORTH); + addPixel(northSouthGrindstone, 2, 2, 0, 12, 12, 16); + + Grindstone eastWestGrindstone = (Grindstone) Material.GRINDSTONE.createBlockData(); + eastWestGrindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL); + eastWestGrindstone.setFacing(BlockFace.EAST); + addPixel(eastWestGrindstone, 0, 2, 2, 16, 12, 12); + + Hopper hopper = (Hopper) Material.HOPPER.createBlockData(); + hopper.setFacing(BlockFace.NORTH); + addPixel(hopper, 0, 4, 0, 16, 12, 16); + + Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData(); + cocoaNorth.setAge(2); + cocoaNorth.setFacing(BlockFace.NORTH); + addPixel(cocoaNorth, 4, 3, 1, 8, 9, 8); + + Cocoa cocoaSouth = (Cocoa) Material.COCOA.createBlockData(); + cocoaSouth.setAge(2); + cocoaSouth.setFacing(BlockFace.SOUTH); + addPixel(cocoaSouth, 4, 3, 7, 8, 9, 8); + + Cocoa cocoaWest = (Cocoa) Material.COCOA.createBlockData(); + cocoaWest.setAge(2); + cocoaWest.setFacing(BlockFace.WEST); + addPixel(cocoaWest, 1, 3, 4, 8, 9, 8); + + Cocoa cocoaEast = (Cocoa) Material.COCOA.createBlockData(); + cocoaEast.setAge(2); + cocoaEast.setFacing(BlockFace.EAST); + addPixel(cocoaEast, 7, 3, 4, 8, 9, 8); + + TurtleEgg singleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData(); + singleTurtleEgg.setEggs(1); + singleTurtleEgg.setHatch(0); + addPixel(singleTurtleEgg, 4, 0, 3, 9, 7, 9); + + TurtleEgg doubleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData(); + doubleTurtleEgg.setEggs(2); + doubleTurtleEgg.setHatch(0); + addPixel(doubleTurtleEgg, 1, 0, 1, 14, 7, 14); + + Bell doubleAttachedBellEast = (Bell) Material.BELL.createBlockData(); + doubleAttachedBellEast.setAttachment(Bell.Attachment.DOUBLE_WALL); + doubleAttachedBellEast.setFacing(BlockFace.EAST); + addPixel(doubleAttachedBellEast, 0, 4, 4, 16, 11, 8); + + Bell doubleAttachedBellNorth = (Bell) Material.BELL.createBlockData(); + doubleAttachedBellNorth.setAttachment(Bell.Attachment.DOUBLE_WALL); + doubleAttachedBellNorth.setFacing(BlockFace.NORTH); + addPixel(doubleAttachedBellNorth, 4, 4, 0, 8, 11, 16); + + Bell floorBellNorth = (Bell) Material.BELL.createBlockData(); + floorBellNorth.setAttachment(Bell.Attachment.FLOOR); + addPixel(floorBellNorth, 0, 0, 4, 16, 16, 8); + + Bell floorBellEast = (Bell) Material.BELL.createBlockData(); + floorBellEast.setAttachment(Bell.Attachment.FLOOR); + floorBellEast.setFacing(BlockFace.EAST); + addPixel(floorBellEast, 4, 0, 0, 8, 16, 16); + + Bell ceilingBell = (Bell) Material.BELL.createBlockData(); + ceilingBell.setAttachment(Bell.Attachment.CEILING); + addPixel(ceilingBell, 4, 4, 4, 8, 12, 8); + + Bell singleAttachedBellNorth = (Bell) Material.BELL.createBlockData(); + singleAttachedBellNorth.setAttachment(Bell.Attachment.SINGLE_WALL); + singleAttachedBellNorth.setFacing(BlockFace.NORTH); + addPixel(singleAttachedBellNorth, 4, 4, 0, 8, 11, 13); + + Bell singleAttachedBellSouth = (Bell) Material.BELL.createBlockData(); + singleAttachedBellSouth.setAttachment(Bell.Attachment.SINGLE_WALL); + singleAttachedBellSouth.setFacing(BlockFace.SOUTH); + addPixel(singleAttachedBellSouth, 4, 4, 3, 8, 11, 13); + + Bell singleAttachedBellWest = (Bell) Material.BELL.createBlockData(); + singleAttachedBellWest.setAttachment(Bell.Attachment.SINGLE_WALL); + singleAttachedBellWest.setFacing(BlockFace.WEST); + addPixel(singleAttachedBellWest, 0, 4, 4, 13, 11, 8); + + Bell singleAttachedBellEast = (Bell) Material.BELL.createBlockData(); + singleAttachedBellEast.setAttachment(Bell.Attachment.SINGLE_WALL); + singleAttachedBellEast.setFacing(BlockFace.EAST); + addPixel(singleAttachedBellEast, 3, 4, 4, 13, 11, 8); + + addPixel(Material.CHEST.createBlockData(), 1, 0, 1, 14, 14, 14); + + Snow snowLayers8 = (Snow) Material.SNOW.createBlockData(); + snowLayers8.setLayers(8); + addPixel(snowLayers8, 0, 0, 0, 16, 14, 16); + + addPixel(Material.CHORUS_PLANT.createBlockData(), 3, 3, 3, 10, 10, 10); + + Directional headNorth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData(); + headNorth.setFacing(BlockFace.NORTH); + addPixel(headNorth, 4, 4, 8, 8, 8, 8); + + Directional headSouth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData(); + headSouth.setFacing(BlockFace.SOUTH); + addPixel(headSouth, 4, 4, 0, 8, 8, 8); + + Directional headWest = (Directional) Material.PLAYER_WALL_HEAD.createBlockData(); + headWest.setFacing(BlockFace.WEST); + addPixel(headWest, 8, 4, 4, 8, 8, 8); + + Directional headEast = (Directional) Material.PLAYER_WALL_HEAD.createBlockData(); + headEast.setFacing(BlockFace.EAST); + addPixel(headEast, 0, 4, 4, 8, 8, 8); + + Snow snowLayers7 = (Snow) Material.SNOW.createBlockData(); + snowLayers7.setLayers(7); + addPixel(snowLayers7, 0, 0, 0, 16, 12, 16); + + Snow snowLayers6 = (Snow) Material.SNOW.createBlockData(); + snowLayers6.setLayers(6); + addPixel(snowLayers6, 0, 0, 0, 16, 10, 16); + + addPixel(Material.STONECUTTER.createBlockData(), 0, 0, 0, 16, 9, 16); + + addPixel(Material.PLAYER_HEAD.createBlockData(), 4, 0, 4, 8, 8, 8); + + addPixel(Material.CAKE.createBlockData(), 1, 0, 1, 14, 8, 14); + + Slab bottomSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData(); + bottomSlab.setType(Slab.Type.BOTTOM); + addPixel(bottomSlab, 0, 0, 0, 16, 8, 16); + + Slab topSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData(); + topSlab.setType(Slab.Type.TOP); + addPixel(topSlab, 0, 8, 0, 16, 8, 16); + + SeaPickle quadSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData(); + quadSeaPickle.setWaterlogged(false); + quadSeaPickle.setPickles(4); + addPixel(quadSeaPickle, 2, 0, 2, 12, 7, 12); + + Campfire campfire = (Campfire) Material.CAMPFIRE.createBlockData(); + campfire.setSignalFire(false); + campfire.setLit(false); + addPixel(campfire, 0, 0, 0, 16, 7, 16); + + SeaPickle trippleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData(); + trippleSeaPickle.setWaterlogged(false); + trippleSeaPickle.setPickles(3); + addPixel(trippleSeaPickle, 2, 0, 2, 12, 6, 12); + + SeaPickle doubleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData(); + doubleSeaPickle.setWaterlogged(false); + doubleSeaPickle.setPickles(2); + addPixel(doubleSeaPickle, 3, 0, 3, 10, 6, 10); + + SeaPickle singleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData(); + singleSeaPickle.setWaterlogged(false); + singleSeaPickle.setPickles(1); + addPixel(singleSeaPickle, 6, 0, 6, 4, 6, 4); + + addPixel(Material.FLOWER_POT.createBlockData(), 5, 0, 5, 6, 6, 6); + + addPixel(Material.DAYLIGHT_DETECTOR.createBlockData(), 0, 0, 0, 16, 6, 16); + + Snow snowLayers3 = (Snow) Material.SNOW.createBlockData(); + snowLayers3.setLayers(3); + addPixel(snowLayers3, 0, 0, 0, 16, 4, 16); + + TrapDoor bottomTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + bottomTrapDoor.setHalf(Bisected.Half.BOTTOM); + addPixel(bottomTrapDoor, 0, 0, 0, 16, 3, 16); + + TrapDoor topTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + topTrapDoor.setHalf(Bisected.Half.TOP); + addPixel(topTrapDoor, 0, 13, 0, 16, 3, 16); + + Snow snowLayers2 = (Snow) Material.SNOW.createBlockData(); + snowLayers2.setLayers(2); + addPixel(snowLayers2, 0, 0, 0, 16, 2, 16); + + addPixel(Material.WHITE_CARPET.createBlockData(), 0, 0, 0, 16, 1, 16); + + Directional endRodBottomTop = (Directional) Material.END_ROD.createBlockData(); + endRodBottomTop.setFacing(BlockFace.UP); + addPixel(endRodBottomTop, 6, 0, 6, 4, 16, 4); + + Directional endRodNorthSouth = (Directional) Material.END_ROD.createBlockData(); + endRodNorthSouth.setFacing(BlockFace.NORTH); + addPixel(endRodNorthSouth, 6, 6, 0, 4, 4, 16); + + Directional endRodEastWest = (Directional) Material.END_ROD.createBlockData(); + endRodNorthSouth.setFacing(BlockFace.EAST); + addPixel(endRodEastWest, 0, 6, 6, 16, 4, 4); + + Waterlogged conduit = (Waterlogged) Material.CONDUIT.createBlockData(); + conduit.setWaterlogged(false); + addPixel(conduit, 5, 5, 5, 6, 6, 6); + + Lantern floorLantern = (Lantern) Material.LANTERN.createBlockData(); + addPixel(floorLantern, 5, 0, 5, 6, 9, 6); + + Lantern ceilingLantern = (Lantern) Material.LANTERN.createBlockData(); + ceilingLantern.setHanging(true); + addPixel(ceilingLantern, 5, 1, 5, 6, 15, 6); + + addPixel(Material.END_STONE_BRICK_WALL.createBlockData(),4, 0, 4, 8, 24, 8); + + addPixel(Material.NETHER_BRICK_FENCE.createBlockData(),6, 0, 6, 4, 24, 4); + + addPixel(Material.IRON_BARS.createBlockData(), 7, 0, 7, 2, 16, 2); + + TrapDoor northTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + northTrapDoor.setFacing(BlockFace.NORTH); + northTrapDoor.setOpen(true); + addPixel(northTrapDoor, 0, 0, 13, 16, 16, 3); + + TrapDoor southTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + southTrapDoor.setFacing(BlockFace.SOUTH); + southTrapDoor.setOpen(true); + addPixel(southTrapDoor, 0, 0, 0, 16, 16, 3); + + TrapDoor westTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + westTrapDoor.setFacing(BlockFace.WEST); + westTrapDoor.setOpen(true); + addPixel(westTrapDoor, 13, 0, 0, 3, 16, 16); + + TrapDoor eastTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); + eastTrapDoor.setFacing(BlockFace.EAST); + eastTrapDoor.setOpen(true); + addPixel(eastTrapDoor, 0, 0, 0, 3, 16, 16); + } + + private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel) { + elements.add(new BlockBoundingBox(blockData, new Cuboid(pixelToBlock(xPixel), pixelToBlock(yPixel), pixelToBlock(zPixel), pixelToBlock(dxPixel), pixelToBlock(dyPixel), pixelToBlock(dzPixel)))); + } + + private static double pixelToBlock(double pixel) { + return 1.0 / 16 * pixel; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Cuboid.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Cuboid.java new file mode 100644 index 00000000..fb8b8633 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Cuboid.java @@ -0,0 +1,80 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau; + +import de.steamwar.bausystem.region.Point; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Cuboid { + private double x; + private double y; + private double z; + private double dx; + private double dy; + private double dz; + + public boolean intersects(Cuboid cuboid) { + Cuboid helpCuboid = helpIntersect(cuboid); + Cuboid c1 = helpIntersect(helpCuboid); + Cuboid c2 = cuboid.helpIntersect(c1); + + if (c1.dx == 0 && c2.dx == 0) { + return false; + } + if (c1.dy == 0 && c2.dy == 0) { + return false; + } + if (c1.dz == 0 && c2.dz == 0) { + return false; + } + return c1.equals(c2); + } + + private Cuboid helpIntersect(Cuboid cuboid) { + double minX = Math.max(x, cuboid.x); + double minY = Math.max(y, cuboid.y); + double minZ = Math.max(z, cuboid.z); + double maxX = Math.min(x + dx, cuboid.x + cuboid.dx); + double maxY = Math.min(y + dy, cuboid.y + cuboid.dy); + double maxZ = Math.min(z + dz, cuboid.z + cuboid.dz); + + double nx = round(Math.min(minX, maxX)); + double ny = round(Math.min(minY, maxY)); + double nz = round(Math.min(minZ, maxZ)); + double dx = round(Math.max(minX, maxX) - nx); + double dy = round(Math.max(minY, maxY) - ny); + double dz = round(Math.max(minZ, maxZ) - nz); + return new Cuboid(nx, ny, nz, dx, dy, dz); + } + + private static double round(double value) { + value *= 100000000000000L; + value = Math.round(value); + value /= 100000000000000L; + return value; + } + + public Cuboid add(Point point) { + return new Cuboid(x + point.getX(), y + point.getY(), z + point.getZ(), dx, dy, dz); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java index 51d66fd5..074e5c27 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/Laufbau.java @@ -19,253 +19,101 @@ package de.steamwar.bausystem.features.slaves.laufbau; -import de.steamwar.bausystem.features.tracer.TNTPosition; -import de.steamwar.bausystem.features.tracer.show.StoredRecords; -import de.steamwar.bausystem.region.Point; -import de.steamwar.bausystem.utils.FlatteningWrapper; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Getter; -import lombok.ToString; -import org.bukkit.Bukkit; +import de.steamwar.bausystem.features.slaves.laufbau.states.*; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.BlockFace; -import org.bukkit.block.data.Bisected; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.Campfire; -import org.bukkit.block.data.type.Fence; -import org.bukkit.block.data.type.Slab; -import org.bukkit.block.data.type.TrapDoor; +import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - public class Laufbau { - @AllArgsConstructor - @ToString - @Getter - private static class BlockDataWithBoundingBox { - private BlockData blockData; - private Cuboid cuboid; - } - - private static List elements = new ArrayList<>(); - - static { - elements.add(new BlockDataWithBoundingBox(Material.AIR.createBlockData(), new Cuboid(0, 0, 0, 0, 0, 0))); - elements.add(new BlockDataWithBoundingBox(Material.END_STONE.createBlockData(), new Cuboid(0, 0, 0, 1, 1, 1))); - - BlockData soulSand = Material.SOUL_SAND.createBlockData(); - elements.add(new BlockDataWithBoundingBox(soulSand, new Cuboid(0, 0, 0, 1, 0.9375, 1))); - - BlockData stoneCutter = Material.STONECUTTER.createBlockData(); - elements.add(new BlockDataWithBoundingBox(stoneCutter, new Cuboid(0, 0, 0, 1, 0.5625, 1))); - - Slab bottomSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData(); - bottomSlab.setType(Slab.Type.BOTTOM); - elements.add(new BlockDataWithBoundingBox(bottomSlab, new Cuboid(0, 0, 0, 1, 0.5, 1))); - - Campfire campfire = (Campfire) Material.CAMPFIRE.createBlockData(); - campfire.setSignalFire(false); - campfire.setLit(false); - elements.add(new BlockDataWithBoundingBox(campfire, new Cuboid(0, 0, 0, 1, 0.4375, 1))); - - Slab topSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData(); - topSlab.setType(Slab.Type.TOP); - elements.add(new BlockDataWithBoundingBox(topSlab, new Cuboid(0, 0.5, 0, 1, 0.5, 1))); - - TrapDoor bottomTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - bottomTrapDoor.setHalf(Bisected.Half.BOTTOM); - elements.add(new BlockDataWithBoundingBox(bottomTrapDoor, new Cuboid(0, 0, 0, 1, 0.1875, 1))); - - TrapDoor topTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - topTrapDoor.setHalf(Bisected.Half.TOP); - elements.add(new BlockDataWithBoundingBox(topTrapDoor, new Cuboid(0, 0.8125, 0, 1, 0.1875, 1))); - - Fence endStoneBrickWall = (Fence) Material.END_STONE_BRICK_WALL.createBlockData(); - elements.add(new BlockDataWithBoundingBox(endStoneBrickWall, new Cuboid(0.25, 0, 0.25, 0.5, 1.5, 0.5))); - - Fence fence = (Fence) Material.NETHER_BRICK_FENCE.createBlockData(); - elements.add(new BlockDataWithBoundingBox(fence, new Cuboid(0.375, 0, 0.375, 0.25, 1.5, 0.25))); - - Fence ironBars = (Fence) Material.IRON_BARS.createBlockData(); - elements.add(new BlockDataWithBoundingBox(ironBars, new Cuboid(0.4375, 0, 0.4375, 0.125, 1, 0.125))); - - TrapDoor northTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - northTrapDoor.setFacing(BlockFace.NORTH); - northTrapDoor.setOpen(true); - elements.add(new BlockDataWithBoundingBox(northTrapDoor, new Cuboid(0, 0, 0.8125, 1, 1, 0.1875))); - - TrapDoor southTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - southTrapDoor.setFacing(BlockFace.SOUTH); - southTrapDoor.setOpen(true); - elements.add(new BlockDataWithBoundingBox(southTrapDoor, new Cuboid(0, 0, 0, 1, 1, 0.1875))); - - TrapDoor westTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - westTrapDoor.setFacing(BlockFace.WEST); - westTrapDoor.setOpen(true); - elements.add(new BlockDataWithBoundingBox(westTrapDoor, new Cuboid(0.8125, 0, 0, 0.1875, 1, 1))); - - TrapDoor eastTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData(); - eastTrapDoor.setFacing(BlockFace.EAST); - eastTrapDoor.setOpen(true); - elements.add(new BlockDataWithBoundingBox(eastTrapDoor, new Cuboid(0, 0, 0, 0.1875, 1, 1))); - } - - private Set tntPositions = new HashSet<>(); - private Set cuboidList = new HashSet<>(); - private World world; private Location pos1; private Location pos2; - public Laufbau(Location pos1, Location pos2, Material blockMaterial, Material slabMaterial) { + private boolean preferingBlastResistance; + + private FilteringTracesState filteringTracesState = null; + private ProcessingTracesState processingTracesState = null; + private ExpandingTracesState expandingTracesState = null; + private SplittingPointsState splittingPointsState = null; + private ShrinkingOuterPointsState shrinkingOuterPointsState = null; + private CreatingInnerBlocksState creatingInnerBlocksState = null; + private CreatingOuterBlocksState creatingOuterBlocksState = null; + + public Laufbau(Location pos1, Location pos2, boolean preferingBlastResistance) { this.world = pos1.getWorld(); this.pos1 = new Location(world, Math.min(pos1.getBlockX(), pos2.getBlockX()), Math.min(pos1.getBlockY(), pos2.getBlockY()), Math.min(pos1.getBlockZ(), pos2.getBlockZ())); this.pos2 = new Location(world, Math.max(pos1.getBlockX(), pos2.getBlockX()), Math.max(pos1.getBlockY(), pos2.getBlockY()), Math.max(pos1.getBlockZ(), pos2.getBlockZ())); - StoredRecords.getRecords().forEach(record -> { - record.getTnt().forEach(tntRecord -> { - tntRecord.getPositions().forEach(tntPosition -> { - if (FlatteningWrapper.impl.inWater(world, tntPosition.getLocation())) { - return; - } - if (inRegion(tntPosition.getLocation().toLocation(world), 1)) { - tntPositions.add(tntPosition); - } - if (tntPosition.getPreviousLocation() != null && inRegion(tntPosition.getPreviousLocation().toLocation(world), 1)) { - tntPositions.add(tntPosition); - } - }); - }); - }); + this.preferingBlastResistance = preferingBlastResistance; - for (TNTPosition tntPosition : tntPositions) { - Vector location = tntPosition.getLocation(); - Vector previousLocation = tntPosition.getPreviousLocation(); - - if (previousLocation == null) { - cuboidList.add(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); - } else { - Vector movement = location.clone().subtract(previousLocation); - cuboidList.add(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); - if (Math.abs(movement.getX()) > Math.abs(movement.getZ())) { - cuboidList.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); - cuboidList.add(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); - } else { - cuboidList.add(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); - cuboidList.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); - } - } - } - // System.out.println(cuboidList); - // System.out.println(cuboidList.size()); - - Set blockMap = new HashSet<>(); - cuboidList.forEach(cuboid -> { - for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) { - for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) { - for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) { - Location location = new Location(world, x, y, z); - if (inRegion(new Vector(location.getBlockX(), location.getBlockY(), location.getBlockZ()), 0)) { - blockMap.add(new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - } - } - } - } - }); - - Set blockMap2 = new HashSet<>(); - Set blockMap3 = new HashSet<>(); - for (Point point : blockMap) { - boolean isInCuboid = false; - Cuboid tempCuboid = new Cuboid(0, 0, 0, 1, 1, 1).add(point); - for (Cuboid cuboid : cuboidList) { - if (cuboid.intersects(tempCuboid)) { - isInCuboid = true; - break; - } - } - if (!isInCuboid) { - blockMap2.add(point); - } else { - blockMap3.add(point); - } - } - - blockMap2.removeIf(point -> { - Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ()); - Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ()); - Point p3 = new Point(point.getX(), point.getY() - 1, point.getZ()); - Point p4 = new Point(point.getX(), point.getY() + 1, point.getZ()); - Point p5 = new Point(point.getX(), point.getY(), point.getZ() - 1); - Point p6 = new Point(point.getX(), point.getY(), point.getZ() + 1); - - return !blockMap3.contains(p1) && !blockMap3.contains(p2) && !blockMap3.contains(p3) && !blockMap3.contains(p4) && !blockMap3.contains(p5) && !blockMap3.contains(p6); - }); - - blockMap3.forEach(point -> { - List blockDataWithBoundingBoxList = new ArrayList<>(); - for (BlockDataWithBoundingBox blockDataWithBoundingBox : elements) { - Cuboid tempCuboid = blockDataWithBoundingBox.cuboid.add(point); - // Bukkit.getLogger().info(tempCuboid.toString()); - boolean isInCuboid = false; - for (Cuboid cuboid : cuboidList) { - if (cuboid.intersects(tempCuboid)) { - isInCuboid = true; - } - } - if (!isInCuboid) { - blockDataWithBoundingBoxList.add(blockDataWithBoundingBox); - } - } - if (blockDataWithBoundingBoxList.isEmpty()) { - return; - } - - Cuboid currentHighest = blockDataWithBoundingBoxList.get(0).cuboid; - BlockData highestBlockData = blockDataWithBoundingBoxList.get(0).blockData; - - for (BlockDataWithBoundingBox blockDataWithBoundingBox : blockDataWithBoundingBoxList) { - if (currentHighest.getDx() < blockDataWithBoundingBox.cuboid.getDx() && - currentHighest.getDy() < blockDataWithBoundingBox.cuboid.getDy() && - currentHighest.getDz() < blockDataWithBoundingBox.cuboid.getDz()) { - currentHighest = blockDataWithBoundingBox.cuboid; - highestBlockData = blockDataWithBoundingBox.blockData; - } - if (highestBlockData.getMaterial().getBlastResistance() < blockDataWithBoundingBox.blockData.getMaterial().getBlastResistance() && - (currentHighest.getDx() < blockDataWithBoundingBox.cuboid.getDx() || - currentHighest.getDy() < blockDataWithBoundingBox.cuboid.getDy() || - currentHighest.getDz() < blockDataWithBoundingBox.cuboid.getDz())) { - currentHighest = blockDataWithBoundingBox.cuboid; - highestBlockData = blockDataWithBoundingBox.blockData; - } - } - // blockDataMap.put(point, new BlockDataWithBoundingBox(highestBlockData, currentHighest)); - Location location = new Location(world, point.getX(), point.getY(), point.getZ()); - BlockData finalHighestBlockData = highestBlockData; - Bukkit.getOnlinePlayers().forEach(player -> { - player.sendBlockChange(location, finalHighestBlockData); - }); - }); - - display(blockMap2); + filteringTracesState = new FilteringTracesState(world, this::inRegion); } - private void display(Set blockMap) { - BlockData fullBlock = Material.STONE.createBlockData(); - blockMap.forEach(point -> { - Location location = new Location(world, point.getX(), point.getY(), point.getZ()); - Bukkit.getOnlinePlayers().forEach(player -> { - player.sendBlockChange(location, fullBlock); - }); - }); + private LaufbauState getActive() { + if (creatingOuterBlocksState != null) { + return creatingOuterBlocksState; + } + if (creatingInnerBlocksState != null) { + return creatingInnerBlocksState; + } + if (shrinkingOuterPointsState != null) { + return shrinkingOuterPointsState; + } + if (splittingPointsState != null) { + return splittingPointsState; + } + if (expandingTracesState != null) { + return expandingTracesState; + } + if (processingTracesState != null) { + return processingTracesState; + } + return filteringTracesState; + } + + private void createNextState() { + if (creatingOuterBlocksState != null) { + return; + } + if (creatingInnerBlocksState != null) { + creatingOuterBlocksState = new CreatingOuterBlocksState(shrinkingOuterPointsState.getShrunkOuterPoints(), world); + return; + } + if (shrinkingOuterPointsState != null) { + creatingInnerBlocksState = new CreatingInnerBlocksState(splittingPointsState.getInnerPoints(), world, processingTracesState.getCuboidList(), splittingPointsState.getIntersectedCuboid(), preferingBlastResistance); + return; + } + if (splittingPointsState != null) { + shrinkingOuterPointsState = new ShrinkingOuterPointsState(splittingPointsState.getOuterPoints(), splittingPointsState.getInnerPoints()); + return; + } + if (expandingTracesState != null) { + splittingPointsState = new SplittingPointsState(expandingTracesState.getBlocks(), processingTracesState.getCuboidList()); + return; + } + if (processingTracesState != null) { + expandingTracesState = new ExpandingTracesState(processingTracesState.getCuboidList(), world, this::inRegion); + return; + } + processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions()); + } + + public String actionBarMessage(Player p) { + return getActive().actionBarMessage(p); + } + + public boolean hasNext() { + return getActive().hasNext(); + } + + public void next() { + LaufbauState state = getActive(); + state.next(); + if (!state.hasNext()) { + createNextState(); + } } private boolean inRegion(Location location, int expansion) { @@ -288,60 +136,4 @@ public class Laufbau { } return false; } - - @Data - @AllArgsConstructor - private static class Cuboid { - private double x; - private double y; - private double z; - private double dx; - private double dy; - private double dz; - - private boolean intersects(Cuboid cuboid) { - Cuboid helpCuboid = helpIntersect(cuboid); - Cuboid c1 = helpIntersect(helpCuboid); - Cuboid c2 = cuboid.helpIntersect(c1); - - if (c1.dx == 0 && c2.dx == 0) { - return false; - } - if (c1.dy == 0 && c2.dy == 0) { - return false; - } - if (c1.dz == 0 && c2.dz == 0) { - return false; - } - return c1.equals(c2); - } - - private Cuboid helpIntersect(Cuboid cuboid) { - double minX = Math.max(x, cuboid.x); - double minY = Math.max(y, cuboid.y); - double minZ = Math.max(z, cuboid.z); - double maxX = Math.min(x + dx, cuboid.x + cuboid.dx); - double maxY = Math.min(y + dy, cuboid.y + cuboid.dy); - double maxZ = Math.min(z + dz, cuboid.z + cuboid.dz); - - double nx = round(Math.min(minX, maxX)); - double ny = round(Math.min(minY, maxY)); - double nz = round(Math.min(minZ, maxZ)); - double dx = round(Math.max(minX, maxX) - nx); - double dy = round(Math.max(minY, maxY) - ny); - double dz = round(Math.max(minZ, maxZ) - nz); - return new Cuboid(nx, ny, nz, dx, dy, dz); - } - - private static double round(double value) { - value *= 100000000000000L; - value = Math.round(value); - value /= 100000000000000L; - return value; - } - - public Cuboid add(Point point) { - return new Cuboid(x + point.getX(), y + point.getY(), z + point.getZ(), dx, dy, dz); - } - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java index 9f8f952e..7c438be1 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java @@ -21,8 +21,8 @@ package de.steamwar.bausystem.features.slaves.laufbau; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.features.slaves.WorldEditUtils; -import de.steamwar.bausystem.features.slaves.panzern.Panzern; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import de.steamwar.bausystem.shared.Pair; @@ -32,6 +32,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; import java.util.ArrayList; import java.util.HashSet; @@ -62,7 +63,7 @@ public class LaufbauCommand extends SWCommand { } @Register - public void laufbauSelection(Player player, @Mapper("block") Material blockMaterial, @Mapper("slab") Material slabMaterial) { + public void laufbauSelection(Player player, /*@Mapper("block") Material blockMaterial, @Mapper("slab") Material slabMaterial*/ boolean preferingBlastResistance) { if (!permissionCheck(player, Permission.WORLDEDIT)) { return; } @@ -71,7 +72,27 @@ public class LaufbauCommand extends SWCommand { BauSystem.MESSAGE.send("LAUFBAU_NO_WORLDEDIT", player); return; } - Laufbau laufbau = new Laufbau(selection.getKey(), selection.getValue(), blockMaterial, slabMaterial); + Laufbau laufbau = new Laufbau(selection.getKey(), selection.getValue(), preferingBlastResistance); + new BukkitRunnable() { + @Override + public void run() { + long totalTime = 0; + while (true) { + if (!laufbau.hasNext()) { + BauSystem.MESSAGE.send("LAUFBAU_DONE", player); + cancel(); + return; + } + long time = System.currentTimeMillis(); + laufbau.next(); + totalTime += System.currentTimeMillis() - time; + if (totalTime > 40) { + break; + } + } + SWUtils.sendToActionbar(player, laufbau.actionBarMessage(player)); + } + }.runTaskTimer(BauSystem.getInstance(), 1, 1); } @Mapper(value = "block", local = true) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingInnerBlocksState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingInnerBlocksState.java new file mode 100644 index 00000000..5ef5f6aa --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingInnerBlocksState.java @@ -0,0 +1,120 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox; +import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; +import de.steamwar.bausystem.region.Point; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CreatingInnerBlocksState implements LaufbauState { + + private List innerBlocks; + private int index = 0; + + private World world; + private List cuboidList; + private Map> intersectedCuboid; + private boolean preferingBlastResistance; + + public CreatingInnerBlocksState(List innerBlocks, World world, List cuboidList, Map> intersectedCuboid, boolean preferingBlastResistance) { + this.innerBlocks = innerBlocks; + this.world = world; + this.cuboidList = cuboidList; + this.intersectedCuboid = intersectedCuboid; + this.preferingBlastResistance = preferingBlastResistance; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_CREATING_INNER_BLOCKS", p), index, innerBlocks.size()); + } + + @Override + public boolean hasNext() { + return index < innerBlocks.size(); + } + + @Override + public void next() { + Point point = innerBlocks.get(index); + index++; + + List neededCuboids = intersectedCuboid.get(point); + List blockDataWithBoundingBoxList = new ArrayList<>(); + for (BlockBoundingBox blockDataWithBoundingBox : BlockBoundingBox.elements) { + Cuboid tempCuboid = blockDataWithBoundingBox.cuboid.add(point); + + List extendedCuboids = null; + if (tempCuboid.getDy() > 1) { + extendedCuboids = cuboidList; + } + + boolean isInCuboid = false; + for (Cuboid cuboid : extendedCuboids == null ? neededCuboids : extendedCuboids) { + if (cuboid.intersects(tempCuboid)) { + isInCuboid = true; + break; + } + } + if (!isInCuboid) { + blockDataWithBoundingBoxList.add(blockDataWithBoundingBox); + } + } + if (blockDataWithBoundingBoxList.isEmpty()) { + return; + } + + Cuboid currentHighest = blockDataWithBoundingBoxList.get(0).cuboid; + BlockData highestBlockData = blockDataWithBoundingBoxList.get(0).blockData; + + for (BlockBoundingBox blockDataWithBoundingBox : blockDataWithBoundingBoxList) { + if (currentHighest.getDx() < blockDataWithBoundingBox.cuboid.getDx() && + currentHighest.getDy() < blockDataWithBoundingBox.cuboid.getDy() && + currentHighest.getDz() < blockDataWithBoundingBox.cuboid.getDz()) { + currentHighest = blockDataWithBoundingBox.cuboid; + highestBlockData = blockDataWithBoundingBox.blockData; + } + if (preferingBlastResistance) { + if (highestBlockData.getMaterial().getBlastResistance() < blockDataWithBoundingBox.blockData.getMaterial().getBlastResistance() && + (currentHighest.getDx() >= blockDataWithBoundingBox.cuboid.getDx() || + currentHighest.getDy() >= blockDataWithBoundingBox.cuboid.getDy() || + currentHighest.getDz() >= blockDataWithBoundingBox.cuboid.getDz())) { + currentHighest = blockDataWithBoundingBox.cuboid; + highestBlockData = blockDataWithBoundingBox.blockData; + } + } + } + Location location = new Location(world, point.getX(), point.getY(), point.getZ()); + BlockData finalHighestBlockData = highestBlockData; + Bukkit.getOnlinePlayers().forEach(player -> { + player.sendBlockChange(location, finalHighestBlockData); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingOuterBlocksState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingOuterBlocksState.java new file mode 100644 index 00000000..799a709f --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/CreatingOuterBlocksState.java @@ -0,0 +1,66 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.region.Point; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Player; + +import java.util.List; + +public class CreatingOuterBlocksState implements LaufbauState { + + private List outerBlocks; + private int index = 0; + + private World world; + + public CreatingOuterBlocksState(List outerBlocks, World world) { + this.outerBlocks = outerBlocks; + this.world = world; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_CREATING_OUTER_BLOCKS", p), index, outerBlocks.size()); + } + + @Override + public boolean hasNext() { + return index < outerBlocks.size(); + } + + @Override + public void next() { + Point point = outerBlocks.get(index); + index++; + + BlockData fullBlock = Material.STONE.createBlockData(); + Location location = new Location(world, point.getX(), point.getY(), point.getZ()); + Bukkit.getOnlinePlayers().forEach(player -> { + player.sendBlockChange(location, fullBlock); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ExpandingTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ExpandingTracesState.java new file mode 100644 index 00000000..f8d9e3fd --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ExpandingTracesState.java @@ -0,0 +1,79 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; +import de.steamwar.bausystem.region.Point; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiPredicate; + +public class ExpandingTracesState implements LaufbauState { + + private List cuboidList; + private int totalCuboids; + + private World world; + private BiPredicate inRegionCheck; + + @Getter + private Set blocks = new HashSet<>(); + + public ExpandingTracesState(List cuboidList, World world, BiPredicate inRegionCheck) { + this.cuboidList = new ArrayList<>(cuboidList); + this.totalCuboids = cuboidList.size(); + this.world = world; + this.inRegionCheck = inRegionCheck; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_EXPANDING_TRACES", p), totalCuboids - cuboidList.size(), totalCuboids); + } + + @Override + public boolean hasNext() { + return !cuboidList.isEmpty(); + } + + @Override + public void next() { + Cuboid cuboid = cuboidList.remove(0); + for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) { + for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) { + for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) { + Location location = new Location(world, x, y, z); + if (inRegionCheck.test(new Vector(location.getBlockX(), location.getBlockY(), location.getBlockZ()), 0)) { + blocks.add(new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + } + } + } + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java new file mode 100644 index 00000000..ac4e8de6 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/FilteringTracesState.java @@ -0,0 +1,89 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.features.tracer.show.Record; +import de.steamwar.bausystem.features.tracer.show.StoredRecords; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiPredicate; + +public class FilteringTracesState implements LaufbauState { + + private World world; + private BiPredicate inRegionCheck; + + private int totalRecord; + private List recordList; + private List tntRecords = new ArrayList<>(); + + @Getter + private List tntPositions = new ArrayList<>(); + + public FilteringTracesState(World world, BiPredicate inRegionCheck) { + recordList = new ArrayList<>(StoredRecords.getRecords()); + totalRecord = recordList.size(); + + this.world = world; + this.inRegionCheck = inRegionCheck; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_FILTERING_TRACES", p), totalRecord - recordList.size(), totalRecord); + } + + @Override + public boolean hasNext() { + return !recordList.isEmpty() || !tntRecords.isEmpty(); + } + + @Override + public void next() { + if (tntRecords.isEmpty()) { + Record record = recordList.remove(0); + tntRecords.addAll(record.getTnt()); + } + if (tntRecords.isEmpty()) { + return; + } + + Record.TNTRecord tntRecord = tntRecords.remove(0); + tntRecord.getPositions().forEach(tntPosition -> { + if (FlatteningWrapper.impl.inWater(world, tntPosition.getLocation())) { + return; + } + if (inRegionCheck.test(tntPosition.getLocation().toLocation(world), 1)) { + tntPositions.add(tntPosition); + } + if (tntPosition.getPreviousLocation() != null && inRegionCheck.test(tntPosition.getPreviousLocation().toLocation(world), 1)) { + tntPositions.add(tntPosition); + } + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java new file mode 100644 index 00000000..4d6b6e89 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/LaufbauState.java @@ -0,0 +1,31 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import org.bukkit.entity.Player; + +public interface LaufbauState { + + String actionBarMessage(Player p); + + boolean hasNext(); + + void next(); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java new file mode 100644 index 00000000..5d95f7e9 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ProcessingTracesState.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; +import de.steamwar.bausystem.features.tracer.TNTPosition; +import lombok.Getter; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class ProcessingTracesState implements LaufbauState { + + private int totalTNTPositions; + private List tntPositionList; + + @Getter + private List cuboidList = new ArrayList<>(); + + public ProcessingTracesState(List tntPositionList) { + this.tntPositionList = tntPositionList; + this.totalTNTPositions = tntPositionList.size(); + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalTNTPositions - tntPositionList.size(), totalTNTPositions); + } + + @Override + public boolean hasNext() { + return !tntPositionList.isEmpty(); + } + + @Override + public void next() { + TNTPosition tntPosition = tntPositionList.remove(0); + Vector location = tntPosition.getLocation(); + Vector previousLocation = tntPosition.getPreviousLocation(); + + if (previousLocation == null) { + cuboidList.add(new Cuboid(location.getX() - 0.49, location.getY(), location.getZ() - 0.49, 0.98, 0.98, 0.98)); + } else { + Vector movement = location.clone().subtract(previousLocation); + cuboidList.add(new Cuboid(previousLocation.getX() - 0.49, Math.min(previousLocation.getY(), location.getY()), previousLocation.getZ() - 0.49, 0.98, Math.abs(movement.getY()) + 0.98, 0.98)); + if (Math.abs(movement.getX()) > Math.abs(movement.getZ())) { + cuboidList.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), previousLocation.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + cuboidList.add(new Cuboid(location.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + } else { + cuboidList.add(new Cuboid(previousLocation.getX() - 0.49, location.getY(), Math.min(previousLocation.getZ(), location.getZ()) - 0.49, 0.98, 0.98, Math.abs(movement.getZ()) + 0.98)); + cuboidList.add(new Cuboid(Math.min(previousLocation.getX(), location.getX()) - 0.49, location.getY(), location.getZ() - 0.49, Math.abs(movement.getX()) + 0.98, 0.98, 0.98)); + } + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ShrinkingOuterPointsState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ShrinkingOuterPointsState.java new file mode 100644 index 00000000..dd754e0e --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/ShrinkingOuterPointsState.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.region.Point; +import lombok.Getter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class ShrinkingOuterPointsState implements LaufbauState { + + private List outerPoints; + private List innerPoints; + private int index = 0; + + @Getter + private List shrunkOuterPoints = new ArrayList<>(); + + public ShrinkingOuterPointsState(List outerPoints, List innerPoints) { + this.outerPoints = outerPoints; + this.innerPoints = innerPoints; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_SHRINKING_POINTS", p), index, outerPoints.size()); + } + + @Override + public boolean hasNext() { + return index < outerPoints.size(); + } + + @Override + public void next() { + Point point = outerPoints.get(index); + index++; + + Point p1 = new Point(point.getX() - 1, point.getY(), point.getZ()); + Point p2 = new Point(point.getX() + 1, point.getY(), point.getZ()); + Point p3 = new Point(point.getX(), point.getY() - 1, point.getZ()); + Point p4 = new Point(point.getX(), point.getY() + 1, point.getZ()); + Point p5 = new Point(point.getX(), point.getY(), point.getZ() - 1); + Point p6 = new Point(point.getX(), point.getY(), point.getZ() + 1); + + if (!(!innerPoints.contains(p1) && !innerPoints.contains(p2) && !innerPoints.contains(p3) && !innerPoints.contains(p4) && !innerPoints.contains(p5) && !innerPoints.contains(p6))) { + shrunkOuterPoints.add(point); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/SplittingPointsState.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/SplittingPointsState.java new file mode 100644 index 00000000..199d9135 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/states/SplittingPointsState.java @@ -0,0 +1,80 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.slaves.laufbau.states; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; +import de.steamwar.bausystem.region.Point; +import lombok.Getter; +import org.bukkit.entity.Player; + +import java.util.*; + +public class SplittingPointsState implements LaufbauState { + + private List blocks; + private int totalBlocks; + private List cuboidList; + + @Getter + private List innerPoints = new ArrayList<>(); + + @Getter + private List outerPoints = new ArrayList<>(); + + @Getter + private Map> intersectedCuboid = new HashMap<>(); + + public SplittingPointsState(Set blocks, List cuboidList) { + this.blocks = new ArrayList<>(blocks); + this.totalBlocks = blocks.size(); + this.cuboidList = cuboidList; + } + + @Override + public String actionBarMessage(Player p) { + return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_SPLITTING_POINTS", p), totalBlocks - blocks.size(), totalBlocks); + } + + @Override + public boolean hasNext() { + return !blocks.isEmpty(); + } + + @Override + public void next() { + Point point = blocks.remove(0); + boolean isInCuboid = false; + Cuboid tempCuboid = new Cuboid(0, 0, 0, 1, 1, 1).add(point); + List intersectedCuboids = new ArrayList<>(); + for (Cuboid cuboid : cuboidList) { + if (cuboid.intersects(tempCuboid)) { + isInCuboid = true; + intersectedCuboids.add(cuboid); + } + } + if (!isInCuboid) { + outerPoints.add(point); + } else { + innerPoints.add(point); + intersectedCuboid.put(point, intersectedCuboids); + } + } +}