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.BaseItemStack;
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.entity.BaseEntity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.WorldData;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.Biome;
@ -167,7 +170,7 @@ public class BukkitWorld extends AbstractWorld {
for (int z = 0; z < 16; ++z) {
Vector pt = min.add(x, y, z);
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]);
} else { // Otherwise fool with history
editSession.rememberChange(pt, history[index],
editSession.rawGetBlock(pt));
editSession.getFullBlock(pt));
}
}
}
@ -362,7 +365,32 @@ public class BukkitWorld extends AbstractWorld {
}
@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();
if (adapter != null) {
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
public BaseBiome getBiome(Vector2D position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();

View File

@ -68,7 +68,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override
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
@ -78,7 +78,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override
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;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.BaseEntity;
import org.bukkit.Location;
import org.bukkit.Material;
@ -89,7 +90,7 @@ public interface BukkitImplAdapter {
* @param notifyAndLight notify and light if set
* @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.

View File

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

View File

@ -19,8 +19,11 @@
package com.sk89q.worldedit;
import static com.google.common.base.Preconditions.checkNotNull;
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.SchematicCommands;
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.Region;
import com.sk89q.worldedit.schematic.SchematicFormat;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.world.DataException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
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.
@ -71,7 +68,7 @@ public class CuboidClipboard {
UP_DOWN
}
private BaseBlock[][][] data;
private BlockStateHolder[][][] data;
private Vector offset;
private Vector origin;
private Vector size;
@ -154,186 +151,6 @@ public class CuboidClipboard {
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.
*
@ -426,12 +243,12 @@ public class CuboidClipboard {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
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) {
continue;
}
if (noAir && block.isAir()) {
if (noAir && block.getBlockType() == BlockTypes.AIR) {
continue;
}
@ -481,10 +298,10 @@ public class CuboidClipboard {
* @deprecated use {@link #getBlock(Vector)} instead
*/
@Deprecated
public BaseBlock getPoint(Vector position) throws ArrayIndexOutOfBoundsException {
final BaseBlock block = getBlock(position);
public BlockStateHolder getPoint(Vector position) throws ArrayIndexOutOfBoundsException {
final BlockStateHolder block = getBlock(position);
if (block == null) {
return new BaseBlock(BlockID.AIR);
return BlockTypes.AIR.getDefaultState();
}
return block;
@ -499,7 +316,7 @@ public class CuboidClipboard {
* @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
*/
public BaseBlock getBlock(Vector position) throws ArrayIndexOutOfBoundsException {
public BlockStateHolder getBlock(Vector position) throws ArrayIndexOutOfBoundsException {
return data[position.getBlockX()][position.getBlockY()][position.getBlockZ()];
}
@ -599,88 +416,6 @@ public class CuboidClipboard {
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.
*/

View File

@ -22,6 +22,9 @@ package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
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.entity.BaseEntity;
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());
/**
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
* Used by {@link #setBlock(Vector, BlockStateHolder, Stage)} to
* determine which {@link Extent}s should be bypassed.
*/
public enum Stage {
@ -365,25 +368,18 @@ public class EditSession implements Extent {
}
@Override
public BaseBlock getLazyBlock(Vector position) {
public LazyBlock getLazyBlock(Vector position) {
return world.getLazyBlock(position);
}
@Override
public BaseBlock getBlock(Vector position) {
public BlockState getBlock(Vector position) {
return world.getBlock(position);
}
/**
* Gets the block type at a position.
*
* @param position the position
* @return a block
* @deprecated Use {@link #getBlock(Vector)}
*/
@Deprecated
public BaseBlock rawGetBlock(Vector position) {
return getBlock(position);
@Override
public BaseBlock getFullBlock(Vector position) {
return world.getFullBlock(position);
}
/**
@ -432,7 +428,7 @@ public class EditSession implements Extent {
* @return whether the block changed
* @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) {
case BEFORE_HISTORY:
return bypassNone.setBlock(position, block);
@ -452,7 +448,7 @@ public class EditSession implements Extent {
* @param block the block
* @return whether the block changed
*/
public boolean rawSetBlock(Vector position, BaseBlock block) {
public boolean rawSetBlock(Vector position, BlockStateHolder block) {
try {
return setBlock(position, block, Stage.BEFORE_CHANGE);
} catch (WorldEditException e) {
@ -467,7 +463,7 @@ public class EditSession implements Extent {
* @param block the block
* @return whether the block changed
*/
public boolean smartSetBlock(Vector position, BaseBlock block) {
public boolean smartSetBlock(Vector position, BlockStateHolder block) {
try {
return setBlock(position, block, Stage.BEFORE_REORDER);
} catch (WorldEditException e) {
@ -476,7 +472,7 @@ public class EditSession implements Extent {
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws MaxChangedBlocksException {
public boolean setBlock(Vector position, BlockStateHolder block) throws MaxChangedBlocksException {
try {
return setBlock(position, block, Stage.BEFORE_HISTORY);
} catch (MaxChangedBlocksException e) {
@ -606,7 +602,7 @@ public class EditSession implements Extent {
* @param searchBlocks the list of blocks to search
* @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);
Counter count = new Counter();
RegionMaskingFilter filter = new RegionMaskingFilter(mask, count);
@ -626,7 +622,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @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);
}
@ -781,7 +777,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @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));
}
@ -795,7 +791,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @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);
return replaceBlocks(region, mask, pattern);
}
@ -948,7 +944,7 @@ public class EditSession implements Extent {
final int maxY = region.getMaximumPoint().getBlockY();
final ArbitraryShape shape = new RegionShape(region) {
@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) {
// Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region
return defaultMaterial;
@ -1647,7 +1643,7 @@ public class EditSession implements Extent {
for (int z = basePosition.getBlockZ() - size; z <= basePosition.getBlockZ()
+ size; ++z) {
// 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;
}
// The gods don't want a tree here
@ -1739,9 +1735,9 @@ public class EditSession implements Extent {
* @return the results
*/
// TODO reduce code duplication - probably during ops-redux
public List<Countable<BaseBlock>> getBlockDistributionWithData(Region region) {
List<Countable<BaseBlock>> distribution = new ArrayList<>();
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<>();
public List<Countable<BlockStateHolder>> getBlockDistributionWithData(Region region) {
List<Countable<BlockStateHolder>> distribution = new ArrayList<>();
Map<BlockStateHolder, Countable<BlockStateHolder>> map = new HashMap<>();
if (region instanceof CuboidRegion) {
// Doing this for speed
@ -1760,12 +1756,12 @@ public class EditSession implements Extent {
for (int z = minZ; z <= maxZ; ++z) {
Vector pt = new Vector(x, y, z);
BaseBlock blk = getBlock(pt);
BlockStateHolder blk = getBlock(pt);
if (map.containsKey(blk)) {
map.get(blk).increment();
} else {
Countable<BaseBlock> c = new Countable<>(blk, 1);
Countable<BlockStateHolder> c = new Countable<>(blk, 1);
map.put(blk, c);
distribution.add(c);
}
@ -1774,12 +1770,12 @@ public class EditSession implements Extent {
}
} else {
for (Vector pt : region) {
BaseBlock blk = getBlock(pt);
BlockStateHolder blk = getBlock(pt);
if (map.containsKey(blk)) {
map.get(blk).increment();
} else {
Countable<BaseBlock> c = new Countable<>(blk, 1);
Countable<BlockStateHolder> c = new Countable<>(blk, 1);
map.put(blk, c);
}
}
@ -1803,13 +1799,14 @@ public class EditSession implements Extent {
final ArbitraryShape shape = new ArbitraryShape(region) {
@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);
environment.setCurrentBlock(current);
final Vector scaled = current.subtract(zero).divide(unit);
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;
}
@ -1847,7 +1844,7 @@ public class EditSession implements Extent {
final BlockVector sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue());
// read block from world
final BaseBlock material = world.getBlock(sourcePosition);
final BaseBlock material = world.getFullBlock(sourcePosition);
// queue operation
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.BlockTypes;
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.value.StateValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -69,6 +67,13 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/
@Deprecated
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
public BaseBlock(int id, int data) {
this(id);
}
/**
@ -119,6 +125,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/
@Deprecated
public BaseBlock(int id, int data, @Nullable CompoundTag nbtData) {
this(id);
setNbtData(nbtData);
}
@ -325,51 +332,9 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
* @param o other block
* @return true if equal
*/
public boolean equalsFuzzy(BaseBlock o) {
if (!getBlockType().equals(o.getBlockType())) {
return false;
}
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
public boolean equalsFuzzy(BlockStateHolder o) {
return this.getState().equalsFuzzy(o);
}
@Override

View File

@ -21,7 +21,9 @@ package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
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.registry.BundledItemData;
import javax.annotation.Nullable;
@ -44,6 +46,7 @@ public class BaseItem implements NbtValued {
*/
@Deprecated
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.worldedit.PlayerDirection;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import javax.annotation.Nullable;
@ -671,9 +672,9 @@ public enum BlockType {
* @param block the block
* @return true if the block can be passed through
*/
public static boolean canPassThrough(BaseBlock block) {
public static boolean canPassThrough(BlockStateHolder 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
* @return the y offset
*/
public static double centralTopLimit(BaseBlock block) {
public static double centralTopLimit(BlockStateHolder 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;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import java.util.Collection;
/**
@ -36,9 +38,9 @@ public final class Blocks {
* @param o the 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
for (BaseBlock b : collection) {
for (BlockStateHolder b : collection) {
if (b.equalsFuzzy(o)) {
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.value.StateValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -108,6 +110,33 @@ public class BlockState implements BlockStateHolder<BlockState> {
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.
*

View File

@ -56,4 +56,12 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
* @return The states
*/
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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -639,7 +640,7 @@ public class SelectionCommands {
context.setSession(session);
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);
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 {
int size;
List<Countable<BaseBlock>> distributionData;
List<Countable<BlockStateHolder>> distributionData;
if (args.hasFlag('c')) {
// TODO: Update for new clipboard
@ -677,7 +678,7 @@ public class SelectionCommands {
player.print("# total blocks: " + size);
for (Countable<BaseBlock> c : distributionData) {
for (Countable<BlockStateHolder> c : distributionData) {
String name = c.getID().getBlockType().getName();
String str = String.format("%-7s (%.3f%%) %s #%s%s",
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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.command.tool.*;
@ -109,7 +110,7 @@ public class ToolCommands {
context.setRestricted(true);
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);
session.setTool(itemStack.getType(), new BlockReplacer(targetBlock));
player.print("Block replacer tool bound to " + itemStack.getType().getName() + ".");
@ -207,8 +208,8 @@ public class ToolCommands {
context.setRestricted(true);
context.setPreferringWildcard(false);
BaseBlock secondary = we.getBlockFactory().parseFromInput(args.getString(0), context);
BaseBlock primary = we.getBlockFactory().parseFromInput(args.getString(1), context);
BlockStateHolder secondary = we.getBlockFactory().parseFromInput(args.getString(0), context);
BlockStateHolder primary = we.getBlockFactory().parseFromInput(args.getString(1), context);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.Command;
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.WorldEdit;
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.command.util.CreatureButcher;
import com.sk89q.worldedit.command.util.EntityRemover;
@ -69,8 +71,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
/**
* Utility commands.
*/
@ -257,7 +257,7 @@ public class UtilityCommands {
context.setRestricted(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));
we.checkMaxRadius(size);
@ -279,7 +279,7 @@ public class UtilityCommands {
int size = Math.max(1, args.getInteger(0));
int affected;
Set<BaseBlock> from;
Set<BlockStateHolder> from;
Pattern to;
ParserContext context = new ParserContext();

View File

@ -20,8 +20,8 @@
package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
@ -32,9 +32,9 @@ import com.sk89q.worldedit.extent.inventory.BlockBag;
*/
public class BlockReplacer implements DoubleActionBlockTool {
private BaseBlock targetBlock;
private BlockStateHolder targetBlock;
public BlockReplacer(BaseBlock targetBlock) {
public BlockReplacer(BlockStateHolder 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) {
EditSession editSession = session.createEditSession(player);
targetBlock = (editSession).getBlock(clicked.toVector());
BlockType type = targetBlock.getBlockType().getLegacyType();
BlockType type = targetBlock.getBlockType();
if (type != null) {
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.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
@ -35,10 +36,10 @@ import com.sk89q.worldedit.util.Location;
*/
public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTool {
private BaseBlock primary;
private BaseBlock secondary;
private BlockStateHolder primary;
private BlockStateHolder secondary;
public LongRangeBuildTool(BaseBlock primary, BaseBlock secondary) {
public LongRangeBuildTool(BlockStateHolder primary, BlockStateHolder secondary) {
super("worldedit.tool.lrbuild");
this.primary = primary;
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.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
@ -45,7 +46,7 @@ public class QueryTool implements BlockTool {
World world = (World) clicked.getExtent();
EditSession editSession = session.createEditSession(player);
BaseBlock block = editSession.getBlock(clicked.toVector());
BlockStateHolder block = editSession.getFullBlock(clicked.toVector());
player.print("\u00A79@" + clicked.toVector() + ": " + "\u00A7e"
+ "#" + block.getBlockType() + "\u00A77" + " ("

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockTypes;
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 z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
double y = startY;
final List<BaseBlock> blockTypes = new ArrayList<>();
final List<BlockStateHolder> blockTypes = new ArrayList<>();
for (; y > position.getBlockY() - size; --y) {
final Vector pt = new Vector(x, y, z);
final BaseBlock block = editSession.getBlock(pt);
if (!block.isAir()) {
final BlockStateHolder block = editSession.getBlock(pt);
if (block.getBlockType() != BlockTypes.AIR) {
blockTypes.add(block);
editSession.setBlock(pt, air);
}
@ -55,7 +56,7 @@ public class GravityBrush implements Brush {
Vector pt = new Vector(x, y, z);
Collections.reverse(blockTypes);
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++));
}
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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
@ -35,7 +36,7 @@ import java.util.Set;
* <p>Instances of this class can be taken from
* {@link WorldEdit#getBlockFactory()}.</p>
*/
public class BlockFactory extends AbstractFactory<BaseBlock> {
public class BlockFactory extends AbstractFactory<BlockStateHolder> {
/**
* Create a new instance.
@ -56,8 +57,8 @@ public class BlockFactory extends AbstractFactory<BaseBlock> {
* @return a set of blocks
* @throws InputParseException thrown in error with the input
*/
public Set<BaseBlock> parseFromListInput(String input, ParserContext context) throws InputParseException {
Set<BaseBlock> blocks = new HashSet<>();
public Set<BlockStateHolder> parseFromListInput(String input, ParserContext context) throws InputParseException {
Set<BlockStateHolder> blocks = new HashSet<>();
for (String token : input.split(",")) {
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.metadata.MobType;
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.BlockTypes;
import com.sk89q.worldedit.entity.Player;
@ -54,7 +55,7 @@ import java.util.regex.Pattern;
/**
* Parses block input strings.
*/
class DefaultBlockParser extends InputParser<BaseBlock> {
class DefaultBlockParser extends InputParser<BlockStateHolder> {
protected DefaultBlockParser(WorldEdit worldEdit) {
super(worldEdit);
@ -75,14 +76,14 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
}
@Override
public BaseBlock parseFromInput(String input, ParserContext context)
public BlockStateHolder parseFromInput(String input, ParserContext context)
throws InputParseException {
String originalInput = input;
input = input.replace("_", " ");
input = input.replace(";", "|");
Exception suppressed = null;
try {
BaseBlock modified = parseLogic(input, context);
BlockStateHolder modified = parseLogic(input, context);
if (modified != null) {
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 BaseBlock parseLogic(String input, ParserContext context)
private BlockStateHolder parseLogic(String input, ParserContext context)
throws InputParseException, NoMatchException,
DisallowedUsageException {
BlockType blockType;
Map<State, StateValue> blockStates = new HashMap<>();
String[] blockAndExtraData = input.split("\\|");
String[] blockAndExtraData = input.trim().split("\\|");
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");
}
String typeString = matcher.group(1);
String[] stateProperties = EMPTY_STRING_ARRAY;
if (matcher.groupCount() == 2) {
if (matcher.groupCount() == 3) {
stateProperties = matcher.group(2).split(",");
}
@ -145,10 +146,7 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
} catch (IncompleteRegionException e) {
throw new InputParseException("Your selection is not complete.");
}
final BaseBlock blockInHand = world.getBlock(primaryPosition);
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
final BlockState blockInHand = world.getBlock(primaryPosition);
blockType = blockInHand.getBlockType();
blockStates = blockInHand.getStates();
@ -239,7 +237,7 @@ class DefaultBlockParser extends InputParser<BaseBlock> {
return new SkullBlock(state, type.replace(" ", "_")); // valid MC usernames
} 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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -40,7 +41,7 @@ class RandomPatternParser extends InputParser<Pattern> {
RandomPattern randomPattern = new RandomPattern();
for (String token : input.split(",")) {
BaseBlock block;
BlockStateHolder block;
double chance;

View File

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

View File

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

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.history.change.BlockChange;
@ -58,8 +59,8 @@ public class ChangeSetExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
BaseBlock previous = getBlock(location);
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
BlockStateHolder previous = getBlock(location);
changeSet.add(new BlockChange(location.toBlockVector(), previous, 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.Vector2D;
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.world.biome.BaseBiome;
@ -37,20 +40,14 @@ public interface InputExtent {
* is undefined (an air block could be returned). However, {@code null}
* 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
* {@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
* @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
@ -73,7 +70,15 @@ public interface InputExtent {
* @param position position of 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.

View File

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

View File

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

View File

@ -22,7 +22,7 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
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.world.biome.BaseBiome;
@ -35,8 +35,8 @@ public interface OutputExtent {
/**
* 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
* {@link BaseBlock} do not affect the world until this method is called again.
* not tie the given {@link BlockStateHolder} to the world, so future changes to the
* {@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
* 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)
* @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.

View File

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

View File

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

View File

@ -23,6 +23,9 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
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.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
@ -45,8 +48,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockArrayClipboard implements Clipboard {
private final Region region;
private Vector origin = new Vector();
private final BaseBlock[][][] blocks;
private Vector origin;
private final BlockStateHolder[][][] blocks;
private final List<ClipboardEntity> entities = new ArrayList<>();
/**
@ -120,12 +123,38 @@ public class BlockArrayClipboard implements Clipboard {
}
@Override
public BaseBlock getBlock(Vector position) {
public BlockState getBlock(Vector position) {
if (region.contains(position)) {
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) {
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
public BaseBlock getLazyBlock(Vector position) {
return getBlock(position);
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
if (region.contains(position)) {
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;
} else {
return false;

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.extent.clipboard.io;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import javax.annotation.Nullable;
import java.io.DataInputStream;
@ -38,7 +37,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import static com.google.common.base.Preconditions.checkNotNull;
@ -59,8 +57,7 @@ public enum ClipboardFormat {
@Override
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream));
return new SchematicWriter(nbtStream);
throw new UnsupportedOperationException("This clipboard format is deprecated.");
}
@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.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
@ -79,7 +80,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
if (blockBag != null) {
BaseBlock lazyBlock = getExtent().getLazyBlock(position);
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.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
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.Extent;
@ -43,9 +44,9 @@ import java.util.*;
*/
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
private TupleArrayList<BlockVector, BaseBlock> stage1 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BaseBlock> stage2 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BaseBlock> stage3 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BlockStateHolder> stage1 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BlockStateHolder> stage2 = new TupleArrayList<>();
private TupleArrayList<BlockVector, BlockStateHolder> stage3 = new TupleArrayList<>();
private boolean enabled;
/**
@ -87,7 +88,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
BaseBlock lazyBlock = getLazyBlock(location);
if (!enabled) {
@ -97,18 +98,18 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
if (BlockType.shouldPlaceLast(block.getBlockType().getLegacyId())) {
// Place torches, etc. last
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())) {
// Place signs, reed, etc even later
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())) {
// Destroy torches, etc. first
super.setBlock(location, new BaseBlock(BlockTypes.AIR));
super.setBlock(location, BlockTypes.AIR.getDefaultState());
return super.setBlock(location, block);
} else {
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();
final Set<BlockVector> blocks = new HashSet<>();
final Map<BlockVector, BaseBlock> blockTypes = new HashMap<>();
for (Map.Entry<BlockVector, BaseBlock> entry : stage3) {
final Map<BlockVector, BlockStateHolder> blockTypes = new HashMap<>();
for (Map.Entry<BlockVector, BlockStateHolder> entry : stage3) {
final BlockVector pt = entry.getKey();
blocks.add(pt);
blockTypes.put(pt, entry.getValue());
@ -148,10 +149,10 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
assert (blockTypes.containsKey(current));
final BaseBlock baseBlock = blockTypes.get(current);
final BlockStateHolder baseBlock = blockTypes.get(current);
final int type = baseBlock.getBlockType().getLegacyId();
final int data = baseBlock.getData();
// final int data = baseBlock.getData();
switch (type) {
case BlockID.WOODEN_DOOR:
@ -161,13 +162,13 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
case BlockID.DARK_OAK_DOOR:
case BlockID.SPRUCE_DOOR:
case BlockID.IRON_DOOR:
if ((data & 0x8) == 0) {
// Deal with lower door halves being attached to the floor AND the upper half
BlockVector upperBlock = current.add(0, 1, 0).toBlockVector();
if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
walked.addFirst(upperBlock);
}
}
// TODO if ((data & 0x8) == 0) {
// // Deal with lower door halves being attached to the floor AND the upper half
// BlockVector upperBlock = current.add(0, 1, 0).toBlockVector();
// if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
// walked.addFirst(upperBlock);
// }
// }
break;
case BlockID.MINECART_TRACKS:
@ -183,7 +184,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
break;
}
final PlayerDirection attachment = BlockType.getAttachment(type, data);
final PlayerDirection attachment = BlockType.getAttachment(type, 0); // TODO
if (attachment == null) {
// Block is not attached to anything => we can place it
break;

View File

@ -24,6 +24,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
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.Extent;
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
* @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);
return block;
}
@Override
public BaseBlock getBlock(Vector position) {
public BlockState getBlock(Vector position) {
return transformBlock(super.getBlock(position), false);
}
@Override
public BaseBlock getLazyBlock(Vector position) {
public LazyBlock getLazyBlock(Vector position) {
return transformBlock(super.getLazyBlock(position), false);
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
return super.setBlock(location, transformBlock(new BaseBlock(block), true));
public BaseBlock getFullBlock(Vector position) {
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
* @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);
}
@ -121,7 +129,7 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
* @param changedBlock the block to change
* @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(transform);
checkNotNull(registry);

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
@ -77,7 +78,7 @@ public class BlockChangeLimiter extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (limit >= 0) {
if (count >= 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.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
@ -49,7 +50,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
}
@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 BlockType type = block.getBlockType();
if (y < 0 || y > world.getMaxY()) {
@ -61,16 +62,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
return false;
}
if (block.getData() < 0) {
throw new SevereValidationException("Cannot set a data value that is less than 0");
}
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.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
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.Extent;
@ -52,7 +53,7 @@ public class BlockQuirkExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException {
BaseBlock lazyBlock = getExtent().getLazyBlock(position);
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.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World;
@ -61,7 +62,7 @@ public class ChunkLoadingExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
world.checkLoadedChunk(location);
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.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
@ -84,7 +85,7 @@ public class FastModeExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (enabled) {
dirtyChunks.add(new BlockVector2D(location.getBlockX() >> 4, location.getBlockZ() >> 4));
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.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.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.World;
@ -79,8 +81,8 @@ public class SurvivalModeExtent extends AbstractDelegateExtent {
}
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
if (toolUse && block.isAir()) {
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
if (toolUse && block.getBlockType() == BlockTypes.AIR) {
world.simulateBlockMine(location);
return true;
} else {

View File

@ -24,6 +24,7 @@ import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.internal.helper.MCDirections;
@ -68,7 +69,7 @@ public class ExtentBlockCopy implements RegionFunction {
@Override
public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = source.getBlock(position);
BaseBlock block = source.getFullBlock(position);
Vector orig = position.subtract(from);
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.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.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -104,7 +105,7 @@ public class FloraGenerator implements RegionFunction {
@Override
public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position);
BlockStateHolder block = editSession.getBlock(position);
if (block.getBlockType() == BlockTypes.GRASS) {
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.WorldEditException;
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.BlockTypes;
import com.sk89q.worldedit.function.RegionFunction;
@ -50,7 +51,7 @@ public class ForestGenerator implements RegionFunction {
@Override
public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position);
BlockStateHolder block = editSession.getBlock(position);
BlockType t = block.getBlockType();
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.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.function.RegionFunction;
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 {
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) {
Vector testPos = pos.add(0, i, 0);
if (editSession.getBlock(testPos).isAir()) {
if (editSession.getBlock(testPos).getBlockType() == BlockTypes.AIR) {
pos = testPos;
} else {
break;
}
}
setBlockIfAir(editSession, pos, new BaseBlock(BlockTypes.OAK_LEAVES));
setBlockIfAir(editSession, pos, BlockTypes.OAK_LEAVES.getDefaultState());
affected++;
int t = random.nextInt(4);
int h = random.nextInt(3) - 1;
Vector p;
BaseBlock log = new BaseBlock(BlockTypes.OAK_LOG);
BlockState log = BlockTypes.OAK_LOG.getDefaultState();
switch (t) {
case 0:
@ -159,7 +161,7 @@ public class GardenPatchGenerator implements RegionFunction {
@Override
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);
}
@ -167,9 +169,9 @@ public class GardenPatchGenerator implements RegionFunction {
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);
}
@ -202,8 +204,8 @@ public class GardenPatchGenerator implements RegionFunction {
* @return if block was changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
private static boolean setBlockIfAir(EditSession session, Vector position, BaseBlock block) throws MaxChangedBlocksException {
return session.getBlock(position).isAir() && session.setBlock(position, block);
private static boolean setBlockIfAir(EditSession session, Vector position, BlockStateHolder block) throws MaxChangedBlocksException {
return session.getBlock(position).getBlockType() == BlockTypes.AIR && session.setBlock(position, block);
}
/**

View File

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

View File

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

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent;
import java.util.Iterator;
@ -37,7 +38,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockMapEntryPlacer implements Operation {
private final Extent extent;
private final Iterator<Map.Entry<BlockVector, BaseBlock>> iterator;
private final Iterator<Map.Entry<BlockVector, BlockStateHolder>> iterator;
/**
* Create a new instance.
@ -45,7 +46,7 @@ public class BlockMapEntryPlacer implements Operation {
* @param extent the extent to set the blocks on
* @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(iterator);
this.extent = extent;
@ -55,7 +56,7 @@ public class BlockMapEntryPlacer implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) {
Map.Entry<BlockVector, BaseBlock> entry = iterator.next();
Map.Entry<BlockVector, BlockStateHolder> entry = iterator.next();
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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
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 {
private BaseBlock block;
private BlockStateHolder block;
/**
* Create a new pattern with the given block.
*
* @param block the block
*/
public BlockPattern(BaseBlock block) {
public BlockPattern(BlockStateHolder block) {
setBlock(block);
}
@ -45,7 +46,7 @@ public class BlockPattern extends AbstractPattern {
*
* @return the block that is always returned
*/
public BaseBlock getBlock() {
public BlockStateHolder getBlock() {
return block;
}
@ -54,13 +55,13 @@ public class BlockPattern extends AbstractPattern {
*
* @param block the block
*/
public void setBlock(BaseBlock block) {
public void setBlock(BlockStateHolder block) {
checkNotNull(block);
this.block = block;
}
@Override
public BaseBlock apply(Vector position) {
public BlockStateHolder apply(Vector position) {
return block;
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import static com.google.common.base.Preconditions.checkNotNull;
@ -45,7 +46,7 @@ public class ClipboardPattern extends AbstractPattern {
}
@Override
public BaseBlock apply(Vector position) {
public BlockStateHolder apply(Vector position) {
int xp = Math.abs(position.getBlockX()) % size.getBlockX();
int yp = Math.abs(position.getBlockY()) % size.getBlockY();
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.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 {
/**
* Return a {@link BaseBlock} for the given position.
* Return a {@link BlockStateHolder} for the given position.
*
* @param position the position
* @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.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import java.util.ArrayList;
import java.util.List;
@ -53,7 +54,7 @@ public class RandomPattern extends AbstractPattern {
}
@Override
public BaseBlock apply(Vector position) {
public BlockStateHolder apply(Vector position) {
double r = random.nextDouble();
double offset = 0;

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
@ -83,7 +84,7 @@ public class RepeatingExtentPattern extends AbstractPattern {
}
@Override
public BaseBlock apply(Vector position) {
public BlockStateHolder apply(Vector position) {
Vector base = position.add(offset);
Vector size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1);
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.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.UndoContext;
@ -37,8 +38,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class BlockChange implements Change {
private final BlockVector position;
private final BaseBlock previous;
private final BaseBlock current;
private final BlockStateHolder previous;
private final BlockStateHolder current;
/**
* Create a new block change.
@ -47,7 +48,7 @@ public class BlockChange implements Change {
* @param previous the previous 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(previous);
checkNotNull(current);
@ -70,7 +71,7 @@ public class BlockChange implements Change {
*
* @return the previous block
*/
public BaseBlock getPrevious() {
public BlockStateHolder getPrevious() {
return previous;
}
@ -79,7 +80,7 @@ public class BlockChange implements Change {
*
* @return the current block
*/
public BaseBlock getCurrent() {
public BlockStateHolder getCurrent() {
return current;
}

View File

@ -23,6 +23,7 @@ import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import com.sk89q.worldedit.BlockVector;
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.Change;
import com.sk89q.worldedit.util.collection.TupleArrayList;
@ -43,8 +44,8 @@ import static java.util.Map.Entry;
*/
public class BlockOptimizedHistory extends ArrayListHistory {
private final TupleArrayList<BlockVector, BaseBlock> previous = new TupleArrayList<>();
private final TupleArrayList<BlockVector, BaseBlock> current = new TupleArrayList<>();
private final TupleArrayList<BlockVector, BlockStateHolder> previous = new TupleArrayList<>();
private final TupleArrayList<BlockVector, BlockStateHolder> current = new TupleArrayList<>();
@Override
public void add(Change change) {
@ -85,7 +86,7 @@ public class BlockOptimizedHistory extends ArrayListHistory {
*
* @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());
}

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.NoMatchException;
@ -169,7 +170,7 @@ public class WorldEditBinding extends BindingHelper {
@BindingMatch(type = BaseBlock.class,
behavior = BindingBehavior.CONSUMES,
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);
ParserContext parserContext = new ParserContext();
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.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockTypes;
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
if (newHeight > curHeight) {
// 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
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.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region;
@ -35,45 +33,15 @@ import com.sk89q.worldedit.regions.Region;
public abstract class ArbitraryShape {
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) {
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() {
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.
*
@ -83,60 +51,7 @@ public abstract class ArbitraryShape {
* @param defaultMaterial The material returned by the pattern for the current block.
* @return material to place or null to not place anything.
*/
protected abstract BaseBlock getMaterial(int x, int y, int z, BaseBlock 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;
}
}
protected abstract BlockStateHolder getMaterial(int x, int y, int z, BlockStateHolder defaultMaterial);
/**
* Generates the shape.
@ -156,7 +71,7 @@ public abstract class ArbitraryShape {
int z = position.getBlockZ();
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)) {
++affected;
}
@ -164,43 +79,11 @@ public abstract class ArbitraryShape {
continue;
}
final BaseBlock material = getMaterialCached(x, y, z, pattern);
final BlockStateHolder material = getMaterial(x, y, z, pattern.apply(position));
if (material == null) {
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)) {
++affected;
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.regions.shape;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.regions.Region;
/**
@ -34,7 +35,7 @@ public class RegionShape extends ArbitraryShape {
}
@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))) {
return null;
}

View File

@ -25,7 +25,6 @@ import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.NamedTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
@ -39,16 +38,12 @@ import com.sk89q.worldedit.world.DataException;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class MCEditSchematicFormat extends SchematicFormat {
@ -206,91 +201,7 @@ public class MCEditSchematicFormat extends SchematicFormat {
@Override
public void save(CuboidClipboard clipboard, File file) throws IOException, DataException {
int width = clipboard.getWidth();
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();
throw new UnsupportedOperationException("Saving is deprecated");
}
@Override

View File

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

View File

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

View File

@ -283,6 +283,6 @@ public class TreeGenerator {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
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.LocalSession;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import java.io.IOException;
@ -55,6 +56,10 @@ public class YAMLConfiguration extends LocalConfiguration {
profile = config.getBoolean("debug", profile);
wandItem = config.getString("wand-item", wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
} catch (Throwable e) {
}
defaultChangeLimit = Math.max(-1, config.getInt(
"limits.max-blocks-changed.default", defaultChangeLimit));
@ -99,6 +104,10 @@ public class YAMLConfiguration extends LocalConfiguration {
useInventoryCreativeOverride);
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);
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.BaseItemStack;
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.extension.platform.Platform;
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.util.Direction;
import java.util.HashMap;
import java.util.PriorityQueue;
import javax.annotation.Nullable;
@ -51,7 +54,7 @@ public abstract class AbstractWorld implements World {
}
@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);
}
@ -63,10 +66,10 @@ public abstract class AbstractWorld implements World {
@Override
public Mask createLiquidMask() {
return new BlockMask(this,
new BaseBlock(BlockTypes.LAVA),
new BaseBlock(BlockTypes.FLOWING_LAVA),
new BaseBlock(BlockTypes.WATER),
new BaseBlock(BlockTypes.FLOWING_WATER));
new BlockState(BlockTypes.LAVA, new HashMap<>()),
new BlockState(BlockTypes.FLOWING_LAVA, new HashMap<>()),
new BlockState(BlockTypes.WATER, new HashMap<>()),
new BlockState(BlockTypes.FLOWING_WATER, new HashMap<>()));
}
@Override

View File

@ -26,6 +26,9 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
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.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
@ -57,7 +60,7 @@ public class NullWorld extends AbstractWorld {
}
@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;
}
@ -101,13 +104,18 @@ public class NullWorld extends AbstractWorld {
}
@Override
public BaseBlock getBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR);
public BlockState getBlock(Vector position) {
return BlockTypes.AIR.getDefaultState();
}
@Override
public BaseBlock getLazyBlock(Vector position) {
return new BaseBlock(BlockTypes.AIR);
public LazyBlock getLazyBlock(Vector position) {
return new LazyBlock(getBlock(position), this, position);
}
@Override
public BaseBlock getFullBlock(Vector position) {
return new BaseBlock(getBlock(position));
}
@Override

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.Extent;
@ -75,7 +76,7 @@ public interface World extends Extent {
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
* should be notified that changes have been made and lighting operations
* should be executed.
@ -92,7 +93,7 @@ public interface World extends Extent {
* @param notifyAndLight true to to notify and light
* @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.
@ -165,7 +166,7 @@ public interface World extends Extent {
/**
* 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
* may causes lighting errors to accumulate. Use of this method, if
* 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.BlockMaterial;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.world.registry.state.State;
import javax.annotation.Nullable;
@ -38,7 +40,7 @@ public interface BlockRegistry {
* @return the block, which may be null if no block exists
*/
@Nullable
BaseBlock createFromId(String id);
BlockState createFromId(String id);
/**
* Create a new block using its legacy numeric ID.
@ -48,7 +50,7 @@ public interface BlockRegistry {
*/
@Nullable
@Deprecated
BaseBlock createFromId(int id);
BlockState createFromId(int id);
/**
* 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
*/
@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.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.world.registry.state.State;
@ -35,13 +37,13 @@ public class BundledBlockRegistry implements BlockRegistry {
@Nullable
@Override
public BaseBlock createFromId(String id) {
return new BaseBlock(BlockTypes.getBlockType(id));
public BlockState createFromId(String id) {
return BlockTypes.getBlockType(id).getDefaultState();
}
@Nullable
@Override
public BaseBlock createFromId(int legacyId) {
public BlockState createFromId(int legacyId) {
String id = BundledBlockData.getInstance().fromLegacyId(legacyId);
if (id != null) {
return createFromId(id);
@ -58,7 +60,7 @@ public class BundledBlockRegistry implements BlockRegistry {
@Nullable
@Override
public Map<String, ? extends State> getStates(BaseBlock block) {
public Map<String, ? extends State> getStates(BlockStateHolder block) {
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.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.ItemTypes;
import com.sk89q.worldedit.entity.BaseEntity;
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.WorldGenerator;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import javax.annotation.Nullable;
@ -116,7 +120,7 @@ public class ForgeWorld extends AbstractWorld {
*/
ForgeWorld(World world) {
checkNotNull(world);
this.worldRef = new WeakReference<World>(world);
this.worldRef = new WeakReference<>(world);
}
/**
@ -155,7 +159,7 @@ public class ForgeWorld extends AbstractWorld {
}
@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(block);
@ -168,17 +172,17 @@ public class ForgeWorld extends AbstractWorld {
Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4);
BlockPos pos = new BlockPos(x, y, z);
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);
boolean successful = successState != null;
// Create the TileEntity
if (successful) {
if (block.hasNbtData()) {
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
// Kill the old TileEntity
world.removeTileEntity(pos);
NBTTagCompound nativeTag = NBTConverter.toNative(block.getNbtData());
nativeTag.setString("id", block.getNbtId());
NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData());
nativeTag.setString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag);
}
}
@ -347,7 +351,24 @@ public class ForgeWorld extends AbstractWorld {
}
@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();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
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
public int hashCode() {
return getWorld().hashCode();

View File

@ -27,6 +27,7 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.entity.BaseEntity;
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.biome.BaseBiome;
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.block.BlockSnapshot;
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.trait.BlockTrait;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.property.block.GroundLuminanceProperty;
import org.spongepowered.api.data.property.block.SkyLuminanceProperty;
@ -51,7 +57,10 @@ import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
@ -107,14 +116,26 @@ public abstract class SpongeWorld extends AbstractWorld {
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);
private static final BlockSnapshot.Builder builder = BlockSnapshot.builder();
@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(block);
@ -133,9 +154,9 @@ public abstract class SpongeWorld extends AbstractWorld {
snapshot.restore(true, notifyAndLight ? BlockChangeFlags.ALL : BlockChangeFlags.NONE);
// Create the TileEntity
if (block.hasNbtData()) {
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
// Kill the old TileEntity
world.getTileEntity(pos).ifPresent(tileEntity -> applyTileEntityData(tileEntity, block));
world.getTileEntity(pos).ifPresent(tileEntity -> applyTileEntityData(tileEntity, (BaseBlock) block));
}
return true;

View File

@ -22,7 +22,9 @@ package com.sk89q.worldedit.sponge.config;
import com.google.common.reflect.TypeToken;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
@ -58,6 +60,10 @@ public class ConfigurateConfiguration extends LocalConfiguration {
profile = node.getNode("debug").getBoolean(profile);
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));
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);
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);
navigationUseGlass = node.getNode("navigation", "use-glass").getBoolean(navigationUseGlass);