Add lazycut

This commit is contained in:
Jesse Boyd 2016-12-23 16:25:42 +11:00
parent 5fe9aff4e4
commit 50ac6c86a0
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
4 changed files with 192 additions and 109 deletions

View File

@ -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<? extends Entity> getEntities() {
return editSession.getEntities(getRegion());
}
@Override
public void forEach(RunnableVal2<Vector, BaseBlock> 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<String, Tag> 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<String, Tag> 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<String, Tag> 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() {

View File

@ -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<? extends Entity> getEntities() {
return editSession.getEntities(getRegion());
}
@Override
public void forEach(RunnableVal2<Vector, BaseBlock> 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<String, Tag> 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<String, Tag> 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<String, Tag> 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);
}
}
}
}
}
}
}

View File

@ -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<Vector, BaseBlock> task, boolean air) {
super.forEach(task, air);
editSession.flushQueue();
}
}

View File

@ -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",