From 50ac6c86a023f266cfde858a2cdc9e6aeb574ead Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Fri, 23 Dec 2016 16:25:42 +1100 Subject: [PATCH] Add lazycut --- .../object/clipboard/ReadOnlyClipboard.java | 111 +-------------- .../object/clipboard/WorldCopyClipboard.java | 127 ++++++++++++++++++ .../object/clipboard/WorldCutClipboard.java | 35 +++++ .../worldedit/command/ClipboardCommands.java | 28 ++++ 4 files changed, 192 insertions(+), 109 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/object/clipboard/WorldCopyClipboard.java create mode 100644 core/src/main/java/com/boydti/fawe/object/clipboard/WorldCutClipboard.java diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java index c02b2053..31c4d16f 100644 --- a/core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java @@ -1,131 +1,24 @@ package com.boydti.fawe.object.clipboard; -import com.boydti.fawe.object.RunnableVal2; -import com.boydti.fawe.util.ReflectionUtils; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import java.util.List; -import java.util.Map; public abstract class ReadOnlyClipboard extends FaweClipboard { - private final Region region; + public final Region region; public ReadOnlyClipboard(Region region) { this.region = region; } public static ReadOnlyClipboard of(final EditSession editSession, final Region region) { - final Vector origin = region.getMinimumPoint(); - final int mx = origin.getBlockX(); - final int my = origin.getBlockY(); - final int mz = origin.getBlockZ(); - return new ReadOnlyClipboard(region) { - @Override - public BaseBlock getBlock(int x, int y, int z) { - return editSession.getLazyBlock(mx + x, my + y, mz + z); - } - - public BaseBlock getBlockAbs(int x, int y, int z) { - return editSession.getLazyBlock(x, y, z); - } - - @Override - public List getEntities() { - return editSession.getEntities(getRegion()); - } - - @Override - public void forEach(RunnableVal2 task, boolean air) { - Vector min = region.getMinimumPoint(); - Vector max = region.getMaximumPoint(); - Vector pos = new Vector(); - if (region instanceof CuboidRegion) { - if (air) { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - BaseBlock block = getBlockAbs(x, y, z); - pos.x = x - mx; - pos.y = y - my; - pos.z = z - mz; - CompoundTag tag = block.getNbtData(); - if (tag != null) { - Map values = ReflectionUtils.getMap(tag.getValue()); - values.put("x", new IntTag((int) pos.x)); - values.put("y", new IntTag((int) pos.y)); - values.put("z", new IntTag((int) pos.z)); - } - task.run(pos, block); - } - } - } - } else { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - BaseBlock block = getBlockAbs(x, y, z); - if (block == EditSession.nullBlock) { - continue; - } - pos.x = x - mx; - pos.y = y - my; - pos.z = z - mz; - CompoundTag tag = block.getNbtData(); - if (tag != null) { - Map values = ReflectionUtils.getMap(tag.getValue()); - values.put("x", new IntTag((int) pos.x)); - values.put("y", new IntTag((int) pos.y)); - values.put("z", new IntTag((int) pos.z)); - } - task.run(pos, block); - } - } - } - } - } else { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - pos.x = x; - pos.y = y; - pos.z = z; - if (region.contains(pos)) { - BaseBlock block = getBlockAbs(x, y, z); - if (!air && block == EditSession.nullBlock) { - continue; - } - pos.x -= mx; - pos.y -= my; - pos.z -= mz; - CompoundTag tag = block.getNbtData(); - if (tag != null) { - Map values = ReflectionUtils.getMap(tag.getValue()); - values.put("x", new IntTag((int) pos.x)); - values.put("y", new IntTag((int) pos.y)); - values.put("z", new IntTag((int) pos.z)); - } - task.run(pos, block); - } else if (air) { - pos.x -= mx; - pos.y -= my; - pos.z -= mz; - task.run(pos, EditSession.nullBlock); - } - } - } - } - } - } - }; + return new WorldCopyClipboard(editSession, region); } public Region getRegion() { diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCopyClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCopyClipboard.java new file mode 100644 index 00000000..a7a04f64 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCopyClipboard.java @@ -0,0 +1,127 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.object.RunnableVal2; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import java.util.List; +import java.util.Map; + +public class WorldCopyClipboard extends ReadOnlyClipboard { + + public final int mx,my,mz; + public final EditSession editSession; + + public WorldCopyClipboard(EditSession editSession, Region region) { + super(region); + final Vector origin = region.getMinimumPoint(); + this.mx = origin.getBlockX(); + this.my = origin.getBlockY(); + this.mz = origin.getBlockZ(); + this.editSession = editSession; + } + + @Override + public BaseBlock getBlock(int x, int y, int z) { + return editSession.getLazyBlock(mx + x, my + y, mz + z); + } + + public BaseBlock getBlockAbs(int x, int y, int z) { + return editSession.getLazyBlock(x, y, z); + } + + @Override + public List getEntities() { + return editSession.getEntities(getRegion()); + } + + @Override + public void forEach(RunnableVal2 task, boolean air) { + Vector min = region.getMinimumPoint(); + Vector max = region.getMaximumPoint(); + Vector pos = new Vector(); + if (region instanceof CuboidRegion) { + if (air) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + BaseBlock block = getBlockAbs(x, y, z); + pos.x = x - mx; + pos.y = y - my; + pos.z = z - mz; + CompoundTag tag = block.getNbtData(); + if (tag != null) { + Map values = ReflectionUtils.getMap(tag.getValue()); + values.put("x", new IntTag((int) pos.x)); + values.put("y", new IntTag((int) pos.y)); + values.put("z", new IntTag((int) pos.z)); + } + task.run(pos, block); + } + } + } + } else { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + BaseBlock block = getBlockAbs(x, y, z); + if (block == EditSession.nullBlock) { + continue; + } + pos.x = x - mx; + pos.y = y - my; + pos.z = z - mz; + CompoundTag tag = block.getNbtData(); + if (tag != null) { + Map values = ReflectionUtils.getMap(tag.getValue()); + values.put("x", new IntTag((int) pos.x)); + values.put("y", new IntTag((int) pos.y)); + values.put("z", new IntTag((int) pos.z)); + } + task.run(pos, block); + } + } + } + } + } else { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + pos.x = x; + pos.y = y; + pos.z = z; + if (region.contains(pos)) { + BaseBlock block = getBlockAbs(x, y, z); + if (!air && block == EditSession.nullBlock) { + continue; + } + pos.x -= mx; + pos.y -= my; + pos.z -= mz; + CompoundTag tag = block.getNbtData(); + if (tag != null) { + Map values = ReflectionUtils.getMap(tag.getValue()); + values.put("x", new IntTag((int) pos.x)); + values.put("y", new IntTag((int) pos.y)); + values.put("z", new IntTag((int) pos.z)); + } + task.run(pos, block); + } else if (air) { + pos.x -= mx; + pos.y -= my; + pos.z -= mz; + task.run(pos, EditSession.nullBlock); + } + } + } + } + } + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCutClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCutClipboard.java new file mode 100644 index 00000000..1992c256 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/WorldCutClipboard.java @@ -0,0 +1,35 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.object.RunnableVal2; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.regions.Region; + +public class WorldCutClipboard extends WorldCopyClipboard { + public WorldCutClipboard(EditSession editSession, Region region) { + super(editSession, region); + } + + @Override + public BaseBlock getBlock(int x, int y, int z) { + int xx = mx + x; + int yy = my + y; + int zz = mz + z; + BaseBlock block = editSession.getLazyBlock(xx, yy, zz); + editSession.setBlock(xx, yy, zz, EditSession.nullBlock); + return block; + } + + public BaseBlock getBlockAbs(int x, int y, int z) { + BaseBlock block = editSession.getLazyBlock(x, y, z); + editSession.setBlock(x, y, z, EditSession.nullBlock); + return block; + } + + @Override + public void forEach(RunnableVal2 task, boolean air) { + super.forEach(task, air); + editSession.flushQueue(); + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index e5a37fa1..9ced3e85 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -23,6 +23,7 @@ import com.boydti.fawe.FaweAPI; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; +import com.boydti.fawe.object.clipboard.WorldCutClipboard; import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.util.ImgurUtility; import com.boydti.fawe.util.MaskTraverser; @@ -157,6 +158,33 @@ public class ClipboardCommands { BBC.COMMAND_COPY.send(player, region.getArea()); } + @Command( + aliases = { "/lazycut" }, + flags = "em", + desc = "Lazily cut the selection to the clipboard", + help = "Lazily cut the selection to the clipboard\n" + + "Flags:\n" + + " -e controls whether entities are cut\n" + + " -m sets a source mask so that excluded blocks become air\n" + + "WARNING: Pasting entities cannot yet be undone!", + max = 0 + ) + @CommandPermissions("worldedit.clipboard.lazycopy") + public void lazyCut(Player player, LocalSession session, EditSession editSession, + @Selection final Region region, @Switch('e') boolean copyEntities, + @Switch('m') Mask mask) throws WorldEditException { + + final Vector origin = region.getMinimumPoint(); + final int mx = origin.getBlockX(); + final int my = origin.getBlockY(); + final int mz = origin.getBlockZ(); + ReadOnlyClipboard lazyClipboard = new WorldCutClipboard(editSession, region); + BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard); + clipboard.setOrigin(session.getPlacementPosition(player)); + session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData())); + BBC.COMMAND_CUT.send(player, region.getArea()); + } + @Command( aliases = { "/cut" }, flags = "em",