Changes to NBT-handling in operations and extents, changes to match the widely supported setBlock functionality, minor code cleanup

This commit is contained in:
IronApollo
2019-03-25 13:31:12 -04:00
parent 16c22b75da
commit 3236bdd78e
57 changed files with 347 additions and 417 deletions

View File

@ -201,13 +201,13 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
int x = position.getBlockX() - mx;
int y = position.getBlockY() - my;
int z = position.getBlockZ() - mz;
return IMP.getBlock(x, y, z);
return IMP.getBlock(x, y, z).toImmutableState();
}
return EditSession.nullBlock;
}
public BlockState getBlockAbs(int x, int y, int z) {
return IMP.getBlock(x, y, z);
return IMP.getBlock(x, y, z).toImmutableState();
}
@Override
@ -228,7 +228,13 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return getLazyBlock(position).toBaseBlock();
if(region.contains(position)) {
int x = position.getBlockX() - mx;
int y = position.getBlockY() - my;
int z = position.getBlockZ() - mz;
return IMP.getBlock(x, y, z);
}
return EditSession.nullBlock.toBaseBlock();
}
@Override

View File

@ -33,6 +33,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
@ -125,67 +126,25 @@ public class SpongeSchematicWriter implements ClipboardWriter {
FaweClipboard.BlockReader reader = new FaweClipboard.BlockReader() {
@Override
public void run(int x, int y, int z, BlockState block) {
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
try {
CompoundTag tile = block.getNbtData();
if (tile != null) {
Map<String, Tag> values = tile.getValue();
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData();
if (hasNbt) {
BaseBlock localBlock = (BaseBlock)block;
Map<String, Tag> values = localBlock.getNbtData().getValue();
values.remove("id"); // Remove 'id' if it exists. We want 'Id'
// Positions are kept in NBT, we don't want that.
values.remove("x");
values.remove("y");
values.remove("z");
if (!values.containsKey("Id")) values.put("Id", new StringTag(block.getNbtId()));
if (!values.containsKey("Id")) values.put("Id", new StringTag(localBlock.getNbtId()));
values.put("Pos", new IntArrayTag(new int[]{
x,
y,
z
}));
numTiles[0]++;
tilesOut.writeTagPayload(tile);
//=======
//
// Map<String, Tag> schematic = new HashMap<>();
// schematic.put("Version", new IntTag(1));
//
// Map<String, Tag> metadata = new HashMap<>();
// metadata.put("WEOffsetX", new IntTag(offset.getBlockX()));
// metadata.put("WEOffsetY", new IntTag(offset.getBlockY()));
// metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ()));
//
// schematic.put("Metadata", new CompoundTag(metadata));
//
// schematic.put("Width", new ShortTag((short) width));
// schematic.put("Height", new ShortTag((short) height));
// schematic.put("Length", new ShortTag((short) length));
//
// // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
// schematic.put("Offset", new IntArrayTag(new int[]{
// min.getBlockX(),
// min.getBlockY(),
// min.getBlockZ(),
// }));
//
// int paletteMax = 0;
// Map<String, Integer> palette = new HashMap<>();
//
// List<CompoundTag> tileEntities = new ArrayList<>();
//
// ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length);
//
// for (int y = 0; y < height; y++) {
// int y0 = min.getBlockY() + y;
// for (int z = 0; z < length; z++) {
// int z0 = min.getBlockZ() + z;
// for (int x = 0; x < width; x++) {
// int x0 = min.getBlockX() + x;
// BlockVector3 point = BlockVector3.at(x0, y0, z0);
// BaseBlock block = clipboard.getFullBlock(point);
// if (block.getNbtData() != null) {
// Map<String, Tag> values = new HashMap<>();
// for (Map.Entry<String, Tag> entry : block.getNbtData().getValue().entrySet()) {
// values.put(entry.getKey(), entry.getValue());
//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
tilesOut.writeTagPayload(localBlock.getNbtData());
}
int ordinal = block.getOrdinal();
char value = palette[ordinal];
@ -208,7 +167,7 @@ public class SpongeSchematicWriter implements ClipboardWriter {
((BlockArrayClipboard) clipboard).IMP.forEach(reader, true);
} else {
for (BlockVector3 pt : region) {
BlockState block = clipboard.getBlock(pt);
BaseBlock block = clipboard.getFullBlock(pt);
int x = pt.getBlockX() - min.getBlockX();
int y = pt.getBlockY() - min.getBlockY();
int z = pt.getBlockZ() - min.getBlockY();

View File

@ -51,7 +51,7 @@ public abstract class AbstractLoggingExtent extends AbstractDelegateExtent {
}
@Override
public final boolean setBlock(BlockVector3 position, BlockStateHolder block) throws WorldEditException {
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block) throws WorldEditException {
onBlockChange(position, block);
return super.setBlock(position, block);
}

View File

@ -105,38 +105,38 @@ public class BlockTransformExtent extends ResettableExtent {
* @param reverse true to transform in the opposite direction
* @return the same block
*/
private <T extends BlockStateHolder<T>> T transformBlock(T block, boolean reverse) {
protected <T extends BlockStateHolder<T>> T transformBlock(T block, boolean reverse) {
return transform(block, reverse ? transform.inverse() : transform);
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return transformFast(super.getLazyBlock(position)).toImmutableState();
return transformBlock(super.getLazyBlock(position), false).toImmutableState();
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return transformFast(super.getLazyBlock(x, y, z)).toImmutableState();
return transformBlock(super.getLazyBlock(x, y, z), false).toImmutableState();
}
@Override
public BlockState getBlock(BlockVector3 position) {
return transformFast(super.getBlock(position)).toImmutableState();
return transformBlock(super.getBlock(position), false).toImmutableState();
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return transformFast(super.getFullBlock(position).toImmutableState());
return transformBlock(super.getFullBlock(position), false);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
return super.setBlock(x, y, z, transformFastInverse((BlockState)block));
return super.setBlock(x, y, z, transformBlock(block, true));
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
return super.setBlock(location, transformFastInverse((BlockState)block));
return super.setBlock(location, transformBlock(block, true));
}
private static final Set<String> directionNames = Sets.newHashSet("north", "south", "east", "west");
@ -240,61 +240,6 @@ public class BlockTransformExtent extends ResettableExtent {
}
return result;
}
public final BaseBlock transformFast(BlockState block) {
BaseBlock transformed = transformBlock(block, false).toBaseBlock();
if (block.hasNbtData()) {
CompoundTag tag = block.getNbtData();
if (tag.containsKey("Rot")) {
int rot = tag.asInt("Rot");
Direction direction = Direction.fromRotationIndex(rot).get();
if (direction != null) {
Vector3 applyAbsolute = transform.apply(direction.toVector());
Vector3 applyOrigin = transform.apply(Vector3.ZERO);
Vector3 newAbsolute = Vector3.at(applyAbsolute.getX() - applyOrigin.getX(), applyAbsolute.getY() - applyOrigin.getY(), applyAbsolute.getZ() - applyOrigin.getZ());
Direction newDirection = Direction.findClosest(newAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
if (newDirection != null) {
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
values.put("Rot", new ByteTag((byte) newDirection.toRotationIndex().getAsInt()));
}
}
transformed.setNbtData(tag);
}
}
return transformed;
}
public final BaseBlock transformFastInverse(BlockState block) {
BaseBlock transformed = transformBlock(block, true).toBaseBlock();
if (block.hasNbtData()) {
CompoundTag tag = block.getNbtData();
if (tag.containsKey("Rot")) {
int rot = tag.asInt("Rot");
Direction direction = Direction.fromRotationIndex(rot).get();
if (direction != null) {
Vector3 applyAbsolute = getTransform().inverse().apply(direction.toVector());
Vector3 applyOrigin = getTransform().inverse().apply(Vector3.ZERO);
Vector3 newAbsolute = Vector3.at(applyAbsolute.getX() - applyOrigin.getX(), applyAbsolute.getY() - applyOrigin.getY(), applyAbsolute.getZ() - applyOrigin.getZ());
Direction newDirection = Direction.findClosest(newAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
if (newDirection != null) {
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
values.put("Rot", new ByteTag((byte) newDirection.toRotationIndex().getAsInt()));
}
}
}
transformed.setNbtData(tag);
}
return transformed;
}
/**
* Get the new value with the transformed direction.

View File

@ -91,7 +91,7 @@ public class SurvivalModeExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
if (toolUse && block.getBlockType().getMaterial().isAir()) {
world.simulateBlockMine(BlockVector3.at(x, y, z));
return true;