From f07343da5bdf7e37d8c0f7493c04aa24ab602411 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Mon, 4 Oct 2021 21:52:06 +0200 Subject: [PATCH] Add Panzern Add PanzernCommand Signed-off-by: yoyosource --- BauSystem_Main/src/BauSystem.properties | 8 +- .../bausystem/features/panzern/Panzern.java | 166 ++++++++++++++++++ .../features/panzern/PanzernCommand.java | 105 +++++++++++ 3 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/panzern/Panzern.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/panzern/PanzernCommand.java diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 5d1b2f0c..3f2e08af 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -517,4 +517,10 @@ LOCK_SCHEM_LOCKED=§e{0} §7von §e{1} §7wurde von §e{2} §7auf §eNORMAL §7z LOCK_SCHEM_HELP=§8/§eschemlock §8[§7Owner§8] [§7Schematic§8] [§7Grund§8] - §7Sperre eine Schematic AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert. -AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt \ No newline at end of file +AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt + +# Panzern +PANZERN_HELP = §8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Panzer deine WorldEdit Auswahl +PANZERN_NO_PERM = §cDu darfst hier nicht das Panzern System verwenden +PANZERN_PROGRESS = §e{0} §7Blöcke übrig +PANZERN_DONE = §aZuende gepanzert \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/Panzern.java b/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/Panzern.java new file mode 100644 index 00000000..655aa640 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/Panzern.java @@ -0,0 +1,166 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.panzern; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.type.Stairs; + +import java.util.HashSet; +import java.util.Set; + +public class Panzern { + + private static final BlockFace[] BLOCK_FACES = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN}; + + private Set current = new HashSet<>(); + private Set emptyBlocks = new HashSet<>(); + + private World world; + private Location pos1; + private Location pos2; + private Material blockMaterial; + private Material slabMaterial; + + public Panzern(Location pos1, Location pos2, Material blockMaterial, Material slabMaterial) { + 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())); + current.add(this.pos1); + current.add(this.pos2); + this.blockMaterial = blockMaterial; + this.slabMaterial = slabMaterial; + } + + public boolean hasNext() { + return !current.isEmpty(); + } + + public void next() { + Location toCheck = current.iterator().next(); + current.remove(toCheck); + + Set adjacent = new HashSet<>(); + boolean hasRedstone = false; + boolean belowRedstone = false; + boolean belowCarpet = false; + boolean adjacentPiston = false; + boolean adjacentSlime = false; + for (BlockFace blockFace : BLOCK_FACES) { + Location now = toCheck.clone().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ()); + if (inRegion(now)) { + adjacent.add(now); + } + Block block = world.getBlockAt(now); + if (block.getType() == Material.SLIME_BLOCK || block.getType() == Material.HONEY_BLOCK) { + adjacentSlime = true; + } + if (block.getType() == Material.PISTON || block.getType() == Material.STICKY_PISTON) { + Directional directional = (Directional) block.getBlockData(); + if (directional.getFacing() == blockFace.getOppositeFace()) { + adjacentPiston = true; + } + } + if (blockFace != BlockFace.UP && blockFace != BlockFace.DOWN) { + hasRedstone |= block.getType() == Material.REDSTONE_WIRE; + } + if (blockFace == BlockFace.DOWN) { + belowRedstone |= block.getType() == Material.REDSTONE_WIRE; + belowCarpet |= block.getType().name().contains("CARPET"); + } + if (blockFace == BlockFace.DOWN && stairCheck(now)) { + belowCarpet = true; + } + now = toCheck.clone().add(blockFace.getModX() * 2, blockFace.getModY() * 2, blockFace.getModZ() * 2); + Block blockOuter = world.getBlockAt(now); + if (blockFace == BlockFace.DOWN && stairCheck(now)) { + belowCarpet = true; + } + if (blockFace != BlockFace.DOWN && blockFace != BlockFace.UP) { + now = toCheck.clone().add(blockFace.getModX(), -2, blockFace.getModZ()); + Block blockOuterOther = world.getBlockAt(now); + if (stairCheck(now)) { + Stairs stairs = (Stairs) blockOuterOther.getBlockData(); + if (stairs.getFacing() == blockFace) { + belowCarpet = true; + } + } + } + if (block.getType().isAir()) { + continue; + } + if (blockOuter.getType() == Material.PISTON || blockOuter.getType() == Material.STICKY_PISTON) { + Directional directional = (Directional) blockOuter.getBlockData(); + if (directional.getFacing() == blockFace.getOppositeFace()) { + adjacentPiston = true; + } + } + + } + current.addAll(adjacent); + + if (belowCarpet || adjacentPiston) { + emptyBlocks.add(toCheck); + return; + } + if (adjacentSlime) { + world.getBlockAt(toCheck).setType(Material.JUKEBOX); + } else if (belowRedstone && hasRedstone) { + world.getBlockAt(toCheck).setType(slabMaterial); + } else { + world.getBlockAt(toCheck).setType(blockMaterial); + } + } + + private boolean stairCheck(Location location) { + Block block = world.getBlockAt(location); + if (block.getBlockData() instanceof Stairs) { + Stairs stairs = (Stairs) block.getBlockData(); + return stairs.getHalf() == Bisected.Half.BOTTOM; + } + return false; + } + + private boolean inRegion(Location location) { + if (location.getBlockX() >= pos1.getBlockX()) { + if (location.getBlockY() >= pos1.getBlockY()) { + if (location.getBlockZ() >= pos1.getBlockZ()) { + if (location.getBlockX() <= pos2.getBlockX()) { + if (location.getBlockY() <= pos2.getBlockY()) { + if (location.getBlockZ() <= pos2.getBlockZ()) { + return world.getBlockAt(location).getType().isAir() && !emptyBlocks.contains(location); + } + } + } + } + } + } + return false; + } + + public int blocksLeft() { + return current.size(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/PanzernCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/PanzernCommand.java new file mode 100644 index 00000000..96b008ba --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/panzern/PanzernCommand.java @@ -0,0 +1,105 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.panzern; + +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.RegionSelector; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.shared.Pair; +import de.steamwar.command.SWCommand; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@Linked(LinkageType.COMMAND) +public class PanzernCommand extends SWCommand { + + public PanzernCommand() { + super("panzern", "panzersklave"); + } + + private boolean permissionCheck(Player player, Permission permission) { + if (Permission.hasPermission(player, permission)) { + return true; + } + BauSystem.MESSAGE.send("PANZERN_NO_PERM", player); + return false; + } + + @Register + public void genericHelp(Player player, String... args) { + BauSystem.MESSAGE.send("COMMAND_HELP_HEAD", player, "panzern"); + BauSystem.MESSAGE.send("PANZERN_HELP", player); + } + + @Register + public void panzerSelection(Player player, Material blockMaterial, Material slabMaterial) { + if (!permissionCheck(player, Permission.WORLDEDIT)) { + return; + } + Pair selection = getSelection(player); + if (selection == null) { + return; + } + Panzern panzern = new Panzern(selection.getKey(), selection.getValue(), blockMaterial, slabMaterial); + new BukkitRunnable() { + @Override + public void run() { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("PANZERN_PROGRESS", player, panzern.blocksLeft())); + for (int i = 0; i < 1000; i++) { + if (!panzern.hasNext()) { + BauSystem.MESSAGE.send("PANZERN_DONE", player); + cancel(); + return; + } + panzern.next(); + } + } + }.runTaskTimer(BauSystem.getInstance(), 1, 1); + } + + private Pair getSelection(Player player) { + RegionSelector regionSelector = WorldEdit.getInstance() + .getSessionManager() + .get(BukkitAdapter.adapt(player)) + .getRegionSelector(BukkitAdapter.adapt(player.getWorld())); + + try { + BlockVector3 min = regionSelector.getRegion().getMinimumPoint(); + BlockVector3 max = regionSelector.getRegion().getMaximumPoint(); + return new Pair<>(adapt(player.getWorld(), min), adapt(player.getWorld(), max)); + } catch (IncompleteRegionException e) { + return null; + } + } + + private Location adapt(World world, BlockVector3 blockVector3) { + return new Location(world, blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ()); + } +}