From d8684f1fc7044c40ca7b33ed71e895c0205abd6f Mon Sep 17 00:00:00 2001 From: youhavetrouble Date: Sat, 15 Apr 2023 23:00:41 +0200 Subject: [PATCH] working copy and paste functionalities --- .../me/youhavetrouble/blockedit/BEPlayer.java | 3 +- .../youhavetrouble/blockedit/BlockEdit.java | 2 + .../blockedit/commands/PasteCommand.java | 46 +++++++++++++++++++ .../blockedit/operations/PasteOperation.java | 17 +++++++ .../blockedit/util/Clipboard.java | 4 +- .../blockedit/util/Selection.java | 21 +++++++++ 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/youhavetrouble/blockedit/commands/PasteCommand.java create mode 100644 src/main/java/me/youhavetrouble/blockedit/operations/PasteOperation.java diff --git a/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java b/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java index aeb0ff7..9f6c233 100644 --- a/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java +++ b/src/main/java/me/youhavetrouble/blockedit/BEPlayer.java @@ -39,7 +39,8 @@ public class BEPlayer { public void setClipboardFromSelection() { if (selection == null) throw new IllegalStateException("Selection is null"); // add every block between selection points to clipboard - clipboard.setBaseLocation(getPlayer().getLocation()); + clipboard.clear(); + clipboard.setBaseLocation(getPlayer().getLocation().toBlockLocation()); for (int x = (int) selection.getMinX(); x <= selection.getMaxX(); x++) { for (int y = (int) selection.getMinY(); y <= selection.getMaxY(); y++) { for (int z = (int) selection.getMinZ(); z <= selection.getMaxZ(); z++) { diff --git a/src/main/java/me/youhavetrouble/blockedit/BlockEdit.java b/src/main/java/me/youhavetrouble/blockedit/BlockEdit.java index 8aa60bb..e95c42c 100644 --- a/src/main/java/me/youhavetrouble/blockedit/BlockEdit.java +++ b/src/main/java/me/youhavetrouble/blockedit/BlockEdit.java @@ -28,6 +28,8 @@ public final class BlockEdit extends JavaPlugin { registerCommand(new DeselCommand()); registerCommand(new Pos1Command()); registerCommand(new Pos2Command()); + registerCommand(new CopyCommand()); + registerCommand(new PasteCommand()); } diff --git a/src/main/java/me/youhavetrouble/blockedit/commands/PasteCommand.java b/src/main/java/me/youhavetrouble/blockedit/commands/PasteCommand.java new file mode 100644 index 0000000..dc15fb1 --- /dev/null +++ b/src/main/java/me/youhavetrouble/blockedit/commands/PasteCommand.java @@ -0,0 +1,46 @@ +package me.youhavetrouble.blockedit.commands; + +import me.youhavetrouble.blockedit.BEPlayer; +import me.youhavetrouble.blockedit.api.BlockEditAPI; +import me.youhavetrouble.blockedit.operations.PasteOperation; +import me.youhavetrouble.blockedit.util.Selection; +import net.kyori.adventure.text.Component; +import org.bukkit.block.BlockState; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; + +public class PasteCommand extends Command { + + public PasteCommand() { + super("paste"); + setPermission("blockedit.command.paste"); + } + + @Override + public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args) { + + if (!(sender instanceof Player player)) { + sender.sendMessage(Component.text("You need to be a player to do this")); + return true; + } + BEPlayer bePlayer = BEPlayer.getByPlayer(player); + Vector playerLocationVector = player.getLocation().toBlockLocation().toVector(); + + HashMap absoluteBlocks = new HashMap<>(bePlayer.getClipboard().getBlocks().size()); + + bePlayer.getClipboard().getBlocks().forEach((vector, blockState) -> { + Vector absolutePosition = vector.clone().add(playerLocationVector); + absoluteBlocks.put(absolutePosition, blockState); + }); + + Selection selection = Selection.fromClipboard(absoluteBlocks.keySet(), player.getWorld()); + BlockEditAPI.runOperation(selection, 1, new PasteOperation(absoluteBlocks)); + + return false; + } +} diff --git a/src/main/java/me/youhavetrouble/blockedit/operations/PasteOperation.java b/src/main/java/me/youhavetrouble/blockedit/operations/PasteOperation.java new file mode 100644 index 0000000..53a608c --- /dev/null +++ b/src/main/java/me/youhavetrouble/blockedit/operations/PasteOperation.java @@ -0,0 +1,17 @@ +package me.youhavetrouble.blockedit.operations; + +import me.youhavetrouble.blockedit.api.BlockEditOperation; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.util.Vector; + +import java.util.Map; + +public record PasteOperation(Map blockStateMap) implements BlockEditOperation { + + @Override + public void transformBlock(Block block) { + if (!blockStateMap.containsKey(block.getLocation().toVector())) return; + block.setBlockData(blockStateMap.get(block.getLocation().toVector()).getBlockData()); + } +} diff --git a/src/main/java/me/youhavetrouble/blockedit/util/Clipboard.java b/src/main/java/me/youhavetrouble/blockedit/util/Clipboard.java index 2c3d26f..f74e717 100644 --- a/src/main/java/me/youhavetrouble/blockedit/util/Clipboard.java +++ b/src/main/java/me/youhavetrouble/blockedit/util/Clipboard.java @@ -30,7 +30,7 @@ public class Clipboard { } public void setBaseLocation(Location baseLocation) { - this.baseLocation = baseLocation; + this.baseLocation = baseLocation.toBlockLocation(); this.baseLocationVector = baseLocation.toVector(); } @@ -54,7 +54,7 @@ public class Clipboard { * Rotates clipboard by specified degrees around the base location. * @param angle angle in degrees */ - public void rotate(int angle) { + public void rotate(double angle) { for (Map.Entry entry : this.blocks.entrySet()) { Vector relativeLocation = entry.getKey(); relativeLocation.rotateAroundAxis(baseLocationVector, angle); diff --git a/src/main/java/me/youhavetrouble/blockedit/util/Selection.java b/src/main/java/me/youhavetrouble/blockedit/util/Selection.java index d534fcc..a27bd07 100644 --- a/src/main/java/me/youhavetrouble/blockedit/util/Selection.java +++ b/src/main/java/me/youhavetrouble/blockedit/util/Selection.java @@ -4,7 +4,9 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; +import java.util.Set; import java.util.UUID; public class Selection extends BoundingBox { @@ -43,4 +45,23 @@ public class Selection extends BoundingBox { public void setWorldUuid(UUID worldUuid) { this.worldUuid = worldUuid; } + + public static Selection fromClipboard(Set locations, World world) { + Vector closestVector = new Vector(Double.MAX_VALUE,Double.MAX_VALUE,Double.MAX_VALUE); + Vector farthestVector = new Vector(Double.MIN_VALUE,Double.MIN_VALUE,Double.MIN_VALUE); + + for (Vector vector : locations) { + if (vector.getX() + vector.getY() + vector.getZ() < closestVector.getX() + closestVector.getY() + closestVector.getZ()) { + closestVector = vector; + } + if (vector.getX() + vector.getY() + vector.getZ() > farthestVector.getX() + farthestVector.getY() + farthestVector.getZ()) { + farthestVector = vector; + } + } + + Location minLocation = closestVector.toLocation(world); + Location maxLocation = farthestVector.toLocation(world); + + return new Selection(minLocation, maxLocation, world.getUID()); + } }