Add anvil copy and paste

This commit is contained in:
Jesse Boyd 2017-04-04 20:14:51 +10:00
parent 4a9464c307
commit 9b1d32475c
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
4 changed files with 425 additions and 138 deletions

View File

@ -4,18 +4,22 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.jnbt.anvil.MCAChunk;
import com.boydti.fawe.jnbt.anvil.MCAClipboard;
import com.boydti.fawe.jnbt.anvil.MCAFilter;
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.mask.FaweBlockMatcher;
import com.boydti.fawe.object.number.MutableLong;
import com.boydti.fawe.util.ArrayUtil;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.StringMan;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
@ -32,7 +36,6 @@ import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -87,7 +90,7 @@ public class AnvilCommands {
}
@Command(
aliases = {"/replaceallpattern", "/reap", "/repallpat"},
aliases = {"replaceallpattern", "reap", "repallpat"},
usage = "<folder> [from-block] <to-pattern>",
desc = "Replace all blocks in the selection with another",
flags = "dm",
@ -388,12 +391,13 @@ public class AnvilCommands {
}
@Command(
aliases = {"removelayer"},
aliases = {"removelayers"},
usage = "<id>",
desc = "Replace all blocks in the selection with another"
desc = "Removes matching chunk layers",
help = "Remove if all the selected layers in a chunk match the provided id"
)
@CommandPermissions("worldedit.anvil.removelayer")
public void removeLayer(Player player, EditSession editSession, @Selection Region selection, int id) throws WorldEditException {
public void removeLayers(Player player, EditSession editSession, @Selection Region selection, int id) throws WorldEditException {
Vector min = selection.getMinimumPoint();
Vector max = selection.getMaximumPoint();
int minY = min.getBlockY();
@ -422,7 +426,7 @@ public class AnvilCommands {
for (int y = startY; y <= endY; y++) {
int indexStart = y << 8;
int indexEnd = indexStart + 255;
Arrays.fill(ids, indexStart, indexEnd + 1, (byte) 0);
ArrayUtil.fill(ids, indexStart, indexEnd + 1, (byte) 0);
}
chunk.setModified();
}
@ -434,71 +438,79 @@ public class AnvilCommands {
}
}
//
// @Command(
// aliases = {"copychunks"},
// desc = "Lazily copy chunks to your anvil clipboard"
// )
// @CommandPermissions("worldedit.anvil.copychunks")
// public void copy(Player player, LocalSession session, EditSession editSession, @Selection Region selection) throws WorldEditException {
// if (!(selection instanceof CuboidRegion)) {
// BBC.NO_REGION.send(player);
// return;
// }
// CuboidRegion cuboid = (CuboidRegion) selection;
// String worldName = Fawe.imp().getWorldName(editSession.getWorld());
// FaweQueue tmp = SetQueue.IMP.getNewQueue(worldName, true, false);
// File folder = tmp.getSaveFolder();
// MCAQueue queue = new MCAQueue(worldName, folder, tmp.hasSky());
// Vector origin = session.getPlacementPosition(player);
// MCAClipboard clipboard = new MCAClipboard(queue, cuboid, origin);
// FawePlayer fp = FawePlayer.wrap(player);
// fp.setMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD, clipboard);
// BBC.COMMAND_COPY.send(player, selection.getArea());
// }
//
// @Command(
// aliases = {"pastechunks"},
// desc = "Paste chunks from your anvil clipboard"
// )
// @CommandPermissions("worldedit.anvil.pastechunks")
// public void paste(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
// FawePlayer fp = FawePlayer.wrap(player);
// MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
// if (clipboard == null) {
// fp.sendMessage(BBC.getPrefix() + "You must first copy to your clipboard");
// return;
// }
// CuboidRegion cuboid = clipboard.getRegion();
// RegionWrapper copyRegion = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint());
// Vector offset = player.getPosition().subtract(clipboard.getOrigin());
// int oX = offset.getBlockX();
// int oZ = offset.getBlockZ();
// RegionWrapper pasteRegion = new RegionWrapper(copyRegion.minX + oX, copyRegion.maxX + oX, copyRegion.minZ + oZ, copyRegion.maxZ + oZ);
// String pasteWorldName = Fawe.imp().getWorldName(editSession.getWorld());
// FaweQueue tmpTo = SetQueue.IMP.getNewQueue(pasteWorldName, true, false);
// FaweQueue tmpFrom = SetQueue.IMP.getNewQueue(clipboard.getQueue().getWorldName(), true, false);
// File folder = tmpTo.getSaveFolder();
// MCAQueue copyQueue = clipboard.getQueue();
// MCAQueue pasteQueue = new MCAQueue(pasteWorldName, folder, tmpTo.hasSky());
// player.print(BBC.getPrefix() + "Safely unloading regions...");
// tmpTo.setMCA(new Runnable() {
// @Override
// public void run() {
// tmpFrom.setMCA(new Runnable() {
// @Override
// public void run() {
// try {
// player.print(BBC.getPrefix() + "Performing operation...");
// pasteQueue.pasteRegion(copyQueue, copyRegion, offset);
// player.print(BBC.getPrefix() + "Safely loading regions...");
// } catch (Throwable e) {
// e.printStackTrace();
// }
// }
// }, copyRegion, false);
// }
// }, pasteRegion, true);
// player.print("Done!");
// }
@Command(
aliases = {"copy"},
desc = "Lazily copy chunks to your anvil clipboard"
)
@CommandPermissions("worldedit.anvil.copychunks")
public void copy(Player player, LocalSession session, EditSession editSession, @Selection Region selection) throws WorldEditException {
if (!(selection instanceof CuboidRegion)) {
BBC.NO_REGION.send(player);
return;
}
CuboidRegion cuboid = (CuboidRegion) selection;
String worldName = Fawe.imp().getWorldName(editSession.getWorld());
FaweQueue tmp = SetQueue.IMP.getNewQueue(worldName, true, false);
File folder = tmp.getSaveFolder();
MCAQueue queue = new MCAQueue(worldName, folder, tmp.hasSky());
Vector origin = session.getPlacementPosition(player);
MCAClipboard clipboard = new MCAClipboard(queue, cuboid, origin);
FawePlayer fp = FawePlayer.wrap(player);
fp.setMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD, clipboard);
BBC.COMMAND_COPY.send(player, selection.getArea());
}
@Command(
aliases = {"paste"},
desc = "Paste chunks from your anvil clipboard",
help =
"Paste the chunks from your anvil clipboard.\n" +
"The -c will align the paste to the chunks.",
flags = "c"
)
@CommandPermissions("worldedit.anvil.pastechunks")
public void paste(Player player, LocalSession session, EditSession editSession, @Switch('c') boolean alignChunk) throws WorldEditException {
FawePlayer fp = FawePlayer.wrap(player);
MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
if (clipboard == null) {
fp.sendMessage(BBC.getPrefix() + "You must first copy to your clipboard");
return;
}
CuboidRegion cuboid = clipboard.getRegion();
RegionWrapper copyRegion = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint());
final Vector offset = player.getPosition().subtract(clipboard.getOrigin());
if (alignChunk) {
offset.setComponents((offset.getBlockX() >> 4) << 4, offset.getBlockY(), (offset.getBlockZ() >> 4) << 4);
}
int oX = offset.getBlockX();
int oZ = offset.getBlockZ();
RegionWrapper pasteRegion = new RegionWrapper(copyRegion.minX + oX, copyRegion.maxX + oX, copyRegion.minZ + oZ, copyRegion.maxZ + oZ);
String pasteWorldName = Fawe.imp().getWorldName(editSession.getWorld());
FaweQueue tmpTo = SetQueue.IMP.getNewQueue(pasteWorldName, true, false);
FaweQueue tmpFrom = SetQueue.IMP.getNewQueue(clipboard.getQueue().getWorldName(), true, false);
File folder = tmpTo.getSaveFolder();
MCAQueue copyQueue = clipboard.getQueue();
MCAQueue pasteQueue = new MCAQueue(pasteWorldName, folder, tmpTo.hasSky());
player.print(BBC.getPrefix() + "Safely unloading regions...");
tmpTo.setMCA(new Runnable() {
@Override
public void run() {
tmpFrom.setMCA(new Runnable() {
@Override
public void run() {
try {
player.print(BBC.getPrefix() + "Performing operation...");
pasteQueue.pasteRegion(copyQueue, copyRegion, offset);
player.print(BBC.getPrefix() + "Safely loading regions...");
} catch (Throwable e) {
e.printStackTrace();
}
}
}, copyRegion, false);
}
}, pasteRegion, true);
player.print("Done!");
}
}

