Further work on BlockState transition

This commit is contained in:
Matthew Miller 2018-06-18 22:51:21 +10:00
parent e99190225e
commit 484687a49d
76 changed files with 2911 additions and 10010 deletions

View File

@ -30,15 +30,18 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.WorldData; import com.sk89q.worldedit.world.registry.WorldData;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.TreeType; import org.bukkit.TreeType;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
@ -167,7 +170,7 @@ public class BukkitWorld extends AbstractWorld {
for (int z = 0; z < 16; ++z) { for (int z = 0; z < 16; ++z) {
Vector pt = min.add(x, y, z); Vector pt = min.add(x, y, z);
int index = y * 16 * 16 + z * 16 + x; int index = y * 16 * 16 + z * 16 + x;
history[index] = editSession.getBlock(pt); history[index] = editSession.getFullBlock(pt);
} }
} }
} }
@ -190,7 +193,7 @@ public class BukkitWorld extends AbstractWorld {
editSession.smartSetBlock(pt, history[index]); editSession.smartSetBlock(pt, history[index]);
} else { // Otherwise fool with history } else { // Otherwise fool with history
editSession.rememberChange(pt, history[index], editSession.rememberChange(pt, history[index],
editSession.rawGetBlock(pt)); editSession.getFullBlock(pt));
} }
} }
} }
@ -362,7 +365,32 @@ public class BukkitWorld extends AbstractWorld {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public com.sk89q.worldedit.blocks.type.BlockState getBlock(Vector position) {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
BlockType blockType = BlockTypes.getBlockType(BundledBlockData.getInstance().fromLegacyId(bukkitBlock.getTypeId()));
return blockType.getDefaultState(); // TODO Data
}
@Override
public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} else {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return bukkitBlock.setTypeIdAndData(block.getBlockType().getLegacyId(), (byte) 0, notifyAndLight); // TODO Data
}
}
@Override
public LazyBlock getLazyBlock(Vector position) {
World world = getWorld();
Block bukkitBlock = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return new LazyBlock(bukkitBlock.getTypeId(), bukkitBlock.getData(), this, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) { if (adapter != null) {
return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position)); return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position));
@ -372,24 +400,6 @@ public class BukkitWorld extends AbstractWorld {
} }
} }
@Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} else {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return bukkitBlock.setTypeIdAndData(block.getBlockType().getLegacyId(), (byte) block.getData(), notifyAndLight);
}
}
@Override
public BaseBlock getLazyBlock(Vector position) {
World world = getWorld();
Block bukkitBlock = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return new LazyBlock(bukkitBlock.getTypeId(), bukkitBlock.getData(), this, position);
}
@Override @Override
public BaseBiome getBiome(Vector2D position) { public BaseBiome getBiome(Vector2D position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();

View File

@ -68,7 +68,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override @Override
public int getTypeId(int x, int y, int z) { public int getTypeId(int x, int y, int z) {
return editSession.getBlock(new Vector(x, y, z)).getId(); return editSession.getBlock(new Vector(x, y, z)).getBlockType().getLegacyId();
} }
@Override @Override
@ -78,7 +78,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override @Override
public boolean isEmpty(int x, int y, int z) { public boolean isEmpty(int x, int y, int z) {
return editSession.getBlock(new Vector(x, y, z)).isAir(); return editSession.getBlock(new Vector(x, y, z)).getBlockType() == BlockTypes.AIR;
} }
} }

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.bukkit.adapter; package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -89,7 +90,7 @@ public interface BukkitImplAdapter {
* @param notifyAndLight notify and light if set * @param notifyAndLight notify and light if set
* @return true if a block was likely changed * @return true if a block was likely changed
*/ */
boolean setBlock(Location location, BaseBlock state, boolean notifyAndLight); boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight);
/** /**
* Get the state for the given entity. * Get the state for the given entity.

View File

@ -95,7 +95,7 @@ public class LazyBlock extends BaseBlock {
@Override @Override
public CompoundTag getNbtData() { public CompoundTag getNbtData() {
if (!loaded) { if (!loaded) {
BaseBlock loadedBlock = extent.getBlock(position); BaseBlock loadedBlock = extent.getFullBlock(position);
super.setNbtData(loadedBlock.getNbtData()); super.setNbtData(loadedBlock.getNbtData());
loaded = true; loaded = true;
} }

View File

@ -19,8 +19,11 @@
package com.sk89q.worldedit; package com.sk89q.worldedit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.command.ClipboardCommands; import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.SchematicCommands; import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -30,18 +33,12 @@ import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
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.schematic.SchematicFormat; import com.sk89q.worldedit.schematic.SchematicFormat;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.DataException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* The clipboard remembers the state of a cuboid region. * The clipboard remembers the state of a cuboid region.
@ -71,7 +68,7 @@ public class CuboidClipboard {
UP_DOWN UP_DOWN
} }
private BaseBlock[][][] data; private BlockStateHolder[][][] data;
private Vector offset; private Vector offset;
private Vector origin; private Vector origin;
private Vector size; private Vector size;
@ -154,186 +151,6 @@ public class CuboidClipboard {
return size.getBlockY(); return size.getBlockY();
} }
/**
* Rotate the clipboard in 2D. It can only rotate by angles divisible by 90.
*
* @param angle in degrees
*/
public void rotate2D(int angle) {
angle = angle % 360;
if (angle % 90 != 0) { // Can only rotate 90 degrees at the moment
return;
}
final boolean reverse = angle < 0;
final int numRotations = Math.abs((int) Math.floor(angle / 90.0));
final int width = getWidth();
final int length = getLength();
final int height = getHeight();
final Vector sizeRotated = size.transform2D(angle, 0, 0, 0, 0);
final int shiftX = sizeRotated.getX() < 0 ? -sizeRotated.getBlockX() - 1 : 0;
final int shiftZ = sizeRotated.getZ() < 0 ? -sizeRotated.getBlockZ() - 1 : 0;
final BaseBlock[][][] newData = new BaseBlock
[Math.abs(sizeRotated.getBlockX())]
[Math.abs(sizeRotated.getBlockY())]
[Math.abs(sizeRotated.getBlockZ())];
for (int x = 0; x < width; ++x) {
for (int z = 0; z < length; ++z) {
final Vector2D v = new Vector2D(x, z).transform2D(angle, 0, 0, shiftX, shiftZ);
final int newX = v.getBlockX();
final int newZ = v.getBlockZ();
for (int y = 0; y < height; ++y) {
final BaseBlock block = data[x][y][z];
newData[newX][y][newZ] = block;
if (block == null) {
continue;
}
if (reverse) {
for (int i = 0; i < numRotations; ++i) {
block.rotate90Reverse();
}
} else {
for (int i = 0; i < numRotations; ++i) {
block.rotate90();
}
}
}
}
}
data = newData;
size = new Vector(Math.abs(sizeRotated.getBlockX()),
Math.abs(sizeRotated.getBlockY()),
Math.abs(sizeRotated.getBlockZ()));
offset = offset.transform2D(angle, 0, 0, 0, 0)
.subtract(shiftX, 0, shiftZ);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
*/
public void flip(FlipDirection dir) {
flip(dir, false);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
* @param aroundPlayer flip the offset around the player
*/
public void flip(FlipDirection dir, boolean aroundPlayer) {
checkNotNull(dir);
final int width = getWidth();
final int length = getLength();
final int height = getHeight();
switch (dir) {
case WEST_EAST:
final int wid = (int) Math.ceil(width / 2.0f);
for (int xs = 0; xs < wid; ++xs) {
for (int z = 0; z < length; ++z) {
for (int y = 0; y < height; ++y) {
final BaseBlock block1 = data[xs][y][z];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (xs == width - xs - 1) {
continue;
}
final BaseBlock block2 = data[width - xs - 1][y][z];
if (block2 != null) {
block2.flip(dir);
}
data[xs][y][z] = block2;
data[width - xs - 1][y][z] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setX(1 - offset.getX() - width);
}
break;
case NORTH_SOUTH:
final int len = (int) Math.ceil(length / 2.0f);
for (int zs = 0; zs < len; ++zs) {
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
final BaseBlock block1 = data[x][y][zs];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (zs == length - zs - 1) {
continue;
}
final BaseBlock block2 = data[x][y][length - zs - 1];
if (block2 != null) {
block2.flip(dir);
}
data[x][y][zs] = block2;
data[x][y][length - zs - 1] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setZ(1 - offset.getZ() - length);
}
break;
case UP_DOWN:
final int hei = (int) Math.ceil(height / 2.0f);
for (int ys = 0; ys < hei; ++ys) {
for (int x = 0; x < width; ++x) {
for (int z = 0; z < length; ++z) {
final BaseBlock block1 = data[x][ys][z];
if (block1 != null) {
block1.flip(dir);
}
// Skip the center plane
if (ys == height - ys - 1) {
continue;
}
final BaseBlock block2 = data[x][height - ys - 1][z];
if (block2 != null) {
block2.flip(dir);
}
data[x][ys][z] = block2;
data[x][height - ys - 1][z] = block1;
}
}
}
if (aroundPlayer) {
offset = offset.setY(1 - offset.getY() - height);
}
break;
}
}
/** /**
* Copies blocks to the clipboard. * Copies blocks to the clipboard.
* *
@ -426,12 +243,12 @@ public class CuboidClipboard {
for (int x = 0; x < size.getBlockX(); ++x) { for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) { for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) { for (int z = 0; z < size.getBlockZ(); ++z) {
final BaseBlock block = data[x][y][z]; final BlockStateHolder block = data[x][y][z];
if (block == null) { if (block == null) {
continue; continue;
} }
if (noAir && block.isAir()) { if (noAir && block.getBlockType() == BlockTypes.AIR) {
continue; continue;
} }
@ -481,10 +298,10 @@ public class CuboidClipboard {
* @deprecated use {@link #getBlock(Vector)} instead * @deprecated use {@link #getBlock(Vector)} instead
*/ */
@Deprecated @Deprecated
public BaseBlock getPoint(Vector position) throws ArrayIndexOutOfBoundsException { public BlockStateHolder getPoint(Vector position) throws ArrayIndexOutOfBoundsException {
final BaseBlock block = getBlock(position); final BlockStateHolder block = getBlock(position);
if (block == null) { if (block == null) {
return new BaseBlock(BlockID.AIR); return BlockTypes.AIR.getDefaultState();
} }
return block; return block;
@ -499,7 +316,7 @@ public class CuboidClipboard {
* @return null, if this block was outside the (non-cuboid) selection while copying * @return null, if this block was outside the (non-cuboid) selection while copying
* @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard * @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard
*/ */
public BaseBlock getBlock(Vector position) throws ArrayIndexOutOfBoundsException { public BlockStateHolder getBlock(Vector position) throws ArrayIndexOutOfBoundsException {
return data[position.getBlockX()][position.getBlockY()][position.getBlockZ()]; return data[position.getBlockX()][position.getBlockY()][position.getBlockZ()];
} }
@ -599,88 +416,6 @@ public class CuboidClipboard {
this.offset = offset; this.offset = offset;
} }
/**
* Get the block distribution inside a clipboard.
*
* @return a block distribution
*/
public List<Countable<Integer>> getBlockDistribution() {
List<Countable<Integer>> distribution = new ArrayList<>();
Map<Integer, Countable<Integer>> map = new HashMap<>();
int maxX = getWidth();
int maxY = getHeight();
int maxZ = getLength();
for (int x = 0; x < maxX; ++x) {
for (int y = 0; y < maxY; ++y) {
for (int z = 0; z < maxZ; ++z) {
final BaseBlock block = data[x][y][z];
if (block == null) {
continue;
}
int id = block.getId();
if (map.containsKey(id)) {
map.get(id).increment();
} else {
Countable<Integer> c = new Countable<>(id, 1);
map.put(id, c);
distribution.add(c);
}
}
}
}
Collections.sort(distribution);
// Collections.reverse(distribution);
return distribution;
}
/**
* Get the block distribution inside a clipboard with data values.
*
* @return a block distribution
*/
// TODO reduce code duplication
public List<Countable<BaseBlock>> getBlockDistributionWithData() {
List<Countable<BaseBlock>> distribution = new ArrayList<>();
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<>();
int maxX = getWidth();
int maxY = getHeight();
int maxZ = getLength();
for (int x = 0; x < maxX; ++x) {
for (int y = 0; y < maxY; ++y) {
for (int z = 0; z < maxZ; ++z) {
final BaseBlock block = data[x][y][z];
if (block == null) {
continue;
}
// Strip the block from metadata that is not part of our key
final BaseBlock bareBlock = new BaseBlock(block.getId(), block.getData());
if (map.containsKey(bareBlock)) {
map.get(bareBlock).increment();
} else {
Countable<BaseBlock> c = new Countable<>(bareBlock, 1);
map.put(bareBlock, c);
distribution.add(c);
}
}
}
}
Collections.sort(distribution);
// Collections.reverse(distribution);
return distribution;
}
/** /**
* Stores a copied entity. * Stores a copied entity.
*/ */

View File

@ -22,6 +22,9 @@ package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -101,7 +104,7 @@ public class EditSession implements Extent {
private static final Logger log = Logger.getLogger(EditSession.class.getCanonicalName()); private static final Logger log = Logger.getLogger(EditSession.class.getCanonicalName());
/** /**
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to * Used by {@link #setBlock(Vector, BlockStateHolder, Stage)} to
* determine which {@link Extent}s should be bypassed. * determine which {@link Extent}s should be bypassed.
*/ */
public enum Stage { public enum Stage {
@ -365,25 +368,18 @@ public class EditSession implements Extent {
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
return world.getLazyBlock(position); return world.getLazyBlock(position);
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
return world.getBlock(position); return world.getBlock(position);
} }
/** @Override
* Gets the block type at a position. public BaseBlock getFullBlock(Vector position) {
* return world.getFullBlock(position);
* @param position the position
* @return a block
* @deprecated Use {@link #getBlock(Vector)}
*/
@Deprecated
public BaseBlock rawGetBlock(Vector position) {
return getBlock(position);
} }
/** /**
@ -432,7 +428,7 @@ public class EditSession implements Extent {
* @return whether the block changed * @return whether the block changed
* @throws WorldEditException thrown on a set error * @throws WorldEditException thrown on a set error
*/ */
public boolean setBlock(Vector position, BaseBlock block, Stage stage) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block, Stage stage) throws WorldEditException {
switch (stage) { switch (stage) {
case BEFORE_HISTORY: case BEFORE_HISTORY:
return bypassNone.setBlock(position, block); return bypassNone.setBlock(position, block);
@ -452,7 +448,7 @@ public class EditSession implements Extent {
* @param block the block * @param block the block
* @return whether the block changed * @return whether the block changed
*/ */
public boolean rawSetBlock(Vector position, BaseBlock block) { public boolean rawSetBlock(Vector position, BlockStateHolder block) {
try { try {
return setBlock(position, block, Stage.BEFORE_CHANGE); return setBlock(position, block, Stage.BEFORE_CHANGE);
} catch (WorldEditException e) { } catch (WorldEditException e) {
@ -467,7 +463,7 @@ public class EditSession implements Extent {
* @param block the block * @param block the block
* @return whether the block changed * @return whether the block changed
*/ */
public boolean smartSetBlock(Vector position, BaseBlock block) { public boolean smartSetBlock(Vector position, BlockStateHolder block) {
try { try {
return setBlock(position, block, Stage.BEFORE_REORDER); return setBlock(position, block, Stage.BEFORE_REORDER);
} catch (WorldEditException e) { } catch (WorldEditException e) {
@ -476,7 +472,7 @@ public class EditSession implements Extent {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block) throws MaxChangedBlocksException { public boolean setBlock(Vector position, BlockStateHolder block) throws MaxChangedBlocksException {
try { try {
return setBlock(position, block, Stage.BEFORE_HISTORY); return setBlock(position, block, Stage.BEFORE_HISTORY);
} catch (MaxChangedBlocksException e) { } catch (MaxChangedBlocksException e) {
@ -606,7 +602,7 @@ public class EditSession implements Extent {
* @param searchBlocks the list of blocks to search * @param searchBlocks the list of blocks to search
* @return the number of blocks that matched the pattern * @return the number of blocks that matched the pattern
*/ */
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) { public int countBlocks(Region region, Set<BlockStateHolder> searchBlocks) {
FuzzyBlockMask mask = new FuzzyBlockMask(this, searchBlocks); FuzzyBlockMask mask = new FuzzyBlockMask(this, searchBlocks);
Counter count = new Counter(); Counter count = new Counter();
RegionMaskingFilter filter = new RegionMaskingFilter(mask, count); RegionMaskingFilter filter = new RegionMaskingFilter(mask, count);
@ -626,7 +622,7 @@ public class EditSession implements Extent {
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int fillXZ(Vector origin, BaseBlock block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException { public int fillXZ(Vector origin, BlockStateHolder block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
return fillXZ(origin, new BlockPattern(block), radius, depth, recursive); return fillXZ(origin, new BlockPattern(block), radius, depth, recursive);
} }
@ -781,7 +777,7 @@ public class EditSession implements Extent {
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int replaceBlocks(Region region, Set<BaseBlock> filter, BaseBlock replacement) throws MaxChangedBlocksException { public int replaceBlocks(Region region, Set<BlockStateHolder> filter, BlockStateHolder replacement) throws MaxChangedBlocksException {
return replaceBlocks(region, filter, new BlockPattern(replacement)); return replaceBlocks(region, filter, new BlockPattern(replacement));
} }
@ -795,7 +791,7 @@ public class EditSession implements Extent {
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException { public int replaceBlocks(Region region, Set<BlockStateHolder> filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new ExistingBlockMask(this) : new FuzzyBlockMask(this, filter); Mask mask = filter == null ? new ExistingBlockMask(this) : new FuzzyBlockMask(this, filter);
return replaceBlocks(region, mask, pattern); return replaceBlocks(region, mask, pattern);
} }
@ -948,7 +944,7 @@ public class EditSession implements Extent {
final int maxY = region.getMaximumPoint().getBlockY(); final int maxY = region.getMaximumPoint().getBlockY();
final ArbitraryShape shape = new RegionShape(region) { final ArbitraryShape shape = new RegionShape(region) {
@Override @Override
protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { protected BlockStateHolder getMaterial(int x, int y, int z, BlockStateHolder defaultMaterial) {
if (y > maxY || y < minY) { if (y > maxY || y < minY) {
// Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region // Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region
return defaultMaterial; return defaultMaterial;
@ -1647,7 +1643,7 @@ public class EditSession implements Extent {
for (int z = basePosition.getBlockZ() - size; z <= basePosition.getBlockZ() for (int z = basePosition.getBlockZ() - size; z <= basePosition.getBlockZ()
+ size; ++z) { + size; ++z) {
// Don't want to be in the ground // Don't want to be in the ground
if (!getBlock(new Vector(x, basePosition.getBlockY(), z)).isAir()) { if (getBlock(new Vector(x, basePosition.getBlockY(), z)).getBlockType() != BlockTypes.AIR) {
continue; continue;
} }
// The gods don't want a tree here // The gods don't want a tree here
@ -1739,9 +1735,9 @@ public class EditSession implements Extent {
* @return the results * @return the results
*/ */
// TODO reduce code duplication - probably during ops-redux // TODO reduce code duplication - probably during ops-redux
public List<Countable<BaseBlock>> getBlockDistributionWithData(Region region) { public List<Countable<BlockStateHolder>> getBlockDistributionWithData(Region region) {
List<Countable<BaseBlock>> distribution = new ArrayList<>(); List<Countable<BlockStateHolder>> distribution = new ArrayList<>();
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<>(); Map<BlockStateHolder, Countable<BlockStateHolder>> map = new HashMap<>();
if (region instanceof CuboidRegion) { if (region instanceof CuboidRegion) {
// Doing this for speed // Doing this for speed
@ -1760,12 +1756,12 @@ public class EditSession implements Extent {
for (int z = minZ; z <= maxZ; ++z) { for (int z = minZ; z <= maxZ; ++z) {
Vector pt = new Vector(x, y, z); Vector pt = new Vector(x, y, z);
BaseBlock blk = getBlock(pt); BlockStateHolder blk = getBlock(pt);
if (map.containsKey(blk)) { if (map.containsKey(blk)) {
map.get(blk).increment(); map.get(blk).increment();
} else { } else {
Countable<BaseBlock> c = new Countable<>(blk, 1); Countable<BlockStateHolder> c = new Countable<>(blk, 1);
map.put(blk, c); map.put(blk, c);
distribution.add(c); distribution.add(c);
} }
@ -1774,12 +1770,12 @@ public class EditSession implements Extent {
} }
} else { } else {
for (Vector pt : region) { for (Vector pt : region) {
BaseBlock blk = getBlock(pt); BlockStateHolder blk = getBlock(pt);
if (map.containsKey(blk)) { if (map.containsKey(blk)) {
map.get(blk).increment(); map.get(blk).increment();
} else { } else {
Countable<BaseBlock> c = new Countable<>(blk, 1); Countable<BlockStateHolder> c = new Countable<>(blk, 1);
map.put(blk, c); map.put(blk, c);
} }
} }
@ -1803,13 +1799,14 @@ public class EditSession implements Extent {
final ArbitraryShape shape = new ArbitraryShape(region) { final ArbitraryShape shape = new ArbitraryShape(region) {
@Override @Override
protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { protected BlockStateHolder getMaterial(int x, int y, int z, BlockStateHolder defaultMaterial) {
final Vector current = new Vector(x, y, z); final Vector current = new Vector(x, y, z);
environment.setCurrentBlock(current); environment.setCurrentBlock(current);
final Vector scaled = current.subtract(zero).divide(unit); final Vector scaled = current.subtract(zero).divide(unit);
try { try {
if (expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getBlockType().getLegacyId(), defaultMaterial.getData()) <= 0) { if (expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getBlockType().getLegacyId(), 0) <= 0) {
// TODO data
return null; return null;
} }
@ -1847,7 +1844,7 @@ public class EditSession implements Extent {
final BlockVector sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue()); final BlockVector sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue());
// read block from world // read block from world
final BaseBlock material = world.getBlock(sourcePosition); final BaseBlock material = world.getFullBlock(sourcePosition);
// queue operation // queue operation
queue.put(position, material); queue.put(position, material);

View File

@ -28,12 +28,10 @@ import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.state.State; import com.sk89q.worldedit.world.registry.state.State;
import com.sk89q.worldedit.world.registry.state.value.StateValue; import com.sk89q.worldedit.world.registry.state.value.StateValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -69,6 +67,13 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/ */
@Deprecated @Deprecated
public BaseBlock(int id) { public BaseBlock(int id) {
try {
this.blockState = BlockTypes.getBlockType(BundledBlockData.getInstance().fromLegacyId(id)).getDefaultState();
} catch (Exception e) {
System.out.println(id);
System.out.println(BundledBlockData.getInstance().fromLegacyId(id));
e.printStackTrace();
}
} }
/** /**
@ -108,6 +113,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/ */
@Deprecated @Deprecated
public BaseBlock(int id, int data) { public BaseBlock(int id, int data) {
this(id);
} }
/** /**
@ -119,6 +125,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/ */
@Deprecated @Deprecated
public BaseBlock(int id, int data, @Nullable CompoundTag nbtData) { public BaseBlock(int id, int data, @Nullable CompoundTag nbtData) {
this(id);
setNbtData(nbtData); setNbtData(nbtData);
} }
@ -325,51 +332,9 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
* @param o other block * @param o other block
* @return true if equal * @return true if equal
*/ */
public boolean equalsFuzzy(BaseBlock o) { @Override
if (!getBlockType().equals(o.getBlockType())) { public boolean equalsFuzzy(BlockStateHolder o) {
return false; return this.getState().equalsFuzzy(o);
}
List<State> differingStates = new ArrayList<>();
for (State state : o.getStates().keySet()) {
if (getState(state) == null) {
differingStates.add(state);
}
}
for (State state : getStates().keySet()) {
if (o.getState(state) == null) {
differingStates.add(state);
}
}
for (State state : differingStates) {
if (!getState(state).equals(o.getState(state))) {
return false;
}
}
return true;
}
/**
* @deprecated This method is silly, use {@link #containsFuzzy(java.util.Collection, BaseBlock)} instead.
*/
@Deprecated
public boolean inIterable(Iterable<BaseBlock> iter) {
for (BaseBlock block : iter) {
if (block.equalsFuzzy(this)) {
return true;
}
}
return false;
}
/**
* @deprecated Use {@link Blocks#containsFuzzy(Collection, BaseBlock)}
*/
@Deprecated
public static boolean containsFuzzy(Collection<BaseBlock> collection, BaseBlock o) {
return Blocks.containsFuzzy(collection, o);
} }
@Override @Override

View File

@ -21,7 +21,9 @@ package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.type.ItemType; import com.sk89q.worldedit.blocks.type.ItemType;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.world.NbtValued; import com.sk89q.worldedit.world.NbtValued;
import com.sk89q.worldedit.world.registry.BundledItemData;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -44,6 +46,7 @@ public class BaseItem implements NbtValued {
*/ */
@Deprecated @Deprecated
public BaseItem(int id) { public BaseItem(int id) {
this(ItemTypes.getItemType(BundledItemData.getInstance().fromLegacyId(id)));
} }
/** /**

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.blocks;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.PlayerDirection; import com.sk89q.worldedit.PlayerDirection;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -671,9 +672,9 @@ public enum BlockType {
* @param block the block * @param block the block
* @return true if the block can be passed through * @return true if the block can be passed through
*/ */
public static boolean canPassThrough(BaseBlock block) { public static boolean canPassThrough(BlockStateHolder block) {
checkNotNull(block); checkNotNull(block);
return canPassThrough(block.getId(), block.getData()); return canPassThrough(block.getBlockType().getLegacyId());
} }
/** /**
@ -769,9 +770,9 @@ public enum BlockType {
* @param block the block * @param block the block
* @return the y offset * @return the y offset
*/ */
public static double centralTopLimit(BaseBlock block) { public static double centralTopLimit(BlockStateHolder block) {
checkNotNull(block); checkNotNull(block);
return centralTopLimit(block.getId(), block.getData()); return centralTopLimit(block.getBlockType().getLegacyId(), 0);
} }
/** /**

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import java.util.Collection; import java.util.Collection;
/** /**
@ -36,9 +38,9 @@ public final class Blocks {
* @param o the block * @param o the block
* @return true if the collection contains the given block * @return true if the collection contains the given block
*/ */
public static boolean containsFuzzy(Collection<? extends BaseBlock> collection, BaseBlock o) { public static boolean containsFuzzy(Collection<? extends BlockStateHolder> collection, BlockStateHolder o) {
// Allow masked data in the searchBlocks to match various types // Allow masked data in the searchBlocks to match various types
for (BaseBlock b : collection) { for (BlockStateHolder b : collection) {
if (b.equalsFuzzy(o)) { if (b.equalsFuzzy(o)) {
return true; return true;
} }

View File

@ -26,8 +26,10 @@ import com.google.common.collect.Table;
import com.sk89q.worldedit.world.registry.state.State; import com.sk89q.worldedit.world.registry.state.State;
import com.sk89q.worldedit.world.registry.state.value.StateValue; import com.sk89q.worldedit.world.registry.state.value.StateValue;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -108,6 +110,33 @@ public class BlockState implements BlockStateHolder<BlockState> {
return Collections.unmodifiableMap(this.values); return Collections.unmodifiableMap(this.values);
} }
@Override
public boolean equalsFuzzy(BlockStateHolder o) {
if (!getBlockType().equals(o.getBlockType())) {
return false;
}
List<State> differingStates = new ArrayList<>();
for (Object state : o.getStates().keySet()) {
if (getState((State) state) == null) {
differingStates.add((State) state);
}
}
for (State state : getStates().keySet()) {
if (o.getState(state) == null) {
differingStates.add(state);
}
}
for (State state : differingStates) {
if (!getState(state).equals(o.getState(state))) {
return false;
}
}
return true;
}
/** /**
* Internal method used for creating the initial BlockState. * Internal method used for creating the initial BlockState.
* *

View File

@ -56,4 +56,12 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
* @return The states * @return The states
*/ */
Map<State, StateValue> getStates(); Map<State, StateValue> getStates();
/**
* Checks if the type is the same, and if the matched states are the same.
*
* @param o other block
* @return true if equal
*/
boolean equalsFuzzy(BlockStateHolder o);
} }

View File

@ -35,6 +35,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.ItemTypes; import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
@ -639,7 +640,7 @@ public class SelectionCommands {
context.setSession(session); context.setSession(session);
context.setRestricted(false); context.setRestricted(false);
Set<BaseBlock> searchBlocks = we.getBlockFactory().parseFromListInput(args.getString(0), context); Set<BlockStateHolder> searchBlocks = we.getBlockFactory().parseFromListInput(args.getString(0), context);
int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks); int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks);
player.print("Counted: " + count); player.print("Counted: " + count);
} }
@ -660,7 +661,7 @@ public class SelectionCommands {
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException { public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
int size; int size;
List<Countable<BaseBlock>> distributionData; List<Countable<BlockStateHolder>> distributionData;
if (args.hasFlag('c')) { if (args.hasFlag('c')) {
// TODO: Update for new clipboard // TODO: Update for new clipboard
@ -677,7 +678,7 @@ public class SelectionCommands {
player.print("# total blocks: " + size); player.print("# total blocks: " + size);
for (Countable<BaseBlock> c : distributionData) { for (Countable<BlockStateHolder> c : distributionData) {
String name = c.getID().getBlockType().getName(); String name = c.getID().getBlockType().getName();
String str = String.format("%-7s (%.3f%%) %s #%s%s", String str = String.format("%-7s (%.3f%%) %s #%s%s",
String.valueOf(c.getAmount()), String.valueOf(c.getAmount()),

View File

@ -25,6 +25,7 @@ import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.command.tool.*; import com.sk89q.worldedit.command.tool.*;
@ -109,7 +110,7 @@ public class ToolCommands {
context.setRestricted(true); context.setRestricted(true);
context.setPreferringWildcard(false); context.setPreferringWildcard(false);
BaseBlock targetBlock = we.getBlockFactory().parseFromInput(args.getString(0), context); BlockStateHolder targetBlock = we.getBlockFactory().parseFromInput(args.getString(0), context);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new BlockReplacer(targetBlock)); session.setTool(itemStack.getType(), new BlockReplacer(targetBlock));
player.print("Block replacer tool bound to " + itemStack.getType().getName() + "."); player.print("Block replacer tool bound to " + itemStack.getType().getName() + ".");
@ -207,8 +208,8 @@ public class ToolCommands {
context.setRestricted(true); context.setRestricted(true);
context.setPreferringWildcard(false); context.setPreferringWildcard(false);
BaseBlock secondary = we.getBlockFactory().parseFromInput(args.getString(0), context); BlockStateHolder secondary = we.getBlockFactory().parseFromInput(args.getString(0), context);
BaseBlock primary = we.getBlockFactory().parseFromInput(args.getString(1), context); BlockStateHolder primary = we.getBlockFactory().parseFromInput(args.getString(1), context);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command; package com.sk89q.worldedit.command;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
@ -31,7 +33,7 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.command.util.CreatureButcher; import com.sk89q.worldedit.command.util.CreatureButcher;
import com.sk89q.worldedit.command.util.EntityRemover; import com.sk89q.worldedit.command.util.EntityRemover;
@ -69,8 +71,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
/** /**
* Utility commands. * Utility commands.
*/ */
@ -257,7 +257,7 @@ public class UtilityCommands {
context.setRestricted(false); context.setRestricted(false);
context.setPreferringWildcard(false); context.setPreferringWildcard(false);
BaseBlock block = we.getBlockFactory().parseFromInput(args.getString(0), context); BlockStateHolder block = we.getBlockFactory().parseFromInput(args.getString(0), context);
int size = Math.max(1, args.getInteger(1, 50)); int size = Math.max(1, args.getInteger(1, 50));
we.checkMaxRadius(size); we.checkMaxRadius(size);
@ -279,7 +279,7 @@ public class UtilityCommands {
int size = Math.max(1, args.getInteger(0)); int size = Math.max(1, args.getInteger(0));
int affected; int affected;
Set<BaseBlock> from; Set<BlockStateHolder> from;
Pattern to; Pattern to;
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();

View File

@ -20,8 +20,8 @@
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
@ -32,9 +32,9 @@ import com.sk89q.worldedit.extent.inventory.BlockBag;
*/ */
public class BlockReplacer implements DoubleActionBlockTool { public class BlockReplacer implements DoubleActionBlockTool {
private BaseBlock targetBlock; private BlockStateHolder targetBlock;
public BlockReplacer(BaseBlock targetBlock) { public BlockReplacer(BlockStateHolder targetBlock) {
this.targetBlock = targetBlock; this.targetBlock = targetBlock;
} }
@ -67,7 +67,7 @@ public class BlockReplacer implements DoubleActionBlockTool {
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
EditSession editSession = session.createEditSession(player); EditSession editSession = session.createEditSession(player);
targetBlock = (editSession).getBlock(clicked.toVector()); targetBlock = (editSession).getBlock(clicked.toVector());
BlockType type = targetBlock.getBlockType().getLegacyType(); BlockType type = targetBlock.getBlockType();
if (type != null) { if (type != null) {
player.print("Replacer tool switched to: " + type.getName()); player.print("Replacer tool switched to: " + type.getName());

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
@ -35,10 +36,10 @@ import com.sk89q.worldedit.util.Location;
*/ */
public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool { public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool {
private BaseBlock primary; private BlockStateHolder primary;
private BaseBlock secondary; private BlockStateHolder secondary;
public LongRangeBuildTool(BaseBlock primary, BaseBlock secondary) { public LongRangeBuildTool(BlockStateHolder primary, BlockStateHolder secondary) {
super("worldedit.tool.lrbuild"); super("worldedit.tool.lrbuild");
this.primary = primary; this.primary = primary;
this.secondary = secondary; this.secondary = secondary;

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.MobSpawnerBlock; import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock; import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
@ -45,7 +46,7 @@ public class QueryTool implements BlockTool {
World world = (World) clicked.getExtent(); World world = (World) clicked.getExtent();
EditSession editSession = session.createEditSession(player); EditSession editSession = session.createEditSession(player);
BaseBlock block = editSession.getBlock(clicked.toVector()); BlockStateHolder block = editSession.getFullBlock(clicked.toVector());
player.print("\u00A79@" + clicked.toVector() + ": " + "\u00A7e" player.print("\u00A79@" + clicked.toVector() + ": " + "\u00A7e"
+ "#" + block.getBlockType() + "\u00A77" + " (" + "#" + block.getBlockType() + "\u00A77" + " ("

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
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.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
@ -43,11 +44,11 @@ public class GravityBrush implements Brush {
for (double x = position.getBlockX() + size; x > position.getBlockX() - size; --x) { for (double x = position.getBlockX() + size; x > position.getBlockX() - size; --x) {
for (double z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) { for (double z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
double y = startY; double y = startY;
final List<BaseBlock> blockTypes = new ArrayList<>(); final List<BlockStateHolder> blockTypes = new ArrayList<>();
for (; y > position.getBlockY() - size; --y) { for (; y > position.getBlockY() - size; --y) {
final Vector pt = new Vector(x, y, z); final Vector pt = new Vector(x, y, z);
final BaseBlock block = editSession.getBlock(pt); final BlockStateHolder block = editSession.getBlock(pt);
if (!block.isAir()) { if (block.getBlockType() != BlockTypes.AIR) {
blockTypes.add(block); blockTypes.add(block);
editSession.setBlock(pt, air); editSession.setBlock(pt, air);
} }
@ -55,7 +56,7 @@ public class GravityBrush implements Brush {
Vector pt = new Vector(x, y, z); Vector pt = new Vector(x, y, z);
Collections.reverse(blockTypes); Collections.reverse(blockTypes);
for (int i = 0; i < blockTypes.size();) { for (int i = 0; i < blockTypes.size();) {
if (editSession.getBlock(pt).isAir()) { if (editSession.getBlock(pt).getBlockType() == BlockTypes.AIR) {
editSession.setBlock(pt, blockTypes.get(i++)); editSession.setBlock(pt, blockTypes.get(i++));
} }
pt = pt.add(0, 1, 0); pt = pt.add(0, 1, 0);

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.internal.registry.AbstractFactory; import com.sk89q.worldedit.internal.registry.AbstractFactory;
@ -35,7 +36,7 @@ import java.util.Set;
* <p>Instances of this class can be taken from * <p>Instances of this class can be taken from
* {@link WorldEdit#getBlockFactory()}.</p> * {@link WorldEdit#getBlockFactory()}.</p>
*/ */
public class BlockFactory extends AbstractFactory<BaseBlock> { public class BlockFactory extends AbstractFactory<BlockStateHolder> {
/** /**
* Create a new instance. * Create a new instance.
@ -56,8 +57,8 @@ public class BlockFactory extends AbstractFactory<BaseBlock> {
* @return a set of blocks * @return a set of blocks
* @throws InputParseException thrown in error with the input * @throws InputParseException thrown in error with the input
*/ */
public Set<BaseBlock> parseFromListInput(String input, ParserContext context) throws InputParseException { public Set<BlockStateHolder> parseFromListInput(String input, ParserContext context) throws InputParseException {
Set<BaseBlock> blocks = new HashSet<>(); Set<BlockStateHolder> blocks = new HashSet<>();
for (String token : input.split(",")) { for (String token : input.split(",")) {
blocks.add(parseFromInput(token, context)); blocks.add(parseFromInput(token, context));
} }

View File

@ -30,6 +30,7 @@ import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock; import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.blocks.metadata.MobType; import com.sk89q.worldedit.blocks.metadata.MobType;
import com.sk89q.worldedit.blocks.type.BlockState; import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
@ -54,7 +55,7 @@ import java.util.regex.Pattern;
/** /**
* Parses block input strings. * Parses block input strings.
*/ */
class DefaultBlockParser extends InputParser<BaseBlock> { class DefaultBlockParser extends InputParser<BlockStateHolder> {
protected DefaultBlockParser(WorldEdit worldEdit) { protected DefaultBlockParser(WorldEdit worldEdit) {
super(worldEdit); super(worldEdit);
@ -75,14 +76,14 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
} }
@Override @Override
public BaseBlock parseFromInput(String input, ParserContext context) public BlockStateHolder parseFromInput(String input, ParserContext context)
throws InputParseException { throws InputParseException {
String originalInput = input; String originalInput = input;
input = input.replace("_", " "); input = input.replace("_", " ");
input = input.replace(";", "|"); input = input.replace(";", "|");
Exception suppressed = null; Exception suppressed = null;
try { try {
BaseBlock modified = parseLogic(input, context); BlockStateHolder modified = parseLogic(input, context);
if (modified != null) { if (modified != null) {
return modified; return modified;
} }
@ -99,22 +100,22 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
} }
} }
private static Pattern blockStatePattern = Pattern.compile("([a-z:]+)(?:\\[([a-zA-Z0-9=, ]+)\\])?", Pattern.CASE_INSENSITIVE); private static Pattern blockStatePattern = Pattern.compile("([a-z:]+)(?:\\[([a-zA-Z0-9=, ]+)])?", Pattern.CASE_INSENSITIVE);
private static String[] EMPTY_STRING_ARRAY = new String[]{}; private static String[] EMPTY_STRING_ARRAY = new String[]{};
private BaseBlock parseLogic(String input, ParserContext context) private BlockStateHolder parseLogic(String input, ParserContext context)
throws InputParseException, NoMatchException, throws InputParseException, NoMatchException,
DisallowedUsageException { DisallowedUsageException {
BlockType blockType; BlockType blockType;
Map<State, StateValue> blockStates = new HashMap<>(); Map<State, StateValue> blockStates = new HashMap<>();
String[] blockAndExtraData = input.split("\\|"); String[] blockAndExtraData = input.trim().split("\\|");
Matcher matcher = blockStatePattern.matcher(blockAndExtraData[0]); Matcher matcher = blockStatePattern.matcher(blockAndExtraData[0]);
if (matcher.groupCount() < 1 || matcher.groupCount() > 2) { if (!matcher.matches() || matcher.groupCount() < 2 || matcher.groupCount() > 3) {
throw new InputParseException("Invalid format"); throw new InputParseException("Invalid format");
} }
String typeString = matcher.group(1); String typeString = matcher.group(1);
String[] stateProperties = EMPTY_STRING_ARRAY; String[] stateProperties = EMPTY_STRING_ARRAY;
if (matcher.groupCount() == 2) { if (matcher.groupCount() == 3) {
stateProperties = matcher.group(2).split(","); stateProperties = matcher.group(2).split(",");
} }
@ -145,10 +146,7 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
} catch (IncompleteRegionException e) { } catch (IncompleteRegionException e) {
throw new InputParseException("Your selection is not complete."); throw new InputParseException("Your selection is not complete.");
} }
final BaseBlock blockInHand = world.getBlock(primaryPosition); final BlockState blockInHand = world.getBlock(primaryPosition);
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType(); blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates(); blockStates = blockInHand.getStates();
@ -239,7 +237,7 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
return new SkullBlock(state, type.replace(" ", "_")); // valid MC usernames return new SkullBlock(state, type.replace(" ", "_")); // valid MC usernames
} else { } else {
return new BaseBlock(state); return state;
} }
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -40,7 +41,7 @@ class RandomPatternParser extends InputParser<Pattern> {
RandomPattern randomPattern = new RandomPattern(); RandomPattern randomPattern = new RandomPattern();
for (String token : input.split(",")) { for (String token : input.split(",")) {
BaseBlock block; BlockStateHolder block;
double chance; double chance;

View File

@ -23,8 +23,9 @@ import com.sk89q.worldedit.PlayerDirection;
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;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.blocks.type.ItemType; import com.sk89q.worldedit.blocks.type.ItemType;
import com.sk89q.worldedit.blocks.type.ItemTypes; import com.sk89q.worldedit.blocks.type.ItemTypes;
@ -110,9 +111,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
if (free == 2) { if (free == 2) {
if (y - 1 != origY) { if (y - 1 != origY) {
final Vector pos = new Vector(x, y - 2, z); final Vector pos = new Vector(x, y - 2, z);
final int id = world.getBlock(pos).getId(); final BlockState state = world.getBlock(pos);
final int data = world.getBlock(pos).getData(); setPosition(new Vector(x + 0.5, y - 2 + BlockType.centralTopLimit(state), z + 0.5));
setPosition(new Vector(x + 0.5, y - 2 + BlockType.centralTopLimit(id, data), z + 0.5));
} }
return; return;
@ -131,10 +131,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
while (y >= 0) { while (y >= 0) {
final Vector pos = new Vector(x, y, z); final Vector pos = new Vector(x, y, z);
final int id = world.getBlock(pos).getId(); final BlockState id = world.getBlock(pos);
final int data = world.getBlock(pos).getData(); if (!BlockType.canPassThrough(id.getBlockType().getLegacyId())) {
if (!BlockType.canPassThrough(id, data)) { setPosition(new Vector(x + 0.5, y + BlockType.centralTopLimit(id), z + 0.5));
setPosition(new Vector(x + 0.5, y + BlockType.centralTopLimit(id, data), z + 0.5));
return; return;
} }
@ -169,11 +168,11 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
++spots; ++spots;
if (spots == 2) { if (spots == 2) {
final Vector platform = new Vector(x, y - 2, z); final Vector platform = new Vector(x, y - 2, z);
final BaseBlock block = world.getBlock(platform); final BlockStateHolder block = world.getBlock(platform);
final int type = block.getId(); final com.sk89q.worldedit.blocks.type.BlockType type = block.getBlockType();
// Don't get put in lava! // Don't get put in lava!
if (type == BlockID.LAVA || type == BlockID.STATIONARY_LAVA) { if (type == BlockTypes.LAVA || type == BlockTypes.FLOWING_LAVA) {
return false; return false;
} }
@ -211,11 +210,11 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
// stand upon // stand upon
while (y >= 0) { while (y >= 0) {
final Vector platform = new Vector(x, y, z); final Vector platform = new Vector(x, y, z);
final BaseBlock block = world.getBlock(platform); final BlockStateHolder block = world.getBlock(platform);
final int type = block.getId(); final com.sk89q.worldedit.blocks.type.BlockType type = block.getBlockType();
// Don't want to end up in lava // Don't want to end up in lava
if (type != BlockID.AIR && type != BlockID.LAVA && type != BlockID.STATIONARY_LAVA) { if (type != BlockTypes.AIR && type != BlockTypes.LAVA && type != BlockTypes.FLOWING_LAVA) {
// Found a block! // Found a block!
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5)); setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
return true; return true;
@ -248,7 +247,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
Extent world = getLocation().getExtent(); Extent world = getLocation().getExtent();
// No free space above // No free space above
if (world.getBlock(new Vector(x, y, z)).getId() != 0) { if (world.getBlock(new Vector(x, y, z)).getBlockType() != BlockTypes.AIR) {
return false; return false;
} }

View File

@ -23,6 +23,9 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
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.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
@ -64,17 +67,22 @@ public abstract class AbstractDelegateExtent implements Extent {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
return extent.getBlock(position); return extent.getBlock(position);
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
return extent.getLazyBlock(position); return extent.getLazyBlock(position);
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public BaseBlock getFullBlock(Vector position) {
return extent.getFullBlock(position);
}
@Override
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
return extent.setBlock(location, block); return extent.setBlock(location, block);
} }

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
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.history.change.BlockChange; import com.sk89q.worldedit.history.change.BlockChange;
@ -58,8 +59,8 @@ public class ChangeSetExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
BaseBlock previous = getBlock(location); BlockStateHolder previous = getBlock(location);
changeSet.add(new BlockChange(location.toBlockVector(), previous, block)); changeSet.add(new BlockChange(location.toBlockVector(), previous, block));
return super.setBlock(location, block); return super.setBlock(location, block);
} }

View File

@ -22,6 +22,9 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
@ -37,20 +40,14 @@ public interface InputExtent {
* is undefined (an air block could be returned). However, {@code null} * is undefined (an air block could be returned). However, {@code null}
* should <strong>not</strong> be returned.</p> * should <strong>not</strong> be returned.</p>
* *
* <p>The returned block is mutable and is a snapshot of the block at the time * <p>The returned block is immutable and is a snapshot of the block at the time
* of call. It has no position attached to it, so it could be reused in * of call. It has no position attached to it, so it could be reused in
* {@link Pattern}s and so on.</p> * {@link Pattern}s and so on.</p>
* *
* <p>Calls to this method can actually be quite expensive, so cache results
* whenever it is possible, while being aware of the mutability aspect.
* The cost, however, depends on the implementation and particular extent.
* If only basic information about the block is required, then use of
* {@link #getLazyBlock(Vector)} is recommended.</p>
*
* @param position position of the block * @param position position of the block
* @return the block * @return the block
*/ */
BaseBlock getBlock(Vector position); BlockState getBlock(Vector position);
/** /**
* Get a lazy, immutable snapshot of the block at the given location that only * Get a lazy, immutable snapshot of the block at the given location that only
@ -73,7 +70,15 @@ public interface InputExtent {
* @param position position of the block * @param position position of the block
* @return the block * @return the block
*/ */
BaseBlock getLazyBlock(Vector position); LazyBlock getLazyBlock(Vector position);
/**
* Get a immutable snapshot of the block at the given location.
*
* @param position position of the block
* @return the block
*/
BaseBlock getFullBlock(Vector position);
/** /**
* Get the biome at the given location. * Get the biome at the given location.

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -65,7 +66,7 @@ public class MaskingExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
return mask.test(location) && super.setBlock(location, block); return mask.test(location) && super.setBlock(location, block);
} }

View File

@ -23,6 +23,9 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -70,13 +73,18 @@ public class NullExtent implements Extent {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR); return BlockTypes.AIR.getDefaultState();
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR); return new LazyBlock(BlockTypes.AIR, this, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
return new BaseBlock(getBlock(position));
} }
@Nullable @Nullable
@ -86,7 +94,7 @@ public class NullExtent implements Extent {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
return false; return false;
} }

View File

@ -22,7 +22,7 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
@ -35,8 +35,8 @@ public interface OutputExtent {
/** /**
* Change the block at the given location to the given block. The operation may * Change the block at the given location to the given block. The operation may
* not tie the given {@link BaseBlock} to the world, so future changes to the * not tie the given {@link BlockStateHolder} to the world, so future changes to the
* {@link BaseBlock} do not affect the world until this method is called again. * {@link BlockStateHolder} do not affect the world until this method is called again.
* *
* <p>The return value of this method indicates whether the change was probably * <p>The return value of this method indicates whether the change was probably
* successful. It may not be successful if, for example, the location is out * successful. It may not be successful if, for example, the location is out
@ -50,7 +50,7 @@ public interface OutputExtent {
* @return true if the block was successfully set (return value may not be accurate) * @return true if the block was successfully set (return value may not be accurate)
* @throws WorldEditException thrown on an error * @throws WorldEditException thrown on an error
*/ */
boolean setBlock(Vector position, BaseBlock block) throws WorldEditException; boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException;
/** /**
* Set the biome. * Set the biome.

View File

@ -19,10 +19,13 @@
package com.sk89q.worldedit.extent.buffer; package com.sk89q.worldedit.extent.buffer;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
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.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -37,8 +40,6 @@ import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Buffers changes to an {@link Extent} and allows later retrieval for * Buffers changes to an {@link Extent} and allows later retrieval for
* actual application of the changes. * actual application of the changes.
@ -48,9 +49,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pattern { public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pattern {
private static final BaseBlock AIR = new BaseBlock(BlockTypes.AIR); private static final BlockState AIR = BlockTypes.AIR.getDefaultState();
private final Map<BlockVector, BaseBlock> buffer = new LinkedHashMap<>(); private final Map<BlockVector, BlockStateHolder> buffer = new LinkedHashMap<>();
private final Mask mask; private final Mask mask;
private Vector min = null; private Vector min = null;
private Vector max = null; private Vector max = null;
@ -79,7 +80,7 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
// Update minimum // Update minimum
if (min == null) { if (min == null) {
min = location; min = location;
@ -104,8 +105,8 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
} }
@Override @Override
public BaseBlock apply(Vector pos) { public BlockStateHolder apply(Vector pos) {
BaseBlock block = buffer.get(pos.toBlockVector()); BlockStateHolder block = buffer.get(pos.toBlockVector());
if (block != null) { if (block != null) {
return block; return block;
} else { } else {

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent.cache;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
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.blocks.LazyBlock;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -43,13 +44,13 @@ public class LastAccessExtentCache extends AbstractDelegateExtent {
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
BlockVector blockVector = position.toBlockVector(); BlockVector blockVector = position.toBlockVector();
CachedBlock lastBlock = this.lastBlock; CachedBlock lastBlock = this.lastBlock;
if (lastBlock != null && lastBlock.position.equals(blockVector)) { if (lastBlock != null && lastBlock.position.equals(blockVector)) {
return lastBlock.block; return lastBlock.block;
} else { } else {
BaseBlock block = super.getLazyBlock(position); LazyBlock block = super.getLazyBlock(position);
this.lastBlock = new CachedBlock(blockVector, block); this.lastBlock = new CachedBlock(blockVector, block);
return block; return block;
} }
@ -57,9 +58,9 @@ public class LastAccessExtentCache extends AbstractDelegateExtent {
private static class CachedBlock { private static class CachedBlock {
private final BlockVector position; private final BlockVector position;
private final BaseBlock block; private final LazyBlock block;
private CachedBlock(BlockVector position, BaseBlock block) { private CachedBlock(BlockVector position, LazyBlock block) {
this.position = position; this.position = position;
this.block = block; this.block = block;
} }

View File

@ -23,6 +23,9 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -45,8 +48,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockArrayClipboard implements Clipboard { public class BlockArrayClipboard implements Clipboard {
private final Region region; private final Region region;
private Vector origin = new Vector(); private Vector origin;
private final BaseBlock[][][] blocks; private final BlockStateHolder[][][] blocks;
private final List<ClipboardEntity> entities = new ArrayList<>(); private final List<ClipboardEntity> entities = new ArrayList<>();
/** /**
@ -120,12 +123,38 @@ public class BlockArrayClipboard implements Clipboard {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
if (region.contains(position)) { if (region.contains(position)) {
Vector v = position.subtract(region.getMinimumPoint()); Vector v = position.subtract(region.getMinimumPoint());
BaseBlock block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()]; BlockStateHolder block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()];
if (block != null) { if (block != null) {
return new BaseBlock(block); if (block instanceof BlockState) {
return (BlockState) block;
} else if (block instanceof BaseBlock) {
return ((BaseBlock) block).getState();
}
}
}
return BlockTypes.AIR.getDefaultState();
}
@Override
public LazyBlock getLazyBlock(Vector position) {
return new LazyBlock(getBlock(position), null, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
if (region.contains(position)) {
Vector v = position.subtract(region.getMinimumPoint());
BlockStateHolder block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()];
if (block != null) {
if (block instanceof BlockState) {
return new BaseBlock((BlockState) block);
} else if (block instanceof BaseBlock) {
return (BaseBlock) block;
}
} }
} }
@ -133,15 +162,10 @@ public class BlockArrayClipboard implements Clipboard {
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
return getBlock(position);
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
if (region.contains(position)) { if (region.contains(position)) {
Vector v = position.subtract(region.getMinimumPoint()); Vector v = position.subtract(region.getMinimumPoint());
blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()] = new BaseBlock(block); blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()] = block;
return true; return true;
} else { } else {
return false; return false;

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.extent.clipboard.io;
import com.sk89q.jnbt.NBTConstants; import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.DataInputStream; import java.io.DataInputStream;
@ -38,7 +37,6 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -59,8 +57,7 @@ public enum ClipboardFormat {
@Override @Override
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream)); throw new UnsupportedOperationException("This clipboard format is deprecated.");
return new SchematicWriter(nbtStream);
} }
@Override @Override

View File

@ -1,218 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.clipboard.io;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.registry.WorldData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Writes schematic files based that are compatible with MCEdit and other editors.
*/
public class SchematicWriter implements ClipboardWriter {
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
private final NBTOutputStream outputStream;
/**
* Create a new schematic writer.
*
* @param outputStream the output stream to write to
*/
public SchematicWriter(NBTOutputStream outputStream) {
checkNotNull(outputStream);
this.outputStream = outputStream;
}
@Override
public void write(Clipboard clipboard, WorldData data) throws IOException {
Region region = clipboard.getRegion();
Vector origin = clipboard.getOrigin();
Vector min = region.getMinimumPoint();
Vector offset = min.subtract(origin);
int width = region.getWidth();
int height = region.getHeight();
int length = region.getLength();
if (width > MAX_SIZE) {
throw new IllegalArgumentException("Width of region too large for a .schematic");
}
if (height > MAX_SIZE) {
throw new IllegalArgumentException("Height of region too large for a .schematic");
}
if (length > MAX_SIZE) {
throw new IllegalArgumentException("Length of region too large for a .schematic");
}
// ====================================================================
// Metadata
// ====================================================================
HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag((short) width));
schematic.put("Length", new ShortTag((short) length));
schematic.put("Height", new ShortTag((short) height));
schematic.put("Materials", new StringTag("Alpha"));
schematic.put("WEOriginX", new IntTag(min.getBlockX()));
schematic.put("WEOriginY", new IntTag(min.getBlockY()));
schematic.put("WEOriginZ", new IntTag(min.getBlockZ()));
schematic.put("WEOffsetX", new IntTag(offset.getBlockX()));
schematic.put("WEOffsetY", new IntTag(offset.getBlockY()));
schematic.put("WEOffsetZ", new IntTag(offset.getBlockZ()));
// ====================================================================
// Block handling
// ====================================================================
byte[] blocks = new byte[width * height * length];
byte[] addBlocks = null;
byte[] blockData = new byte[width * height * length];
List<Tag> tileEntities = new ArrayList<>();
for (Vector point : region) {
Vector relative = point.subtract(min);
int x = relative.getBlockX();
int y = relative.getBlockY();
int z = relative.getBlockZ();
int index = y * width * length + z * width + x;
BaseBlock block = clipboard.getBlock(point);
// Save 4096 IDs in an AddBlocks section
if (block.getId() > 255) {
if (addBlocks == null) { // Lazily create section
addBlocks = new byte[(blocks.length >> 1) + 1];
}
addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
addBlocks[index >> 1] & 0xF0 | (block.getId() >> 8) & 0xF
: addBlocks[index >> 1] & 0xF | ((block.getId() >> 8) & 0xF) << 4);
}
blocks[index] = (byte) block.getId();
blockData[index] = (byte) block.getData();
// Store TileEntity data
CompoundTag rawTag = block.getNbtData();
if (rawTag != null) {
Map<String, Tag> values = new HashMap<>();
for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
values.put("id", new StringTag(block.getNbtId()));
values.put("x", new IntTag(x));
values.put("y", new IntTag(y));
values.put("z", new IntTag(z));
CompoundTag tileEntityTag = new CompoundTag(values);
tileEntities.add(tileEntityTag);
}
}
schematic.put("Blocks", new ByteArrayTag(blocks));
schematic.put("Data", new ByteArrayTag(blockData));
schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
if (addBlocks != null) {
schematic.put("AddBlocks", new ByteArrayTag(addBlocks));
}
// ====================================================================
// Entities
// ====================================================================
List<Tag> entities = new ArrayList<>();
for (Entity entity : clipboard.getEntities()) {
BaseEntity state = entity.getState();
if (state != null) {
Map<String, Tag> values = new HashMap<>();
// Put NBT provided data
CompoundTag rawTag = state.getNbtData();
if (rawTag != null) {
values.putAll(rawTag.getValue());
}
// Store our location data, overwriting any
values.put("id", new StringTag(state.getTypeId()));
values.put("Pos", writeVector(entity.getLocation().toVector(), "Pos"));
values.put("Rotation", writeRotation(entity.getLocation(), "Rotation"));
CompoundTag entityTag = new CompoundTag(values);
entities.add(entityTag);
}
}
schematic.put("Entities", new ListTag(CompoundTag.class, entities));
// ====================================================================
// Output
// ====================================================================
CompoundTag schematicTag = new CompoundTag(schematic);
outputStream.writeNamedTag("Schematic", schematicTag);
}
private Tag writeVector(Vector vector, String name) {
List<DoubleTag> list = new ArrayList<>();
list.add(new DoubleTag(vector.getX()));
list.add(new DoubleTag(vector.getY()));
list.add(new DoubleTag(vector.getZ()));
return new ListTag(DoubleTag.class, list);
}
private Tag writeRotation(Location location, String name) {
List<FloatTag> list = new ArrayList<>();
list.add(new FloatTag(location.getYaw()));
list.add(new FloatTag(location.getPitch()));
return new ListTag(FloatTag.class, list);
}
@Override
public void close() throws IOException {
outputStream.close();
}
}

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent.inventory;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -79,7 +80,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
if (blockBag != null) { if (blockBag != null) {
BaseBlock lazyBlock = getExtent().getLazyBlock(position); BaseBlock lazyBlock = getExtent().getLazyBlock(position);
int existing = lazyBlock.getBlockType().getLegacyId(); int existing = lazyBlock.getBlockType().getLegacyId();

View File

@ -1,57 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.logging;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
/**
* An abstract class to implement block loggers and so on with.
*/
public abstract class AbstractLoggingExtent extends AbstractDelegateExtent {
/**
* Create a new instance.
*
* @param extent the extent
*/
protected AbstractLoggingExtent(Extent extent) {
super(extent);
}
/**
* Called when a block is being changed.
*
* @param position the position
* @param newBlock the new block to replace the old one
*/
protected void onBlockChange(Vector position, BaseBlock newBlock) {
}
@Override
public final boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
onBlockChange(position, block);
return super.setBlock(position, block);
}
}

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -43,9 +44,9 @@ import java.util.*;
*/ */
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent { public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
private TupleArrayList<BlockVector, BaseBlock> stage1 = new TupleArrayList<>(); private TupleArrayList<BlockVector, BlockStateHolder> stage1 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BaseBlock> stage2 = new TupleArrayList<>(); private TupleArrayList<BlockVector, BlockStateHolder> stage2 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BaseBlock> stage3 = new TupleArrayList<>(); private TupleArrayList<BlockVector, BlockStateHolder> stage3 = new TupleArrayList<>();
private boolean enabled; private boolean enabled;
/** /**
@ -87,7 +88,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
BaseBlock lazyBlock = getLazyBlock(location); BaseBlock lazyBlock = getLazyBlock(location);
if (!enabled) { if (!enabled) {
@ -97,18 +98,18 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
if (BlockType.shouldPlaceLast(block.getBlockType().getLegacyId())) { if (BlockType.shouldPlaceLast(block.getBlockType().getLegacyId())) {
// Place torches, etc. last // Place torches, etc. last
stage2.put(location.toBlockVector(), block); stage2.put(location.toBlockVector(), block);
return !(lazyBlock.getBlockType() == block.getBlockType() && lazyBlock.getData() == block.getData()); return !(lazyBlock.getBlockType() == block.getBlockType()); // TODO && lazyBlock.getData() == block.getData());
} else if (BlockType.shouldPlaceFinal(block.getBlockType().getLegacyId())) { } else if (BlockType.shouldPlaceFinal(block.getBlockType().getLegacyId())) {
// Place signs, reed, etc even later // Place signs, reed, etc even later
stage3.put(location.toBlockVector(), block); stage3.put(location.toBlockVector(), block);
return !(lazyBlock.getBlockType() == block.getBlockType() && lazyBlock.getData() == block.getData()); return !(lazyBlock.getBlockType() == block.getBlockType()); // TODO && lazyBlock.getData() == block.getData());
} else if (BlockType.shouldPlaceLast(lazyBlock.getBlockType().getLegacyId())) { } else if (BlockType.shouldPlaceLast(lazyBlock.getBlockType().getLegacyId())) {
// Destroy torches, etc. first // Destroy torches, etc. first
super.setBlock(location, new BaseBlock(BlockTypes.AIR)); super.setBlock(location, BlockTypes.AIR.getDefaultState());
return super.setBlock(location, block); return super.setBlock(location, block);
} else { } else {
stage1.put(location.toBlockVector(), block); stage1.put(location.toBlockVector(), block);
return !(lazyBlock.getBlockType() == block.getBlockType() && lazyBlock.getData() == block.getData()); return !(lazyBlock.getBlockType() == block.getBlockType()); // TODO && lazyBlock.getData() == block.getData());
} }
} }
@ -128,8 +129,8 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
Extent extent = getExtent(); Extent extent = getExtent();
final Set<BlockVector> blocks = new HashSet<>(); final Set<BlockVector> blocks = new HashSet<>();
final Map<BlockVector, BaseBlock> blockTypes = new HashMap<>(); final Map<BlockVector, BlockStateHolder> blockTypes = new HashMap<>();
for (Map.Entry<BlockVector, BaseBlock> entry : stage3) { for (Map.Entry<BlockVector, BlockStateHolder> entry : stage3) {
final BlockVector pt = entry.getKey(); final BlockVector pt = entry.getKey();
blocks.add(pt); blocks.add(pt);
blockTypes.put(pt, entry.getValue()); blockTypes.put(pt, entry.getValue());
@ -148,10 +149,10 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
assert (blockTypes.containsKey(current)); assert (blockTypes.containsKey(current));
final BaseBlock baseBlock = blockTypes.get(current); final BlockStateHolder baseBlock = blockTypes.get(current);
final int type = baseBlock.getBlockType().getLegacyId(); final int type = baseBlock.getBlockType().getLegacyId();
final int data = baseBlock.getData(); // final int data = baseBlock.getData();
switch (type) { switch (type) {
case BlockID.WOODEN_DOOR: case BlockID.WOODEN_DOOR:
@ -161,13 +162,13 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
case BlockID.DARK_OAK_DOOR: case BlockID.DARK_OAK_DOOR:
case BlockID.SPRUCE_DOOR: case BlockID.SPRUCE_DOOR:
case BlockID.IRON_DOOR: case BlockID.IRON_DOOR:
if ((data & 0x8) == 0) { // TODO if ((data & 0x8) == 0) {
// Deal with lower door halves being attached to the floor AND the upper half // // Deal with lower door halves being attached to the floor AND the upper half
BlockVector upperBlock = current.add(0, 1, 0).toBlockVector(); // BlockVector upperBlock = current.add(0, 1, 0).toBlockVector();
if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) { // if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
walked.addFirst(upperBlock); // walked.addFirst(upperBlock);
} // }
} // }
break; break;
case BlockID.MINECART_TRACKS: case BlockID.MINECART_TRACKS:
@ -183,7 +184,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
break; break;
} }
final PlayerDirection attachment = BlockType.getAttachment(type, data); final PlayerDirection attachment = BlockType.getAttachment(type, 0); // TODO
if (attachment == null) { if (attachment == null) {
// Block is not attached to anything => we can place it // Block is not attached to anything => we can place it
break; break;

View File

@ -24,6 +24,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
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;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
@ -77,24 +80,29 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
* @param reverse true to transform in the opposite direction * @param reverse true to transform in the opposite direction
* @return the same block * @return the same block
*/ */
private BaseBlock transformBlock(BaseBlock block, boolean reverse) { private <T extends BlockStateHolder> T transformBlock(T block, boolean reverse) {
transform(block, reverse ? transform.inverse() : transform, blockRegistry); transform(block, reverse ? transform.inverse() : transform, blockRegistry);
return block; return block;
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
return transformBlock(super.getBlock(position), false); return transformBlock(super.getBlock(position), false);
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
return transformBlock(super.getLazyBlock(position), false); return transformBlock(super.getLazyBlock(position), false);
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public BaseBlock getFullBlock(Vector position) {
return super.setBlock(location, transformBlock(new BaseBlock(block), true)); return transformBlock(super.getFullBlock(position), false);
}
@Override
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
return super.setBlock(location, transformBlock(block, true));
} }
@ -108,7 +116,7 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
* @param registry the registry * @param registry the registry
* @return the same block * @return the same block
*/ */
public static BaseBlock transform(BaseBlock block, Transform transform, BlockRegistry registry) { public static <T extends BlockStateHolder> T transform(T block, Transform transform, BlockRegistry registry) {
return transform(block, transform, registry, block); return transform(block, transform, registry, block);
} }
@ -121,7 +129,7 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
* @param changedBlock the block to change * @param changedBlock the block to change
* @return the changed block * @return the changed block
*/ */
private static BaseBlock transform(BaseBlock block, Transform transform, BlockRegistry registry, BaseBlock changedBlock) { private static <T extends BlockStateHolder> T transform(T block, Transform transform, BlockRegistry registry, T changedBlock) {
checkNotNull(block); checkNotNull(block);
checkNotNull(transform); checkNotNull(transform);
checkNotNull(registry); checkNotNull(registry);

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -77,7 +78,7 @@ public class BlockChangeLimiter extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (limit >= 0) { if (limit >= 0) {
if (count >= limit) { if (count >= limit) {
throw new MaxChangedBlocksException(limit); throw new MaxChangedBlocksException(limit);

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent.validation;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -49,7 +50,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
final int y = location.getBlockY(); final int y = location.getBlockY();
final BlockType type = block.getBlockType(); final BlockType type = block.getBlockType();
if (y < 0 || y > world.getMaxY()) { if (y < 0 || y > world.getMaxY()) {
@ -61,16 +62,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
return false; return false;
} }
if (block.getData() < 0) {
throw new SevereValidationException("Cannot set a data value that is less than 0");
}
return super.setBlock(location, block); return super.setBlock(location, block);
} }
private static class SevereValidationException extends WorldEditException {
private SevereValidationException(String message) {
super(message);
}
}
} }

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -52,7 +53,7 @@ public class BlockQuirkExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
BaseBlock lazyBlock = getExtent().getLazyBlock(position); BaseBlock lazyBlock = getExtent().getLazyBlock(position);
int existing = lazyBlock.getBlockType().getLegacyId(); int existing = lazyBlock.getBlockType().getLegacyId();

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent.world;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -61,7 +62,7 @@ public class ChunkLoadingExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
world.checkLoadedChunk(location); world.checkLoadedChunk(location);
return super.setBlock(location, block); return super.setBlock(location, block);
} }

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.BlockVector2D;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext; import com.sk89q.worldedit.function.operation.RunContext;
@ -84,7 +85,7 @@ public class FastModeExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (enabled) { if (enabled) {
dirtyChunks.add(new BlockVector2D(location.getBlockX() >> 4, location.getBlockZ() >> 4)); dirtyChunks.add(new BlockVector2D(location.getBlockX() >> 4, location.getBlockZ() >> 4));
return world.setBlock(location, block, false); return world.setBlock(location, block, false);

View File

@ -22,6 +22,8 @@ package com.sk89q.worldedit.extent.world;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -79,8 +81,8 @@ public class SurvivalModeExtent extends AbstractDelegateExtent {
} }
@Override @Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (toolUse && block.isAir()) { if (toolUse && block.getBlockType() == BlockTypes.AIR) {
world.simulateBlockMine(location); world.simulateBlockMine(location);
return true; return true;
} else { } else {

View File

@ -24,6 +24,7 @@ import com.sk89q.jnbt.CompoundTagBuilder;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.internal.helper.MCDirections; import com.sk89q.worldedit.internal.helper.MCDirections;
@ -68,7 +69,7 @@ public class ExtentBlockCopy implements RegionFunction {
@Override @Override
public boolean apply(Vector position) throws WorldEditException { public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = source.getBlock(position); BaseBlock block = source.getFullBlock(position);
Vector orig = position.subtract(from); Vector orig = position.subtract(from);
Vector transformed = transform.apply(orig); Vector transformed = transform.apply(orig);

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -104,7 +105,7 @@ public class FloraGenerator implements RegionFunction {
@Override @Override
public boolean apply(Vector position) throws WorldEditException { public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position); BlockStateHolder block = editSession.getBlock(position);
if (block.getBlockType() == BlockTypes.GRASS) { if (block.getBlockType() == BlockTypes.GRASS) {
editSession.setBlock(position.add(0, 1, 0), temperatePattern.apply(position)); editSession.setBlock(position.add(0, 1, 0), temperatePattern.apply(position));

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
@ -50,7 +51,7 @@ public class ForestGenerator implements RegionFunction {
@Override @Override
public boolean apply(Vector position) throws WorldEditException { public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position); BlockStateHolder block = editSession.getBlock(position);
BlockType t = block.getBlockType(); BlockType t = block.getBlockType();
if (t == BlockTypes.GRASS || t == BlockTypes.DIRT) { if (t == BlockTypes.GRASS || t == BlockTypes.DIRT) {

View File

@ -24,6 +24,8 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
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;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -86,25 +88,25 @@ public class GardenPatchGenerator implements RegionFunction {
*/ */
private void placeVine(Vector basePos, Vector pos) throws MaxChangedBlocksException { private void placeVine(Vector basePos, Vector pos) throws MaxChangedBlocksException {
if (pos.distance(basePos) > 4) return; if (pos.distance(basePos) > 4) return;
if (!editSession.getBlock(pos).isAir()) return; if (editSession.getBlock(pos).getBlockType() != BlockTypes.AIR) return;
for (int i = -1; i > -3; --i) { for (int i = -1; i > -3; --i) {
Vector testPos = pos.add(0, i, 0); Vector testPos = pos.add(0, i, 0);
if (editSession.getBlock(testPos).isAir()) { if (editSession.getBlock(testPos).getBlockType() == BlockTypes.AIR) {
pos = testPos; pos = testPos;
} else { } else {
break; break;
} }
} }
setBlockIfAir(editSession, pos, new BaseBlock(BlockTypes.OAK_LEAVES)); setBlockIfAir(editSession, pos, BlockTypes.OAK_LEAVES.getDefaultState());
affected++; affected++;
int t = random.nextInt(4); int t = random.nextInt(4);
int h = random.nextInt(3) - 1; int h = random.nextInt(3) - 1;
Vector p; Vector p;
BaseBlock log = new BaseBlock(BlockTypes.OAK_LOG); BlockState log = BlockTypes.OAK_LOG.getDefaultState();
switch (t) { switch (t) {
case 0: case 0:
@ -159,7 +161,7 @@ public class GardenPatchGenerator implements RegionFunction {
@Override @Override
public boolean apply(Vector position) throws WorldEditException { public boolean apply(Vector position) throws WorldEditException {
if (!editSession.getBlock(position).isAir()) { if (editSession.getBlock(position).getBlockType() != BlockTypes.AIR) {
position = position.add(0, 1, 0); position = position.add(0, 1, 0);
} }
@ -167,9 +169,9 @@ public class GardenPatchGenerator implements RegionFunction {
return false; return false;
} }
BaseBlock leavesBlock = new BaseBlock(BlockTypes.OAK_LEAVES); BlockState leavesBlock = BlockTypes.OAK_LEAVES.getDefaultState();
if (editSession.getBlock(position).isAir()) { if (editSession.getBlock(position).getBlockType() == BlockTypes.AIR) {
editSession.setBlock(position, leavesBlock); editSession.setBlock(position, leavesBlock);
} }
@ -202,8 +204,8 @@ public class GardenPatchGenerator implements RegionFunction {
* @return if block was changed * @return if block was changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
private static boolean setBlockIfAir(EditSession session, Vector position, BaseBlock block) throws MaxChangedBlocksException { private static boolean setBlockIfAir(EditSession session, Vector position, BlockStateHolder block) throws MaxChangedBlocksException {
return session.getBlock(position).isAir() && session.setBlock(position, block); return session.getBlock(position).getBlockType() == BlockTypes.AIR && session.setBlock(position, block);
} }
/** /**

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.function.mask; package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
@ -40,7 +42,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class BlockMask extends AbstractExtentMask { public class BlockMask extends AbstractExtentMask {
private final Set<BaseBlock> blocks = new HashSet<>(); private final Set<BlockStateHolder> blocks = new HashSet<>();
/** /**
* Create a new block mask. * Create a new block mask.
@ -48,7 +50,7 @@ public class BlockMask extends AbstractExtentMask {
* @param extent the extent * @param extent the extent
* @param blocks a list of blocks to match * @param blocks a list of blocks to match
*/ */
public BlockMask(Extent extent, Collection<BaseBlock> blocks) { public BlockMask(Extent extent, Collection<BlockStateHolder> blocks) {
super(extent); super(extent);
checkNotNull(blocks); checkNotNull(blocks);
this.blocks.addAll(blocks); this.blocks.addAll(blocks);
@ -60,7 +62,7 @@ public class BlockMask extends AbstractExtentMask {
* @param extent the extent * @param extent the extent
* @param block an array of blocks to match * @param block an array of blocks to match
*/ */
public BlockMask(Extent extent, BaseBlock... block) { public BlockMask(Extent extent, BlockStateHolder... block) {
this(extent, Arrays.asList(checkNotNull(block))); this(extent, Arrays.asList(checkNotNull(block)));
} }
@ -69,7 +71,7 @@ public class BlockMask extends AbstractExtentMask {
* *
* @param blocks a list of blocks * @param blocks a list of blocks
*/ */
public void add(Collection<BaseBlock> blocks) { public void add(Collection<BlockStateHolder> blocks) {
checkNotNull(blocks); checkNotNull(blocks);
this.blocks.addAll(blocks); this.blocks.addAll(blocks);
} }
@ -79,7 +81,7 @@ public class BlockMask extends AbstractExtentMask {
* *
* @param block an array of blocks * @param block an array of blocks
*/ */
public void add(BaseBlock... block) { public void add(BlockStateHolder... block) {
add(Arrays.asList(checkNotNull(block))); add(Arrays.asList(checkNotNull(block)));
} }
@ -88,14 +90,14 @@ public class BlockMask extends AbstractExtentMask {
* *
* @return a list of blocks * @return a list of blocks
*/ */
public Collection<BaseBlock> getBlocks() { public Collection<BlockStateHolder> getBlocks() {
return blocks; return blocks;
} }
@Override @Override
public boolean test(Vector vector) { public boolean test(Vector vector) {
BaseBlock block = getExtent().getBlock(vector); BlockStateHolder block = getExtent().getBlock(vector);
return blocks.contains(block) || blocks.contains(new BaseBlock(block.getBlockType())); return blocks.contains(block) || blocks.contains(block);
} }
@Nullable @Nullable

View File

@ -22,26 +22,25 @@ package com.sk89q.worldedit.function.mask;
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.blocks.Blocks; import com.sk89q.worldedit.blocks.Blocks;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import java.util.Collection; import java.util.Collection;
public class FuzzyBlockMask extends BlockMask { public class FuzzyBlockMask extends BlockMask {
public FuzzyBlockMask(Extent extent, Collection<BaseBlock> blocks) { public FuzzyBlockMask(Extent extent, Collection<BlockStateHolder> blocks) {
super(extent, blocks); super(extent, blocks);
} }
public FuzzyBlockMask(Extent extent, BaseBlock... block) { public FuzzyBlockMask(Extent extent, BlockStateHolder... block) {
super(extent, block); super(extent, block);
} }
@Override @Override
public boolean test(Vector vector) { public boolean test(Vector vector) {
Extent extent = getExtent(); Extent extent = getExtent();
Collection<BaseBlock> blocks = getBlocks(); Collection<BlockStateHolder> blocks = getBlocks();
BaseBlock lazyBlock = extent.getLazyBlock(vector); return Blocks.containsFuzzy(blocks, extent.getFullBlock(vector));
BaseBlock compare = new BaseBlock(lazyBlock.getState());
return Blocks.containsFuzzy(blocks, compare);
} }
} }

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import java.util.Iterator; import java.util.Iterator;
@ -37,7 +38,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockMapEntryPlacer implements Operation { public class BlockMapEntryPlacer implements Operation {
private final Extent extent; private final Extent extent;
private final Iterator<Map.Entry<BlockVector, BaseBlock>> iterator; private final Iterator<Map.Entry<BlockVector, BlockStateHolder>> iterator;
/** /**
* Create a new instance. * Create a new instance.
@ -45,7 +46,7 @@ public class BlockMapEntryPlacer implements Operation {
* @param extent the extent to set the blocks on * @param extent the extent to set the blocks on
* @param iterator the iterator * @param iterator the iterator
*/ */
public BlockMapEntryPlacer(Extent extent, Iterator<Map.Entry<BlockVector, BaseBlock>> iterator) { public BlockMapEntryPlacer(Extent extent, Iterator<Map.Entry<BlockVector, BlockStateHolder>> iterator) {
checkNotNull(extent); checkNotNull(extent);
checkNotNull(iterator); checkNotNull(iterator);
this.extent = extent; this.extent = extent;
@ -55,7 +56,7 @@ public class BlockMapEntryPlacer implements Operation {
@Override @Override
public Operation resume(RunContext run) throws WorldEditException { public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) { while (iterator.hasNext()) {
Map.Entry<BlockVector, BaseBlock> entry = iterator.next(); Map.Entry<BlockVector, BlockStateHolder> entry = iterator.next();
extent.setBlock(entry.getKey(), entry.getValue()); extent.setBlock(entry.getKey(), entry.getValue());
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
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.blocks.type.BlockStateHolder;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -29,14 +30,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class BlockPattern extends AbstractPattern { public class BlockPattern extends AbstractPattern {
private BaseBlock block; private BlockStateHolder block;
/** /**
* Create a new pattern with the given block. * Create a new pattern with the given block.
* *
* @param block the block * @param block the block
*/ */
public BlockPattern(BaseBlock block) { public BlockPattern(BlockStateHolder block) {
setBlock(block); setBlock(block);
} }
@ -45,7 +46,7 @@ public class BlockPattern extends AbstractPattern {
* *
* @return the block that is always returned * @return the block that is always returned
*/ */
public BaseBlock getBlock() { public BlockStateHolder getBlock() {
return block; return block;
} }
@ -54,13 +55,13 @@ public class BlockPattern extends AbstractPattern {
* *
* @param block the block * @param block the block
*/ */
public void setBlock(BaseBlock block) { public void setBlock(BlockStateHolder block) {
checkNotNull(block); checkNotNull(block);
this.block = block; this.block = block;
} }
@Override @Override
public BaseBlock apply(Vector position) { public BlockStateHolder apply(Vector position) {
return block; return block;
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
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.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -45,7 +46,7 @@ public class ClipboardPattern extends AbstractPattern {
} }
@Override @Override
public BaseBlock apply(Vector position) { public BlockStateHolder apply(Vector position) {
int xp = Math.abs(position.getBlockX()) % size.getBlockX(); int xp = Math.abs(position.getBlockX()) % size.getBlockX();
int yp = Math.abs(position.getBlockY()) % size.getBlockY(); int yp = Math.abs(position.getBlockY()) % size.getBlockY();
int zp = Math.abs(position.getBlockZ()) % size.getBlockZ(); int zp = Math.abs(position.getBlockZ()) % size.getBlockZ();

View File

@ -21,18 +21,19 @@ package com.sk89q.worldedit.function.pattern;
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.blocks.type.BlockStateHolder;
/** /**
* Returns a {@link BaseBlock} for a given position. * Returns a {@link BlockStateHolder} for a given position.
*/ */
public interface Pattern { public interface Pattern {
/** /**
* Return a {@link BaseBlock} for the given position. * Return a {@link BlockStateHolder} for the given position.
* *
* @param position the position * @param position the position
* @return a block * @return a block
*/ */
BaseBlock apply(Vector position); BlockStateHolder apply(Vector position);
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
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.blocks.type.BlockStateHolder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -53,7 +54,7 @@ public class RandomPattern extends AbstractPattern {
} }
@Override @Override
public BaseBlock apply(Vector position) { public BlockStateHolder apply(Vector position) {
double r = random.nextDouble(); double r = random.nextDouble();
double offset = 0; double offset = 0;

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
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.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -83,7 +84,7 @@ public class RepeatingExtentPattern extends AbstractPattern {
} }
@Override @Override
public BaseBlock apply(Vector position) { public BlockStateHolder apply(Vector position) {
Vector base = position.add(offset); Vector base = position.add(offset);
Vector size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1); Vector size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1);
int x = base.getBlockX() % size.getBlockX(); int x = base.getBlockX() % size.getBlockX();

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.history.change;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.UndoContext; import com.sk89q.worldedit.history.UndoContext;
@ -37,8 +38,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockChange implements Change { public class BlockChange implements Change {
private final BlockVector position; private final BlockVector position;
private final BaseBlock previous; private final BlockStateHolder previous;
private final BaseBlock current; private final BlockStateHolder current;
/** /**
* Create a new block change. * Create a new block change.
@ -47,7 +48,7 @@ public class BlockChange implements Change {
* @param previous the previous block * @param previous the previous block
* @param current the current block * @param current the current block
*/ */
public BlockChange(BlockVector position, BaseBlock previous, BaseBlock current) { public BlockChange(BlockVector position, BlockStateHolder previous, BlockStateHolder current) {
checkNotNull(position); checkNotNull(position);
checkNotNull(previous); checkNotNull(previous);
checkNotNull(current); checkNotNull(current);
@ -70,7 +71,7 @@ public class BlockChange implements Change {
* *
* @return the previous block * @return the previous block
*/ */
public BaseBlock getPrevious() { public BlockStateHolder getPrevious() {
return previous; return previous;
} }
@ -79,7 +80,7 @@ public class BlockChange implements Change {
* *
* @return the current block * @return the current block
*/ */
public BaseBlock getCurrent() { public BlockStateHolder getCurrent() {
return current; return current;
} }

View File

@ -23,6 +23,7 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.history.change.BlockChange; import com.sk89q.worldedit.history.change.BlockChange;
import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.Change;
import com.sk89q.worldedit.util.collection.TupleArrayList; import com.sk89q.worldedit.util.collection.TupleArrayList;
@ -43,8 +44,8 @@ import static java.util.Map.Entry;
*/ */
public class BlockOptimizedHistory extends ArrayListHistory { public class BlockOptimizedHistory extends ArrayListHistory {
private final TupleArrayList<BlockVector, BaseBlock> previous = new TupleArrayList<>(); private final TupleArrayList<BlockVector, BlockStateHolder> previous = new TupleArrayList<>();
private final TupleArrayList<BlockVector, BaseBlock> current = new TupleArrayList<>(); private final TupleArrayList<BlockVector, BlockStateHolder> current = new TupleArrayList<>();
@Override @Override
public void add(Change change) { public void add(Change change) {
@ -85,7 +86,7 @@ public class BlockOptimizedHistory extends ArrayListHistory {
* *
* @return a function * @return a function
*/ */
private Function<Entry<BlockVector, BaseBlock>, Change> createTransform() { private Function<Entry<BlockVector, BlockStateHolder>, Change> createTransform() {
return entry -> new BlockChange(entry.getKey(), entry.getValue(), entry.getValue()); return entry -> new BlockChange(entry.getKey(), entry.getValue(), entry.getValue());
} }

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.NoMatchException;
@ -169,7 +170,7 @@ public class WorldEditBinding extends BindingHelper {
@BindingMatch(type = BaseBlock.class, @BindingMatch(type = BaseBlock.class,
behavior = BindingBehavior.CONSUMES, behavior = BindingBehavior.CONSUMES,
consumedCount = 1) consumedCount = 1)
public BaseBlock getBaseBlock(ArgumentStack context) throws ParameterException, WorldEditException { public BlockStateHolder getBaseBlock(ArgumentStack context) throws ParameterException, WorldEditException {
Actor actor = context.getContext().getLocals().get(Actor.class); Actor actor = context.getContext().getLocals().get(Actor.class);
ParserContext parserContext = new ParserContext(); ParserContext parserContext = new ParserContext();
parserContext.setActor(context.getContext().getLocals().get(Actor.class)); parserContext.setActor(context.getContext().getLocals().get(Actor.class));

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
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.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
@ -145,7 +146,7 @@ public class HeightMap {
// Depending on growing or shrinking we need to start at the bottom or top // Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) { if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding) // Set the top block of the column to be the same type (this might go wrong with rounding)
BaseBlock existing = session.getBlock(new Vector(xr, curHeight, zr)); BlockState existing = session.getBlock(new Vector(xr, curHeight, zr));
// Skip water/lava // Skip water/lava
if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.FLOWING_WATER if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.FLOWING_WATER

View File

@ -22,9 +22,7 @@ package com.sk89q.worldedit.regions.shape;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
@ -35,45 +33,15 @@ import com.sk89q.worldedit.regions.Region;
public abstract class ArbitraryShape { public abstract class ArbitraryShape {
protected final Region extent; protected final Region extent;
private int cacheOffsetX;
private int cacheOffsetY;
private int cacheOffsetZ;
@SuppressWarnings("FieldCanBeLocal")
private int cacheSizeX;
private int cacheSizeY;
private int cacheSizeZ;
public ArbitraryShape(Region extent) { public ArbitraryShape(Region extent) {
this.extent = extent; this.extent = extent;
Vector min = extent.getMinimumPoint();
Vector max = extent.getMaximumPoint();
cacheOffsetX = min.getBlockX() - 1;
cacheOffsetY = min.getBlockY() - 1;
cacheOffsetZ = min.getBlockZ() - 1;
cacheSizeX = (int) (max.getX() - cacheOffsetX + 2);
cacheSizeY = (int) (max.getY() - cacheOffsetY + 2);
cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2);
cache = new short[cacheSizeX * cacheSizeY * cacheSizeZ];
} }
protected Region getExtent() { protected Region getExtent() {
return extent; return extent;
} }
/**
* Cache entries:
* 0 = unknown
* -1 = outside
* -2 = inside but type and data 0
* > 0 = inside, value = (type | (data << 8)), not handling data < 0
*/
private final short[] cache;
/** /**
* Override this function to specify the shape to generate. * Override this function to specify the shape to generate.
* *
@ -83,60 +51,7 @@ public abstract class ArbitraryShape {
* @param defaultMaterial The material returned by the pattern for the current block. * @param defaultMaterial The material returned by the pattern for the current block.
* @return material to place or null to not place anything. * @return material to place or null to not place anything.
*/ */
protected abstract BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial); protected abstract BlockStateHolder getMaterial(int x, int y, int z, BlockStateHolder defaultMaterial);
private BaseBlock getMaterialCached(int x, int y, int z, Pattern pattern) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
final short cacheEntry = cache[index];
switch (cacheEntry) {
case 0:
// unknown, fetch material
final BaseBlock material = getMaterial(x, y, z, pattern.apply(new BlockVector(x, y, z)));
if (material == null) {
// outside
cache[index] = -1;
return null;
}
short newCacheEntry = (short) (material.getBlockType().getLegacyId() | ((material.getData() + 1) << 8));
if (newCacheEntry == 0) {
// type and data 0
newCacheEntry = -2;
}
cache[index] = newCacheEntry;
return material;
case -1:
// outside
return null;
case -2:
// type and data 0
return new BaseBlock(BlockTypes.AIR);
}
return new BaseBlock(cacheEntry & 255, ((cacheEntry >> 8) - 1) & 15);
}
private boolean isInsideCached(int x, int y, int z, Pattern pattern) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
switch (cache[index]) {
case 0:
// unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape
return getMaterialCached(x, y, z, pattern) != null;
case -1:
// outside
return false;
default:
// inside
return true;
}
}
/** /**
* Generates the shape. * Generates the shape.
@ -156,7 +71,7 @@ public abstract class ArbitraryShape {
int z = position.getBlockZ(); int z = position.getBlockZ();
if (!hollow) { if (!hollow) {
final BaseBlock material = getMaterial(x, y, z, pattern.apply(position)); final BlockStateHolder material = getMaterial(x, y, z, pattern.apply(position));
if (material != null && editSession.setBlock(position, material)) { if (material != null && editSession.setBlock(position, material)) {
++affected; ++affected;
} }
@ -164,43 +79,11 @@ public abstract class ArbitraryShape {
continue; continue;
} }
final BaseBlock material = getMaterialCached(x, y, z, pattern); final BlockStateHolder material = getMaterial(x, y, z, pattern.apply(position));
if (material == null) { if (material == null) {
continue; continue;
} }
boolean draw = false;
do {
if (!isInsideCached(x + 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x - 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z + 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z - 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y + 1, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y - 1, z, pattern)) {
draw = true;
break;
}
} while (false);
if (!draw) {
continue;
}
if (editSession.setBlock(position, material)) { if (editSession.setBlock(position, material)) {
++affected; ++affected;
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.regions.shape;
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.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
/** /**
@ -34,7 +35,7 @@ public class RegionShape extends ArbitraryShape {
} }
@Override @Override
protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) { protected BlockStateHolder getMaterial(int x, int y, int z, BlockStateHolder defaultMaterial) {
if (!this.extent.contains(new Vector(x, y, z))) { if (!this.extent.contains(new Vector(x, y, z))) {
return null; return null;
} }

View File

@ -25,7 +25,6 @@ import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTConstants; import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.NamedTag; import com.sk89q.jnbt.NamedTag;
import com.sk89q.jnbt.ShortTag; import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
@ -39,16 +38,12 @@ import com.sk89q.worldedit.world.DataException;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class MCEditSchematicFormat extends SchematicFormat { public class MCEditSchematicFormat extends SchematicFormat {
@ -206,91 +201,7 @@ public class MCEditSchematicFormat extends SchematicFormat {
@Override @Override
public void save(CuboidClipboard clipboard, File file) throws IOException, DataException { public void save(CuboidClipboard clipboard, File file) throws IOException, DataException {
int width = clipboard.getWidth(); throw new UnsupportedOperationException("Saving is deprecated");
int height = clipboard.getHeight();
int length = clipboard.getLength();
if (width > MAX_SIZE) {
throw new DataException("Width of region too large for a .schematic");
}
if (height > MAX_SIZE) {
throw new DataException("Height of region too large for a .schematic");
}
if (length > MAX_SIZE) {
throw new DataException("Length of region too large for a .schematic");
}
HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag((short) width));
schematic.put("Length", new ShortTag((short) length));
schematic.put("Height", new ShortTag((short) height));
schematic.put("Materials", new StringTag("Alpha"));
schematic.put("WEOriginX", new IntTag(clipboard.getOrigin().getBlockX()));
schematic.put("WEOriginY", new IntTag(clipboard.getOrigin().getBlockY()));
schematic.put("WEOriginZ", new IntTag(clipboard.getOrigin().getBlockZ()));
schematic.put("WEOffsetX", new IntTag(clipboard.getOffset().getBlockX()));
schematic.put("WEOffsetY", new IntTag(clipboard.getOffset().getBlockY()));
schematic.put("WEOffsetZ", new IntTag(clipboard.getOffset().getBlockZ()));
// Copy
byte[] blocks = new byte[width * height * length];
byte[] addBlocks = null;
byte[] blockData = new byte[width * height * length];
ArrayList<Tag> tileEntities = new ArrayList<>();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
for (int z = 0; z < length; ++z) {
int index = y * width * length + z * width + x;
BaseBlock block = clipboard.getPoint(new BlockVector(x, y, z));
// Save 4096 IDs in an AddBlocks section
if (block.getId() > 255) {
if (addBlocks == null) { // Lazily create section
addBlocks = new byte[(blocks.length >> 1) + 1];
}
addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
addBlocks[index >> 1] & 0xF0 | (block.getId() >> 8) & 0xF
: addBlocks[index >> 1] & 0xF | ((block.getId() >> 8) & 0xF) << 4);
}
blocks[index] = (byte) block.getId();
blockData[index] = (byte) block.getData();
// Get the list of key/values from the block
CompoundTag rawTag = block.getNbtData();
if (rawTag != null) {
Map<String, Tag> values = new HashMap<>();
for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
values.put("id", new StringTag(block.getNbtId()));
values.put("x", new IntTag(x));
values.put("y", new IntTag(y));
values.put("z", new IntTag(z));
CompoundTag tileEntityTag = new CompoundTag(values);
tileEntities.add(tileEntityTag);
}
}
}
}
schematic.put("Blocks", new ByteArrayTag(blocks));
schematic.put("Data", new ByteArrayTag(blockData));
schematic.put("Entities", new ListTag(CompoundTag.class, new ArrayList<>()));
schematic.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
if (addBlocks != null) {
schematic.put("AddBlocks", new ByteArrayTag(addBlocks));
}
// Build and output
CompoundTag schematicTag = new CompoundTag(schematic);
NBTOutputStream stream = new NBTOutputStream(new GZIPOutputStream(new FileOutputStream(file)));
stream.writeNamedTag("Schematic", schematicTag);
stream.close();
} }
@Override @Override

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.scripting;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.command.InsufficientArgumentsException; import com.sk89q.worldedit.command.InsufficientArgumentsException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
@ -151,7 +152,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws UnknownItemException * @throws UnknownItemException
* @throws DisallowedItemException * @throws DisallowedItemException
*/ */
public BaseBlock getBlock(String input, boolean allAllowed) throws WorldEditException { public BlockStateHolder getBlock(String input, boolean allAllowed) throws WorldEditException {
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();
context.setActor(player); context.setActor(player);
context.setWorld(player.getWorld()); context.setWorld(player.getWorld());
@ -170,7 +171,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws UnknownItemException * @throws UnknownItemException
* @throws DisallowedItemException * @throws DisallowedItemException
*/ */
public BaseBlock getBlock(String id) throws WorldEditException { public BlockStateHolder getBlock(String id) throws WorldEditException {
return getBlock(id, false); return getBlock(id, false);
} }
@ -199,7 +200,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @throws UnknownItemException * @throws UnknownItemException
* @throws DisallowedItemException * @throws DisallowedItemException
*/ */
public Set<BaseBlock> getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException { public Set<BlockStateHolder> getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException {
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();
context.setActor(player); context.setActor(player);
context.setWorld(player.getWorld()); context.setWorld(player.getWorld());

View File

@ -24,6 +24,7 @@ package com.sk89q.worldedit.util;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository; import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import java.io.File; import java.io.File;
@ -90,6 +91,10 @@ public class PropertiesConfiguration extends LocalConfiguration {
logFormat = getString("log-format", logFormat); logFormat = getString("log-format", logFormat);
registerHelp = getBool("register-help", registerHelp); registerHelp = getBool("register-help", registerHelp);
wandItem = getString("wand-item", wandItem); wandItem = getString("wand-item", wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
} catch (Throwable e) {
}
superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop); superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop); superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
noDoubleSlash = getBool("no-double-slash", noDoubleSlash); noDoubleSlash = getBool("no-double-slash", noDoubleSlash);
@ -97,6 +102,10 @@ public class PropertiesConfiguration extends LocalConfiguration {
useInventoryOverride = getBool("use-inventory-override", useInventoryOverride); useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride); useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
navigationWand = getString("nav-wand-item", navigationWand); navigationWand = getString("nav-wand-item", navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
} catch (Throwable e) {
}
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance); navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
navigationUseGlass = getBool("nav-use-glass", navigationUseGlass); navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
scriptTimeout = getInt("scripting-timeout", scriptTimeout); scriptTimeout = getInt("scripting-timeout", scriptTimeout);

View File

@ -283,6 +283,6 @@ public class TreeGenerator {
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
private static boolean setBlockIfAir(EditSession session, Vector position, BaseBlock block) throws MaxChangedBlocksException { private static boolean setBlockIfAir(EditSession session, Vector position, BaseBlock block) throws MaxChangedBlocksException {
return session.getBlock(position).isAir() && session.setBlock(position, block); return session.getBlock(position).getBlockType() == BlockTypes.AIR && session.setBlock(position, block);
} }
} }

View File

@ -24,6 +24,7 @@ import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.session.SessionManager; import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository; import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import java.io.IOException; import java.io.IOException;
@ -55,6 +56,10 @@ public class YAMLConfiguration extends LocalConfiguration {
profile = config.getBoolean("debug", profile); profile = config.getBoolean("debug", profile);
wandItem = config.getString("wand-item", wandItem); wandItem = config.getString("wand-item", wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
} catch (Throwable e) {
}
defaultChangeLimit = Math.max(-1, config.getInt( defaultChangeLimit = Math.max(-1, config.getInt(
"limits.max-blocks-changed.default", defaultChangeLimit)); "limits.max-blocks-changed.default", defaultChangeLimit));
@ -99,6 +104,10 @@ public class YAMLConfiguration extends LocalConfiguration {
useInventoryCreativeOverride); useInventoryCreativeOverride);
navigationWand = config.getString("navigation-wand.item", navigationWand); navigationWand = config.getString("navigation-wand.item", navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
} catch (Throwable e) {
}
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance); navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass); navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);

View File

@ -26,6 +26,8 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
@ -33,6 +35,7 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import java.util.HashMap;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -51,7 +54,7 @@ public abstract class AbstractWorld implements World {
} }
@Override @Override
public final boolean setBlock(Vector pt, BaseBlock block) throws WorldEditException { public final boolean setBlock(Vector pt, BlockStateHolder block) throws WorldEditException {
return setBlock(pt, block, true); return setBlock(pt, block, true);
} }
@ -63,10 +66,10 @@ public abstract class AbstractWorld implements World {
@Override @Override
public Mask createLiquidMask() { public Mask createLiquidMask() {
return new BlockMask(this, return new BlockMask(this,
new BaseBlock(BlockTypes.LAVA), new BlockState(BlockTypes.LAVA, new HashMap<>()),
new BaseBlock(BlockTypes.FLOWING_LAVA), new BlockState(BlockTypes.FLOWING_LAVA, new HashMap<>()),
new BaseBlock(BlockTypes.WATER), new BlockState(BlockTypes.WATER, new HashMap<>()),
new BaseBlock(BlockTypes.FLOWING_WATER)); new BlockState(BlockTypes.FLOWING_WATER, new HashMap<>()));
} }
@Override @Override

View File

@ -26,6 +26,9 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -57,7 +60,7 @@ public class NullWorld extends AbstractWorld {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
return false; return false;
} }
@ -101,13 +104,18 @@ public class NullWorld extends AbstractWorld {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR); return BlockTypes.AIR.getDefaultState();
} }
@Override @Override
public BaseBlock getLazyBlock(Vector position) { public LazyBlock getLazyBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR); return new LazyBlock(getBlock(position), this, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
return new BaseBlock(getBlock(position));
} }
@Override @Override

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -75,7 +76,7 @@ public interface World extends Extent {
boolean useItem(Vector position, BaseItem item, Direction face); boolean useItem(Vector position, BaseItem item, Direction face);
/** /**
* Similar to {@link Extent#setBlock(Vector, BaseBlock)} but a * Similar to {@link Extent#setBlock(Vector, BlockStateHolder)} but a
* {@code notifyAndLight} parameter indicates whether adjacent blocks * {@code notifyAndLight} parameter indicates whether adjacent blocks
* should be notified that changes have been made and lighting operations * should be notified that changes have been made and lighting operations
* should be executed. * should be executed.
@ -92,7 +93,7 @@ public interface World extends Extent {
* @param notifyAndLight true to to notify and light * @param notifyAndLight true to to notify and light
* @return true if the block was successfully set (return value may not be accurate) * @return true if the block was successfully set (return value may not be accurate)
*/ */
boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException; boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException;
/** /**
* Get the light level at the given block. * Get the light level at the given block.
@ -165,7 +166,7 @@ public interface World extends Extent {
/** /**
* Fix the given chunks after fast mode was used. * Fix the given chunks after fast mode was used.
* *
* <p>Fast mode makes calls to {@link #setBlock(Vector, BaseBlock, boolean)} * <p>Fast mode makes calls to {@link #setBlock(Vector, BlockStateHolder, boolean)}
* with {@code false} for the {@code notifyAndLight} parameter, which * with {@code false} for the {@code notifyAndLight} parameter, which
* may causes lighting errors to accumulate. Use of this method, if * may causes lighting errors to accumulate. Use of this method, if
* it is implemented by the underlying world, corrects those lighting * it is implemented by the underlying world, corrects those lighting

View File

@ -21,6 +21,8 @@ package com.sk89q.worldedit.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial; import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.world.registry.state.State; import com.sk89q.worldedit.world.registry.state.State;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -38,7 +40,7 @@ public interface BlockRegistry {
* @return the block, which may be null if no block exists * @return the block, which may be null if no block exists
*/ */
@Nullable @Nullable
BaseBlock createFromId(String id); BlockState createFromId(String id);
/** /**
* Create a new block using its legacy numeric ID. * Create a new block using its legacy numeric ID.
@ -48,7 +50,7 @@ public interface BlockRegistry {
*/ */
@Nullable @Nullable
@Deprecated @Deprecated
BaseBlock createFromId(int id); BlockState createFromId(int id);
/** /**
* Get the material for the given block. * Get the material for the given block.
@ -66,6 +68,6 @@ public interface BlockRegistry {
* @return a map of states where the key is the state's ID * @return a map of states where the key is the state's ID
*/ */
@Nullable @Nullable
Map<String, ? extends State> getStates(BaseBlock block); Map<String, ? extends State> getStates(BlockStateHolder block);
} }

View File

@ -21,6 +21,8 @@ package com.sk89q.worldedit.world.registry;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial; import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.world.registry.state.State; import com.sk89q.worldedit.world.registry.state.State;
@ -35,13 +37,13 @@ public class BundledBlockRegistry implements BlockRegistry {
@Nullable @Nullable
@Override @Override
public BaseBlock createFromId(String id) { public BlockState createFromId(String id) {
return new BaseBlock(BlockTypes.getBlockType(id)); return BlockTypes.getBlockType(id).getDefaultState();
} }
@Nullable @Nullable
@Override @Override
public BaseBlock createFromId(int legacyId) { public BlockState createFromId(int legacyId) {
String id = BundledBlockData.getInstance().fromLegacyId(legacyId); String id = BundledBlockData.getInstance().fromLegacyId(legacyId);
if (id != null) { if (id != null) {
return createFromId(id); return createFromId(id);
@ -58,7 +60,7 @@ public class BundledBlockRegistry implements BlockRegistry {
@Nullable @Nullable
@Override @Override
public Map<String, ? extends State> getStates(BaseBlock block) { public Map<String, ? extends State> getStates(BlockStateHolder block) {
return BundledBlockData.getInstance().getStatesById(block.getBlockType().getId()); return BundledBlockData.getInstance().getStatesById(block.getBlockType().getId());
} }

View File

@ -31,6 +31,9 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.blocks.type.ItemTypes; import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -84,6 +87,7 @@ import net.minecraft.world.gen.feature.WorldGenTaiga2;
import net.minecraft.world.gen.feature.WorldGenTrees; import net.minecraft.world.gen.feature.WorldGenTrees;
import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -116,7 +120,7 @@ public class ForgeWorld extends AbstractWorld {
*/ */
ForgeWorld(World world) { ForgeWorld(World world) {
checkNotNull(world); checkNotNull(world);
this.worldRef = new WeakReference<World>(world); this.worldRef = new WeakReference<>(world);
} }
/** /**
@ -155,7 +159,7 @@ public class ForgeWorld extends AbstractWorld {
} }
@Override @Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
checkNotNull(position); checkNotNull(position);
checkNotNull(block); checkNotNull(block);
@ -168,17 +172,17 @@ public class ForgeWorld extends AbstractWorld {
Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4);
BlockPos pos = new BlockPos(x, y, z); BlockPos pos = new BlockPos(x, y, z);
IBlockState old = chunk.getBlockState(pos); IBlockState old = chunk.getBlockState(pos);
IBlockState newState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); IBlockState newState = Block.getBlockById(block.getBlockType().getLegacyId()).getDefaultState(); // TODO .getStateFromMeta(block.getData());
IBlockState successState = chunk.setBlockState(pos, newState); IBlockState successState = chunk.setBlockState(pos, newState);
boolean successful = successState != null; boolean successful = successState != null;
// Create the TileEntity // Create the TileEntity
if (successful) { if (successful) {
if (block.hasNbtData()) { if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
// Kill the old TileEntity // Kill the old TileEntity
world.removeTileEntity(pos); world.removeTileEntity(pos);
NBTTagCompound nativeTag = NBTConverter.toNative(block.getNbtData()); NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData());
nativeTag.setString("id", block.getNbtId()); nativeTag.setString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag); TileEntityUtils.setTileEntity(world, position, nativeTag);
} }
} }
@ -347,7 +351,24 @@ public class ForgeWorld extends AbstractWorld {
} }
@Override @Override
public BaseBlock getBlock(Vector position) { public BlockState getBlock(Vector position) {
World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
IBlockState state = world.getBlockState(pos);
return BlockTypes.getBlockType(ForgeRegistries.BLOCKS.getKey(state.getBlock()).toString()).getDefaultState(); // TODO Data
}
@Override
public LazyBlock getLazyBlock(Vector position) {
World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
IBlockState state = world.getBlockState(pos);
return new LazyBlock(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state), this, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
World world = getWorld(); World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
IBlockState state = world.getBlockState(pos); IBlockState state = world.getBlockState(pos);
@ -360,14 +381,6 @@ public class ForgeWorld extends AbstractWorld {
} }
} }
@Override
public BaseBlock getLazyBlock(Vector position) {
World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
IBlockState state = world.getBlockState(pos);
return new LazyBlock(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state), this, position);
}
@Override @Override
public int hashCode() { public int hashCode() {
return getWorld().hashCode(); return getWorld().hashCode();

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.ItemTypes; import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -35,10 +36,15 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.WorldData; import com.sk89q.worldedit.world.registry.WorldData;
import com.sk89q.worldedit.world.registry.state.State;
import com.sk89q.worldedit.world.registry.state.value.StateValue;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.block.BlockState; import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.block.tileentity.TileEntity;
import org.spongepowered.api.block.trait.BlockTrait;
import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.property.block.GroundLuminanceProperty; import org.spongepowered.api.data.property.block.GroundLuminanceProperty;
import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.data.property.block.SkyLuminanceProperty;
@ -51,7 +57,10 @@ import javax.annotation.Nullable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -107,14 +116,26 @@ public abstract class SpongeWorld extends AbstractWorld {
return getWorld().getName(); return getWorld().getName();
} }
protected abstract BlockState getBlockState(BaseBlock block); @SuppressWarnings("WeakerAccess")
protected BlockState getBlockState(BlockStateHolder<?> block) {
if (block instanceof com.sk89q.worldedit.blocks.type.BlockState) {
BlockState state = Sponge.getRegistry().getType(BlockType.class, block.getBlockType().getId()).orElse(BlockTypes.AIR).getDefaultState();
for (Map.Entry<State, StateValue> entry : block.getStates().entrySet()) {
// TODO Convert across states
}
return state;
} else {
throw new UnsupportedOperationException("Missing Sponge adapter for WorldEdit!");
}
}
@SuppressWarnings("WeakerAccess")
protected abstract void applyTileEntityData(TileEntity entity, BaseBlock block); protected abstract void applyTileEntityData(TileEntity entity, BaseBlock block);
private static final BlockSnapshot.Builder builder = BlockSnapshot.builder(); private static final BlockSnapshot.Builder builder = BlockSnapshot.builder();
@Override @Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
checkNotNull(position); checkNotNull(position);
checkNotNull(block); checkNotNull(block);
@ -133,9 +154,9 @@ public abstract class SpongeWorld extends AbstractWorld {
snapshot.restore(true, notifyAndLight ? BlockChangeFlags.ALL : BlockChangeFlags.NONE); snapshot.restore(true, notifyAndLight ? BlockChangeFlags.ALL : BlockChangeFlags.NONE);
// Create the TileEntity // Create the TileEntity
if (block.hasNbtData()) { if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
// Kill the old TileEntity // Kill the old TileEntity
world.getTileEntity(pos).ifPresent(tileEntity -> applyTileEntityData(tileEntity, block)); world.getTileEntity(pos).ifPresent(tileEntity -> applyTileEntityData(tileEntity, (BaseBlock) block));
} }
return true; return true;

View File

@ -22,7 +22,9 @@ package com.sk89q.worldedit.sponge.config;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.session.SessionManager; import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository; import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import ninja.leaping.configurate.ConfigurationOptions; import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.commented.CommentedConfigurationNode;
@ -58,6 +60,10 @@ public class ConfigurateConfiguration extends LocalConfiguration {
profile = node.getNode("debug").getBoolean(profile); profile = node.getNode("debug").getBoolean(profile);
wandItem = node.getNode("wand-item").getString(wandItem); wandItem = node.getNode("wand-item").getString(wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
} catch (Throwable e) {
}
defaultChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "default").getInt(defaultChangeLimit)); defaultChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "default").getInt(defaultChangeLimit));
maxChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "maximum").getInt(maxChangeLimit)); maxChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "maximum").getInt(maxChangeLimit));
@ -98,6 +104,10 @@ public class ConfigurateConfiguration extends LocalConfiguration {
useInventoryCreativeOverride = node.getNode("use-inventory", "creative-mode-overrides").getBoolean(useInventoryCreativeOverride); useInventoryCreativeOverride = node.getNode("use-inventory", "creative-mode-overrides").getBoolean(useInventoryCreativeOverride);
navigationWand = node.getNode("navigation-wand", "item").getString(navigationWand); navigationWand = node.getNode("navigation-wand", "item").getString(navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
} catch (Throwable e) {
}
navigationWandMaxDistance = node.getNode("navigation-wand", "max-distance").getInt(navigationWandMaxDistance); navigationWandMaxDistance = node.getNode("navigation-wand", "max-distance").getInt(navigationWandMaxDistance);
navigationUseGlass = node.getNode("navigation", "use-glass").getBoolean(navigationUseGlass); navigationUseGlass = node.getNode("navigation", "use-glass").getBoolean(navigationUseGlass);