This commit is contained in:
Jesse Boyd
2019-07-18 04:30:02 +10:00
280 changed files with 13872 additions and 8497 deletions

View File

@ -19,6 +19,9 @@
package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.NbtValued;
/**
@ -34,6 +37,17 @@ public interface TileEntityBlock extends NbtValued {
*
* @return tile entity ID, non-null string
*/
String getNbtId();
default String getNbtId() {
CompoundTag nbtData = getNbtData();
if (nbtData == null) {
return "";
}
Tag idTag = nbtData.getValue().get("id");
if (idTag instanceof StringTag) {
return ((StringTag) idTag).getValue();
} else {
return "";
}
}
}

View File

@ -68,7 +68,7 @@ public class AreaPickaxe implements BlockTool {
for (int x = ox - range; x <= ox + range; ++x) {
for (int z = oz - range; z <= oz + range; ++z) {
for (int y = oy + range; y >= oy - range; --y) {
if (editSession.getLazyBlock(x, y, z).getBlockType() != initialType) {
if (initialType.equals(editSession.getBlock(x, y, z))) {
continue;
}

View File

@ -66,7 +66,6 @@ public class EditSessionEvent extends Event implements Cancellable {
private final int maxBlocks;
private final Stage stage;
private Extent extent;
private EditSession session;
private boolean cancelled;
/**
@ -84,14 +83,6 @@ public class EditSessionEvent extends Event implements Cancellable {
this.stage = stage;
}
public void setEditSession(EditSession session) {
this.session = session;
}
public EditSession getEditSession() {
return session;
}
/**
* Get the actor for this event.
*
@ -165,9 +156,7 @@ public class EditSessionEvent extends Event implements Cancellable {
* @return a new event
*/
public EditSessionEvent clone(Stage stage) {
EditSessionEvent clone = new EditSessionEvent(world, actor, maxBlocks, stage);
clone.setEditSession(session);
return clone;
return new EditSessionEvent(world, actor, maxBlocks, stage);
}
}

View File

@ -21,12 +21,7 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory;

View File

@ -43,6 +43,7 @@ import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -101,7 +102,7 @@ public class DefaultPatternParser extends FaweParser<Pattern> {
() -> {
if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
return dispatcher.getAliases().stream().filter(
s -> s.startsWith(command.toLowerCase())
s -> s.startsWith(command.toLowerCase(Locale.ROOT))
).collect(Collectors.toList());
}
);

View File

@ -24,24 +24,34 @@ import com.boydti.fawe.jnbt.anvil.generator.GenBase;
import com.boydti.fawe.jnbt.anvil.generator.OreGen;
import com.boydti.fawe.jnbt.anvil.generator.Resource;
import com.boydti.fawe.jnbt.anvil.generator.SchemGen;
import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MathUtils;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.PropertyGroup;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
@ -51,8 +61,11 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A world, portion of a world, clipboard, or other object that can have blocks
* set or entities placed.
@ -120,33 +133,11 @@ public interface Extent extends InputExtent, OutputExtent {
return null;
}
@Override
default BlockState getBlock(BlockVector3 position) {
return getFullBlock(position).toImmutableState();
}
@Override
default BlockState getLazyBlock(BlockVector3 position) {
return getFullBlock(position).toImmutableState();
}
default BlockState getLazyBlock(int x, int y, int z) {
return getLazyBlock(BlockVector3.at(x, y, z));
}
default <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T state) throws WorldEditException {
return setBlock(BlockVector3.at(x, y, z), state);
}
default boolean setBiome(int x, int y, int z, BiomeType biome) {
return setBiome(BlockVector2.at(x, z), biome);
}
default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY) {
maxY = Math.min(maxY, Math.max(0, maxY));
minY = Math.max(0, minY);
for (int y = maxY; y >= minY; --y) {
BlockState block = getLazyBlock(x, y, z);
BlockState block = getBlock(x, y, z);
if (block.getBlockType().getMaterial().isMovementBlocker()) {
return y;
}
@ -170,20 +161,20 @@ public interface Extent extends InputExtent, OutputExtent {
int clearanceBelow = y - minY;
int clearance = Math.min(clearanceAbove, clearanceBelow);
BlockState block = getLazyBlock(x, y, z);
BlockState block = getBlock(x, y, z);
boolean state = !block.getBlockType().getMaterial().isMovementBlocker();
int data1 = PropertyGroup.LEVEL.get(block);
int data2 = data1;
int offset = state ? 0 : 1;
for (int d = 0; d <= clearance; d++) {
int y1 = y + d;
block = getLazyBlock(x, y1, z);
block = getBlock(x, y1, z);
if (block.getBlockType().getMaterial().isMovementBlocker() == state) {
return ((y1 - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data1));
}
data1 = PropertyGroup.LEVEL.get(block);
int y2 = y - d;
block = getLazyBlock(x, y2, z);
block = getBlock(x, y2, z);
if (block.getBlockType().getMaterial().isMovementBlocker() == state) {
return ((y2 + offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2));
}
@ -192,15 +183,15 @@ public interface Extent extends InputExtent, OutputExtent {
if (clearanceAbove != clearanceBelow) {
if (clearanceAbove < clearanceBelow) {
for (int layer = y - clearance - 1; layer >= minY; layer--) {
block = getLazyBlock(x, layer, z);
block = getBlock(x, layer, z);
if (block.getBlockType().getMaterial().isMovementBlocker() == state) {
return layer + offset << 4;
return ((layer + offset) << 4) + 0;
}
data1 = PropertyGroup.LEVEL.get(block);
}
} else {
for (int layer = y + clearance + 1; layer <= maxY; layer++) {
block = getLazyBlock(x, layer, z);
block = getBlock(x, layer, z);
if (block.getBlockType().getMaterial().isMovementBlocker() == state) {
return ((layer - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2));
}
@ -255,33 +246,33 @@ public interface Extent extends InputExtent, OutputExtent {
int clearanceAbove = maxY - y;
int clearanceBelow = y - minY;
int clearance = Math.min(clearanceAbove, clearanceBelow);
BlockStateHolder block = getLazyBlock(x, y, z);
BlockStateHolder block = getBlock(x, y, z);
boolean state = !block.getBlockType().getMaterial().isMovementBlocker();
int offset = state ? 0 : 1;
for (int d = 0; d <= clearance; d++) {
int y1 = y + d;
block = getLazyBlock(x, y1, z);
block = getBlock(x, y1, z);
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) return y1 - offset;
int y2 = y - d;
block = getLazyBlock(x, y2, z);
block = getBlock(x, y2, z);
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) return y2 + offset;
}
if (clearanceAbove != clearanceBelow) {
if (clearanceAbove < clearanceBelow) {
for (int layer = y - clearance - 1; layer >= minY; layer--) {
block = getLazyBlock(x, layer, z);
block = getBlock(x, layer, z);
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) return layer + offset;
}
} else {
for (int layer = y + clearance + 1; layer <= maxY; layer++) {
block = getLazyBlock(x, layer, z);
block = getBlock(x, layer, z);
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) return layer - offset;
}
}
}
int result = state ? failedMin : failedMax;
if(result > 0 && !ignoreAir) {
block = getLazyBlock(x, result, z);
block = getBlock(x, result, z);
return block.getBlockType().getMaterial().isAir() ? -1 : result;
}
return result;
@ -407,6 +398,10 @@ public interface Extent extends InputExtent, OutputExtent {
return null;
}
default boolean cancel() {
return true;
}
default int getMaxY() {
return 255;
}
@ -423,4 +418,169 @@ public interface Extent extends InputExtent, OutputExtent {
weClipboard.setOrigin(region.getMinimumPoint());
return weClipboard;
}
/**
* Count the number of blocks of a list of types in a region.
*
* @param region the region
* @param searchBlocks the list of blocks to search
* @return the number of blocks that matched the block
*/
default int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
BlockMask mask = new BlockMask(this, searchBlocks);
return countBlocks(region, mask);
}
/**
* Count the number of blocks of a list of types in a region.
*
* @param region the region
* @param searchMask mask to match
* @return the number of blocks that matched the mask
*/
default int countBlocks(Region region, Mask searchMask) {
RegionVisitor visitor = new RegionVisitor(region, searchMask::test);
Operations.completeBlindly(visitor);
return visitor.getAffected();
}
/**
* Sets all the blocks inside a region to a given block type.
*
* @param region the region
* @param block the block
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(block);
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData();
if (canBypassAll(region, false, true) && !hasNbt) {
return changes = queue.setBlocks((CuboidRegion) region, block.getInternalId());
}
try {
if (hasExtraExtents()) {
RegionVisitor visitor = new RegionVisitor(region, new BlockReplace(getExtent(), (block)), this);
Operations.completeBlindly(visitor);
this.changes += visitor.getAffected();
} else {
for (BlockVector3 blockVector3 : region) {
if (getExtent().setBlock(blockVector3, block)) {
changes++;
}
}
}
} catch (final WorldEditException e) {
throw new RuntimeException("Unexpected exception", e);
}
return changes;
}
/**
* Sets all the blocks inside a region to a given pattern.
*
* @param region the region
* @param pattern the pattern that provides the replacement block
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
if (pattern instanceof BlockPattern) {
return setBlocks(region, ((BlockPattern) pattern).getBlock());
}
if (pattern instanceof BlockStateHolder) {
return setBlocks(region, (BlockStateHolder) pattern);
}
BlockReplace replace = new BlockReplace(this, pattern);
RegionVisitor visitor = new RegionVisitor(region, replace, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
}
/**
* Replaces all the blocks matching a given filter, within a given region, to a block
* returned by a given pattern.
*
* @param region the region to replace the blocks within
* @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.function.mask.ExistingBlockMask}
* @param replacement the replacement block
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
return replaceBlocks(region, filter, new BlockPattern(replacement));
}
/**
* Replaces all the blocks matching a given filter, within a given region, to a block
* returned by a given pattern.
*
* @param region the region to replace the blocks within
* @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.function.mask.ExistingBlockMask}
* @param pattern the pattern that provides the new blocks
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMask(this, filter);
return replaceBlocks(region, mask, pattern);
}
/**
* Replaces all the blocks matching a given mask, within a given region, to a block
* returned by a given pattern.
*
* @param region the region to replace the blocks within
* @param mask the mask that blocks must match
* @param pattern the pattern that provides the new blocks
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(mask);
checkNotNull(pattern);
BlockReplace replace = new BlockReplace(this, pattern);
RegionMaskingFilter filter = new RegionMaskingFilter(mask, replace);
RegionVisitor visitor = new RegionVisitor(region, filter);
Operations.completeLegacy(visitor);
return visitor.getAffected();
}
/**
* Sets the blocks at the center of the given region to the given pattern.
* If the center sits between two blocks on a certain axis, then two blocks
* will be placed to mark the center.
*
* @param region the region to find the center of
* @param pattern the replacement pattern
* @return the number of blocks placed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
default int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
Vector3 center = region.getCenter();
Region centerRegion = new CuboidRegion(
getWorld(), // Causes clamping of Y range
BlockVector3.at(((int) center.getX()), ((int) center.getY()), ((int) center.getZ())),
BlockVector3.at(MathUtils.roundHalfUp(center.getX()),
center.getY(), MathUtils.roundHalfUp(center.getZ())));
return setBlocks(centerRegion, pattern);
}
default int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
Operations.completeBlindly(visitor);
return 0;
}
}

View File

@ -23,6 +23,8 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -50,7 +52,13 @@ public interface OutputExtent {
* @return true if the block was successfully set (return value may not be accurate)
* @throws WorldEditException thrown on an error
*/
<T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException;
default <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
return setBlock(position.getX(), position.getY(), position.getZ(), block);
}
default <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return setBlock(MutableBlockVector3.get(x, y, z), block);
}
/**
* Set the biome.
@ -59,7 +67,13 @@ public interface OutputExtent {
* @param biome the biome to set to
* @return true if the biome was successfully set (return value may not be accurate)
*/
boolean setBiome(BlockVector2 position, BiomeType biome);
default boolean setBiome(BlockVector2 position, BiomeType biome) {
return setBiome(position.getX(), 0, position.getBlockZ(), biome);
}
default boolean setBiome(int x, int y, int z, BiomeType biome) {
return setBiome(MutableBlockVector2.get(x, z), biome);
}
/**
* Return an {@link Operation} that should be called to tie up loose ends

View File

@ -0,0 +1,177 @@
package com.sk89q.worldedit.extent;
import com.boydti.fawe.jnbt.anvil.generator.GenBase;
import com.boydti.fawe.jnbt.anvil.generator.Resource;
import com.boydti.fawe.object.extent.LightingExtent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import javax.annotation.Nullable;
import java.util.List;
public class PassthroughExtent extends AbstractDelegateExtent {
private final Extent extent;
public PassthroughExtent(Extent parent) {
super(parent);
this.extent = parent;
}
@Override
public List<? extends Entity> getEntities(Region region) {
return extent.getEntities(region);
}
@Override
public List<? extends Entity> getEntities() {
return extent.getEntities();
}
@Override
@Nullable
public Entity createEntity(Location location, BaseEntity entity) {
return extent.createEntity(location, entity);
}
@Override
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
return extent.getHighestTerrainBlock(x, z, minY, maxY);
}
@Override
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
return extent.getHighestTerrainBlock(x, z, minY, maxY, filter);
}
@Override
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
return extent.getNearestSurfaceLayer(x, z, y, minY, maxY);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, boolean ignoreAir) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
}
@Override
public void addCaves(Region region) throws WorldEditException {
extent.addCaves(region);
}
@Override
public void generate(Region region, GenBase gen) throws WorldEditException {
extent.generate(region, gen);
}
@Override
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
extent.addSchems(region, mask, clipboards, rarity, rotate);
}
@Override
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
extent.spawnResource(region, gen, rarity, frequency);
}
@Override
public boolean contains(BlockVector3 pt) {
return extent.contains(pt);
}
@Override
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
extent.addOre(region, mask, material, size, frequency, rarity, minY, maxY);
}
@Override
public void addOres(Region region, Mask mask) throws WorldEditException {
extent.addOres(region, mask);
}
@Override
public List<Countable<BlockType>> getBlockDistribution(Region region) {
return extent.getBlockDistribution(region);
}
@Override
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
return extent.getBlockDistributionWithData(region);
}
@Override
public BlockArrayClipboard lazyCopy(Region region) {
return extent.lazyCopy(region);
}
@Override
public BlockState getBlock(BlockVector3 position) {
return extent.getBlock(position);
}
@Override
public BlockType getBlockType(BlockVector3 position) {
return extent.getBlockType(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return extent.getFullBlock(position);
}
@Override
public BiomeType getBiome(BlockVector2 position) {
return extent.getBiome(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
return extent.setBlock(position, block);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return extent.setBlock(x, y, z, block);
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
return extent.setBiome(position, biome);
}
}

View File

@ -117,7 +117,7 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
}
@Override
protected void finalize() throws Throwable {
protected void finalize() {
close();
}
@ -196,11 +196,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
return BlockTypes.AIR.getDefaultState();
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
if(region.contains(position)) {
@ -266,8 +261,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
return null;
}
@Override
public int getLight(int x, int y, int z) {
return getBlockLight(x, y, z);
@ -285,11 +278,11 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
@Override
public int getOpacity(int x, int y, int z) {
return getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().getLightOpacity();
return getBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
}
@Override
public int getBrightness(int x, int y, int z) {
return getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().getLightValue();
return getBlock(x, y, z).getBlockType().getMaterial().getLightValue();
}
}

View File

@ -61,7 +61,7 @@ public interface Clipboard extends Extent {
/**
* Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)}
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes.OCEAN} instead of {@code null}
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes#OCEAN} instead of {@code null}
* if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting
* to ocean, instead of having biomes explicitly set.
*

View File

@ -22,7 +22,8 @@ package com.sk89q.worldedit.extent.clipboard.io;
import com.boydti.fawe.object.io.PGZIPOutputStream;
import com.boydti.fawe.object.io.ResettableFileInputStream;
import com.boydti.fawe.object.schematic.PNGWriter;
import com.boydti.fawe.object.schematic.StructureFormat;
import com.boydti.fawe.object.schematic.MinecraftStructure;
import com.google.common.collect.ImmutableSet;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTInputStream;
@ -122,35 +123,41 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
* The structure block format:
* http://minecraft.gamepedia.com/Structure_block_file_format
*/
STRUCTURE("structure", "nbt") {
MINECRAFT_STRUCTURE("structure") {
@Override
public String getPrimaryFileExtension() {
return "nbt";
}
@Override
public ClipboardReader getReader(InputStream inputStream) throws IOException {
inputStream = new BufferedInputStream(inputStream);
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(inputStream)));
return new StructureFormat(nbtStream);
return new MinecraftStructure(nbtStream);
}
@Override
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
outputStream = new BufferedOutputStream(outputStream);
OutputStream gzip;
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
gzip = outputStream;
} else {
gzip = new PGZIPOutputStream(outputStream);
}
OutputStream gzip = new PGZIPOutputStream(outputStream);
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
return new StructureFormat(nbtStream);
return new MinecraftStructure(nbtStream);
}
@Override
public boolean isFormat(File file) {
return file.getName().toLowerCase().endsWith(".nbt");
}
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
NamedTag rootTag = str.readNamedTag();
CompoundTag structureTag = (CompoundTag) rootTag.getTag();
Map<String, Tag> structure = structureTag.getValue();
if (!structure.containsKey("DataVersion")) {
return false;
}
} catch (Exception e) {
return false;
}
@Override
public String getPrimaryFileExtension() {
return "nbt";
return true;
}
},

View File

@ -70,7 +70,7 @@ public class ClipboardFormats {
checkNotNull(format);
for (String key : format.getAliases()) {
String lowKey = key.toLowerCase(Locale.ENGLISH);
String lowKey = key.toLowerCase(Locale.ROOT);
ClipboardFormat old = aliasMap.put(lowKey, format);
if (old != null) {
aliasMap.put(lowKey, old);
@ -78,7 +78,7 @@ public class ClipboardFormats {
}
}
for (String ext : format.getFileExtensions()) {
String lowExt = ext.toLowerCase(Locale.ENGLISH);
String lowExt = ext.toLowerCase(Locale.ROOT);
fileExtensionMap.put(lowExt, format);
}
registeredFormats.add(format);
@ -100,7 +100,7 @@ public class ClipboardFormats {
@Nullable
public static ClipboardFormat findByAlias(String alias) {
checkNotNull(alias);
return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim());
return aliasMap.get(alias.toLowerCase(Locale.ROOT).trim());
}
/**

View File

@ -44,7 +44,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
private final boolean mine;
private int[] missingBlocks = new int[BlockTypes.size()];
private BlockBag blockBag;
private final BlockBag blockBag;
/**
* Create a new instance.
@ -72,15 +72,6 @@ public class BlockBagExtent extends AbstractDelegateExtent {
return blockBag;
}
/**
* Set the block bag.
*
* @param blockBag a block bag, which may be null if none is used
*/
public void setBlockBag(@Nullable BlockBag blockBag) {
this.blockBag = blockBag;
}
/**
* Gets the list of missing blocks and clears the list for the next
* operation.
@ -106,31 +97,27 @@ public class BlockBagExtent extends AbstractDelegateExtent {
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
if (blockBag != null) {
BlockState existing = getLazyBlock(x, y, z);
if (!block.getBlockType().equals(existing.getBlockType())) {
if (!block.getBlockType().getMaterial().isAir()) {
try {
blockBag.fetchPlacedBlock(block.toImmutableState());
} catch (UnplaceableBlockException e) {
throw new FaweException.FaweBlockBagException();
} catch (BlockBagException e) {
missingBlocks[block.getBlockType().getInternalId()]++;
throw new FaweException.FaweBlockBagException();
}
BlockState existing = getBlock(x, y, z);
if (!block.getBlockType().equals(existing.getBlockType())) {
if (!block.getBlockType().getMaterial().isAir()) {
try {
blockBag.fetchPlacedBlock(block.toImmutableState());
} catch (UnplaceableBlockException e) {
throw FaweException.BLOCK_BAG;
} catch (BlockBagException e) {
missingBlocks[block.getBlockType().getInternalId()]++;
throw FaweException.BLOCK_BAG;
}
if (mine) {
if (!existing.getBlockType().getMaterial().isAir()) {
try {
blockBag.storeDroppedBlock(existing);
} catch (BlockBagException ignored) {
}
}
if (mine) {
if (!existing.getBlockType().getMaterial().isAir()) {
try {
blockBag.storeDroppedBlock(existing);
} catch (BlockBagException ignored) {
}
}
}
}
return super.setBlock(x, y, z, block);
}
}

View File

@ -35,5 +35,4 @@ public interface RegionFunction {
* @throws WorldEditException thrown on an error
*/
boolean apply(BlockVector3 position) throws WorldEditException;
}

View File

@ -0,0 +1,84 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.util.StringMan;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public abstract class ABlockMask extends AbstractExtentMask {
public ABlockMask(Extent extent) {
super(extent);
}
public abstract boolean test(BlockState state);
@Override
public String toString() {
List<String> strings = new ArrayList<>();
for (BlockType type : BlockTypes.values) {
if (type != null) {
boolean hasAll = true;
boolean hasAny = false;
List<BlockState> all = type.getAllStates();
for (BlockState state : all) {
hasAll &= test(state);
hasAny = true;
}
if (hasAll) {
strings.add(type.getId());
} else if (hasAny) {
for (BlockState state : all) {
if (test(state)) {
strings.add(state.getAsString());
}
}
}
}
}
return StringMan.join(strings, ",");
}
@Override
public Mask and(Mask mask) {
if (mask instanceof ABlockMask) {
ABlockMask other = (ABlockMask) mask;
BlockMask newMask = new BlockMask(getExtent());
for (BlockState state : BlockTypes.states) {
if (state != null) {
if (test(state) && other.test(state)) {
newMask.add(state);
}
}
}
Mask tmp = newMask.optimize();
if (tmp == null) tmp = newMask;
return tmp;
}
return null;
}
@Override
public Mask or(Mask mask) {
if (mask instanceof ABlockMask) {
ABlockMask other = (ABlockMask) mask;
BlockMask newMask = new BlockMask(getExtent());
for (BlockState state : BlockTypes.states) {
if (state != null) {
if (test(state) || other.test(state)) {
newMask.add(state);
}
}
}
Mask tmp = newMask.optimize();
if (tmp == null) tmp = newMask;
return tmp;
}
return null;
}
}

View File

@ -44,7 +44,7 @@ public abstract class AbstractExtentMask extends AbstractMask {
*
* @return the extent
*/
public Extent getExtent() {
public final Extent getExtent() {
return extent;
}

View File

@ -20,13 +20,10 @@
package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockCategory;
import javax.annotation.Nullable;
/**
* A mask that tests whether a block matches a given {@link BlockCategory}, or tag.
*/
@ -42,12 +39,7 @@ public class BlockCategoryMask extends AbstractExtentMask {
@Override
public boolean test(BlockVector3 vector) {
return category.contains(getExtent().getBlock(vector));
return category.contains(vector.getBlock(getExtent()));
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.blocks.Blocks;
import com.sk89q.worldedit.extent.Extent;
@ -27,9 +28,9 @@ import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import javax.annotation.Nullable;
import java.util.Map;
@Deprecated
public class BlockStateMask extends AbstractExtentMask {
private final Map<String, String> states;
@ -52,7 +53,10 @@ public class BlockStateMask extends AbstractExtentMask {
@Override
public boolean test(BlockVector3 vector) {
BlockState block = getExtent().getBlock(vector);
return test(vector.getBlock(getExtent()));
}
public boolean test(BlockState block) {
final Map<Property<Object>, Object> checkProps = cache
.computeIfAbsent(block.getBlockType(), (b -> Blocks.resolveProperties(states, b)));
if (strict && checkProps.isEmpty()) {
@ -62,9 +66,4 @@ public class BlockStateMask extends AbstractExtentMask {
.allMatch(entry -> block.getState(entry.getKey()) == entry.getValue());
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -20,11 +20,8 @@
package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkArgument;
import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
/**
* Has the criteria where the Y value of passed positions must be within
* a certain range of Y values (inclusive).
@ -51,10 +48,4 @@ public class BoundedHeightMask extends AbstractMask {
return vector.getY() >= minY && vector.getY() <= maxY;
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -19,11 +19,10 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
/**
* A mask that returns true whenever the block at the location is not
* an air block (it contains some other block).
@ -41,13 +40,7 @@ public class ExistingBlockMask extends AbstractExtentMask {
@Override
public boolean test(BlockVector3 vector) {
return !getExtent().getBlock(vector).getBlockType().getMaterial().isAir();
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
return !vector.getBlock(getExtent()).getMaterial().isAir();
}
}

View File

@ -2,6 +2,7 @@ package com.sk89q.worldedit.function.mask;
import javax.annotation.Nullable;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.math.BlockVector3;
public class InverseMask extends AbstractMask {

View File

@ -0,0 +1,38 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Arrays;
public class InverseSingleBlockStateMask extends ABlockMask {
private final char ordinal;
public BlockStateHolder getBlockState() {
return BlockState.getFromOrdinal(ordinal);
}
public InverseSingleBlockStateMask(Extent extent, BlockState state) {
super(extent);
this.ordinal = state.getOrdinalChar();
}
@Override
public boolean test(BlockVector3 vector) {
return ordinal != vector.getOrdinal(getExtent());
}
@Override
public final boolean test(BlockState state) {
return state.getOrdinalChar() != ordinal;
}
@Override
public Mask inverse() {
return new SingleBlockStateMask(getExtent(), BlockState.getFromOrdinal(ordinal));
}
}

View File

@ -0,0 +1,37 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
public class InverseSingleBlockTypeMask extends ABlockMask {
private final int internalId;
public InverseSingleBlockTypeMask(Extent extent, BlockType type) {
super(extent);
this.internalId = type.getInternalId();
}
@Override
public boolean test(BlockVector3 vector) {
return test(vector.getBlock(getExtent()));
}
@Override
public final boolean test(BlockState state) {
return state.getBlockType().getInternalId() != internalId;
}
@Override
public Mask inverse() {
return new SingleBlockTypeMask(getExtent(), BlockTypes.values[internalId]);
}
public BlockType getBlockType() {
return BlockTypes.get(internalId);
}
}

View File

@ -19,8 +19,12 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.DelegateFilter;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.minecraft.util.commands.Link;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
@ -39,6 +43,28 @@ public interface Mask {
*/
boolean test(BlockVector3 vector);
default Filter toFilter(Runnable run) {
return new Filter() {
@Override
public void applyBlock(FilterBlock block) {
if (test(block)) {
run.run();
}
}
};
}
default <T extends Filter> DelegateFilter<T> toFilter(T filter) {
return new DelegateFilter<T>(filter) {
@Override
public void applyBlock(FilterBlock block) {
if (test(block)) {
filter.applyBlock(block);
}
}
};
}
/**
* Get the 2D version of this mask if one exists.
*

View File

@ -178,10 +178,6 @@ public class MaskIntersection extends AbstractMask {
@Override
public boolean test(BlockVector3 vector) {
if (masks.isEmpty()) {
return false;
}
for (Mask mask : masksArray) {
if (!mask.test(vector)) {
return false;

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.google.common.base.Function;
import com.sk89q.worldedit.math.BlockVector3;

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
@ -140,7 +141,7 @@ public final class Masks {
@Override
public Mask or(Mask other) {
return other;
return this;
}
}

View File

@ -22,7 +22,9 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableVector3;
import com.sk89q.worldedit.math.noise.NoiseGenerator;
import javax.annotation.Nullable;
@ -85,8 +87,8 @@ public class NoiseFilter extends AbstractMask {
}
@Override
public boolean test(BlockVector3 vector) {
return noiseGenerator.noise(vector.toVector3()) <= density;
public boolean test(BlockVector3 v) {
return noiseGenerator.noise(MutableVector3.get(v.getX(), v.getY(), v.getZ())) <= density;
}
@Nullable

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;

View File

@ -20,12 +20,9 @@
package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import javax.annotation.Nullable;
/**
* A mask that tests whether given positions are contained within a region.
*/
@ -66,10 +63,4 @@ public class RegionMask extends AbstractMask {
return region.contains(vector);
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -1,19 +0,0 @@
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
public class SingleBlockStateBitMask extends AbstractExtentMask {
private final int bitMask;
protected SingleBlockStateBitMask(Extent extent, int bitMask) {
super(extent);
this.bitMask = bitMask;
}
@Override
public boolean test(BlockVector3 vector) {
int internalId = getExtent().getBlock(vector).getInternalId();
return (internalId & bitMask) == internalId;
}
}

View File

@ -1,28 +1,50 @@
package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
public class SingleBlockStateMask extends AbstractExtentMask {
private final BlockStateHolder state;
import java.util.Arrays;
public class SingleBlockStateMask extends ABlockMask {
private final char ordinal;
public BlockStateHolder getBlockState() {
return state;
return BlockState.getFromOrdinal(ordinal);
}
public SingleBlockStateMask(Extent extent, BlockStateHolder state) {
public SingleBlockStateMask(Extent extent, BlockState state) {
super(extent);
this.state = state;
this.ordinal = state.getOrdinalChar();
}
@Override
public boolean test(BlockVector3 vector) {
return state.equals(getExtent().getBlock(vector));
return ordinal == vector.getOrdinal(getExtent());
}
@Override
public final boolean test(BlockState state) {
return state.getOrdinalChar() == ordinal;
}
@Override
public Mask inverse() {
return new BlockMaskBuilder().add(state).build(getExtent()).inverse();
return new InverseSingleBlockStateMask(getExtent(), BlockState.getFromOrdinal(ordinal));
}
@Override
public Mask and(Mask mask) {
if (mask instanceof ABlockMask) {
ABlockMask other = (ABlockMask) mask;
if (other.test(BlockState.getFromOrdinal(ordinal))) {
return this;
}
return Masks.alwaysFalse();
}
return null;
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -66,5 +67,4 @@ public class BlockPattern extends AbstractPattern {
public BaseBlock apply(BlockVector3 position) {
return block;
}
}

View File

@ -14,17 +14,17 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
*/
@Link(clazz = UtilityCommands.class, value = "patterns")
public interface FawePattern extends Pattern {
@Deprecated
default BaseBlock apply(BlockVector3 position) {
throw new UnsupportedOperationException("Please use apply(extent, get, set)");
}
/**
* Return a {@link BlockStateHolder} for the given position.
*
* @return a block
*/
@Override
boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException;
//
// @Deprecated
// default BaseBlock apply(BlockVector3 position) {
// throw new UnsupportedOperationException("Please use apply(extent, get, set)");
// }
//
// /**
// * Return a {@link BlockStateHolder} for the given position.
// *
// * @return a block
// */
// @Override
// boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException;
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.function.pattern;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.minecraft.util.commands.Link;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.UtilityCommands;
@ -31,7 +33,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
* Returns a {@link BlockStateHolder} for a given position.
*/
@Link(clazz = UtilityCommands.class, value = "patterns")
public interface Pattern {
public interface Pattern extends Filter {
/**
* Return a {@link BlockStateHolder} for the given position.
@ -42,6 +44,11 @@ public interface Pattern {
BaseBlock apply(BlockVector3 position);
default boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, apply(get));
return set.setFullBlock(extent, apply(get));
}
@Override
default void applyBlock(final FilterBlock block) {
apply(block, block, block);
}
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.pattern;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.object.collection.RandomCollection;
import com.boydti.fawe.object.random.SimpleRandom;
import com.boydti.fawe.object.random.TrueRandom;
@ -84,8 +85,8 @@ public class RandomPattern extends AbstractPattern {
}
@Override
public boolean apply(Extent extent, BlockVector3 set, BlockVector3 get) throws WorldEditException {
return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, set, get);
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set);
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.pattern;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;

View File

@ -19,15 +19,10 @@
package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.object.HasFaweQueue;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import java.util.Collection;
import static com.google.common.base.Preconditions.checkNotNull;
/**
@ -43,22 +38,23 @@ public class DirectionalVisitor extends RecursiveVisitor {
private final BlockVector3 dirVec;
public DirectionalVisitor(Mask mask, RegionFunction function, BlockVector3 origin, BlockVector3 direction) {
this(mask, function, origin, direction, Integer.MAX_VALUE, null);
this(mask, function, origin, direction, Integer.MAX_VALUE);
}
public DirectionalVisitor(Mask mask, RegionFunction function, BlockVector3 origin, BlockVector3 direction, int distance, HasFaweQueue hasFaweQueue) {
super(mask, function, distance, hasFaweQueue);
public DirectionalVisitor(Mask mask, RegionFunction function, BlockVector3 origin, BlockVector3 direction, int distance) {
super(mask, function, distance);
checkNotNull(mask);
this.origin = origin;
this.dirVec = direction;
final Collection<BlockVector3> directions = this.getDirections();
directions.clear();
directions.add(BlockVector3.at(1, 0, 0));
directions.add(BlockVector3.at(-1, 0, 0));
directions.add(BlockVector3.at(0, 0, 1));
directions.add(BlockVector3.at(0, 0, -1));
directions.add(BlockVector3.at(0, -1, 0));
directions.add(BlockVector3.at(0, 1, 0));
setDirections(
BlockVector3.at(1, 0, 0),
BlockVector3.at(-1, 0, 0),
BlockVector3.at(0, 0, 1),
BlockVector3.at(0, 0, -1),
BlockVector3.at(0, -1, 0),
BlockVector3.at(0, 1, 0)
);
}
@Override

View File

@ -57,13 +57,13 @@ public class DownwardVisitor extends RecursiveVisitor {
this.baseY = baseY;
Collection<BlockVector3> directions = getDirections();
directions.clear();
directions.add(BlockVector3.UNIT_X);
directions.add(BlockVector3.UNIT_MINUS_X);
directions.add(BlockVector3.UNIT_Z);
directions.add(BlockVector3.UNIT_MINUS_Z);
directions.add(BlockVector3.UNIT_MINUS_Y);
setDirections(
BlockVector3.UNIT_X,
BlockVector3.UNIT_MINUS_X,
BlockVector3.UNIT_Z,
BlockVector3.UNIT_MINUS_Z,
BlockVector3.UNIT_MINUS_Y
);
}
@Override

View File

@ -44,13 +44,13 @@ public class NonRisingVisitor extends RecursiveVisitor {
public NonRisingVisitor(Mask mask, RegionFunction function, int depth, HasFaweQueue hasFaweQueue) {
super(mask, function, depth, hasFaweQueue);
Collection<BlockVector3> directions = getDirections();
directions.clear();
directions.add(BlockVector3.UNIT_X);
directions.add(BlockVector3.UNIT_MINUS_X);
directions.add(BlockVector3.UNIT_Z);
directions.add(BlockVector3.UNIT_MINUS_Z);
directions.add(BlockVector3.UNIT_MINUS_Y);
setDirections(
BlockVector3.UNIT_X,
BlockVector3.UNIT_MINUS_X,
BlockVector3.UNIT_Z,
BlockVector3.UNIT_MINUS_Z,
BlockVector3.UNIT_MINUS_Y
);
}
}

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.object.HasFaweQueue;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.function.RegionFunction;
@ -45,11 +44,7 @@ public class RecursiveVisitor extends BreadthFirstSearch {
* @param function the function
*/
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth) {
this(mask, function, maxDepth, null);
}
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth, HasFaweQueue faweQueue) {
super(function, maxDepth, faweQueue);
super(function, maxDepth);
checkNotNull(mask);
this.mask = mask;
}

View File

@ -20,13 +20,6 @@
package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedFaweQueue;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
@ -34,7 +27,6 @@ import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import java.util.Iterator;
import java.util.List;
/**
@ -48,7 +40,6 @@ public class RegionVisitor implements Operation {
public final RegionFunction function;
public int affected = 0;
public final Iterable<? extends BlockVector3> iterable;
private final MappedFaweQueue queue;
/**
* Deprecated in favor of the other constructors which will preload chunks during iteration
@ -57,22 +48,14 @@ public class RegionVisitor implements Operation {
* @param function
*/
public RegionVisitor(Region region, RegionFunction function) {
this(region, function, (FaweQueue) null);
this((Iterable<BlockVector3>) region, function);
}
public RegionVisitor(Region region, RegionFunction function, EditSession editSession) {
this(region, function, editSession != null ? editSession.getQueue() : null);
}
public RegionVisitor(Region region, RegionFunction function, FaweQueue queue) {
this((Iterable<BlockVector3>) region, function, queue);
}
public RegionVisitor(Iterable<? extends BlockVector3> iterable, RegionFunction function, HasFaweQueue hasQueue) {
@Deprecated
public RegionVisitor(Iterable<BlockVector3> iterable, RegionFunction function) {
this.region = iterable instanceof Region ? (Region) iterable : null;
this.function = function;
this.iterable = iterable;
this.queue = hasQueue != null && hasQueue.getQueue() instanceof MappedFaweQueue ? (MappedFaweQueue) hasQueue.getQueue() : null;
}
/**
@ -86,100 +69,8 @@ public class RegionVisitor implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (queue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 1) {
/*
* The following is done to reduce iteration cost
* - Preload chunks just in time
* - Only check every 16th block for potential chunk loads
* - Stop iteration on exception instead of hasNext
* - Do not calculate the stacktrace as it is expensive
*/
Iterator<? extends BlockVector3> trailIter = iterable.iterator();
Iterator<? extends BlockVector3> leadIter = iterable.iterator();
int lastTrailChunkX = Integer.MIN_VALUE;
int lastTrailChunkZ = Integer.MIN_VALUE;
int lastLeadChunkX = Integer.MIN_VALUE;
int lastLeadChunkZ = Integer.MIN_VALUE;
int loadingTarget = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
try {
for (; ; ) {
BlockVector3 pt = trailIter.next();
apply(pt);
int cx = pt.getBlockX() >> 4;
int cz = pt.getBlockZ() >> 4;
if (cx != lastTrailChunkX || cz != lastTrailChunkZ) {
lastTrailChunkX = cx;
lastTrailChunkZ = cz;
int amount;
if (lastLeadChunkX == Integer.MIN_VALUE) {
lastLeadChunkX = cx;
lastLeadChunkZ = cz;
amount = loadingTarget;
} else {
amount = 1;
}
for (int count = 0; count < amount; ) {
BlockVector3 v = leadIter.next();
int vcx = v.getBlockX() >> 4;
int vcz = v.getBlockZ() >> 4;
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
lastLeadChunkX = vcx;
lastLeadChunkZ = vcz;
queue.queueChunkLoad(vcx, vcz);
count++;
}
// Skip the next 15 blocks
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
leadIter.next();
}
}
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
apply(trailIter.next());
}
} catch (FaweException e) {
throw new RuntimeException(e);
} catch (Throwable ignore) {
ignore.printStackTrace();
}
try {
while (true) {
apply(trailIter.next());
apply(trailIter.next());
}
} catch (FaweException e) {
throw new RuntimeException(e);
} catch (Throwable ignore) {
}
} else {
for (BlockVector3 pt : iterable) {
apply(pt);
}
for (BlockVector3 pt : iterable) {
apply(pt);
}
return null;
}

View File

@ -0,0 +1,342 @@
package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector3;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* A chunk based search algorithm
*/
public class ScanChunk {
private static final int MAX_QUEUE = 34816;
public static final BlockVector3[] DEFAULT_DIRECTIONS = new BlockVector3[6];
public static final BlockVector3[] DIAGONAL_DIRECTIONS;
static {
DEFAULT_DIRECTIONS[0] = (BlockVector3.at(0, -1, 0));
DEFAULT_DIRECTIONS[1] = (BlockVector3.at(0, 1, 0));
DEFAULT_DIRECTIONS[2] = (BlockVector3.at(-1, 0, 0));
DEFAULT_DIRECTIONS[3] = (BlockVector3.at(1, 0, 0));
DEFAULT_DIRECTIONS[4] = (BlockVector3.at(0, 0, -1));
DEFAULT_DIRECTIONS[5] = (BlockVector3.at(0, 0, 1));
List<BlockVector3> list = new ArrayList<>();
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int z = -1; z <= 1; z++) {
if (x != 0 || y != 0 || z != 0) {
BlockVector3 pos = BlockVector3.at(x, y, z);
if (!list.contains(pos)) {
list.add(pos);
}
}
}
}
}
Collections.sort(list, new Comparator<BlockVector3>() {
@Override
public int compare(BlockVector3 o1, BlockVector3 o2) {
return (int) Math.signum(o1.lengthSq() - o2.lengthSq());
}
});
DIAGONAL_DIRECTIONS = list.toArray(new BlockVector3[list.size()]);
}
private final RegionFunction function;
private final BlockVector3[] directions;
private final Long2ObjectOpenHashMap<long[][]> visits;
private final Long2ObjectOpenHashMap<char[][]> queues;
public ScanChunk(final RegionFunction function) {
this.function = function;
this.directions = DEFAULT_DIRECTIONS;
this.queues = new Long2ObjectOpenHashMap<>();
this.visits = new Long2ObjectOpenHashMap<>();
}
public static final long pairInt(int x, int y) {
return (((long) x) << 32) | (y & 0xffffffffL);
}
public boolean isVisited(int x, int y, int z) {
int X = x >> 4;
int Z = z >> 4;
long pair = pairInt(X, Z);
long[][] chunk = visits.get(pair);
if (chunk == null) return false;
int layer = y >> 4;
long[] section = chunk[layer];
if (section == null) return false;
return get(section, getLocalIndex(x & 15, y & 15, z & 15));
}
public void start(int x, int y, int z) {
if (!isVisited(x, y, z)) {
push(x, y, z);
visit(x, y, z);
}
}
public void visit(int x, int y, int z) {
int X = x >> 4;
int Z = z >> 4;
long pair = pairInt(X, Z);
long[][] arrs = visits.get(pair);
if (arrs == null) {
visits.put(pair, arrs = new long[16][]);
}
int layer = y >> 4;
long[] section = arrs[layer];
if (section == null) {
arrs[layer] = section = new long[64];
}
set(section, getLocalIndex(x & 15, y & 15, z & 15));
}
private char[] getOrCreateQueue(long pair, int layer) {
char[][] arrs = queues.get(pair);
if (arrs == null) {
queues.put(pair, arrs = new char[16][]);
}
char[] section = arrs[layer];
if (section == null) {
arrs[layer] = section = newQueue();
}
return section;
}
private void push(int x, int y, int z) {
int X = x >> 4;
int Z = z >> 4;
long pair = pairInt(X, Z);
int layer = y >> 4;
char[] section = getOrCreateQueue(pair, layer);
push(section, x & 15, y & 15, z & 15);
}
private void push(char[] queue, int x, int y, int z) {
char indexStart = queue[0];
char indexEnd = queue[1];
push(indexStart, indexEnd, queue, x, y, z);
}
private void push(char indexStart, char indexEnd, char[] queue, int x, int y, int z) {
char index = getLocalIndex(x, y, z);
if (indexStart > 2) {
queue[0] = --indexStart;
queue[indexStart] = index;
} else {
queue[indexEnd] = index;
queue[0] = ++indexEnd;
}
}
public void process() {
LongArraySet set = new LongArraySet();
while (!queues.isEmpty()) {
// ObjectIterator<Long2ObjectMap.Entry<char[][]>> iter = queues.long2ObjectEntrySet().fastIterator();
// Long2ObjectMap.Entry<char[][]> entry = iter.next();
// long index = entry.getLongKey();
// int X = MathMan.unpairIntX(index);
// int Z = MathMan.unpairIntY(index);
// // check that adjacent chunks aren;t being processed
//
// char[] queue = entry.getValue();
// long[][] visit = visits.get(index);
// if (visit == null) {
// visits.put(index, visit = new long[16][]);
// }
}
}
private ConcurrentLinkedQueue<char[]> queuePool = new ConcurrentLinkedQueue<>();
private char[] newQueue() {
char[] arr = queuePool.poll();
if (arr != null) {
arr[0] = 2;
arr[1] = 2;
return arr;
}
return new char[4096];
}
public void process4(int xx, int yy, int zz, char[] queue, long[] visit) {
char index;
while ((index = queue[0]) != queue[1]) {
queue[0]++;
char triple = queue[index];
int x = index & 15;
int z = (index >> 4) & 15;
int y = index >> 8;
int absX = xx + x;
int absY = yy + y;
int absZ = zz + z;
apply(xx + x, yy + y, zz + z);
int x1 = x, x2 = x;
// find start of scan-line
int i1 = index;
while (true) {
if (x1 < 0) {
// queue in west chunk
break;
}
if (get(visit, i1)) break;
// visit
set(visit, i1);
i1--;
x1--;
}
i1++;
x1++;
// find end of scan-line
int i2 = index;
while (true) {
if (x2 > 15) {
// queue in east chunk
break;
}
if (get(visit, i2)) break;
set(visit, i2);
i2++;
x2++;
}
i2--;
x2--;
// find start
}
}
public void apply(int x, int y, int z) {
}
public void process4(int X, int Z, char[][] queues, long[][] visit) {
int xx = X << 4;
int zz = Z << 4;
// TODO fetch instead of create
final BlockVector3[] dirs = directions;
char[][] dirQueues = new char[directions.length][];
while (true) {
boolean empty = true;
for (int layer = 0; layer < 16; layer++) {
char[] queue = queues[layer];
if (queue == null) continue;
char index;
while ((index = queue[0]) != queue[1]) {
queue[0]++;
char triple = queue[index];
int x = index & 15;
int z = (index >> 4) & 15;
int y = index >> 8;
}
queuePool.add(queue);
queues[layer] = null;
continue;
}
if (empty) break;
}
// empty queues
// while (indexStart != indexEnd) {
// char index = queue[indexStart++];
// byte dirs = 0xF;
// int x = index & 15;
// int z = (index >> 4) & 15;
// int y = index >> 8;
//
// int layer = y >> 4;
// long[] visitBits = visit[layer];
//
// int x1 = x;
// int x2 = x;
//
// // find start of scan-line
// int i1 = index;
// while (true) {
// if (x1 < 0) {
// // queue in adjacent chunk
// break;
// }
// if (get(visitBits, i1--)) break;
// x1--;
// }
// i1++;
// x1++;
//
// // find end of scan-line
// int i2 = index;
// while (true) {
// if (x2 > 15) {
// // queue in adjacent chunk
// break;
// }
// if (get(visitBits, i2++)) break;
// x2++;
// }
// i2--;
// x2--;
//
// boolean scanUp = false;
// boolean scanDown = false;
// boolean scanLeft = false;
// boolean scanRight = false;
//
// for (int i = i1; i <= i2; i++) {
// if (!scanDown && y > 0 && )
// }
//
// for (int i=x1; i<=x2; i++) { // find scan-lines above this one
// if (!inScanLine && y>0 && ip.getPixel(i,y-1)==color)
// {push(i, y-1); inScanLine = true;}
// else if (inScanLine && y>0 && ip.getPixel(i,y-1)!=color)
// inScanLine = false;
// }
//
// inScanLine = false;
// for (int i=x1; i<=x2; i++) { // find scan-lines below this one
// if (!inScanLine && y<height-1 && ip.getPixel(i,y+1)==color)
// {push(i, y+1); inScanLine = true;}
// else if (inScanLine && y<height-1 && ip.getPixel(i,y+1)!=color)
// inScanLine = false;
// }
// }
}
public void set(long[] bits, int i) {
bits[i >> 6] |= (1L << (i & 0x3F));
}
public boolean get(long[] bits, final int i) {
return (bits[i >> 6] & (1L << (i & 0x3F))) != 0;
}
public char getLocalIndex(int x, int y, int z) {
return (char) (x + (z << 4) + (y << 8));
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.math;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
import java.util.Comparator;
/**
* An immutable 3-dimensional vector.
*/
public final class BlockVector3Imp extends BlockVector3 {
public static final BlockVector3Imp ZERO = new BlockVector3Imp(0, 0, 0);
public static final BlockVector3Imp UNIT_X = new BlockVector3Imp(1, 0, 0);
public static final BlockVector3Imp UNIT_Y = new BlockVector3Imp(0, 1, 0);
public static final BlockVector3Imp UNIT_Z = new BlockVector3Imp(0, 0, 1);
public static final BlockVector3Imp ONE = new BlockVector3Imp(1, 1, 1);
public static BlockVector3Imp at(double x, double y, double z) {
return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
}
public static BlockVector3Imp at(int x, int y, int z) {
return new BlockVector3Imp(x, y, z);
}
private final int x, y, z;
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
protected BlockVector3Imp(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public final int getX() {
return x;
}
@Override
public final int getY() {
return y;
}
@Override
public final int getZ() {
return z;
}
@Override
public int hashCode() {
return (getX() ^ (getZ() << 12)) ^ (getY() << 24);
}
@Override
public final BlockVector3 toImmutable() {
return this;
}
@Override
public String toString() {
return "(" + getX() + ", " + getY() + ", " + getZ() + ")";
}
}

View File

@ -1,25 +1,37 @@
package com.sk89q.worldedit.math;
import com.boydti.fawe.FaweCache;
public class MutableBlockVector3 extends BlockVector3 {
private static ThreadLocal<MutableBlockVector3> MUTABLE_CACHE = ThreadLocal.withInitial(() -> new MutableBlockVector3());
public static MutableBlockVector3 at(double x, double y, double z) {
return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
}
public static MutableBlockVector3 at(int x, int y, int z) {
return new MutableBlockVector3(x, y, z);
}
public static MutableBlockVector3 get(int x, int y, int z) {
return MUTABLE_CACHE.get().setComponents(x, y, z);
return FaweCache.MUTABLE_BLOCKVECTOR3.get().setComponents(x, y, z);
}
public MutableBlockVector3() {}
public MutableBlockVector3(BlockVector3 other) {
super(other.getX(), other.getY(), other.getZ());
this(other.getX(), other.getY(), other.getZ());
}
public MutableBlockVector3 setComponents(BlockVector3 other) {
return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ());
}
private int x,y,z;
public MutableBlockVector3(int x, int y, int z) {
super(x, y, z);
this.x = x;
this.y = y;
this.z = z;
}
@Override
@ -30,6 +42,21 @@ public class MutableBlockVector3 extends BlockVector3 {
return this;
}
@Override
public final int getX() {
return x;
}
@Override
public final int getY() {
return y;
}
@Override
public final int getZ() {
return z;
}
@Override
public MutableBlockVector3 mutX(double x) {
this.x = (int) x;

View File

@ -27,13 +27,14 @@ import com.sk89q.worldedit.regions.iterator.RegionIterator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public abstract class AbstractRegion implements Region {
public abstract class AbstractRegion extends AbstractSet<BlockVector3> implements Region {
protected World world;
@ -41,6 +42,11 @@ public abstract class AbstractRegion implements Region {
this.world = world;
}
@Override
public int size() {
return getArea();
}
@Override
public Vector3 getCenter() {
return getMinimumPoint().add(getMaximumPoint()).toVector3().divide(2);
@ -100,21 +106,6 @@ public abstract class AbstractRegion implements Region {
return points;
}
/**
* Get the number of blocks in the region.
*
* @return number of blocks
*/
@Override
public int getArea() {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return (max.getX() - min.getX() + 1) *
(max.getY() - min.getY() + 1) *
(max.getZ() - min.getZ() + 1);
}
/**
* Get X-size.
*

View File

@ -19,12 +19,20 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@ -54,14 +62,23 @@ public interface Region extends Iterable<BlockVector3>, Cloneable {
*
* @return center point
*/
Vector3 getCenter();
default Vector3 getCenter() {
return getMinimumPoint().add(getMaximumPoint()).toVector3().divide(2);
}
/**
* Get the number of blocks in the region.
*
* @return number of blocks
*/
int getArea();
default int getArea() {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return (max.getX() - min.getX() + 1) *
(max.getY() - min.getY() + 1) *
(max.getZ() - min.getZ() + 1);
}
/**
* Get X-size.
@ -128,7 +145,9 @@ public interface Region extends Iterable<BlockVector3>, Cloneable {
* @param position the position
* @return true if contained
*/
boolean contains(BlockVector3 position);
default boolean contains(BlockVector3 position) {
return contains(position.getX(), position.getY(), position.getZ());
}
/**
* Get a list of chunks.
@ -172,4 +191,63 @@ public interface Region extends Iterable<BlockVector3>, Cloneable {
* @return the points.
*/
List<BlockVector2> polygonize(int maxPoints);
default int getMinY() {
return getMinimumPoint().getY();
}
default int getMaxY() {
return getMaximumPoint().getY();
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int minSection = Math.max(0, getMinY() >> 4);
int maxSection = Math.min(15, getMaxY() >> 4);
for (int layer = minSection; layer <= maxSection; layer++) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, this);
}
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, final int minY, final int maxY) {
int minSection = minY >> 4;
int maxSection = maxY >> 4;
int yStart = (minY & 15);
int yEnd = (maxY & 15);
if (minSection == maxSection) {
filter(chunk, filter, block, get, set, minSection, yStart, yEnd);
return;
}
if (yStart != 0) {
filter(chunk, filter, block, get, set, minSection, yStart, 15);
minSection++;
}
if (yEnd != 15) {
filter(chunk, filter, block, get, set, minSection, 0, yEnd);
maxSection--;
}
for (int layer = minSection; layer < maxSection; layer++) {
filter(chunk, filter, block, get, set, layer);
}
return;
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter);
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, minX, minY, minZ, maxX, maxY, maxZ);
}
default void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, int layer, int yStart, int yEnd) {
if (!get.hasSection(layer) || !filter.appliesLayer(chunk, layer)) return;
block = block.init(get, set, layer);
block.filter(filter, yStart, yEnd);
}
}

View File

@ -19,9 +19,6 @@
package com.sk89q.worldedit.regions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Iterators;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World;
@ -31,6 +28,9 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An intersection of several other regions. Any location that is contained in one
* of the child regions is considered as contained by this region.

View File

@ -1,191 +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.regions;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.Identity;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
/**
* Transforms another region according to a provided vector {@code Transform}.
*
* @see Transform
*/
public class TransformRegion extends AbstractRegion {
private final Region region;
private Transform transform = new Identity();
/**
* Create a new instance.
*
* @param region the region
* @param transform the transform
*/
public TransformRegion(Region region, Transform transform) {
this(null, region, transform);
}
/**
* Create a new instance.
*
* @param world the world, which may be null
* @param region the region
* @param transform the transform
*/
public TransformRegion(@Nullable World world, Region region, Transform transform) {
super(world);
checkNotNull(region);
checkNotNull(transform);
this.region = region;
this.transform = transform;
}
/**
* Get the untransformed, base region.
*
* @return the base region
*/
public Region getRegion() {
return region;
}
/**
* Get the transform that is applied.
*
* @return the transform
*/
public Transform getTransform() {
return transform;
}
/**
* Set the transform that is applied.
*
* @param transform the transform
*/
public void setTransform(Transform transform) {
checkNotNull(transform);
this.transform = transform;
}
@Override
public BlockVector3 getMinimumPoint() {
return transform.apply(region.getMinimumPoint().toVector3()).toBlockPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return transform.apply(region.getMaximumPoint().toVector3()).toBlockPoint();
}
@Override
public Vector3 getCenter() {
return transform.apply(region.getCenter());
}
@Override
public int getArea() {
return region.getArea(); // Cannot transform this
}
@Override
public int getWidth() {
return getMaximumPoint().subtract(getMinimumPoint()).getBlockX() + 1;
}
@Override
public int getHeight() {
return getMaximumPoint().subtract(getMinimumPoint()).getBlockY() + 1;
}
@Override
public int getLength() {
return getMaximumPoint().subtract(getMinimumPoint()).getBlockZ() + 1;
}
@Override
public void expand(BlockVector3... changes) throws RegionOperationException {
throw new RegionOperationException("Can't expand a TransformedRegion");
}
@Override
public void contract(BlockVector3... changes) throws RegionOperationException {
throw new RegionOperationException("Can't contract a TransformedRegion");
}
@Override
public void shift(BlockVector3 change) throws RegionOperationException {
throw new RegionOperationException("Can't change a TransformedRegion");
}
@Override
public boolean contains(BlockVector3 position) {
return region.contains(transform.inverse().apply(position.toVector3()).toBlockPoint());
}
@Override
public List<BlockVector2> polygonize(int maxPoints) {
List<BlockVector2> origPoints = region.polygonize(maxPoints);
List<BlockVector2> transformedPoints = new ArrayList<>();
for (BlockVector2 vector : origPoints) {
transformedPoints.add(transform.apply(vector.toVector3(0)).toVector2().toBlockPoint());
}
return transformedPoints;
}
@Override
public Iterator<BlockVector3> iterator() {
final Iterator<BlockVector3> it = region.iterator();
return new Iterator<BlockVector3>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public BlockVector3 next() {
BlockVector3 next = it.next();
if (next != null) {
return transform.apply(next.toVector3()).toBlockPoint();
} else {
return null;
}
}
@Override
public void remove() {
it.remove();
}
};
}
}

View File

@ -6,6 +6,7 @@ import com.sk89q.util.ReflectionUtil;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
@ -100,7 +101,7 @@ public enum PropertyKey {
PropertyKey property = PropertyKey.get(id);
if (property == null) {
Fawe.debug("Registering property " + id);
property = ReflectionUtils.addEnum(PropertyKey.class, id.toUpperCase());
property = ReflectionUtils.addEnum(PropertyKey.class, id.toUpperCase(Locale.ROOT));
if (property.getId() == null) {
try {
ReflectionUtils.setFailsafeFieldValue(PropertyKey.class.getDeclaredField("id"), property, property.name().toLowerCase());

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region;

View File

@ -35,6 +35,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@ -104,12 +105,12 @@ public class SimpleDispatcher implements Dispatcher {
@Override
public boolean contains(String alias) {
return commands.containsKey(alias.toLowerCase());
return commands.containsKey(alias.toLowerCase(Locale.ROOT));
}
@Override
public CommandMapping get(String alias) {
return commands.get(alias.toLowerCase());
return commands.get(alias.toLowerCase(Locale.ROOT));
}
@Override

View File

@ -23,6 +23,7 @@ import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
public final class ArgumentUtils {
@ -35,7 +36,7 @@ public final class ArgumentUtils {
}
List<String> suggestions = Lists.newArrayList();
for (String item : items) {
if (item.toLowerCase().startsWith(s)) {
if (item.toLowerCase(Locale.ROOT).startsWith(s)) {
suggestions.add(item);
}
}

View File

@ -30,6 +30,7 @@ import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@ -55,7 +56,7 @@ public abstract class BranchingCommand<T> implements CommandExecutor<T> {
public T call(CommandArgs args, CommandLocals locals) throws CommandException {
try {
String classifier = args.next();
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase());
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase(Locale.ROOT));
if (executor != null) {
return executor.call(args, locals);
} else {
@ -72,7 +73,7 @@ public abstract class BranchingCommand<T> implements CommandExecutor<T> {
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
String classifier = args.next();
try {
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase());
CommandExecutor<? extends T> executor = options.get(classifier.toLowerCase(Locale.ROOT));
if (executor != null) {
return executor.getSuggestions(args, locals);
}

View File

@ -43,6 +43,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
/**
@ -348,10 +349,10 @@ public class ParametricCallable extends AParametricCallable {
*/
private static String generateName(Type type, Annotation classifier, int index) {
if (classifier != null) {
return classifier.annotationType().getSimpleName().toLowerCase();
return classifier.annotationType().getSimpleName().toLowerCase(Locale.ROOT);
} else {
if (type instanceof Class<?>) {
return ((Class<?>) type).getSimpleName().toLowerCase();
return ((Class<?>) type).getSimpleName().toLowerCase(Locale.ROOT);
} else {
return "unknown" + index;
}

View File

@ -45,7 +45,7 @@ public final class IncendoPaste implements Paster{
if (pasteApplication == null || pasteApplication.isEmpty()) {
throw new IllegalArgumentException("paste application cannot be null, nor empty");
}
if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ENGLISH))) {
if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ROOT))) {
throw new IllegalArgumentException(
String.format("Unknown application name: %s", pasteApplication));
}

View File

@ -81,12 +81,12 @@ public class NullWorld extends AbstractWorld {
}
@Override
public BiomeType getBiome(BlockVector2 position) {
public BiomeType getBiomeType(int x, int z) {
return BiomeTypes.THE_VOID;
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return false;
}
@ -132,13 +132,18 @@ public class NullWorld extends AbstractWorld {
}
@Override
public BlockState getBlock(BlockVector3 position) {
public BlockState getBlock(int x, int y, int z) {
return BlockTypes.AIR.getDefaultState();
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
public BaseBlock getFullBlock(int x, int y, int z) {
return BlockTypes.AIR.getDefaultState().toBaseBlock();
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return false;
}
@Override

View File

@ -67,6 +67,7 @@ public interface World extends Extent {
*
* @return the maximum Y
*/
@Override
int getMaxY();
/**
@ -106,7 +107,9 @@ 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)
*/
<B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException;
default <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
return setBlock(position, block);
}
/**
* Notifies the simulation that the block at the given location has

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.object.string.MutableCharSequence;
import com.boydti.fawe.util.StringMan;
@ -49,6 +50,7 @@ import java.util.stream.Stream;
public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
private final int internalId;
private final int ordinal;
private final char ordinalChar;
private final BlockType blockType;
private BlockMaterial material;
private BaseBlock emptyBaseBlock;
@ -57,7 +59,8 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
this.blockType = blockType;
this.internalId = internalId;
this.ordinal = ordinal;
this.emptyBaseBlock = new BaseBlock(this);
this.ordinalChar = (char) ordinal;
this.emptyBaseBlock = new ImmutableBaseBlock(this);
}
/**
@ -214,7 +217,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, this);
return set.setBlock(extent, this);
}
@Override
@ -270,6 +273,24 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
}
}
public <V> BlockState withProperties(final BlockState other) {
BlockType ot = other.getBlockType();
if (ot == blockType) {
return other;
}
if (ot.getProperties().isEmpty() || blockType.getProperties().isEmpty()) {
return this;
}
BlockState newState = this;
for (Property<?> prop: ot.getProperties()) {
PropertyKey key = prop.getKey();
if (blockType.hasProperty(key)) {
newState = newState.with(key, other.getState(key));
}
}
return this;
}
@Override
public Map<Property<?>, Object> getStates() {
BlockType type = this.getBlockType();
@ -333,10 +354,15 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return material;
}
@Override
public int getOrdinal() {
return this.ordinal;
}
@Override
public final int getOrdinal() {
return this.ordinal;
}
@Override
public final char getOrdinalChar() {
return this.ordinalChar;
}
@Override
public String toString() {

View File

@ -64,6 +64,9 @@ public interface BlockStateHolder<B extends BlockStateHolder<B>> extends FawePat
@Deprecated
int getOrdinal();
@Deprecated
char getOrdinalChar();
BlockMaterial getMaterial();
/**
* Get type id (legacy uses)

View File

@ -41,7 +41,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -61,22 +63,31 @@ public final class BlockTypes {
@Nullable public static final BlockType ACACIA_PLANKS = null;
@Nullable public static final BlockType ACACIA_PRESSURE_PLATE = null;
@Nullable public static final BlockType ACACIA_SAPLING = null;
@Nullable public static final BlockType ACACIA_SIGN = null;
@Nullable public static final BlockType ACACIA_SLAB = null;
@Nullable public static final BlockType ACACIA_STAIRS = null;
@Nullable public static final BlockType ACACIA_TRAPDOOR = null;
@Nullable public static final BlockType ACACIA_WALL_SIGN = null;
@Nullable public static final BlockType ACACIA_WOOD = null;
@Nullable public static final BlockType ACTIVATOR_RAIL = null;
@Nullable public static final BlockType AIR = null;
@Nullable public static final BlockType ALLIUM = null;
@Nullable public static final BlockType ANDESITE = null;
@Nullable public static final BlockType ANDESITE_SLAB = null;
@Nullable public static final BlockType ANDESITE_STAIRS = null;
@Nullable public static final BlockType ANDESITE_WALL = null;
@Nullable public static final BlockType ANVIL = null;
@Nullable public static final BlockType ATTACHED_MELON_STEM = null;
@Nullable public static final BlockType ATTACHED_PUMPKIN_STEM = null;
@Nullable public static final BlockType AZURE_BLUET = null;
@Nullable public static final BlockType BAMBOO = null;
@Nullable public static final BlockType BAMBOO_SAPLING = null;
@Nullable public static final BlockType BARREL = null;
@Nullable public static final BlockType BARRIER = null;
@Nullable public static final BlockType BEACON = null;
@Nullable public static final BlockType BEDROCK = null;
@Nullable public static final BlockType BEETROOTS = null;
@Nullable public static final BlockType BELL = null;
@Nullable public static final BlockType BIRCH_BUTTON = null;
@Nullable public static final BlockType BIRCH_DOOR = null;
@Nullable public static final BlockType BIRCH_FENCE = null;
@ -86,9 +97,11 @@ public final class BlockTypes {
@Nullable public static final BlockType BIRCH_PLANKS = null;
@Nullable public static final BlockType BIRCH_PRESSURE_PLATE = null;
@Nullable public static final BlockType BIRCH_SAPLING = null;
@Nullable public static final BlockType BIRCH_SIGN = null;
@Nullable public static final BlockType BIRCH_SLAB = null;
@Nullable public static final BlockType BIRCH_STAIRS = null;
@Nullable public static final BlockType BIRCH_TRAPDOOR = null;
@Nullable public static final BlockType BIRCH_WALL_SIGN = null;
@Nullable public static final BlockType BIRCH_WOOD = null;
@Nullable public static final BlockType BLACK_BANNER = null;
@Nullable public static final BlockType BLACK_BED = null;
@ -102,6 +115,7 @@ public final class BlockTypes {
@Nullable public static final BlockType BLACK_TERRACOTTA = null;
@Nullable public static final BlockType BLACK_WALL_BANNER = null;
@Nullable public static final BlockType BLACK_WOOL = null;
@Nullable public static final BlockType BLAST_FURNACE = null;
@Nullable public static final BlockType BLUE_BANNER = null;
@Nullable public static final BlockType BLUE_BED = null;
@Nullable public static final BlockType BLUE_CARPET = null;
@ -125,6 +139,7 @@ public final class BlockTypes {
@Nullable public static final BlockType BREWING_STAND = null;
@Nullable public static final BlockType BRICK_SLAB = null;
@Nullable public static final BlockType BRICK_STAIRS = null;
@Nullable public static final BlockType BRICK_WALL = null;
@Nullable public static final BlockType BRICKS = null;
@Nullable public static final BlockType BROWN_BANNER = null;
@Nullable public static final BlockType BROWN_BED = null;
@ -147,7 +162,9 @@ public final class BlockTypes {
@Nullable public static final BlockType BUBBLE_CORAL_WALL_FAN = null;
@Nullable public static final BlockType CACTUS = null;
@Nullable public static final BlockType CAKE = null;
@Nullable public static final BlockType CAMPFIRE = null;
@Nullable public static final BlockType CARROTS = null;
@Nullable public static final BlockType CARTOGRAPHY_TABLE = null;
@Nullable public static final BlockType CARVED_PUMPKIN = null;
@Nullable public static final BlockType CAULDRON = null;
@Nullable public static final BlockType CAVE_AIR = null;
@ -172,13 +189,17 @@ public final class BlockTypes {
@Nullable public static final BlockType COCOA = null;
@Nullable public static final BlockType COMMAND_BLOCK = null;
@Nullable public static final BlockType COMPARATOR = null;
@Nullable public static final BlockType COMPOSTER = null;
@Nullable public static final BlockType CONDUIT = null;
@Nullable public static final BlockType CORNFLOWER = null;
@Nullable public static final BlockType CRACKED_STONE_BRICKS = null;
@Nullable public static final BlockType CRAFTING_TABLE = null;
@Nullable public static final BlockType CREEPER_HEAD = null;
@Nullable public static final BlockType CREEPER_WALL_HEAD = null;
@Nullable public static final BlockType CUT_RED_SANDSTONE = null;
@Nullable public static final BlockType CUT_RED_SANDSTONE_SLAB = null;
@Nullable public static final BlockType CUT_SANDSTONE = null;
@Nullable public static final BlockType CUT_SANDSTONE_SLAB = null;
@Nullable public static final BlockType CYAN_BANNER = null;
@Nullable public static final BlockType CYAN_BED = null;
@Nullable public static final BlockType CYAN_CARPET = null;
@ -202,9 +223,11 @@ public final class BlockTypes {
@Nullable public static final BlockType DARK_OAK_PLANKS = null;
@Nullable public static final BlockType DARK_OAK_PRESSURE_PLATE = null;
@Nullable public static final BlockType DARK_OAK_SAPLING = null;
@Nullable public static final BlockType DARK_OAK_SIGN = null;
@Nullable public static final BlockType DARK_OAK_SLAB = null;
@Nullable public static final BlockType DARK_OAK_STAIRS = null;
@Nullable public static final BlockType DARK_OAK_TRAPDOOR = null;
@Nullable public static final BlockType DARK_OAK_WALL_SIGN = null;
@Nullable public static final BlockType DARK_OAK_WOOD = null;
@Nullable public static final BlockType DARK_PRISMARINE = null;
@Nullable public static final BlockType DARK_PRISMARINE_SLAB = null;
@ -235,6 +258,9 @@ public final class BlockTypes {
@Nullable public static final BlockType DIAMOND_BLOCK = null;
@Nullable public static final BlockType DIAMOND_ORE = null;
@Nullable public static final BlockType DIORITE = null;
@Nullable public static final BlockType DIORITE_SLAB = null;
@Nullable public static final BlockType DIORITE_STAIRS = null;
@Nullable public static final BlockType DIORITE_WALL = null;
@Nullable public static final BlockType DIRT = null;
@Nullable public static final BlockType DISPENSER = null;
@Nullable public static final BlockType DRAGON_EGG = null;
@ -250,6 +276,9 @@ public final class BlockTypes {
@Nullable public static final BlockType END_PORTAL_FRAME = null;
@Nullable public static final BlockType END_ROD = null;
@Nullable public static final BlockType END_STONE = null;
@Nullable public static final BlockType END_STONE_BRICK_SLAB = null;
@Nullable public static final BlockType END_STONE_BRICK_STAIRS = null;
@Nullable public static final BlockType END_STONE_BRICK_WALL = null;
@Nullable public static final BlockType END_STONE_BRICKS = null;
@Nullable public static final BlockType ENDER_CHEST = null;
@Nullable public static final BlockType FARMLAND = null;
@ -259,6 +288,7 @@ public final class BlockTypes {
@Nullable public static final BlockType FIRE_CORAL_BLOCK = null;
@Nullable public static final BlockType FIRE_CORAL_FAN = null;
@Nullable public static final BlockType FIRE_CORAL_WALL_FAN = null;
@Nullable public static final BlockType FLETCHING_TABLE = null;
@Nullable public static final BlockType FLOWER_POT = null;
@Nullable public static final BlockType FROSTED_ICE = null;
@Nullable public static final BlockType FURNACE = null;
@ -268,6 +298,9 @@ public final class BlockTypes {
@Nullable public static final BlockType GOLD_BLOCK = null;
@Nullable public static final BlockType GOLD_ORE = null;
@Nullable public static final BlockType GRANITE = null;
@Nullable public static final BlockType GRANITE_SLAB = null;
@Nullable public static final BlockType GRANITE_STAIRS = null;
@Nullable public static final BlockType GRANITE_WALL = null;
@Nullable public static final BlockType GRASS = null;
@Nullable public static final BlockType GRASS_BLOCK = null;
@Nullable public static final BlockType GRASS_PATH = null;
@ -296,6 +329,7 @@ public final class BlockTypes {
@Nullable public static final BlockType GREEN_TERRACOTTA = null;
@Nullable public static final BlockType GREEN_WALL_BANNER = null;
@Nullable public static final BlockType GREEN_WOOL = null;
@Nullable public static final BlockType GRINDSTONE = null;
@Nullable public static final BlockType HAY_BLOCK = null;
@Nullable public static final BlockType HEAVY_WEIGHTED_PRESSURE_PLATE = null;
@Nullable public static final BlockType HOPPER = null;
@ -316,6 +350,7 @@ public final class BlockTypes {
@Nullable public static final BlockType IRON_ORE = null;
@Nullable public static final BlockType IRON_TRAPDOOR = null;
@Nullable public static final BlockType JACK_O_LANTERN = null;
@Nullable public static final BlockType JIGSAW = null;
@Nullable public static final BlockType JUKEBOX = null;
@Nullable public static final BlockType JUNGLE_BUTTON = null;
@Nullable public static final BlockType JUNGLE_DOOR = null;
@ -326,17 +361,21 @@ public final class BlockTypes {
@Nullable public static final BlockType JUNGLE_PLANKS = null;
@Nullable public static final BlockType JUNGLE_PRESSURE_PLATE = null;
@Nullable public static final BlockType JUNGLE_SAPLING = null;
@Nullable public static final BlockType JUNGLE_SIGN = null;
@Nullable public static final BlockType JUNGLE_SLAB = null;
@Nullable public static final BlockType JUNGLE_STAIRS = null;
@Nullable public static final BlockType JUNGLE_TRAPDOOR = null;
@Nullable public static final BlockType JUNGLE_WALL_SIGN = null;
@Nullable public static final BlockType JUNGLE_WOOD = null;
@Nullable public static final BlockType KELP = null;
@Nullable public static final BlockType KELP_PLANT = null;
@Nullable public static final BlockType LADDER = null;
@Nullable public static final BlockType LANTERN = null;
@Nullable public static final BlockType LAPIS_BLOCK = null;
@Nullable public static final BlockType LAPIS_ORE = null;
@Nullable public static final BlockType LARGE_FERN = null;
@Nullable public static final BlockType LAVA = null;
@Nullable public static final BlockType LECTERN = null;
@Nullable public static final BlockType LEVER = null;
@Nullable public static final BlockType LIGHT_BLUE_BANNER = null;
@Nullable public static final BlockType LIGHT_BLUE_BED = null;
@ -364,6 +403,7 @@ public final class BlockTypes {
@Nullable public static final BlockType LIGHT_GRAY_WOOL = null;
@Nullable public static final BlockType LIGHT_WEIGHTED_PRESSURE_PLATE = null;
@Nullable public static final BlockType LILAC = null;
@Nullable public static final BlockType LILY_OF_THE_VALLEY = null;
@Nullable public static final BlockType LILY_PAD = null;
@Nullable public static final BlockType LIME_BANNER = null;
@Nullable public static final BlockType LIME_BED = null;
@ -377,6 +417,7 @@ public final class BlockTypes {
@Nullable public static final BlockType LIME_TERRACOTTA = null;
@Nullable public static final BlockType LIME_WALL_BANNER = null;
@Nullable public static final BlockType LIME_WOOL = null;
@Nullable public static final BlockType LOOM = null;
@Nullable public static final BlockType MAGENTA_BANNER = null;
@Nullable public static final BlockType MAGENTA_BED = null;
@Nullable public static final BlockType MAGENTA_CARPET = null;
@ -393,7 +434,12 @@ public final class BlockTypes {
@Nullable public static final BlockType MELON = null;
@Nullable public static final BlockType MELON_STEM = null;
@Nullable public static final BlockType MOSSY_COBBLESTONE = null;
@Nullable public static final BlockType MOSSY_COBBLESTONE_SLAB = null;
@Nullable public static final BlockType MOSSY_COBBLESTONE_STAIRS = null;
@Nullable public static final BlockType MOSSY_COBBLESTONE_WALL = null;
@Nullable public static final BlockType MOSSY_STONE_BRICK_SLAB = null;
@Nullable public static final BlockType MOSSY_STONE_BRICK_STAIRS = null;
@Nullable public static final BlockType MOSSY_STONE_BRICK_WALL = null;
@Nullable public static final BlockType MOSSY_STONE_BRICKS = null;
@Nullable public static final BlockType MOVING_PISTON = null;
@Nullable public static final BlockType MUSHROOM_STEM = null;
@ -401,6 +447,7 @@ public final class BlockTypes {
@Nullable public static final BlockType NETHER_BRICK_FENCE = null;
@Nullable public static final BlockType NETHER_BRICK_SLAB = null;
@Nullable public static final BlockType NETHER_BRICK_STAIRS = null;
@Nullable public static final BlockType NETHER_BRICK_WALL = null;
@Nullable public static final BlockType NETHER_BRICKS = null;
@Nullable public static final BlockType NETHER_PORTAL = null;
@Nullable public static final BlockType NETHER_QUARTZ_ORE = null;
@ -417,9 +464,11 @@ public final class BlockTypes {
@Nullable public static final BlockType OAK_PLANKS = null;
@Nullable public static final BlockType OAK_PRESSURE_PLATE = null;
@Nullable public static final BlockType OAK_SAPLING = null;
@Nullable public static final BlockType OAK_SIGN = null;
@Nullable public static final BlockType OAK_SLAB = null;
@Nullable public static final BlockType OAK_STAIRS = null;
@Nullable public static final BlockType OAK_TRAPDOOR = null;
@Nullable public static final BlockType OAK_WALL_SIGN = null;
@Nullable public static final BlockType OAK_WOOD = null;
@Nullable public static final BlockType OBSERVER = null;
@Nullable public static final BlockType OBSIDIAN = null;
@ -459,22 +508,31 @@ public final class BlockTypes {
@Nullable public static final BlockType PLAYER_WALL_HEAD = null;
@Nullable public static final BlockType PODZOL = null;
@Nullable public static final BlockType POLISHED_ANDESITE = null;
@Nullable public static final BlockType POLISHED_ANDESITE_SLAB = null;
@Nullable public static final BlockType POLISHED_ANDESITE_STAIRS = null;
@Nullable public static final BlockType POLISHED_DIORITE = null;
@Nullable public static final BlockType POLISHED_DIORITE_SLAB = null;
@Nullable public static final BlockType POLISHED_DIORITE_STAIRS = null;
@Nullable public static final BlockType POLISHED_GRANITE = null;
@Nullable public static final BlockType POLISHED_GRANITE_SLAB = null;
@Nullable public static final BlockType POLISHED_GRANITE_STAIRS = null;
@Nullable public static final BlockType POPPY = null;
@Nullable public static final BlockType POTATOES = null;
@Nullable public static final BlockType POTTED_ACACIA_SAPLING = null;
@Nullable public static final BlockType POTTED_ALLIUM = null;
@Nullable public static final BlockType POTTED_AZURE_BLUET = null;
@Nullable public static final BlockType POTTED_BAMBOO = null;
@Nullable public static final BlockType POTTED_BIRCH_SAPLING = null;
@Nullable public static final BlockType POTTED_BLUE_ORCHID = null;
@Nullable public static final BlockType POTTED_BROWN_MUSHROOM = null;
@Nullable public static final BlockType POTTED_CACTUS = null;
@Nullable public static final BlockType POTTED_CORNFLOWER = null;
@Nullable public static final BlockType POTTED_DANDELION = null;
@Nullable public static final BlockType POTTED_DARK_OAK_SAPLING = null;
@Nullable public static final BlockType POTTED_DEAD_BUSH = null;
@Nullable public static final BlockType POTTED_FERN = null;
@Nullable public static final BlockType POTTED_JUNGLE_SAPLING = null;
@Nullable public static final BlockType POTTED_LILY_OF_THE_VALLEY = null;
@Nullable public static final BlockType POTTED_OAK_SAPLING = null;
@Nullable public static final BlockType POTTED_ORANGE_TULIP = null;
@Nullable public static final BlockType POTTED_OXEYE_DAISY = null;
@ -484,6 +542,7 @@ public final class BlockTypes {
@Nullable public static final BlockType POTTED_RED_TULIP = null;
@Nullable public static final BlockType POTTED_SPRUCE_SAPLING = null;
@Nullable public static final BlockType POTTED_WHITE_TULIP = null;
@Nullable public static final BlockType POTTED_WITHER_ROSE = null;
@Nullable public static final BlockType POWERED_RAIL = null;
@Nullable public static final BlockType PRISMARINE = null;
@Nullable public static final BlockType PRISMARINE_BRICK_SLAB = null;
@ -491,6 +550,7 @@ public final class BlockTypes {
@Nullable public static final BlockType PRISMARINE_BRICKS = null;
@Nullable public static final BlockType PRISMARINE_SLAB = null;
@Nullable public static final BlockType PRISMARINE_STAIRS = null;
@Nullable public static final BlockType PRISMARINE_WALL = null;
@Nullable public static final BlockType PUMPKIN = null;
@Nullable public static final BlockType PUMPKIN_STEM = null;
@Nullable public static final BlockType PURPLE_BANNER = null;
@ -522,11 +582,15 @@ public final class BlockTypes {
@Nullable public static final BlockType RED_GLAZED_TERRACOTTA = null;
@Nullable public static final BlockType RED_MUSHROOM = null;
@Nullable public static final BlockType RED_MUSHROOM_BLOCK = null;
@Nullable public static final BlockType RED_NETHER_BRICK_SLAB = null;
@Nullable public static final BlockType RED_NETHER_BRICK_STAIRS = null;
@Nullable public static final BlockType RED_NETHER_BRICK_WALL = null;
@Nullable public static final BlockType RED_NETHER_BRICKS = null;
@Nullable public static final BlockType RED_SAND = null;
@Nullable public static final BlockType RED_SANDSTONE = null;
@Nullable public static final BlockType RED_SANDSTONE_SLAB = null;
@Nullable public static final BlockType RED_SANDSTONE_STAIRS = null;
@Nullable public static final BlockType RED_SANDSTONE_WALL = null;
@Nullable public static final BlockType RED_SHULKER_BOX = null;
@Nullable public static final BlockType RED_STAINED_GLASS = null;
@Nullable public static final BlockType RED_STAINED_GLASS_PANE = null;
@ -547,18 +611,28 @@ public final class BlockTypes {
@Nullable public static final BlockType SANDSTONE = null;
@Nullable public static final BlockType SANDSTONE_SLAB = null;
@Nullable public static final BlockType SANDSTONE_STAIRS = null;
@Nullable public static final BlockType SANDSTONE_WALL = null;
@Nullable public static final BlockType SCAFFOLDING = null;
@Nullable public static final BlockType SEA_LANTERN = null;
@Nullable public static final BlockType SEA_PICKLE = null;
@Nullable public static final BlockType SEAGRASS = null;
@Nullable public static final BlockType SHULKER_BOX = null;
@Nullable public static final BlockType SIGN = null;
@Nullable public static final BlockType SKELETON_SKULL = null;
@Nullable public static final BlockType SKELETON_WALL_SKULL = null;
@Nullable public static final BlockType SLIME_BLOCK = null;
@Nullable public static final BlockType SMITHING_TABLE = null;
@Nullable public static final BlockType SMOKER = null;
@Nullable public static final BlockType SMOOTH_QUARTZ = null;
@Nullable public static final BlockType SMOOTH_QUARTZ_SLAB = null;
@Nullable public static final BlockType SMOOTH_QUARTZ_STAIRS = null;
@Nullable public static final BlockType SMOOTH_RED_SANDSTONE = null;
@Nullable public static final BlockType SMOOTH_RED_SANDSTONE_SLAB = null;
@Nullable public static final BlockType SMOOTH_RED_SANDSTONE_STAIRS = null;
@Nullable public static final BlockType SMOOTH_SANDSTONE = null;
@Nullable public static final BlockType SMOOTH_SANDSTONE_SLAB = null;
@Nullable public static final BlockType SMOOTH_SANDSTONE_STAIRS = null;
@Nullable public static final BlockType SMOOTH_STONE = null;
@Nullable public static final BlockType SMOOTH_STONE_SLAB = null;
@Nullable public static final BlockType SNOW = null;
@Nullable public static final BlockType SNOW_BLOCK = null;
@Nullable public static final BlockType SOUL_SAND = null;
@ -573,18 +647,23 @@ public final class BlockTypes {
@Nullable public static final BlockType SPRUCE_PLANKS = null;
@Nullable public static final BlockType SPRUCE_PRESSURE_PLATE = null;
@Nullable public static final BlockType SPRUCE_SAPLING = null;
@Nullable public static final BlockType SPRUCE_SIGN = null;
@Nullable public static final BlockType SPRUCE_SLAB = null;
@Nullable public static final BlockType SPRUCE_STAIRS = null;
@Nullable public static final BlockType SPRUCE_TRAPDOOR = null;
@Nullable public static final BlockType SPRUCE_WALL_SIGN = null;
@Nullable public static final BlockType SPRUCE_WOOD = null;
@Nullable public static final BlockType STICKY_PISTON = null;
@Nullable public static final BlockType STONE = null;
@Nullable public static final BlockType STONE_BRICK_SLAB = null;
@Nullable public static final BlockType STONE_BRICK_STAIRS = null;
@Nullable public static final BlockType STONE_BRICK_WALL = null;
@Nullable public static final BlockType STONE_BRICKS = null;
@Nullable public static final BlockType STONE_BUTTON = null;
@Nullable public static final BlockType STONE_PRESSURE_PLATE = null;
@Nullable public static final BlockType STONE_SLAB = null;
@Nullable public static final BlockType STONE_STAIRS = null;
@Nullable public static final BlockType STONECUTTER = null;
@Nullable public static final BlockType STRIPPED_ACACIA_LOG = null;
@Nullable public static final BlockType STRIPPED_ACACIA_WOOD = null;
@Nullable public static final BlockType STRIPPED_BIRCH_LOG = null;
@ -601,6 +680,7 @@ public final class BlockTypes {
@Nullable public static final BlockType STRUCTURE_VOID = null;
@Nullable public static final BlockType SUGAR_CANE = null;
@Nullable public static final BlockType SUNFLOWER = null;
@Nullable public static final BlockType SWEET_BERRY_BUSH = null;
@Nullable public static final BlockType TALL_GRASS = null;
@Nullable public static final BlockType TALL_SEAGRASS = null;
@Nullable public static final BlockType TERRACOTTA = null;
@ -616,7 +696,6 @@ public final class BlockTypes {
@Nullable public static final BlockType TURTLE_EGG = null;
@Nullable public static final BlockType VINE = null;
@Nullable public static final BlockType VOID_AIR = null;
@Nullable public static final BlockType WALL_SIGN = null;
@Nullable public static final BlockType WALL_TORCH = null;
@Nullable public static final BlockType WATER = null;
@Nullable public static final BlockType WET_SPONGE = null;
@ -634,6 +713,7 @@ public final class BlockTypes {
@Nullable public static final BlockType WHITE_TULIP = null;
@Nullable public static final BlockType WHITE_WALL_BANNER = null;
@Nullable public static final BlockType WHITE_WOOL = null;
@Nullable public static final BlockType WITHER_ROSE = null;
@Nullable public static final BlockType WITHER_SKELETON_SKULL = null;
@Nullable public static final BlockType WITHER_SKELETON_WALL_SKULL = null;
@Nullable public static final BlockType YELLOW_BANNER = null;
@ -651,6 +731,10 @@ public final class BlockTypes {
@Nullable public static final BlockType ZOMBIE_HEAD = null;
@Nullable public static final BlockType ZOMBIE_WALL_HEAD = null;
// deprecated
@Deprecated @Nullable public static BlockType SIGN;
@Deprecated @Nullable public static BlockType WALL_SIGN;
/*
-----------------------------------------------------
Settings
@ -812,7 +896,7 @@ public final class BlockTypes {
for (Field field : oldFields) {
if (field.getType() == int.class) {
int internalId = field.getInt(null);
String id = "minecraft:" + field.getName().toLowerCase();
String id = "minecraft:" + field.getName().toLowerCase(Locale.ROOT);
String defaultState = blockMap.remove(id);
if (defaultState == null) {
if (internalId != 0) {
@ -844,10 +928,14 @@ public final class BlockTypes {
// Add to $Registry
for (BlockType type : values) {
$REGISTRY.put(type.getId().toLowerCase(), type);
$REGISTRY.put(type.getId().toLowerCase(Locale.ROOT), type);
}
states = stateList.toArray(new BlockState[stateList.size()]);
// Init deprecated
SIGN = OAK_SIGN;
WALL_SIGN = OAK_WALL_SIGN;
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
@ -858,7 +946,7 @@ public final class BlockTypes {
// Get the enum name (remove namespace if minecraft:)
int propStart = id.indexOf('[');
String typeName = id.substring(0, propStart == -1 ? id.length() : propStart);
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase();
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(Locale.ROOT);
BlockType existing = new BlockType(id, internalId, states);
@ -888,7 +976,7 @@ public final class BlockTypes {
*/
public static BlockType parse(final String type) throws InputParseException {
final String inputLower = type.toLowerCase();
final String inputLower = type.toLowerCase(Locale.ROOT);
String input = inputLower;
if (!input.split("\\[", 2)[0].contains(":")) input = "minecraft:" + input;

View File

@ -0,0 +1,50 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import javax.annotation.Nullable;
public final class ImmutableBaseBlock extends BaseBlock {
public ImmutableBaseBlock(BlockState blockState) {
super(blockState);
}
@Nullable
@Override
public CompoundTag getNbtData() {
return null;
}
@Override
public boolean hasNbtData() {
return false;
}
@Override
public String getNbtId() {
return "";
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return set.setBlock(extent, toBlockState());
}
@Override
public <V> BaseBlock with(Property<V> property, V value) {
return toImmutableState().with(property, value).toBaseBlock();
}
@Override
public BaseBlock toBaseBlock(CompoundTag compoundTag) {
if (compoundTag != null) {
return new BaseBlock(this.toImmutableState(), compoundTag);
}
return this;
}
}