View File

@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.util.ArrayUtil;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
@ -113,63 +114,201 @@ public class MCAChunk extends FaweChunk<Void> {
return buffered.toByteArray();
}
public void copyFrom(MCAChunk other, int minY, int maxY) {
for (int layer = 0; layer < ids.length; layer++) {
byte[] otherIds = other.ids[layer];
byte[] currentIds = ids[layer];
int by = layer << 4;
int ty = layer >> 4;
if (by >= minY && ty <= maxY) {
if (otherIds != null) {
ids[layer] = otherIds;
data[layer] = other.data[layer];
skyLight[layer] = other.skyLight[layer];
blockLight[layer] = other.blockLight[layer];
} else {
ids[layer] = null;
public void copyFrom(MCAChunk other, int minX, int maxX, int minY, int maxY, int minZ, int maxZ, int offsetX, int offsetY, int offsetZ) {
minY = Math.max(-offsetY - minY, minY);
maxY = Math.min(255 - offsetY, maxY);
minZ = Math.max(-offsetZ - minZ, minZ);
maxZ = Math.min(15 - offsetZ, maxZ);
minX = Math.max(-offsetX - minX, minX);
maxX = Math.min(15 - offsetX, maxX);
if (minX > maxX || minZ > maxZ || minY > maxY) return;
int startLayer = minY >> 4;
int endLayer = maxY >> 4;
for (int otherY = minY, thisY = minY + offsetY; otherY <= maxY; otherY++, thisY++) {
int thisLayer = thisY >> 4;
int otherLayer = otherY >> 4;
byte[] thisIds = ids[thisLayer];
byte[] otherIds = other.ids[otherLayer];
if (otherIds == null) {
if (thisIds != null) {
int indexY = (thisY & 15) << 8;
byte[] thisData = data[thisLayer];
byte[] thisSkyLight = skyLight[thisLayer];
byte[] thisBlockLight = blockLight[thisLayer];
for (int otherZ = minZ, thisZ = minZ + offsetZ; otherZ <= maxZ; otherZ++, thisZ++) {
int startIndex = indexY + (thisZ << 4) + minX + offsetX;
int endIndex = startIndex + maxX - minX;
ArrayUtil.fill(thisIds, startIndex, endIndex + 1, (byte) 0);
int startIndexShift = startIndex >> 1;
int endIndexShift = endIndex >> 1;
if ((startIndex & 1) != 0) {
startIndexShift++;
setNibble(startIndex, thisData, (byte) 0);
setNibble(startIndex, thisSkyLight, (byte) 0);
setNibble(startIndex, thisBlockLight, (byte) 0);
}
if ((endIndex & 1) != 1) {
endIndexShift--;
setNibble(endIndex, thisData, (byte) 0);
setNibble(endIndex, thisSkyLight, (byte) 0);
setNibble(endIndex, thisBlockLight, (byte) 0);
}
ArrayUtil.fill(thisData, startIndexShift, endIndexShift + 1, (byte) 0);
ArrayUtil.fill(thisSkyLight, startIndexShift, endIndexShift + 1, (byte) 0);
ArrayUtil.fill(thisBlockLight, startIndexShift, endIndexShift + 1, (byte) 0);
}
}
} else {
by = Math.max(by, minY) & 15;
ty = Math.min(ty, maxY) & 15;
int indexStart = by << 8;
int indexEnd = 255 + (ty << 8);
int indexStartShift = indexStart >> 1;
int indexEndShift = indexEnd >> 1;
if (otherIds == null) {
if (currentIds != null) {
Arrays.fill(currentIds, indexStart, indexEnd, (byte) 0);
Arrays.fill(data[layer], indexStartShift, indexEndShift, (byte) 0);
Arrays.fill(skyLight[layer], indexStartShift, indexEndShift, (byte) 0);
Arrays.fill(blockLight[layer], indexStartShift, indexEndShift, (byte) 0);
continue;
} else if (thisIds == null) {
ids[thisLayer] = thisIds = new byte[4096];
data[thisLayer] = new byte[2048];
skyLight[thisLayer] = new byte[2048];
blockLight[thisLayer] = new byte[2048];
}
int indexY = (thisY & 15) << 8;
int otherIndexY = (otherY & 15) << 8;
byte[] thisData = data[thisLayer];
byte[] thisSkyLight = skyLight[thisLayer];
byte[] thisBlockLight = blockLight[thisLayer];
byte[] otherData = other.data[otherLayer];
byte[] otherSkyLight = other.skyLight[otherLayer];
byte[] otherBlockLight = other.blockLight[otherLayer];
for (int otherZ = minZ, thisZ = minZ + offsetZ; otherZ <= maxZ; otherZ++, thisZ++) {
int startIndex = indexY + (thisZ << 4) + minX + offsetX;
int endIndex = startIndex + maxX - minX;
int otherStartIndex = otherIndexY + (otherZ << 4) + minX;
int otherEndIndex = otherStartIndex + maxX - minX;
System.arraycopy(otherIds, otherStartIndex, thisIds, startIndex, endIndex - startIndex + 1);
if ((startIndex & 1) == (otherStartIndex & 1)) {
int startIndexShift = startIndex >> 1;
int endIndexShift = endIndex >> 1;
int otherStartIndexShift = otherStartIndex >> 1;
int otherEndIndexShift = otherEndIndex >> 1;
if ((startIndex & 1) != 0) {
startIndexShift++;
otherStartIndexShift++;
setNibble(startIndex, thisData, getNibble(otherStartIndex, otherData));
setNibble(startIndex, thisSkyLight, getNibble(otherStartIndex, otherSkyLight));
setNibble(startIndex, thisBlockLight, getNibble(otherStartIndex, otherBlockLight));
}
if ((endIndex & 1) != 1) {
endIndexShift--;
otherEndIndexShift--;
setNibble(endIndex, thisData, getNibble(otherEndIndex, otherData));
setNibble(endIndex, thisSkyLight, getNibble(otherEndIndex, otherSkyLight));
setNibble(endIndex, thisBlockLight, getNibble(otherEndIndex, otherBlockLight));
}
System.arraycopy(otherData, otherStartIndexShift, thisData, startIndexShift, endIndexShift - startIndexShift + 1);
System.arraycopy(otherSkyLight, otherStartIndexShift, thisSkyLight, startIndexShift, endIndexShift - startIndexShift + 1);
System.arraycopy(otherBlockLight, otherStartIndexShift, thisBlockLight, startIndexShift, endIndexShift - startIndexShift + 1);
} else {
if (currentIds == null) {
currentIds = this.ids[layer] = new byte[4096];
this.data[layer] = new byte[2048];
this.skyLight[layer] = new byte[2048];
this.blockLight[layer] = new byte[2048];
for (int thisIndex = startIndex, otherIndex = otherStartIndex; thisIndex <= endIndex; thisIndex++, otherIndex++) {
setNibble(thisIndex, thisData, getNibble(otherIndex, otherData));
setNibble(thisIndex, thisSkyLight, getNibble(otherIndex, otherSkyLight));
setNibble(thisIndex, thisBlockLight, getNibble(otherIndex, otherBlockLight));
}
System.arraycopy(other.ids[layer], indexStart, ids[layer], indexStart, indexEnd - indexStart);
System.arraycopy(other.data[layer], indexStartShift, data[layer], indexStartShift, indexEndShift - indexStartShift);
System.arraycopy(other.skyLight[layer], indexStartShift, skyLight[layer], indexStartShift, indexEndShift - indexStartShift);
System.arraycopy(other.blockLight[layer], indexStartShift, blockLight[layer], indexStartShift, indexEndShift - indexStartShift);
}
}
}
}
public void copyFrom(MCAChunk other, int minY, int maxY, int offsetY) {
minY = Math.max(-offsetY - minY, minY);
maxY = Math.min(255 - offsetY, maxY);
if (minY > maxY) return;
if ((offsetY & 15) == 0) {
int offsetLayer = offsetY >> 4;
int startLayer = minY >> 4;
int endLayer = maxY >> 4;
for (int thisLayer = startLayer + offsetLayer, otherLayer = startLayer; thisLayer < endLayer; thisLayer++, otherLayer++) {
byte[] otherIds = other.ids[otherLayer];
byte[] currentIds = ids[thisLayer];
int by = otherLayer << 4;
int ty = otherLayer >> 4;
if (by >= minY && ty <= maxY) {
if (otherIds != null) {
ids[thisLayer] = otherIds;
data[thisLayer] = other.data[otherLayer];
skyLight[thisLayer] = other.skyLight[otherLayer];
blockLight[thisLayer] = other.blockLight[otherLayer];
} else {
ids[thisLayer] = null;
}
} else {
by = Math.max(by, minY) & 15;
ty = Math.min(ty, maxY) & 15;
int indexStart = by << 8;
int indexEnd = 256 + (ty << 8);
int indexStartShift = indexStart >> 1;
int indexEndShift = indexEnd >> 1;
if (otherIds == null) {
if (currentIds != null) {
ArrayUtil.fill(currentIds, indexStart, indexEnd, (byte) 0);
ArrayUtil.fill(data[thisLayer], indexStartShift, indexEndShift, (byte) 0);
ArrayUtil.fill(skyLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
ArrayUtil.fill(blockLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
}
} else {
if (currentIds == null) {
currentIds = this.ids[thisLayer] = new byte[4096];
this.data[thisLayer] = new byte[2048];
this.skyLight[thisLayer] = new byte[2048];
this.blockLight[thisLayer] = new byte[2048];
}
System.arraycopy(other.ids[otherLayer], indexStart, currentIds, indexStart, indexEnd - indexStart);
System.arraycopy(other.data[otherLayer], indexStartShift, data[thisLayer], indexStartShift, indexEndShift - indexStartShift);
System.arraycopy(other.skyLight[otherLayer], indexStartShift, skyLight[thisLayer], indexStartShift, indexEndShift - indexStartShift);
System.arraycopy(other.blockLight[otherLayer], indexStartShift, blockLight[thisLayer], indexStartShift, indexEndShift - indexStartShift);
}
}
}
} else {
for (int otherY = minY, thisY = minY + offsetY; otherY <= maxY; otherY++, thisY++) {
int otherLayer = otherY >> 4;
int thisLayer = thisY >> 4;
byte[] thisIds = this.ids[thisLayer];
byte[] otherIds = other.ids[otherLayer];
int thisStartIndex = (thisY & 15) << 8;
int thisStartIndexShift = thisStartIndex >> 1;
if (otherIds == null) {
if (thisIds == null) {
continue;
}
ArrayUtil.fill(thisIds, thisStartIndex, thisStartIndex + 256, (byte) 0);
ArrayUtil.fill(this.data[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
ArrayUtil.fill(this.skyLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
ArrayUtil.fill(this.blockLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
continue;
} else if (thisIds == null) {
ids[thisLayer] = thisIds = new byte[4096];
data[thisLayer] = new byte[2048];
skyLight[thisLayer] = new byte[2048];
blockLight[thisLayer] = new byte[2048];
}
int otherStartIndex = (otherY & 15) << 8;
int otherStartIndexShift = otherStartIndex >> 1;
System.arraycopy(other.ids[otherLayer], otherStartIndex, thisIds, thisStartIndex, 256);
System.arraycopy(other.data[otherLayer], otherStartIndexShift, data[thisLayer], thisStartIndexShift, 128);
System.arraycopy(other.skyLight[otherLayer], otherStartIndexShift, skyLight[thisLayer], thisStartIndexShift, 128);
System.arraycopy(other.blockLight[otherLayer], otherStartIndexShift, blockLight[thisLayer], thisStartIndexShift, 128);
}
}
// Copy nbt
int thisMinY = minY + offsetY;
int thisMaxY = maxY + offsetY;
if (!tiles.isEmpty()) {
Iterator<Map.Entry<Short, CompoundTag>> iter = tiles.entrySet().iterator();
while (iter.hasNext()) {
int y = MathMan.untripleBlockCoordY(iter.next().getKey());
if (y >= minY && y <= maxY) iter.remove();
if (y >= thisMinY && y <= thisMaxY) iter.remove();
}
}
if (!other.tiles.isEmpty()) {
for (Map.Entry<Short, CompoundTag> entry : other.tiles.entrySet()) {
short key = entry.getKey();
int key = entry.getKey();
int y = MathMan.untripleBlockCoordY(key);
if (y >= minY && y <= maxY) {
tiles.put(key, entry.getValue());
tiles.put((short) (key + offsetY), entry.getValue());
}
}
}

View File

@ -82,7 +82,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
}
public void pasteRegion(MCAQueue from, final RegionWrapper regionFrom, Vector offset) throws IOException {
offset = new Vector((offset.getBlockX() >> 4) << 4, 0, (offset.getBlockZ() >> 4) << 4);
int oX = offset.getBlockX();
int oZ = offset.getBlockZ();
int oY = offset.getBlockY();
@ -107,44 +106,123 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
}
MCAFile mcaFile = new MCAFile(null, file);
mcaFile.init();
// If oX & 15 == 0 && oZ && 15 == 0
if ((oX & 15) == 0 && (oZ & 15) == 0) {
if (oY == 0) {
if (regionFrom.minY == 0 && regionFrom.maxY == 255) {
for (int cz = bcz; cz <= tcz; cz++) {
for (int cx = bcx; cx <= tcx; cx++) {
FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
if (!(chunk instanceof NullFaweChunk)) {
for (int cz = bcz; cz <= tcz; cz++) {
for (int cx = bcx; cx <= tcx; cx++) {
int bx = cx << 4;
int bz = cz << 4;
int tx = bx + 15;
int tz = bz + 15;
if (oX == 0 && oZ == 0) {
if (bx >= regionTo.minX && tx <= regionTo.maxX && bz >= regionTo.minZ && tz <= regionTo.maxZ) {
FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
if (!(chunk instanceof NullFaweChunk)) {
if (regionTo.minY == 0 && regionTo.maxY == 255) {
MCAChunk mcaChunk = (MCAChunk) chunk;
mcaChunk.setLoc(null, cx, cz);
mcaChunk.setModified();
mcaFile.setChunk(mcaChunk);
} else {
MCAChunk newChunk = mcaFile.getChunk(cx, cz);
if (newChunk == null) {
newChunk = new MCAChunk(this, cx, cz);
mcaFile.setChunk(newChunk);
} else {
newChunk.setModified();
}
newChunk.copyFrom((MCAChunk) chunk, regionFrom.minY, regionFrom.maxY, oY);
}
}
continue;
}
}
bx = Math.max(regionTo.minX, bx);
bz = Math.max(regionTo.minZ, bz);
tx = Math.min(regionTo.maxX, tx);
tz = Math.min(regionTo.maxZ, tz);
int obx = bx - oX;
int obz = bz - oZ;
int otx = tx - oX;
int otz = tz - oZ;
int otherBCX = (obx) >> 4;
int otherBCZ = (obz) >> 4;
int otherTCX = (otx) >> 4;
int otherTCZ = (otz) >> 4;
MCAChunk newChunk = mcaFile.getChunk(cx, cz);
if (newChunk == null) {
newChunk = new MCAChunk(this, cx, cz);
mcaFile.setChunk(newChunk);
} else {
for (int cz = bcz; cz <= tcz; cz++) {
for (int cx = bcx; cx <= tcx; cx++) {
FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
if (!(chunk instanceof NullFaweChunk)) {
MCAChunk mcaChunk = (MCAChunk) chunk;
MCAChunk toChunk = mcaFile.getChunk(cx, cz);
if (toChunk == null || (toChunk.getMinLayer() << 4 >= regionTo.minY && (toChunk.getMaxLayer() << 4) + 15 <= regionTo.maxY)) {
mcaChunk.setLoc(null, cx, cz);
mcaChunk.setModified();
mcaFile.setChunk(mcaChunk);
} else {
}
}
newChunk.setModified();
}
int cbx = (cx << 4) - oX;
int cbz = (cz << 4) - oZ;
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) {
FaweChunk chunk = from.getFaweChunk(otherCX, otherCZ);
if (!(chunk instanceof NullFaweChunk)) {
MCAChunk other = (MCAChunk) chunk;
int ocbx = otherCX << 4;
int ocbz = otherCZ << 4;
int octx = ocbx + 15;
int octz = ocbz + 15;
int minY = regionFrom.minY;
int maxY = regionFrom.maxY;
int offsetY = oY;
int minX = obx > ocbx ? (obx - ocbx) & 15 : 0;
int maxX = otx < octx ? (otx - ocbx) : 15;
int minZ = obz > ocbz ? (obz - ocbz) & 15 : 0;
int maxZ = otz < octz ? (otz - ocbz) : 15;
int offsetX = ocbx - cbx;
int offsetZ = ocbz - cbz;
newChunk.copyFrom(other, minX, maxX, minY, maxY, minZ, maxZ, offsetX, offsetY, offsetZ);
}
}
}
} else if ((oY & 15) == 0) {
} else {
}
} else {
}
// If oX & 15 == 0 && oZ && 15 == 0
// if ((oX & 15) == 0 && (oZ & 15) == 0) {
// if (oY == 0) {
// if (regionFrom.minY == 0 && regionFrom.maxY == 255) {
// for (int cz = bcz; cz <= tcz; cz++) {
// for (int cx = bcx; cx <= tcx; cx++) {
// FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
// if (!(chunk instanceof NullFaweChunk)) {
// MCAChunk mcaChunk = (MCAChunk) chunk;
// mcaChunk.setLoc(null, cx, cz);
// mcaChunk.setModified();
// mcaFile.setChunk(mcaChunk);
// }
// }
// }
// } else {
// for (int cz = bcz; cz <= tcz; cz++) {
// for (int cx = bcx; cx <= tcx; cx++) {
// FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
// if (!(chunk instanceof NullFaweChunk)) {
// MCAChunk mcaChunk = (MCAChunk) chunk;
// MCAChunk toChunk = mcaFile.getChunk(cx, cz);
// if (toChunk == null || (toChunk.getMinLayer() << 4 >= regionTo.minY && (toChunk.getMaxLayer() << 4) + 15 <= regionTo.maxY)) {
// mcaChunk.setLoc(null, cx, cz);
// mcaChunk.setModified();
// mcaFile.setChunk(mcaChunk);
// } else {
// // TODO
// }
// }
// }
// }
// }
// } else if ((oY & 15) == 0) {
//
// } else {
//
// }
// } else {
// }
mcaFile.close(pool);
from.clear();
}
@ -152,6 +230,53 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
// [17:52:49 INFO]: RegionFrom 139,3,454->139,3,454
// [17:52:49 INFO]: 8,31 | 132>132,502>502
// [17:52:49 INFO]: Copy from 8,28
// [17:52:49 INFO]: 128/139,448/454
// [17:52:49 INFO]: Set 11>15,3>3,6>15 | -11,0,-6
public static void main(String[] args) {
int ox = 2;
int oz = 0;
int bx = 5;
int bz = 5;
int tx = 5;
int tz = 5;
int obx = bx - ox;
int obz = bz - oz;
int otx = tx - ox;
int otz = tz - oz;
int otherBCX = (obx) >> 4;
int otherBCZ = (obz) >> 4;
int otherTCX = (otx) >> 4;
int otherTCZ = (otz) >> 4;
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) {
int ocbx = otherCX << 4;
int ocbz = otherCZ << 4;
int octx = obx + 15;
int octz = obz + 15;
int offsetX, offsetZ;
int minX = obx > ocbx ? (obx - ocbx) & 15 : 0;
int maxX = otx < octx ? (otx - ocbx) : 15;
int minZ = obz > ocbz ? (obz - ocbz) & 15 : 0;
int maxZ = otz < octz ? (otz - ocbz) : 15;
}
}
}
public <G, T extends MCAFilter<G>> T filterRegion(final T filter, final RegionWrapper region) {
this.filterWorld(new MCAFilter<G>() {
@Override

View File

@ -0,0 +1,11 @@
package com.boydti.fawe.util;
public class ArrayUtil {
public static final void fill(byte[] a, int fromIndex, int toIndex, byte val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
public static final void fill(char[] a, int fromIndex, int toIndex, char val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
}