mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 21:56:33 +01:00
Add anvil copy and paste
This commit is contained in:
parent
4a9464c307
commit
9b1d32475c
@ -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!");
|
||||
}
|
||||
}
|
@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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[layer] = otherIds;
|
||||
data[layer] = other.data[layer];
|
||||
skyLight[layer] = other.skyLight[layer];
|
||||
blockLight[layer] = other.blockLight[layer];
|
||||
ids[thisLayer] = otherIds;
|
||||
data[thisLayer] = other.data[otherLayer];
|
||||
skyLight[thisLayer] = other.skyLight[otherLayer];
|
||||
blockLight[thisLayer] = other.blockLight[otherLayer];
|
||||
} else {
|
||||
ids[layer] = null;
|
||||
ids[thisLayer] = null;
|
||||
}
|
||||
} else {
|
||||
by = Math.max(by, minY) & 15;
|
||||
ty = Math.min(ty, maxY) & 15;
|
||||
int indexStart = by << 8;
|
||||
int indexEnd = 255 + (ty << 8);
|
||||
int indexEnd = 256 + (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);
|
||||
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[layer] = new byte[4096];
|
||||
this.data[layer] = new byte[2048];
|
||||
this.skyLight[layer] = new byte[2048];
|
||||
this.blockLight[layer] = new byte[2048];
|
||||
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[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);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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++) {
|
||||
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 {
|
||||
for (int cz = bcz; cz <= tcz; cz++) {
|
||||
for (int cx = bcx; cx <= tcx; cx++) {
|
||||
FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
|
||||
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 {
|
||||
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 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 {
|
||||
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
|
||||
|
11
core/src/main/java/com/boydti/fawe/util/ArrayUtil.java
Normal file
11
core/src/main/java/com/boydti/fawe/util/ArrayUtil.java
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user