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 dimensions = guessDimensions(volume.get(), width.get(), height.get(), length.get());
Vector min = new Vector(originX.get(), originY.get(), originZ.get()); Vector min = new Vector(originX.get(), originY.get(), originZ.get());
Vector offset = new Vector(offsetX.get(), offsetY.get(), offsetZ.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 // Tiles
addReader("Schematic.TileEntities.#", new RunnableVal2<Integer, CompoundTag>() { addReader("Schematic.TileEntities.#", new RunnableVal2<Integer, CompoundTag>() {

View File

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

View File

@ -7,6 +7,7 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.List; import java.util.List;
public class AbstractDelegateFaweClipboard extends FaweClipboard { public class AbstractDelegateFaweClipboard extends FaweClipboard {
@ -26,6 +27,26 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
return parent.setBlock(x, y, z, block); 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 @Override
public void setId(int index, int id) { public void setId(int index, int id) {
parent.setId(index, id); parent.setId(index, id);
@ -41,6 +62,11 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
return parent.getBlock(index); return parent.getBlock(index);
} }
@Override
public void setBiome(int index, int biome) {
parent.setBiome(index, biome);
}
@Override @Override
public void setAdd(int index, int id) { public void setAdd(int index, int id) {
parent.setAdd(index, id); parent.setAdd(index, id);
@ -96,6 +122,11 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
parent.forEach(task, air); parent.forEach(task, air);
} }
@Override
public void streamBiomes(NBTStreamer.ByteReader task) {
parent.streamBiomes(task);
}
@Override @Override
public void streamIds(NBTStreamer.ByteReader task) { public void streamIds(NBTStreamer.ByteReader task) {
parent.streamIds(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.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -48,6 +49,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
protected int height; protected int height;
protected int width; protected int width;
protected int area; protected int area;
protected int volume;
private final HashMap<IntegerTrio, CompoundTag> nbtMap; private final HashMap<IntegerTrio, CompoundTag> nbtMap;
private final HashSet<ClipboardEntity> entities; private final HashSet<ClipboardEntity> entities;
@ -58,6 +60,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private int last; private int last;
private FileChannel fc; private FileChannel fc;
private boolean hasBiomes;
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) { 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")); 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"); this.braf = new RandomAccessFile(file, "rw");
braf.setLength(file.length()); braf.setLength(file.length());
init(); init();
long size = (braf.length() - HEADER_SIZE) >> 1;
mbb.position(2); mbb.position(2);
last = Integer.MIN_VALUE; last = Integer.MIN_VALUE;
width = (int) mbb.getChar(); width = (int) mbb.getChar();
height = (int) mbb.getChar(); height = (int) mbb.getChar();
length = (int) mbb.getChar(); length = (int) mbb.getChar();
area = width * length; 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(); autoCloseTask();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(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 @Override
public Vector getDimensions() { public Vector getDimensions() {
return new Vector(width, height, length); return new Vector(width, height, length);
@ -128,6 +198,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
this.height = height; this.height = height;
this.length = length; this.length = length;
this.area = width * length; this.area = width * length;
this.volume = width * length * height;
try { try {
if (!file.exists()) { if (!file.exists()) {
File parent = file.getParentFile(); File parent = file.getParentFile();
@ -177,7 +248,8 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
height = dimensions.getBlockY(); height = dimensions.getBlockY();
length = dimensions.getBlockZ(); length = dimensions.getBlockZ();
area = width * length; 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); braf.setLength(size);
init(); init();
mbb.position(2); mbb.position(2);
@ -216,9 +288,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
cb = null; cb = null;
} }
@Override
protected void finalize() throws Throwable {
close();
}
@Override @Override
public void close() { public void close() {
try { try {
if (mbb != null) {
mbb.force(); mbb.force();
fc.close(); fc.close();
braf.close(); braf.close();
@ -227,6 +305,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
mbb = null; mbb = null;
fc = null; fc = null;
braf = null; braf = null;
}
} catch (IOException e) { } catch (IOException e) {
MainUtil.handleError(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.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; 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 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 BaseBlock getBlock(int index);
public abstract void setBiome(int index, int biome);
public abstract void setId(int index, int id); public abstract void setId(int index, int id);
public abstract void setData(int index, int data); 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 run(int x, int y, int z, BaseBlock block);
} }
public abstract void streamBiomes(final NBTStreamer.ByteReader task);
public void streamIds(final NBTStreamer.ByteReader task) { public void streamIds(final NBTStreamer.ByteReader task) {
forEach(new BlockReader() { forEach(new BlockReader() {
private int index = 0; 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.CompoundTag;
import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -37,6 +39,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
private byte[][] add; private byte[][] add;
private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)]; private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)];
private byte[] biomes = null;
private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc; private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex; private final HashMap<Integer, CompoundTag> nbtMapIndex;
@ -86,6 +89,49 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
nbtMapLoc.clear(); 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) { private CompoundTag getTag(int index) {
convertTilesToIndex(); convertTilesToIndex();
return nbtMapIndex.get(index); return nbtMapIndex.get(index);

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.clipboard; package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.jnbt.NBTStreamer;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector; 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.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.List; import java.util.List;
public abstract class ReadOnlyClipboard extends FaweClipboard { 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"); 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 @Override
public abstract BaseBlock getBlock(int x, int y, int z); public abstract BaseBlock getBlock(int x, int y, int z);
@Override
public abstract BaseBiome getBiome(int x, int z);
@Override @Override
public abstract List<? extends Entity> getEntities(); 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.IntTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MutableBlockVector2D;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; 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.function.visitor.RegionVisitor;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class WorldCopyClipboard extends ReadOnlyClipboard { public class WorldCopyClipboard extends ReadOnlyClipboard {
public final int mx, my, mz; public final int mx, my, mz;
private MutableBlockVector2D mutableBlockVector2D = new MutableBlockVector2D();
public final EditSession editSession; public final EditSession editSession;
public WorldCopyClipboard(EditSession editSession, Region region) { public WorldCopyClipboard(EditSession editSession, Region region) {
@ -40,11 +43,21 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
return editSession.getLazyBlock(x, y, z); return editSession.getLazyBlock(x, y, z);
} }
@Override
public BaseBiome getBiome(int x, int z) {
return editSession.getBiome(mutableBlockVector2D.setComponents(mx + x, mz + z));
}
@Override @Override
public List<? extends Entity> getEntities() { public List<? extends Entity> getEntities() {
return editSession.getEntities(getRegion()); return editSession.getEntities(getRegion());
} }
@Override
public boolean hasBiomes() {
return true;
}
@Override @Override
public void forEach(BlockReader task, boolean air) { public void forEach(BlockReader task, boolean air) {
Vector min = region.getMinimumPoint(); Vector min = region.getMinimumPoint();

View File

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

View File

@ -35,7 +35,7 @@ public class Updater {
return; return;
} }
try { 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%"; String versionUrl = "http://empcraft.com/fawe/version.php?%platform%";
URL url = new URL(versionUrl.replace("%platform%", platform)); URL url = new URL(versionUrl.replace("%platform%", platform));
try (Scanner reader = new Scanner(url.openStream())) { try (Scanner reader = new Scanner(url.openStream())) {

View File

@ -246,9 +246,16 @@ public final class NBTInputStream implements Closeable {
is.skipBytes(length << 2); is.skipBytes(length << 2);
return; return;
} }
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++) { for (int i = 0; i < length; i++) {
reader.run(i, is.readInt()); reader.run(i, is.readInt());
} }
}
return; return;
default: default:
throw new IOException("Invalid tag type: " + type + "."); throw new IOException("Invalid tag type: " + type + ".");

View File

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

View File

@ -155,6 +155,21 @@ public class SchematicWriter implements ClipboardWriter {
out.writeNamedTag("WEOffsetZ", (offset.getBlockZ())); out.writeNamedTag("WEOffsetZ", (offset.getBlockZ()));
out.writeNamedTag("Platform", Fawe.imp().getPlatform()); 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.writeNamedTagName("Blocks", NBTConstants.TYPE_BYTE_ARRAY);
out.getOutputStream().writeInt(volume); out.getOutputStream().writeInt(volume);
clipboard.IMP.streamIds(new NBTStreamer.ByteReader() { 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.Identity;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -67,6 +68,7 @@ public class ForwardExtentCopy implements Operation {
private Transform transform = new Identity(); private Transform transform = new Identity();
private Transform currentTransform = null; private Transform currentTransform = null;
private int affected; private int affected;
private boolean copyEntities = true;
/** /**
* Create a new copy using the region's lowest minimum point as the * Create a new copy using the region's lowest minimum point as the
@ -137,6 +139,14 @@ public class ForwardExtentCopy implements Operation {
return sourceMask; 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. * 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); 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++) { for (int i = 0; i < repetitions; i++) {
Operations.completeBlindly(blockVisitor); Operations.completeBlindly(blockVisitor);
if (!entities.isEmpty()) {
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform); ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
entityCopy.setRemoving(removingEntities); entityCopy.setRemoving(removingEntities);
EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy); EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy);
Operations.completeBlindly(entityVisitor); Operations.completeBlindly(entityVisitor);
}
if (transExt != null) { if (transExt != null) {
currentTransform = currentTransform.combine(transform); currentTransform = currentTransform.combine(transform);