Start work on biome copy (will finish later)

This commit is contained in:
Jesse Boyd 2017-07-30 23:38:55 +10:00
parent 249f175672
commit 36fc147cc2
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
16 changed files with 319 additions and 46 deletions

View File

@ -202,6 +202,15 @@ public class CorruptSchematicStreamer {
}
}
});
match("Blocks", new CorruptSchematicStreamer.CorruptReader() {
@Override
public void run(DataInputStream in) throws IOException {
int length = in.readInt();
for (int i = 0; i < length; i++) {
fc.setBiome(i, in.read());
}
}
});
Vector dimensions = guessDimensions(volume.get(), width.get(), height.get(), length.get());
Vector min = new Vector(originX.get(), originY.get(), originZ.get());
Vector offset = new Vector(offsetX.get(), offsetY.get(), offsetZ.get());

View File

@ -60,6 +60,14 @@ public class SchematicStreamer extends NBTStreamer {
}
}
});
ByteReader biomeReader = new ByteReader() {
@Override
public void run(int index, int value) {
fc.setBiome(index, value);
}
};
addReader("Schematic.AWEBiomes.#", biomeReader); // AWE stores as an int[]
addReader("Schematic.Biomes.#", biomeReader); // FAWE stores as a byte[] (4x smaller)
// Tiles
addReader("Schematic.TileEntities.#", new RunnableVal2<Integer, CompoundTag>() {

View File

@ -285,15 +285,13 @@ public abstract class FaweChangeSet implements ChangeSet {
continue;
}
int startY = layer << 4;
int index = 0;
for (int y = 0; y < 16; y++) {
short[][] i1 = FaweCache.CACHE_J[y];
int yy = y + startY;
for (int z = 0; z < 16; z++) {
int zz = z + bz;
short[] i2 = i1[z];
for (int x = 0; x < 16; x++) {
for (int x = 0; x < 16; x++, index++) {
int xx = x + bx;
int index = i2[x];
int combinedIdCurrent = currentLayer[index];
switch (combinedIdCurrent) {
case 0:
@ -314,26 +312,34 @@ public abstract class FaweChangeSet implements ChangeSet {
{
// Tiles created
Map<Short, CompoundTag> tiles = next.getTiles();
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
addTileCreate(entry.getValue());
if (!tiles.isEmpty()) {
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
addTileCreate(entry.getValue());
}
}
// Tiles removed
tiles = previous.getTiles();
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
addTileRemove(entry.getValue());
if (!tiles.isEmpty()) {
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
addTileRemove(entry.getValue());
}
}
}
// Entity changes
{
// Entities created
Set<CompoundTag> entities = next.getEntities();
for (CompoundTag entityTag : entities) {
addEntityCreate(entityTag);
if (!entities.isEmpty()) {
for (CompoundTag entityTag : entities) {
addEntityCreate(entityTag);
}
}
// Entities removed
entities = previous.getEntities();
for (CompoundTag entityTag : entities) {
addEntityRemove(entityTag);
if (!entities.isEmpty()) {
for (CompoundTag entityTag : entities) {
addEntityRemove(entityTag);
}
}
}
}

View File

@ -7,6 +7,7 @@ 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.world.biome.BaseBiome;
import java.util.List;
public class AbstractDelegateFaweClipboard extends FaweClipboard {
@ -26,6 +27,26 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
return parent.setBlock(x, y, z, block);
}
@Override
public boolean hasBiomes() {
return parent.hasBiomes();
}
@Override
public boolean setBiome(int x, int z, byte biome) {
return parent.setBiome(x, z, biome);
}
@Override
public BaseBiome getBiome(int x, int z) {
return parent.getBiome(x, z);
}
@Override
public BaseBiome getBiome(int index) {
return parent.getBiome(index);
}
@Override
public void setId(int index, int id) {
parent.setId(index, id);
@ -41,6 +62,11 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
return parent.getBlock(index);
}
@Override
public void setBiome(int index, int biome) {
parent.setBiome(index, biome);
}
@Override
public void setAdd(int index, int id) {
parent.setAdd(index, id);
@ -96,6 +122,11 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
parent.forEach(task, air);
}
@Override
public void streamBiomes(NBTStreamer.ByteReader task) {
parent.streamBiomes(task);
}
@Override
public void streamIds(NBTStreamer.ByteReader task) {
parent.streamIds(task);

View File

@ -18,6 +18,7 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
@ -48,6 +49,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
protected int height;
protected int width;
protected int area;
protected int volume;
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
private final HashSet<ClipboardEntity> entities;
@ -58,6 +60,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private int last;
private FileChannel fc;
private boolean hasBiomes;
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
this(width, height, length, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd"));
@ -71,14 +74,18 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
this.braf = new RandomAccessFile(file, "rw");
braf.setLength(file.length());
init();
long size = (braf.length() - HEADER_SIZE) >> 1;
mbb.position(2);
last = Integer.MIN_VALUE;
width = (int) mbb.getChar();
height = (int) mbb.getChar();
length = (int) mbb.getChar();
area = width * length;
this.volume = length * width * height;
long size = (braf.length() - HEADER_SIZE) >> 1;
if (size == ((long) width * height * length) + area) {
hasBiomes = true;
}
autoCloseTask();
} catch (IOException e) {
throw new RuntimeException(e);
@ -92,6 +99,69 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
}
}
private boolean initBiome() {
if (!hasBiomes) {
try {
hasBiomes = true;
if (mbb != null) {
this.mbb.force();
this.fc.close();
closeDirectBuffer(mbb);
long volume = (long) length * height * width;
this.braf.setLength(HEADER_SIZE + volume + area);
this.fc = braf.getChannel();
this.mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
}
} catch (IOException e) {
return false;
}
}
return true;
}
@Override
public boolean hasBiomes() {
return hasBiomes;
}
@Override
public boolean setBiome(int x, int z, byte biome) {
setBiome(getIndex(x, 0, z), biome);
return true;
}
@Override
public void setBiome(int index, int biome) {
if (initBiome()) {
mbb.put(HEADER_SIZE + volume + index, (byte) biome);
}
}
@Override
public BaseBiome getBiome(int index) {
if (!hasBiomes()) {
return EditSession.nullBiome;
}
int biomeId = mbb.get(HEADER_SIZE + volume + index) & 0xFF;
return FaweCache.CACHE_BIOME[biomeId];
}
@Override
public void streamBiomes(NBTStreamer.ByteReader task) {
if (!hasBiomes()) return;
int index = 0;
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, index++) {
task.run(index, getBiome(index).getId());
}
}
}
@Override
public BaseBiome getBiome(int x, int z) {
return getBiome(getIndex(x, 0, z));
}
@Override
public Vector getDimensions() {
return new Vector(width, height, length);
@ -128,6 +198,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
this.height = height;
this.length = length;
this.area = width * length;
this.volume = width * length * height;
try {
if (!file.exists()) {
File parent = file.getParentFile();
@ -177,7 +248,8 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
height = dimensions.getBlockY();
length = dimensions.getBlockZ();
area = width * length;
long size = width * height * length * 2l + HEADER_SIZE;
volume = width * length * height;
long size = width * height * length * 2l + HEADER_SIZE + (hasBiomes() ? area : 0);
braf.setLength(size);
init();
mbb.position(2);
@ -216,17 +288,24 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
cb = null;
}
@Override
protected void finalize() throws Throwable {
close();
}
@Override
public void close() {
try {
mbb.force();
fc.close();
braf.close();
file.setWritable(true);
closeDirectBuffer(mbb);
mbb = null;
fc = null;
braf = null;
if (mbb != null) {
mbb.force();
fc.close();
braf.close();
file.setWritable(true);
closeDirectBuffer(mbb);
mbb = null;
fc = null;
braf = null;
}
} catch (IOException e) {
MainUtil.handleError(e);
}

View File

@ -11,6 +11,7 @@ import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -24,8 +25,18 @@ public abstract class FaweClipboard {
public abstract boolean setBlock(int x, int y, int z, BaseBlock block);
public abstract boolean hasBiomes();
public abstract boolean setBiome(int x, int z, byte biome);
public abstract BaseBiome getBiome(int x, int z);
public abstract BaseBiome getBiome(int index);
public abstract BaseBlock getBlock(int index);
public abstract void setBiome(int index, int biome);
public abstract void setId(int index, int id);
public abstract void setData(int index, int data);
@ -59,6 +70,8 @@ public abstract class FaweClipboard {
public abstract void run(int x, int y, int z, BaseBlock block);
}
public abstract void streamBiomes(final NBTStreamer.ByteReader task);
public void streamIds(final NBTStreamer.ByteReader task) {
forEach(new BlockReader() {
private int index = 0;

View File

@ -9,11 +9,13 @@ 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.world.biome.BaseBiome;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -37,6 +39,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
private byte[][] add;
private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)];
private byte[] biomes = null;
private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex;
@ -86,6 +89,49 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
nbtMapLoc.clear();
}
@Override
public boolean hasBiomes() {
return biomes != null;
}
@Override
public boolean setBiome(int x, int z, byte biome) {
setBiome(getIndex(x, 0, z), biome);
return true;
}
@Override
public void setBiome(int index, int biome) {
if (biomes == null) {
biomes = new byte[area];
}
biomes[index] = (byte) biome;
}
@Override
public void streamBiomes(NBTStreamer.ByteReader task) {
if (!hasBiomes()) return;
int index = 0;
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, index++) {
task.run(index, biomes[index] & 0xFF);
}
}
}
@Override
public BaseBiome getBiome(int index) {
if (!hasBiomes()) {
return EditSession.nullBiome;
}
return FaweCache.CACHE_BIOME[biomes[index] & 0xFF];
}
@Override
public BaseBiome getBiome(int x, int z) {
return getBiome(getIndex(x, 0, z));
}
private CompoundTag getTag(int index) {
convertTilesToIndex();
return nbtMapIndex.get(index);

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.jnbt.NBTStreamer;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
@ -8,6 +9,7 @@ import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.List;
public abstract class ReadOnlyClipboard extends FaweClipboard {
@ -40,9 +42,38 @@ public abstract class ReadOnlyClipboard extends FaweClipboard {
throw new UnsupportedOperationException("World based clipboards do not provide index access");
}
@Override
public BaseBiome getBiome(int index) {
throw new UnsupportedOperationException("World based clipboards do not provide index access");
}
@Override
public boolean setBiome(int x, int z, byte biome) {
throw new UnsupportedOperationException("Clipboard is immutable");
}
@Override
public void setBiome(int index, int biome) {
throw new UnsupportedOperationException("Clipboard is immutable");
}
@Override
public void streamBiomes(NBTStreamer.ByteReader task) {
Vector dim = getDimensions();
int index = 0;
for (int z = 0; z <= dim.getBlockZ(); z++) {
for (int x = 0; x <= dim.getBlockX(); x++, index++) {
task.run(index, getBiome(x, z).getId());
}
}
}
@Override
public abstract BaseBlock getBlock(int x, int y, int z);
@Override
public abstract BaseBiome getBiome(int x, int z);
@Override
public abstract List<? extends Entity> getEntities();

View File

@ -5,6 +5,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MutableBlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
@ -14,12 +15,14 @@ import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.List;
import java.util.Map;
public class WorldCopyClipboard extends ReadOnlyClipboard {
public final int mx, my, mz;
private MutableBlockVector2D mutableBlockVector2D = new MutableBlockVector2D();
public final EditSession editSession;
public WorldCopyClipboard(EditSession editSession, Region region) {
@ -40,11 +43,21 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
return editSession.getLazyBlock(x, y, z);
}
@Override
public BaseBiome getBiome(int x, int z) {
return editSession.getBiome(mutableBlockVector2D.setComponents(mx + x, mz + z));
}
@Override
public List<? extends Entity> getEntities() {
return editSession.getEntities(getRegion());
}
@Override
public boolean hasBiomes() {
return true;
}
@Override
public void forEach(BlockReader task, boolean air) {
Vector min = region.getMinimumPoint();

View File

@ -30,4 +30,4 @@ public class WorldCutClipboard extends WorldCopyClipboard {
super.forEach(task, air);
editSession.flushQueue();
}
}
}

View File

@ -325,7 +325,6 @@ public class MainUtil {
if (amount == 0) {
return new FaweOutputStream(os);
}
os = new BufferedOutputStream(os, buffer);
int gzipAmount = amount > 6 ? 1 : 0;
for (int i = 0; i < gzipAmount; i++) {
os = new ZstdOutputStream(os, 22);
@ -343,6 +342,7 @@ public class MainUtil {
os = new LZ4BlockOutputStream(os, buffer, factory.highCompressor());
}
}
os = new BufferedOutputStream(os, buffer);
return new FaweOutputStream(os);
}

View File

@ -35,7 +35,7 @@ public class Updater {
return;
}
try {
String downloadUrl = "http://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target/FastAsyncWorldEdit-%platform%-%version%.jar";
String downloadUrl = "https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/target/FastAsyncWorldEdit-%platform%-%version%.jar";
String versionUrl = "http://empcraft.com/fawe/version.php?%platform%";
URL url = new URL(versionUrl.replace("%platform%", platform));
try (Scanner reader = new Scanner(url.openStream())) {

View File

@ -246,8 +246,15 @@ public final class NBTInputStream implements Closeable {
is.skipBytes(length << 2);
return;
}
for (int i = 0; i < length; i++) {
reader.run(i, is.readInt());
if (reader instanceof NBTStreamer.ByteReader) {
NBTStreamer.ByteReader byteReader = (NBTStreamer.ByteReader) reader;
for (int i = 0; i < length; i++) {
byteReader.run(i, is.readInt());
}
} else {
for (int i = 0; i < length; i++) {
reader.run(i, is.readInt());
}
}
return;
default:

View File

@ -92,15 +92,16 @@ public class ClipboardCommands extends MethodCommands {
desc = "Lazily copy the selection to the clipboard",
help = "Lazily copy the selection to the clipboard\n" +
"Flags:\n" +
" -e controls whether entities are copied\n" +
" -e skips copying entities\n" +
" -m sets a source mask so that excluded blocks become air\n" +
" -b copies biomes\n" +
"WARNING: Pasting entities cannot yet be undone!",
max = 0
)
@CommandPermissions("worldedit.clipboard.lazycopy")
public void lazyCopy(Player player, LocalSession session, EditSession editSession,
@Selection final Region region, @Switch('e') boolean copyEntities,
@Switch('m') Mask mask) throws WorldEditException {
@Selection final Region region, @Switch('e') boolean skipEntities,
@Switch('m') Mask mask, @Switch('b') boolean copyBiomes) throws WorldEditException {
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
@ -113,7 +114,7 @@ public class ClipboardCommands extends MethodCommands {
final int mx = origin.getBlockX();
final int my = origin.getBlockY();
final int mz = origin.getBlockZ();
ReadOnlyClipboard lazyClipboard = ReadOnlyClipboard.of(editSession, region);
ReadOnlyClipboard lazyClipboard = ReadOnlyClipboard.of(editSession, region, !skipEntities, copyBiomes);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
clipboard.setOrigin(session.getPlacementPosition(player));
@ -130,16 +131,17 @@ public class ClipboardCommands extends MethodCommands {
desc = "Copy the selection to the clipboard",
help = "Copy the selection to the clipboard\n" +
"Flags:\n" +
" -e controls whether entities are copied\n" +
" -e skips copying entities\n" +
" -m sets a source mask so that excluded blocks become air\n" +
" -b copies biomes\n" +
"WARNING: Pasting entities cannot yet be undone!",
min = 0,
max = 0
)
@CommandPermissions("worldedit.clipboard.copy")
public void copy(FawePlayer fp, Player player, LocalSession session, EditSession editSession,
@Selection Region region, @Switch('e') boolean copyEntities,
@Switch('m') Mask mask, CommandContext context) throws WorldEditException {
@Selection Region region, @Switch('e') boolean skipEntities,
@Switch('m') Mask mask, CommandContext context, @Switch('b') boolean copyBiomes) throws WorldEditException {
fp.checkConfirmationRegion(getArguments(context), region);
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
@ -154,6 +156,7 @@ public class ClipboardCommands extends MethodCommands {
clipboard.setOrigin(session.getPlacementPosition(player));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setCopyEntities(!skipEntities);
Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(editSession);
@ -175,14 +178,14 @@ public class ClipboardCommands extends MethodCommands {
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" +
" -e skips entity copy\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.lazycut")
public void lazyCut(Player player, LocalSession session, EditSession editSession,
@Selection final Region region, @Switch('e') boolean copyEntities,
@Selection final Region region, @Switch('e') boolean skipEntities,
@Switch('m') Mask mask) throws WorldEditException {
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
@ -199,7 +202,7 @@ public class ClipboardCommands extends MethodCommands {
final int mx = origin.getBlockX();
final int my = origin.getBlockY();
final int mz = origin.getBlockZ();
ReadOnlyClipboard lazyClipboard = new WorldCutClipboard(editSession, region);
ReadOnlyClipboard lazyClipboard = new WorldCutClipboard(editSession, region, skipEntities);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
clipboard.setOrigin(session.getPlacementPosition(player));
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorldData()));
@ -213,7 +216,7 @@ public class ClipboardCommands extends MethodCommands {
desc = "Cut the selection to the clipboard",
help = "Copy the selection to the clipboard\n" +
"Flags:\n" +
" -e controls whether entities are copied\n" +
" -e skips entity copy\n" +
" -m sets a source mask so that excluded blocks become air\n" +
"WARNING: Cutting and pasting entities cannot yet be undone!",
min = 0,
@ -222,7 +225,7 @@ public class ClipboardCommands extends MethodCommands {
@CommandPermissions("worldedit.clipboard.cut")
@Logging(REGION)
public void cut(FawePlayer fp, Player player, LocalSession session, EditSession editSession,
@Selection Region region, @Optional("air") Pattern leavePattern, @Switch('e') boolean copyEntities,
@Selection Region region, @Optional("air") Pattern leavePattern, @Switch('e') boolean skipEntities,
@Switch('m') Mask mask, CommandContext context) throws WorldEditException {
fp.checkConfirmationRegion(getArguments(context), region);
Vector min = region.getMinimumPoint();
@ -240,6 +243,7 @@ public class ClipboardCommands extends MethodCommands {
clipboard.setOrigin(session.getPlacementPosition(player));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
copy.setCopyEntities(!skipEntities);
Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(editSession);

View File

@ -155,6 +155,21 @@ public class SchematicWriter implements ClipboardWriter {
out.writeNamedTag("WEOffsetZ", (offset.getBlockZ()));
out.writeNamedTag("Platform", Fawe.imp().getPlatform());
if (clipboard.IMP.hasBiomes()) {
out.writeNamedTagName("Biomes", NBTConstants.TYPE_BYTE_ARRAY);
out.getOutputStream().writeInt(width * length); // area
clipboard.IMP.streamBiomes(new NBTStreamer.ByteReader() {
@Override
public void run(int index, int byteValue) {
try {
rawStream.writeByte(byteValue);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
out.writeNamedTagName("Blocks", NBTConstants.TYPE_BYTE_ARRAY);
out.getOutputStream().writeInt(volume);
clipboard.IMP.streamIds(new NBTStreamer.ByteReader() {

View File

@ -40,6 +40,7 @@ import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.transform.Identity;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.Region;
import java.util.ArrayList;
import java.util.List;
@ -67,6 +68,7 @@ public class ForwardExtentCopy implements Operation {
private Transform transform = new Identity();
private Transform currentTransform = null;
private int affected;
private boolean copyEntities = true;
/**
* Create a new copy using the region's lowest minimum point as the
@ -137,6 +139,14 @@ public class ForwardExtentCopy implements Operation {
return sourceMask;
}
public void setCopyEntities(boolean copyEntities) {
this.copyEntities = copyEntities;
}
public boolean isCopyEntities() {
return copyEntities;
}
/**
* Set a mask that gets applied to the source extent.
*
@ -249,16 +259,17 @@ public class ForwardExtentCopy implements Operation {
}
RegionVisitor blockVisitor = new RegionVisitor(region, copy, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
List<? extends Entity> entities = source.getEntities(region);
List<? extends Entity> entities = isCopyEntities() ? source.getEntities(region) : new ArrayList<>();
for (int i = 0; i < repetitions; i++) {
Operations.completeBlindly(blockVisitor);
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
entityCopy.setRemoving(removingEntities);
EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy);
Operations.completeBlindly(entityVisitor);
if (!entities.isEmpty()) {
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
entityCopy.setRemoving(removingEntities);
EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy);
Operations.completeBlindly(entityVisitor);
}
if (transExt != null) {
currentTransform = currentTransform.combine(transform);