WIP filter patterns

Dieser Commit ist enthalten in:
Jesse Boyd 2019-05-12 23:32:04 +10:00
Ursprung 459629a2f2
Commit c797dcb194
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 59F1DE6293AF6E1F
61 geänderte Dateien mit 2075 neuen und 793 gelöschten Zeilen

Datei anzeigen

@ -1,10 +1,9 @@
package com.boydti.fawe.bukkit.beta; package com.boydti.fawe.bukkit.beta;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IGetBlocks;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.ISetBlocks; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.QueueHandler; import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.beta.implementation.holder.ChunkHolder; import com.boydti.fawe.beta.implementation.holder.ChunkHolder;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
@ -49,7 +48,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
} }
@Override @Override
public IGetBlocks get() { public IChunkGet get() {
BukkitQueue extent = (BukkitQueue) getExtent(); BukkitQueue extent = (BukkitQueue) getExtent();
return new BukkitGetBlocks(extent.getNmsWorld(), getX(), getZ()); return new BukkitGetBlocks(extent.getNmsWorld(), getX(), getZ());
} }
@ -78,7 +77,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
int Z = getZ(); int Z = getZ();
BukkitQueue extent = (BukkitQueue) getExtent(); BukkitQueue extent = (BukkitQueue) getExtent();
BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet(); BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet();
ISetBlocks set = getOrCreateSet(); IChunkSet set = getOrCreateSet();
Chunk nmsChunk = extent.ensureLoaded(X, Z); Chunk nmsChunk = extent.ensureLoaded(X, Z);

Datei anzeigen

@ -13,7 +13,9 @@ import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID; import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;

Datei anzeigen

@ -1,94 +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.blocks;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.jnbt.CompoundTag;
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 com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
/**
* A implementation of a lazy block for {@link Extent#getLazyBlock(Vector)}
* that takes the block's ID and metadata, but will defer loading of NBT
* data until time of access.
*
* <p>NBT data is later loaded using a call to {@link Extent#getBlock(Vector)}
* with a stored {@link Extent} and location.</p>
*
* <p>All mutators on this object will throw an
* {@link UnsupportedOperationException}.</p>
*/
public class LazyBlock extends BaseBlock {
private final Extent extent;
private final BlockVector3 position;
private boolean loaded = false;
/**
* Create a new lazy block.
*
* @param type the block type
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(BlockType type, Extent extent, BlockVector3 position) {
super(type);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
/**
* Create a new lazy block.
*
* @param state the block state
* @param extent the extent to later load the full block data from
* @param position the position to later load the full block data from
*/
public LazyBlock(BlockState state, Extent extent, BlockVector3 position) {
super(state);
checkNotNull(extent);
checkNotNull(position);
this.extent = extent;
this.position = position;
}
@Override
public CompoundTag getNbtData() {
if (!loaded) {
BaseBlock loadedBlock = extent.getFullBlock(position);
this.nbtData = loadedBlock.getNbtData();
loaded = true;
}
return super.getNbtData();
}
@Override
public void setNbtData(CompoundTag nbtData) {
throw new UnsupportedOperationException("This object is immutable");
}
}

Datei anzeigen

@ -0,0 +1,88 @@
package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.awt.image.BufferedImage;
import java.util.concurrent.ThreadLocalRandom;
public class ArrayFilterBlock extends SimpleFilterBlock {
private final char[] blocks;
private final byte[] heights;
private final int yOffset;
private int x, z, index;
private char ordinal;
private final int width, length;
public ArrayFilterBlock(Extent extent, char[] blocks, byte[] heights, int width, int length, int yOffset) {
super(extent);
this.blocks = blocks;
this.width = width;
this.length = length;
this.heights = heights;
this.yOffset = yOffset;
}
public void filter2D(Filter filter) {
for (z = 0; z < length; z++) {
for (x = 0; x < width; x++, index++) {
ordinal = blocks[ordinal];
filter.applyBlock(this);
}
}
}
@Override
public void setOrdinal(int ordinal) {
blocks[index] = (char) ordinal;
}
@Override
public void setState(BlockState state) {
blocks[index] = state.getOrdinalChar();
}
@Override
public void setFullBlock(BaseBlock block) {
blocks[index] = block.getOrdinalChar();
}
@Override
public int getOrdinal() {
return ordinal;
}
@Override
public BlockState getState() {
return BlockTypes.states[ordinal];
}
@Override
public BaseBlock getBaseBlock() {
return getState().toBaseBlock();
}
@Override
public CompoundTag getTag() {
return null;
}
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return (heights[index] & 0xFF) + yOffset;
}
@Override
public int getZ() {
return z;
}
}

Datei anzeigen

@ -4,6 +4,7 @@ import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
@ -12,11 +13,10 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.sk89q.worldedit.world.block.BlockTypes.states; import static com.sk89q.worldedit.world.block.BlockTypes.states;
public class CharFilterBlock implements FilterBlock { public class CharFilterBlock extends ChunkFilterBlock {
private IQueueExtent queue;
private CharGetBlocks get; private CharGetBlocks get;
private ISetBlocks set; private IChunkSet set;
private char[] getArr; private char[] getArr;
private @Nullable char[] setArr; private @Nullable char[] setArr;
@ -25,14 +25,12 @@ public class CharFilterBlock implements FilterBlock {
// local // local
private int layer, index, x, y, z, xx, yy, zz, X, Z; private int layer, index, x, y, z, xx, yy, zz, X, Z;
@Override public CharFilterBlock(IQueueExtent queueExtent) {
public final FilterBlock init(final IQueueExtent queue) { super(queueExtent);
this.queue = queue;
return this;
} }
@Override @Override
public final FilterBlock init(final int X, final int Z, final IGetBlocks chunk) { public final ChunkFilterBlock init(final int X, final int Z, final IChunkGet chunk) {
this.get = (CharGetBlocks) chunk; this.get = (CharGetBlocks) chunk;
this.X = X; this.X = X;
this.Z = Z; this.Z = Z;
@ -41,11 +39,32 @@ public class CharFilterBlock implements FilterBlock {
return this; return this;
} }
@Override public void flood(final IChunkGet iget, final IChunkSet iset, final int layer, Flood flood, FilterBlockMask mask) {
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final int layer, final Filter filter, final @Nullable Region region, BlockVector3 min, BlockVector3 max) { final int maxDepth = flood.getMaxDepth();
final boolean checkDepth = maxDepth < Character.MAX_VALUE;
if (init(iget, iset, layer)) {
while ((index = flood.poll()) != -1) {
x = index & 15;
z = (index >> 4) & 15;
y = (index >> 8) & 15;
if (mask.applyBlock(this)) {
int depth = index >> 12;
if (checkDepth && depth > maxDepth) {
continue;
}
flood.apply(x, y, z, depth);
}
}
}
}
private final boolean init(final IChunkGet iget, final IChunkSet iset, final int layer) {
this.layer = layer; this.layer = layer;
final CharGetBlocks get = (CharGetBlocks) iget; final CharGetBlocks get = (CharGetBlocks) iget;
if (!get.hasSection(layer)) return; if (!get.hasSection(layer)) return false;
this.set = iset; this.set = iset;
getArr = get.sections[layer].get(get, layer); getArr = get.sections[layer].get(get, layer);
if (set.hasSection(layer)) { if (set.hasSection(layer)) {
@ -56,17 +75,24 @@ public class CharFilterBlock implements FilterBlock {
setArr = null; setArr = null;
} }
this.yy = layer << 4; this.yy = layer << 4;
if (region == null) { return true;
if (min != null && max != null) { }
iterate(min, max, layer, filter);
@Override
public final void filter(final IChunkGet iget, final IChunkSet iset, final int layer, final Filter filter, final @Nullable Region region, BlockVector3 min, BlockVector3 max) {
if (init(iget, iset, layer)) {
if (region == null) {
if (min != null && max != null) {
iterate(min, max, layer, filter);
} else {
iterate(filter);
}
} else { } else {
iterate(filter); if (min != null && max != null) {
} iterate(region, min, max, layer, filter);
} else { } else {
if (min != null && max != null) { iterate(region, filter);
iterate(region, min, max, layer, filter); }
} else {
iterate(region, filter);
} }
} }
} }
@ -227,7 +253,7 @@ public class CharFilterBlock implements FilterBlock {
@Override @Override
public final CompoundTag getTag() { public final CompoundTag getTag() {
return null; return get.getTag(x, y + (layer << 4), z);
} }
public final BlockState getOrdinalBelow() { public final BlockState getOrdinalBelow() {
@ -310,71 +336,135 @@ public class CharFilterBlock implements FilterBlock {
public final BlockState getStateRelative(final int x, final int y, final int z) { public final BlockState getStateRelative(final int x, final int y, final int z) {
final int newX = this.x + x; final int newX = this.x + x;
if (newX >> 4 == 0) { final int newZ = this.z + z;
final int newZ = this.z + z; if (newX >> 4 == 0 && newZ >> 4 == 0) {
if (newZ >> 4 == 0) { final int newY = this.y + y;
final int newY = this.y + y; final int layerAdd = newY >> 4;
final int layerAdd = newY >> 4; switch (layerAdd) {
switch (layerAdd) { case 0:
case 0: return states[getArr[this.index + ((y << 8) + (z << 4) + x)]];
return states[getArr[this.index + ((y << 8) + (z << 4) + x)]]; case 1:
case 1: case 2:
case 2: case 3:
case 3: case 4:
case 4: case 5:
case 5: case 6:
case 6: case 7:
case 7: case 8:
case 8: case 9:
case 9: case 10:
case 10: case 11:
case 11: case 12:
case 12: case 13:
case 13: case 14:
case 14: case 15: {
case 15: { final int newLayer = layer + layerAdd;
final int newLayer = layer + layerAdd; if (newLayer < 16) {
if (newLayer < 16) { final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
final int index = ((newY & 15) << 8) + (newZ << 4) + newX; return states[get.sections[newLayer].get(get, newLayer, index)];
return states[get.sections[newLayer].get(get, newLayer, index)];
}
break;
}
case -1:
case -2:
case -3:
case -4:
case -5:
case -6:
case -7:
case -8:
case -9:
case -10:
case -11:
case -12:
case -13:
case -14:
case -15: {
final int newLayer = layer + layerAdd;
if (newLayer >= 0) {
final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
return states[get.sections[newLayer].get(get, newLayer, index)];
}
break;
} }
break;
}
case -1:
case -2:
case -3:
case -4:
case -5:
case -6:
case -7:
case -8:
case -9:
case -10:
case -11:
case -12:
case -13:
case -14:
case -15: {
final int newLayer = layer + layerAdd;
if (newLayer >= 0) {
final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
return states[get.sections[newLayer].get(get, newLayer, index)];
}
break;
} }
return BlockTypes.__RESERVED__.getDefaultState();
} }
return BlockTypes.__RESERVED__.getDefaultState();
} }
// queue.get
// TODO return normal get block
final int newY = this.y + y + yy; final int newY = this.y + y + yy;
if (newY >= 0 && newY <= 256) { if (newY >= 0 && newY <= 256) {
return queue.getBlock(xx + newX, newY, this.zz + this.z + z); return getExtent().getBlock(xx + newX, newY, this.zz + newZ);
} }
return BlockTypes.__RESERVED__.getDefaultState(); return BlockTypes.__RESERVED__.getDefaultState();
} }
public final BaseBlock getFullBlockRelative(final int x, final int y, final int z) {
final int newX = this.x + x;
final int newZ = this.z + z;
if (newX >> 4 == 0 && newZ >> 4 == 0) {
final int newY = this.y + y;
final int layerAdd = newY >> 4;
BlockState state = BlockTypes.__RESERVED__.getDefaultState();
switch (layerAdd) {
case 0:
state = states[getArr[this.index + ((y << 8) + (z << 4) + x)]];
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15: {
final int newLayer = layer + layerAdd;
if (newLayer < 16) {
final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
state = states[get.sections[newLayer].get(get, newLayer, index)];
}
break;
}
case -1:
case -2:
case -3:
case -4:
case -5:
case -6:
case -7:
case -8:
case -9:
case -10:
case -11:
case -12:
case -13:
case -14:
case -15: {
final int newLayer = layer + layerAdd;
if (newLayer >= 0) {
final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
state = states[get.sections[newLayer].get(get, newLayer, index)];
}
break;
}
}
if (state.getMaterial().hasContainer()) {
final CompoundTag tag = get.getTag(x, y + (layer << 4), z);
return state.toBaseBlock(tag);
}
}
final int newY = this.y + y + yy;
if (newY >= 0 && newY <= 256) {
return getExtent().getFullBlock(xx + newX, newY, this.zz + newZ);
}
return BlockTypes.__RESERVED__.getDefaultState().toBaseBlock();
}
/* /*
Set delegate Set delegate
*/ */
@ -383,6 +473,22 @@ public class CharFilterBlock implements FilterBlock {
return delegate = FULL; return delegate = FULL;
} }
@Override
public BiomeType getBiome(int x, int z) {
if ((x >> 4) == X && (z >> 4) == Z) {
return get.getBiome(x & 15, z & 15);
}
return getExtent().getBiome(x, z);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
if ((x >> 4) == X && (z >> 4) == Z) {
return set.setBiome(x & 15, z & 15, biome);
}
return getExtent().setBiome(x, y, z, biome);
}
private interface SetDelegate { private interface SetDelegate {
void set(CharFilterBlock block, char value); void set(CharFilterBlock block, char value);
} }

Datei anzeigen

@ -0,0 +1,19 @@
package com.boydti.fawe.beta;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import javax.annotation.Nullable;
public abstract class ChunkFilterBlock extends FilterBlock {
public ChunkFilterBlock(Extent extent) {
super(extent);
}
public abstract ChunkFilterBlock init(int X, int Z, IChunkGet chunk);
public abstract void flood(final IChunkGet iget, final IChunkSet iset, final int layer, Flood flood, FilterBlockMask mask);
public abstract void filter(IChunkGet get, IChunkSet set, int layer, Filter filter, @Nullable Region region, BlockVector3 min, BlockVector3 max);
}

Datei anzeigen

@ -10,7 +10,4 @@ public abstract class DelegateFilter implements IDelegateFilter {
public Filter getParent() { public Filter getParent() {
return parent; return parent;
} }
@Override
public abstract Filter fork();
} }

Datei anzeigen

@ -0,0 +1,5 @@
package com.boydti.fawe.beta;
public interface DirectionMask {
boolean apply(int fromX, int fromY, int fromZ, int toX, int toY, int toZ);
}

Datei anzeigen

@ -1,6 +1,7 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
@ -8,64 +9,97 @@ import com.sk89q.worldedit.world.block.BlockState;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public interface FilterBlock { public abstract class FilterBlock extends BlockVector3 implements Extent {
FilterBlock init(IQueueExtent queue); private final Extent extent;
FilterBlock init(int X, int Z, IGetBlocks chunk); public FilterBlock(Extent extent) {
this.extent = extent;
}
void filter(IGetBlocks get, ISetBlocks set, int layer, Filter filter, @Nullable Region region, BlockVector3 min, BlockVector3 max); public final Extent getExtent() {
return extent;
}
void setOrdinal(int ordinal); public abstract void setOrdinal(int ordinal);
void setState(BlockState state); public abstract void setState(BlockState state);
void setFullBlock(BaseBlock block); public abstract void setFullBlock(BaseBlock block);
int getOrdinal(); public abstract int getOrdinal();
BlockState getState(); public abstract BlockState getState();
BaseBlock getBaseBlock(); public abstract BaseBlock getBaseBlock();
CompoundTag getTag(); public abstract CompoundTag getTag();
default BlockState getOrdinalBelow() { @Override
public BlockVector3 getMinimumPoint() {
return getExtent().getMinimumPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return getExtent().getMaximumPoint();
}
@Override
public BlockState getBlock(int x, int y, int z) {
return getStateRelative(x - getX(), y - getY(), z - getZ());
}
@Override
public BaseBlock getFullBlock(int x, int y, int z) {
return getFullBlockRelative(x - getX(), y - getY(), z - getZ());
}
public BlockState getOrdinalBelow() {
return getStateRelative(0, -1, 0); return getStateRelative(0, -1, 0);
} }
default BlockState getStateAbove() { public BlockState getStateAbove() {
return getStateRelative(0, 1, 0); return getStateRelative(0, 1, 0);
} }
default BlockState getStateRelativeY(final int y) { public BlockState getStateRelativeY(final int y) {
return getStateRelative(0, y, 0); return getStateRelative(0, y, 0);
} }
int getX(); public BlockState getStateRelative(final int x, final int y, final int z) {
return getFullBlockRelative(x, y, z).toBlockState();
}
int getY(); public BaseBlock getFullBlockRelative(int x, int y, int z) {
return getExtent().getFullBlock(x + getX(), y + getY(), z + getZ());
}
int getZ(); @Override
public abstract int getX();
default int getLocalX() { @Override
public abstract int getY();
@Override
public abstract int getZ();
public int getLocalX() {
return getX() & 15; return getX() & 15;
} }
default int getLocalY() { public int getLocalY() {
return getY() & 15; return getY() & 15;
} }
default int getLocalZ() { public int getLocalZ() {
return getZ() & 15; return getZ() & 15;
} }
default int getChunkX() { public int getChunkX() {
return getX() >> 4; return getX() >> 4;
} }
default int getChunkZ() { public int getChunkZ() {
return getZ() >> 4; return getZ() >> 4;
} }
BlockState getStateRelative(final int x, final int y, final int z);
} }

Datei anzeigen

@ -0,0 +1,5 @@
package com.boydti.fawe.beta;
public interface FilterBlockMask {
boolean applyBlock(final FilterBlock block);
}

Datei anzeigen

@ -0,0 +1,192 @@
package com.boydti.fawe.beta;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.beta.implementation.WorldChunkCache;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class Flood {
private final int maxBranch;
private final int maxDepth;
private final Direction[] directions;
private int[] queue;
private long[] visit;
private int[][] queues;
private long[][] visits;
private int X, Y, Z;
private ConcurrentLinkedQueue<int[]> queuePool = new ConcurrentLinkedQueue<>();
private final Long2ObjectLinkedOpenHashMap<long[][]> chunkVisits;
private final Long2ObjectLinkedOpenHashMap<int[][]> chunkQueues;
public Flood(int maxBranch, int maxDepth, Direction[] directions) {
this.maxBranch = maxBranch;
this.maxDepth = maxDepth;
this.directions = directions;
this.queues = new int[27][];
this.visits = new long[27][];
this.chunkVisits = new Long2ObjectLinkedOpenHashMap<>();
this.chunkQueues = new Long2ObjectLinkedOpenHashMap<>();
}
public synchronized void run(World world) {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
IQueueExtent fq = queueHandler.getQueue(world);
while (!chunkQueues.isEmpty()) {
long firstKey = chunkQueues.firstLongKey();
int X = MathMan.unpairIntX(firstKey);
int Z = MathMan.unpairIntY(firstKey);
int[][] chunkQueue = chunkQueues.get(firstKey);
// apply
}
}
private void init(int X, int Y, int Z) {
this.X = X;
this.Y = Y;
this.Z = Z;
}
public void start(int x, int y, int z) {
push(x, y, z, 0);
}
private void push(int x, int y, int z, int depth) {
int X = x >> 4;
int Z = z >> 4;
long pair = MathMan.pairInt(X, Z);
int layer = y >> 4;
int[] section = getOrCreateQueue(pair, layer);
int val = (x & 15) + ((z & 15) << 4) + ((y & 15) << 8) + (depth << 12);
push(section, val);
}
private int[] getOrCreateQueue(long pair, int layer) {
int[][] arrs = chunkQueues.get(pair);
if (arrs == null) {
chunkQueues.put(pair, arrs = new int[16][]);
}
int[] section = arrs[layer];
if (section == null) {
arrs[layer] = section = newQueue();
}
return section;
}
private int[] newQueue() {
int[] arr = queuePool.poll();
if (arr != null) {
arr[0] = 2;
arr[1] = 2;
return arr;
}
return new int[4096];
}
public int poll() {
int index = queue[0];
if (index == queue[1]) {
return -1;
}
queue[0] = index + 1;
return queue[index];
}
private void push(int[] queue, int val) {
int indexStart = queue[0];
int indexEnd = queue[1];
push(indexStart, indexEnd, queue, val);
}
private void push(int indexStart, int indexEnd, int[] queue, int val) {
if (indexStart > 2) {
queue[0] = --indexStart;
queue[indexStart] = val;
} else {
queue[indexEnd] = val;
queue[0] = ++indexEnd;
}
}
public Direction[] getDirections() {
return directions;
}
public int getMaxBranch() {
return maxBranch;
}
public int getMaxDepth() {
return maxDepth;
}
public void apply(int x, int y, int z, int depth) {
for (int i = 0, j = 0; i < directions.length && j < maxBranch; i++) {
final Direction dir = directions[i];
final int ty = y + dir.getBlockY();
final int tx = x + dir.getBlockX();
final int tz = z + dir.getBlockZ();
int index;
long[] visit;
int[] queue;
final int or = tx | ty | tz;
if (or > 15 || or < 0) {
visit = this.visit;
queue = this.queue;
index = tx + (tz << 4) + (ty << 8);
} else {
int nextX = tx >> 4;
int nextY = ty >> 4;
int nextZ = tz >> 4;
int sectionIndex = nextX + nextZ * 3 + nextZ * 9 + 13;
visit = visits[sectionIndex];
queue = queues[sectionIndex];
if (visit == null || queue == null) {
long pair = MathMan.pairInt(X + nextX, Z + nextZ);
int layer = Y + nextY;
if (layer < 0 || layer > 15) {
continue;
}
queues[sectionIndex] = queue = getOrCreateQueue(pair, layer);
}
index = (tx & 15) + ((tz & 15) << 4) + ((ty & 15) << 8);
}
if (!getAndSet(visit, index)) {
j++;
push(queue, index + (depth << 12));
}
}
}
public void set(long[] bits, int i) {
bits[i >> 6] |= (1L << (i & 0x3F));
}
public final boolean getAndSet(long[] bits, int i) {
int index = i >> 6;
long offset = (1L << (i & 0x3F));
long val = bits[index];
if ((val & offset) != 0) {
return true;
} else {
bits[index] |= offset;
return false;
}
}
public boolean get(long[] bits, final int i) {
return (bits[i >> 6] & (1L << (i & 0x3F))) != 0;
}
}

Datei anzeigen

@ -11,7 +11,6 @@ import javax.annotation.Nullable;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.function.Supplier;
/** /**
* Represents a chunk in the queue {@link IQueueExtent} * Represents a chunk in the queue {@link IQueueExtent}
@ -72,7 +71,9 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T> {
* @param unitialized a mutable block vector (buffer) * @param unitialized a mutable block vector (buffer)
* @param unitialized2 a mutable block vector (buffer) * @param unitialized2 a mutable block vector (buffer)
*/ */
void filter(Filter filter, FilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2); void filter(Filter filter, ChunkFilterBlock block, @Nullable Region region, MutableBlockVector3 unitialized, MutableBlockVector3 unitialized2);
void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block);
/* set - queues a change */ /* set - queues a change */
boolean setBiome(int x, int y, int z, BiomeType biome); boolean setBiome(int x, int y, int z, BiomeType biome);

Datei anzeigen

@ -1,6 +1,7 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.InputExtent;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
@ -8,11 +9,14 @@ import com.sk89q.worldedit.world.block.BlockState;
/** /**
* Interface for getting blocks * Interface for getting blocks
*/ */
public interface IGetBlocks extends IBlocks, Trimable { public interface IChunkGet extends IBlocks, Trimable, InputExtent {
@Override
BaseBlock getFullBlock(int x, int y, int z); BaseBlock getFullBlock(int x, int y, int z);
@Override
BiomeType getBiome(int x, int z); BiomeType getBiome(int x, int z);
@Override
BlockState getBlock(int x, int y, int z); BlockState getBlock(int x, int y, int z);
CompoundTag getTag(int x, int y, int z); CompoundTag getTag(int x, int y, int z);

Datei anzeigen

@ -1,6 +1,7 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.OutputExtent;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -14,8 +15,8 @@ import java.util.UUID;
/** /**
* Interface for setting blocks * Interface for setting blocks
*/ */
public interface ISetBlocks extends IBlocks { public interface IChunkSet extends IBlocks, OutputExtent {
boolean setBiome(int x, int y, int z, BiomeType biome); boolean setBiome(int x, int z, BiomeType biome);
boolean setBlock(int x, int y, int z, BlockStateHolder holder); boolean setBlock(int x, int y, int z, BlockStateHolder holder);

Datei anzeigen

@ -26,6 +26,11 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
return root; return root;
} }
@Override
default void flood(Flood flood, FilterBlockMask mask, FilterBlock block) {
getParent().flood(flood, mask, block);
}
@Override @Override
default boolean setBiome(final int x, final int y, final int z, final BiomeType biome) { default boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
return getParent().setBiome(x, y, z, biome); return getParent().setBiome(x, y, z, biome);

Datei anzeigen

@ -39,7 +39,11 @@ public interface IDelegateFilter extends Filter {
@Override @Override
default Filter fork() { default Filter fork() {
return newInstance(getParent().fork()); Filter fork = getParent().fork();
if (fork != getParent()) {
return newInstance(fork);
}
return this;
} }
Filter newInstance(Filter other); Filter newInstance(Filter other);

Datei anzeigen

@ -1,7 +1,10 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.WorldChunkCache; import com.boydti.fawe.beta.implementation.WorldChunkCache;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType; 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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -12,7 +15,7 @@ import java.util.concurrent.Future;
* TODO: implement Extent (need to refactor Extent first) * TODO: implement Extent (need to refactor Extent first)
* Interface for a queue based extent which uses chunks * Interface for a queue based extent which uses chunks
*/ */
public interface IQueueExtent extends Flushable, Trimable { public interface IQueueExtent extends Flushable, Trimable, Extent {
void init(WorldChunkCache world); void init(WorldChunkCache world);
/** /**
@ -51,11 +54,26 @@ public interface IQueueExtent extends Flushable, Trimable {
return chunk.getBlock(x & 15, y, z & 15); return chunk.getBlock(x & 15, y, z & 15);
} }
@Override
default BaseBlock getFullBlock(int x, int y, int z) {
final IChunk chunk = getCachedChunk(x >> 4, z >> 4);
return chunk.getFullBlock(x & 15, y, z & 15);
}
default BiomeType getBiome(final int x, final int z) { default BiomeType getBiome(final int x, final int z) {
final IChunk chunk = getCachedChunk(x >> 4, z >> 4); final IChunk chunk = getCachedChunk(x >> 4, z >> 4);
return chunk.getBiome(x & 15, z & 15); return chunk.getBiome(x & 15, z & 15);
} }
@Override
default BlockVector3 getMinimumPoint() {
return getCache().getWorld().getMinimumPoint();
}
@Override
default BlockVector3 getMaximumPoint() {
return getCache().getWorld().getMaximumPoint();
}
/** /**
* Create a new root IChunk object<br> * Create a new root IChunk object<br>
* - Full chunks will be reused, so a more optimized chunk can be returned in that case<br> * - Full chunks will be reused, so a more optimized chunk can be returned in that case<br>
@ -81,5 +99,5 @@ public interface IQueueExtent extends Flushable, Trimable {
@Override @Override
void flush(); void flush();
FilterBlock initFilterBlock(); ChunkFilterBlock initFilterBlock();
} }

Datei anzeigen

@ -0,0 +1,70 @@
package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
public abstract class SimpleFilterBlock extends FilterBlock {
public SimpleFilterBlock(Extent extent) {
super(extent);
}
private int x, y, z, ordinal;
private CompoundTag nbt;
public void init(int x, int y, int z, int ordinal) {
this.x = x;
this.y = y;
this.z = z;
this.ordinal = ordinal;
}
public void init(int x, int y, int z, int ordinal, CompoundTag nbt) {
this.x = x;
this.y = y;
this.z = z;
this.ordinal = ordinal;
this.nbt = nbt;
}
@Override
public int getOrdinal() {
return ordinal;
}
@Override
public BlockState getState() {
return BlockTypes.states[ordinal];
}
@Override
public BaseBlock getBaseBlock() {
return getState().toBaseBlock(nbt);
}
@Override
public CompoundTag getTag() {
return nbt;
}
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return y;
}
@Override
public int getZ() {
return z;
}
}

Datei anzeigen

@ -0,0 +1,26 @@
package com.boydti.fawe.beta.filters;
import com.boydti.fawe.beta.DelegateFilter;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.beta.FilterBlockMask;
import java.awt.image.BufferedImage;
import java.util.concurrent.ThreadLocalRandom;
public class ArrayImageMask implements FilterBlockMask {
private final ThreadLocalRandom r;
private final boolean white;
private final BufferedImage img;
public ArrayImageMask(BufferedImage img, boolean white) {
this.img = img;
this.white = white;
this.r = ThreadLocalRandom.current();
}
@Override
public boolean applyBlock(FilterBlock block) {
int height = img.getRGB(block.getX(), block.getZ()) & 0xFF;
return ((height == 255 || height > 0 && !white && r.nextInt(256) <= height));
}
}

Datei anzeigen

@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock; import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
@ -163,7 +164,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
// Create a chunk that we will reuse/reset for each operation // Create a chunk that we will reuse/reset for each operation
final IQueueExtent queue = getQueue(world); final IQueueExtent queue = getQueue(world);
synchronized (queue) { synchronized (queue) {
FilterBlock block = null; ChunkFilterBlock block = null;
while (true) { while (true) {
// Get the next chunk posWeakChunk // Get the next chunk posWeakChunk

Datei anzeigen

@ -6,8 +6,6 @@ import com.boydti.fawe.beta.FilterBlock;
public abstract class SimpleCharQueueExtent extends SingleThreadQueueExtent { public abstract class SimpleCharQueueExtent extends SingleThreadQueueExtent {
@Override @Override
public FilterBlock initFilterBlock() { public FilterBlock initFilterBlock() {
FilterBlock filter = new CharFilterBlock(); return new CharFilterBlock(this);
filter = filter.init(this);
return filter;
} }
} }

Datei anzeigen

@ -1,6 +1,6 @@
package com.boydti.fawe.beta.implementation; package com.boydti.fawe.beta.implementation;
import com.boydti.fawe.beta.IGetBlocks; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.Trimable; import com.boydti.fawe.beta.Trimable;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
@ -15,7 +15,7 @@ import java.util.function.Supplier;
* - avoids conversion between palette and raw data on every block get * - avoids conversion between palette and raw data on every block get
*/ */
public class WorldChunkCache implements Trimable { public class WorldChunkCache implements Trimable {
protected final Long2ObjectLinkedOpenHashMap<WeakReference<IGetBlocks>> getCache; protected final Long2ObjectLinkedOpenHashMap<WeakReference<IChunkGet>> getCache;
private final World world; private final World world;
protected WorldChunkCache(final World world) { protected WorldChunkCache(final World world) {
@ -37,13 +37,13 @@ public class WorldChunkCache implements Trimable {
* @param provider used to create if it isn't already cached * @param provider used to create if it isn't already cached
* @return cached IGetBlocks * @return cached IGetBlocks
*/ */
public synchronized IGetBlocks get(final long index, final Supplier<IGetBlocks> provider) { public synchronized IChunkGet get(final long index, final Supplier<IChunkGet> provider) {
final WeakReference<IGetBlocks> ref = getCache.get(index); final WeakReference<IChunkGet> ref = getCache.get(index);
if (ref != null) { if (ref != null) {
final IGetBlocks blocks = ref.get(); final IChunkGet blocks = ref.get();
if (blocks != null) return blocks; if (blocks != null) return blocks;
} }
final IGetBlocks blocks = provider.get(); final IChunkGet blocks = provider.get();
getCache.put(index, new WeakReference<>(blocks)); getCache.put(index, new WeakReference<>(blocks));
return blocks; return blocks;
} }
@ -52,11 +52,11 @@ public class WorldChunkCache implements Trimable {
public synchronized boolean trim(final boolean aggressive) { public synchronized boolean trim(final boolean aggressive) {
boolean result = true; boolean result = true;
if (!getCache.isEmpty()) { if (!getCache.isEmpty()) {
final ObjectIterator<Long2ObjectMap.Entry<WeakReference<IGetBlocks>>> iter = getCache.long2ObjectEntrySet().fastIterator(); final ObjectIterator<Long2ObjectMap.Entry<WeakReference<IChunkGet>>> iter = getCache.long2ObjectEntrySet().fastIterator();
while (iter.hasNext()) { while (iter.hasNext()) {
final Long2ObjectMap.Entry<WeakReference<IGetBlocks>> entry = iter.next(); final Long2ObjectMap.Entry<WeakReference<IChunkGet>> entry = iter.next();
final WeakReference<IGetBlocks> value = entry.getValue(); final WeakReference<IChunkGet> value = entry.getValue();
final IGetBlocks igb = value.get(); final IChunkGet igb = value.get();
if (igb == null) iter.remove(); if (igb == null) iter.remove();
else { else {
result = false; result = false;

Datei anzeigen

@ -1,11 +1,11 @@
package com.boydti.fawe.beta.implementation.blocks; package com.boydti.fawe.beta.implementation.blocks;
import com.boydti.fawe.beta.IGetBlocks; import com.boydti.fawe.beta.IChunkGet;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
public abstract class CharGetBlocks extends CharBlocks implements IGetBlocks { public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
@Override @Override
public BaseBlock getFullBlock(final int x, final int y, final int z) { public BaseBlock getFullBlock(final int x, final int y, final int z) {
return BlockTypes.states[get(x, y, z)].toBaseBlock(); return BlockTypes.states[get(x, y, z)].toBaseBlock();

Datei anzeigen

@ -1,6 +1,6 @@
package com.boydti.fawe.beta.implementation.blocks; package com.boydti.fawe.beta.implementation.blocks;
import com.boydti.fawe.beta.ISetBlocks; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
@ -14,7 +14,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
public class CharSetBlocks extends CharBlocks implements ISetBlocks { public class CharSetBlocks extends CharBlocks implements IChunkSet {
public BiomeType[] biomes; public BiomeType[] biomes;
public HashMap<Short, CompoundTag> tiles; public HashMap<Short, CompoundTag> tiles;
public HashSet<CompoundTag> entities; public HashSet<CompoundTag> entities;

Datei anzeigen

@ -1,12 +1,15 @@
package com.boydti.fawe.beta.implementation.holder; package com.boydti.fawe.beta.implementation.holder;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock; import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.beta.FilterBlockMask;
import com.boydti.fawe.beta.Flood;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IGetBlocks; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.ISetBlocks; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent; import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent;
import com.boydti.fawe.beta.implementation.WorldChunkCache; import com.boydti.fawe.beta.implementation.WorldChunkCache;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
@ -23,9 +26,9 @@ import java.util.function.Supplier;
/** /**
* Abstract IChunk class that implements basic get/set blocks * Abstract IChunk class that implements basic get/set blocks
*/ */
public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> { public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
private IGetBlocks get; private IChunkGet get;
private ISetBlocks set; private IChunkSet set;
private IBlockDelegate delegate; private IBlockDelegate delegate;
private IQueueExtent extent; private IQueueExtent extent;
private int X,Z; private int X,Z;
@ -39,9 +42,14 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
} }
@Override @Override
public void filter(final Filter filter, FilterBlock block, @Nullable Region region, final MutableBlockVector3 min, final MutableBlockVector3 max) { public void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block) {
final IGetBlocks get = getOrCreateGet(); // block.flood(get, set, mask, block, );
final ISetBlocks set = getOrCreateSet(); }
@Override
public void filter(final Filter filter, ChunkFilterBlock block, @Nullable Region region, @Nullable final MutableBlockVector3 min, @Nullable final MutableBlockVector3 max) {
final IChunkGet get = getOrCreateGet();
final IChunkSet set = getOrCreateSet();
try { try {
if (region != null) { if (region != null) {
switch (region.getChunkBounds(X, Z, min, max)) { switch (region.getChunkBounds(X, Z, min, max)) {
@ -106,21 +114,21 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
return set == null || set.isEmpty(); return set == null || set.isEmpty();
} }
public final IGetBlocks getOrCreateGet() { public final IChunkGet getOrCreateGet() {
if (get == null) get = newGet(); if (get == null) get = newGet();
return get; return get;
} }
public final ISetBlocks getOrCreateSet() { public final IChunkSet getOrCreateSet() {
if (set == null) set = set(); if (set == null) set = set();
return set; return set;
} }
public ISetBlocks set() { public IChunkSet set() {
return new CharSetBlocks(); return new CharSetBlocks();
} }
private IGetBlocks newGet() { private IChunkGet newGet() {
if (extent instanceof SingleThreadQueueExtent) { if (extent instanceof SingleThreadQueueExtent) {
final WorldChunkCache cache = ((SingleThreadQueueExtent) extent).getCache(); final WorldChunkCache cache = ((SingleThreadQueueExtent) extent).getCache();
return cache.get(MathMan.pairInt(X, Z), this); return cache.get(MathMan.pairInt(X, Z), this);

Datei anzeigen

@ -1,5 +1,8 @@
package com.boydti.fawe.beta.implementation.holder; package com.boydti.fawe.beta.implementation.holder;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.beta.FilterBlockMask;
import com.boydti.fawe.beta.Flood;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IDelegateChunk; import com.boydti.fawe.beta.IDelegateChunk;

Datei anzeigen

@ -2,6 +2,12 @@ package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.ArrayFilterBlock;
import com.boydti.fawe.beta.DelegateFilter;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.beta.SimpleFilterBlock;
import com.boydti.fawe.beta.filters.ArrayImageMask;
import com.boydti.fawe.example.SimpleIntFaweChunk; import com.boydti.fawe.example.SimpleIntFaweChunk;
import com.boydti.fawe.jnbt.anvil.HeightMapMCADrawer; import com.boydti.fawe.jnbt.anvil.HeightMapMCADrawer;
import com.boydti.fawe.jnbt.anvil.MCAChunk; import com.boydti.fawe.jnbt.anvil.MCAChunk;
@ -1022,7 +1028,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
return getLazyBlock(position); return getBlock(position.getX(), position.getY(), position.getZ());
} }
public BlockState getFloor(int x, int z) { public BlockState getFloor(int x, int z) {
@ -1045,12 +1051,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
} }
@Override @Override
public BlockState getLazyBlock(BlockVector3 position) { public BlockState getBlock(int x, int y, int z) {
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return BlockState.getFromInternalId(getCombinedId4Data(x, y, z)); return BlockState.getFromInternalId(getCombinedId4Data(x, y, z));
} }
@ -1340,6 +1341,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
} }
} }
public void test() {
// ArrayImageMask mask = new ArrayImageMask(img, white);
// filter = new ArrayFilterBlock(this, overlayArr, heights.get(), getWidth(), getLength(), 1);
}
public void setOverlay(BufferedImage img, Pattern pattern, boolean white) { public void setOverlay(BufferedImage img, Pattern pattern, boolean white) {
if (pattern instanceof BlockStateHolder) { if (pattern instanceof BlockStateHolder) {
setOverlay(img, ((BlockStateHolder) pattern).getInternalId(), white); setOverlay(img, ((BlockStateHolder) pattern).getInternalId(), white);

Datei anzeigen

@ -72,7 +72,7 @@ public interface FaweQueue extends HasFaweQueue, Extent {
} }
@Override @Override
default BlockState getLazyBlock(int x, int y, int z) { default BlockState getBlock(int x, int y, int z) {
int combinedId4Data = getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId()); int combinedId4Data = getCachedCombinedId4Data(x, y, z, BlockTypes.AIR.getInternalId());
try { try {
BlockState state = BlockState.getFromInternalId(combinedId4Data); BlockState state = BlockState.getFromInternalId(combinedId4Data);

Datei anzeigen

@ -50,6 +50,7 @@ public class SurfaceSpline implements Brush {
n.setContinuity(continuity); n.setContinuity(continuity);
nodes.add(n); nodes.add(n);
} }
MutableBlockVector3 mutable = MutableBlockVector3.at(0, 0, 0);
interpol.setNodes(nodes); interpol.setNodes(nodes);
final double splinelength = interpol.arcLength(0, 1); final double splinelength = interpol.arcLength(0, 1);
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
@ -60,7 +61,7 @@ public class SurfaceSpline implements Brush {
tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, 0, maxY); tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, 0, maxY);
if (tipy == -1) continue; if (tipy == -1) continue;
if (radius == 0) { if (radius == 0) {
BlockVector3 set = MutableBlockVector3.get(tipx, tipy, tipz); BlockVector3 set = mutable.setComponents(tipx, tipy, tipz);
try { try {
pattern.apply(editSession, set, set); pattern.apply(editSession, set, set);
} catch (WorldEditException e) { } catch (WorldEditException e) {

Datei anzeigen

@ -24,7 +24,12 @@ public interface VirtualWorld extends SimpleWorld, FaweQueue, Closeable {
@Override @Override
default BaseBlock getFullBlock(BlockVector3 position) { default BaseBlock getFullBlock(BlockVector3 position) {
return getLazyBlock(position).toBaseBlock(); return getBlock(position).toBaseBlock();
}
@Override
default BaseBlock getFullBlock(int x, int y, int z) {
return getBlock(x, y, z).toBaseBlock();
} }
@Override @Override

Datei anzeigen

@ -43,7 +43,7 @@ public class BlockVectorSet extends AbstractCollection<BlockVector3> implements
int newSize = count + size; int newSize = count + size;
if (newSize > index) { if (newSize > index) {
int localIndex = index - count; int localIndex = index - count;
MutableBlockVector3 pos = new MutableBlockVector3(set.getIndex(localIndex)); BlockVector3 pos = set.getIndex(localIndex);
if (pos != null) { if (pos != null) {
int pair = entry.getIntKey(); int pair = entry.getIntKey();
int cx = MathMan.unpairX(pair); int cx = MathMan.unpairX(pair);

Datei anzeigen

@ -244,9 +244,9 @@ public final class DifferentialArray<T> implements DifferentialCollection<T> {
return dataBytes; return dataBytes;
} }
// public char[] getCharArray() { public char[] getCharArray() {
// return dataChars; return dataChars;
// } }
public int[] getIntArray() { public int[] getIntArray() {
return dataInts; return dataInts;

Datei anzeigen

@ -0,0 +1,213 @@
package com.boydti.fawe.object.collection;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
/**
* Records changes made through the {@link #set(int, int, int, char)} method<br/>
* Changes are not recorded if you edit the raw data
*/
public final class DifferentialCharBlockBuffer implements DifferentialCollection<char[][][][][]> {
private final int width, length;
private final int t1, t2;
private char[][][][][] data;
private char[][][][][] changes;
public DifferentialCharBlockBuffer(int width, int length) {
this.width = width;
this.length = length;
this.t1 = (length + 15) >> 4;
this.t2 = (width + 15) >> 4;
}
@Override
public char[][][][][] get() {
return data;
}
@Override
public void flushChanges(FaweOutputStream out) throws IOException {
boolean modified = isModified();
out.writeBoolean(modified);
if (modified) {
writeArray(changes, 0, 0, out);
}
clearChanges();
}
private void writeArray(Object arr, int level, int index, FaweOutputStream out) throws IOException {
if (level == 4) {
if (arr != null) {
char[] level4 = (char[]) arr;
out.writeVarInt(level4.length);
for (char c : level4) {
out.writeChar(c);
}
} else {
out.writeVarInt(0);
}
} else {
int len = arr == null ? 0 : Array.getLength(arr);
out.writeVarInt(len);
for (int i = 0; i < len; i++) {
Object elem = Array.get(arr, i);
writeArray(elem, level + 1, i, out);
}
}
}
@Override
public void undoChanges(FaweInputStream in) throws IOException {
if (changes != null && changes.length != 0) throw new IllegalStateException("There are uncommitted changes, please flush first");
boolean modified = in.readBoolean();
if (modified) {
int len = in.readVarInt();
if (len == 0) {
data = null;
} else {
for (int i = 0; i < len; i++) {
readArray(data, i, 1, in);
}
}
}
clearChanges();
}
@Override
public void redoChanges(FaweInputStream in) throws IOException {
clearChanges();
throw new UnsupportedOperationException("Not implemented");
}
private void readArray(Object dataElem, int index, int level, FaweInputStream in) throws IOException {
int len = in.readVarInt();
if (level == 4) {
char[][] castedElem = (char[][]) dataElem;
if (len == 0) {
castedElem[index] = null;
} else {
char[] current = castedElem[index];
for (int i = 0; i < len; i++) {
current[i] = in.readChar();
}
}
} else {
if (len == 0) {
Array.set(dataElem, index, null);
} else {
Object nextElem = Array.get(dataElem, index);
for (int i = 0; i < len; i++) {
readArray(nextElem, i, level + 1, in);
}
}
}
}
public boolean isModified() {
return changes != null;
}
public void clearChanges() {
changes = null;
}
public void set(int x, int y, int z, char combined) {
if (combined == 0) combined = 1;
int localX = x & 15;
int localZ = z & 15;
int chunkX = x >> 4;
int chunkZ = z >> 4;
if (data == null) {
data = new char[t1][][][][];
changes = new char[0][][][][];
}
char[][][][] arr = data[chunkZ];
if (arr == null) {
arr = data[chunkZ] = new char[t2][][][];
}
char[][][] arr2 = arr[chunkX];
if (arr2 == null) {
arr2 = arr[chunkX] = new char[256][][];
}
char[][] yMap = arr2[y];
if (yMap == null) {
arr2[y] = yMap = new char[16][];
}
boolean newSection;
char current;
char[] zMap = yMap[localZ];
if (zMap == null) {
yMap[localZ] = zMap = new char[16];
if (changes == null) {
changes = new char[t1][][][][];
} else if (changes != null && changes.length != 0) {
initialChange(changes, chunkX, chunkZ, localX, localZ, y, (char) -combined);
}
} else {
if (changes == null || changes.length == 0) changes = new char[t1][][][][];
appendChange(changes, chunkX, chunkZ, localX, localZ, y, (char) (zMap[localX] - combined));
}
zMap[localX] = combined;
}
private void initialChange(char[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, char combined) {
char[][][][] arr = src[chunkZ];
if (arr == null) {
src[chunkZ] = new char[0][][][];
return;
} else if (arr.length == 0) return;
char[][][] arr2 = arr[chunkX];
if (arr2 == null) {
arr[chunkX] = new char[0][][];
return;
} else if (arr2.length == 0) return;
char[][] yMap = arr2[y];
if (yMap == null) {
arr2[y] = new char[0][];
return;
} else if (yMap.length == 0) return;
char[] zMap = yMap[localZ];
if (zMap == null) {
yMap[localZ] = new char[0];
return;
} else if (zMap.length == 0) return;
char current = zMap[localX];
zMap[localX] = combined;
}
private void appendChange(char[][][][][] src, int chunkX, int chunkZ, int localX, int localZ, int y, char combined) {
char[][][][] arr = src[chunkZ];
if (arr == null || arr.length == 0) {
arr = src[chunkZ] = new char[t2][][][];
}
char[][][] arr2 = arr[chunkX];
if (arr2 == null || arr2.length == 0) {
arr2 = arr[chunkX] = new char[256][][];
}
char[][] yMap = arr2[y];
if (yMap == null || yMap.length == 0) {
arr2[y] = yMap = new char[16][];
}
char[] zMap = yMap[localZ];
if (zMap == null || zMap.length == 0) {
yMap[localZ] = zMap = new char[16];
}
zMap[localX] = combined;
}
}

Datei anzeigen

@ -100,7 +100,7 @@ public class LocalBlockVectorSet implements Set<BlockVector3> {
this.offsetZ = z; this.offsetZ = z;
} }
public BlockVector3 getIndex(int getIndex) { protected BlockVector3 getIndex(int getIndex) {
int size = size(); int size = size();
if (getIndex > size) { if (getIndex > size) {
return null; return null;

Datei anzeigen

@ -2,8 +2,10 @@ package com.boydti.fawe.object.pattern;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.object.DataAnglePattern; import com.boydti.fawe.object.DataAnglePattern;
import com.boydti.fawe.util.TextureHolder; import com.boydti.fawe.util.TextureHolder;
import com.boydti.fawe.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
@ -15,11 +17,11 @@ import com.sk89q.worldedit.world.block.BlockType;
import java.io.IOException; import java.io.IOException;
public class AngleColorPattern extends DataAnglePattern { public class AngleColorPattern extends DataAnglePattern {
protected transient TextureHolder util; protected transient TextureUtil util;
public AngleColorPattern(Extent extent, TextureHolder util, int distance) { public AngleColorPattern(Extent extent, TextureHolder holder, int distance) {
super(extent, distance); super(extent, distance);
this.util = util; this.util = holder.getTextureUtil();
} }
public int getColor(int color, int slope) { public int getColor(int color, int slope) {
@ -31,15 +33,28 @@ public class AngleColorPattern extends DataAnglePattern {
return (((color >> 24) & 0xFF) << 24) + (newRed << 16) + (newGreen << 8) + (newBlue << 0); return (((color >> 24) & 0xFF) << 24) + (newRed << 16) + (newGreen << 8) + (newBlue << 0);
} }
@Override
public void apply(FilterBlock block) {
BlockState state = block.getState();
int slope = getSlope(state, block);
if (slope == -1) return;
int color = util.getColor(state.getBlockType());
if (color == 0) return;
int newColor = getColor(color, slope);
BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock == null) return;
newBlock.apply(block);
}
@Override @Override
public BaseBlock apply(BlockVector3 position) { public BaseBlock apply(BlockVector3 position) {
BaseBlock block = extent.getFullBlock(position); BaseBlock block = extent.getFullBlock(position);
int slope = getSlope(block, position); int slope = getSlope(block, position);
if (slope == -1) return block; if (slope == -1) return block;
int color = util.getTextureUtil().getColor(block.getBlockType()); int color = util.getColor(block.getBlockType());
if (color == 0) return block; if (color == 0) return block;
int newColor = getColor(color, slope); int newColor = getColor(color, slope);
return util.getTextureUtil().getNearestBlock(newColor).getDefaultState().toBaseBlock(); return util.getNearestBlock(newColor).getDefaultState().toBaseBlock();
} }
@Override @Override
@ -51,7 +66,7 @@ public class AngleColorPattern extends DataAnglePattern {
int z = vector.getBlockZ(); int z = vector.getBlockZ();
int height = extent.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY); int height = extent.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY);
if (height > 0) { if (height > 0) {
BlockStateHolder below = extent.getLazyBlock(x, height - 1, z); BlockStateHolder below = extent.getBlock(x, height - 1, z);
if (!below.getBlockType().getMaterial().isMovementBlocker()) { if (!below.getBlockType().getMaterial().isMovementBlocker()) {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
@ -65,16 +80,11 @@ public class AngleColorPattern extends DataAnglePattern {
BlockStateHolder block = extent.getBlock(getPosition); BlockStateHolder block = extent.getBlock(getPosition);
int slope = getSlope(block, getPosition); int slope = getSlope(block, getPosition);
if (slope == -1) return false; if (slope == -1) return false;
int color = util.getTextureUtil().getColor(block.getBlockType()); int color = util.getColor(block.getBlockType());
if (color == 0) return false; if (color == 0) return false;
int newColor = getColor(color, slope); int newColor = getColor(color, slope);
BlockType newBlock = util.getTextureUtil().getNearestBlock(newColor); BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock == null) return false; if (newBlock == null) return false;
return extent.setBlock(setPosition, newBlock.getDefaultState()); return extent.setBlock(setPosition, newBlock.getDefaultState());
} }
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
util = Fawe.get().getCachedTextureUtil(true, 0, 100);
}
} }

Datei anzeigen

@ -1,5 +1,6 @@
package com.boydti.fawe.object.pattern; package com.boydti.fawe.object.pattern;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.schematic.Schematic; import com.boydti.fawe.object.schematic.Schematic;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
@ -25,14 +26,15 @@ public class RandomFullClipboardPattern extends AbstractPattern {
private final Extent extent; private final Extent extent;
private final MutableBlockVector3 mutable = new MutableBlockVector3(); private final MutableBlockVector3 mutable = new MutableBlockVector3();
private final List<ClipboardHolder> clipboards; private final List<ClipboardHolder> clipboards;
private boolean randomRotate; private final boolean randomRotate;
private boolean randomFlip; private final boolean randomFlip;
public RandomFullClipboardPattern(Extent extent, List<ClipboardHolder> clipboards, boolean randomRotate, boolean randomFlip) { public RandomFullClipboardPattern(Extent extent, List<ClipboardHolder> clipboards, boolean randomRotate, boolean randomFlip) {
checkNotNull(clipboards); checkNotNull(clipboards);
this.clipboards = clipboards; this.clipboards = clipboards;
this.extent = extent; this.extent = extent;
this.randomRotate = randomRotate; this.randomRotate = randomRotate;
this.randomFlip = randomFlip;
} }
@Override @Override

Datei anzeigen

@ -86,16 +86,4 @@ public class FaweQueueDelegateExtent extends DelegateFaweQueue {
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException { public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
return parentExtent.setBlock(x, y, z, block); return parentExtent.setBlock(x, y, z, block);
} }
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return parentExtent.getLazyBlock(position);
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return parentExtent.getLazyBlock(x, y, z);
}
} }

Datei anzeigen

@ -2,14 +2,36 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.MCAWorld;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.*; import com.boydti.fawe.object.*;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.changeset.BlockBagChangeSet;
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.FastWorldEditExtent;
import com.boydti.fawe.object.extent.HeightBoundExtent;
import com.boydti.fawe.object.extent.MultiRegionExtent;
import com.boydti.fawe.object.extent.NullExtent;
import com.boydti.fawe.object.extent.ProcessedWEExtent;
import com.boydti.fawe.object.extent.SingleRegionExtent;
import com.boydti.fawe.object.extent.SlowExtent;
import com.boydti.fawe.object.extent.StripNBTExtent;
import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.util.eventbus.EventBus;
@ -190,7 +212,214 @@ public class EditSessionBuilder {
return this; return this;
} }
private boolean wrapped;
private AbstractDelegateExtent wrapExtent(final AbstractDelegateExtent extent, final EventBus eventBus, EditSessionEvent event, final EditSession.Stage stage) {
event = event.clone(stage);
event.setExtent(extent);
eventBus.post(event);
if (event.isCancelled()) {
return new NullExtent(extent, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
}
final Extent toReturn = event.getExtent();
if(toReturn instanceof com.sk89q.worldedit.extent.NullExtent) {
return new NullExtent(toReturn, null);
}
if (!(toReturn instanceof AbstractDelegateExtent)) {
Fawe.debug("Extent " + toReturn + " must be AbstractDelegateExtent");
return extent;
}
if (toReturn != extent) {
String className = toReturn.getClass().getName().toLowerCase();
for (String allowed : Settings.IMP.EXTENT.ALLOWED_PLUGINS) {
if (className.contains(allowed.toLowerCase())) {
this.wrapped = true;
return (AbstractDelegateExtent) toReturn;
}
}
if (Settings.IMP.EXTENT.DEBUG) {
Fawe.debug("&cPotentially unsafe extent blocked: " + toReturn.getClass().getName());
Fawe.debug("&8 - &7For area restrictions, it is recommended to use the FaweAPI");
Fawe.debug("&8 - &7For block logging, it is recommended to use use BlocksHub");
Fawe.debug("&8 - &7To allow this plugin add it to the FAWE `allowed-plugins` list");
Fawe.debug("&8 - &7To hide this message set `debug` to false in the FAWE config.yml");
if (toReturn.getClass().getName().contains("CoreProtect")) {
Fawe.debug("Note on CoreProtect: ");
Fawe.debug(" - If you disable CP's WE logger (CP config) and this still shows, please update CP");
Fawe.debug(" - Use BlocksHub and set `debug` false in the FAWE config");
}
}
}
return extent;
}
public EditSessionBuilder commit() {
// reset
wrapped = false;
//
if (worldName == null) {
if (world == null) {
if (queue == null) {
worldName = "";
} else {
worldName = queue.getWorldName();
}
} else {
worldName = Fawe.imp().getWorldName(world);
}
}
if (world == null && !this.worldName.isEmpty()) {
world = FaweAPI.getWorld(this.worldName);
}
if (eventBus == null) {
eventBus = WorldEdit.getInstance().getEventBus();
}
if (event == null) {
event = new EditSessionEvent(world, player == null ? null : (player.getPlayer()), -1, null);
}
if (player == null && event.getActor() != null) {
player = FawePlayer.wrap(event.getActor());
}
if (limit == null) {
if (player == null) {
limit = FaweLimit.MAX;
} else {
limit = player.getLimit();
}
}
if (autoQueue == null) {
autoQueue = true;
}
if (fastmode == null) {
if (player == null) {
fastmode = !Settings.IMP.HISTORY.ENABLE_FOR_CONSOLE;
} else {
fastmode = player.getSession().hasFastMode();
}
}
if (checkMemory == null) {
checkMemory = player != null && !this.fastmode;
}
if (checkMemory) {
if (MemUtil.isMemoryLimitedSlow()) {
if (Perm.hasPermission(player, "worldedit.fast")) {
BBC.WORLDEDIT_OOM_ADMIN.send(player);
}
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY);
}
}
// this.originalLimit = limit;
this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
// this.limit = limit.copy();
if (queue == null) {
boolean placeChunks = this.fastmode || this.limit.FAST_PLACEMENT;
World unwrapped = WorldWrapper.unwrap(world);
if (unwrapped instanceof FaweQueue) {
queue = (FaweQueue) unwrapped;
} else if (unwrapped instanceof MCAWorld) {
queue = ((MCAWorld) unwrapped).getQueue();
} else if (player != null && world.equals(player.getWorld())) {
queue = player.getFaweQueue(placeChunks, autoQueue);
} else {
queue = SetQueue.IMP.getNewQueue(world, placeChunks, autoQueue);
}
}
if (combineStages == null) {
combineStages =
// If it's enabled in the settings
Settings.IMP.HISTORY.COMBINE_STAGES
// If fast placement is disabled, it's slower to perform a copy on each chunk
&& this.limit.FAST_PLACEMENT
// If the specific queue doesn't support it
&& queue.supports(FaweQueue.Capability.CHANGE_TASKS)
// If the edit uses items from the inventory we can't use a delayed task
&& this.blockBag == null;
}
// if (Settings.IMP.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
// queue = new MCAQueue(queue);
// }
if (!Settings.IMP.QUEUE.PROGRESS.DISPLAY.equalsIgnoreCase("false") && player != null) {
switch (Settings.IMP.QUEUE.PROGRESS.DISPLAY.toLowerCase()) {
case "chat":
this.queue.setProgressTask(new ChatProgressTracker(player));
break;
case "title":
case "true":
default:
this.queue.setProgressTask(new DefaultProgressTracker(player));
}
}
// this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), eventBus, event, EditSession.Stage.BEFORE_CHANGE);
// this.bypassHistory = (this.extent = wrapExtent(bypassAll, eventBus, event, EditSession.Stage.BEFORE_REORDER));
// if (!this.fastMode || changeSet != null) {
// if (changeSet == null) {
// if (Settings.IMP.HISTORY.USE_DISK) {
// UUID uuid = player == null ? EditSession.CONSOLE : player.getUUID();
// if (Settings.IMP.HISTORY.USE_DATABASE) {
// changeSet = new RollbackOptimizedHistory(world, uuid);
// } else {
// changeSet = new DiskStorageHistory(world, uuid);
// }
// } else if (combineStages && Settings.IMP.HISTORY.COMPRESSION_LEVEL == 0 && !(queue instanceof MCAQueue)) {
// changeSet = new CPUOptimizedChangeSet(world);
// } else {
// changeSet = new MemoryOptimizedHistory(world);
// }
// }
// if (this.limit.SPEED_REDUCTION > 0) {
// this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
// }
// if (changeSet instanceof NullChangeSet && Fawe.imp().getBlocksHubApi() != null && player != null) {
// changeSet = LoggingChangeSet.wrap(player, changeSet);
// }
// if (!(changeSet instanceof NullChangeSet)) {
// if (!(changeSet instanceof LoggingChangeSet) && player != null && Fawe.imp().getBlocksHubApi() != null) {
// changeSet = LoggingChangeSet.wrap(player, changeSet);
// }
// if (this.blockBag != null) {
// changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
// }
// if (combineStages) {
// changeTask = changeSet;
// changeSet.addChangeTask(queue);
// } else {
// this.extent = (history = new HistoryExtent(this, bypassHistory, changeSet, queue));
//// if (this.blockBag != null) {
//// this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
//// }
// }
// }
// }
// if (allowedRegions == null) {
// if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions") && !(queue instanceof VirtualWorld)) {
// allowedRegions = player.getCurrentRegions();
// }
// }
// this.maxY = getWorld() == null ? 255 : world.getMaxY();
// if (allowedRegions != null) {
// if (allowedRegions.length == 0) {
// this.extent = new NullExtent(this.extent, BBC.WORLDEDIT_CANCEL_REASON_NO_REGION);
// } else {
// this.extent = new ProcessedWEExtent(this.extent, this.limit);
// if (allowedRegions.length == 1) {
// Region region = allowedRegions[0];
// this.extent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
// } else {
// this.extent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
// }
// }
// } else {
// this.extent = new HeightBoundExtent(this.extent, this.limit, 0, maxY);
// }
// if (this.limit.STRIP_NBT != null && !this.limit.STRIP_NBT.isEmpty()) {
// this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT);
// }
// this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
return this;
}
public EditSession build() { public EditSession build() {
return new EditSession(worldName, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event); return new EditSession(worldName, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
} }
} }

Datei anzeigen

@ -486,7 +486,7 @@ public class TextureUtil implements TextureHolder {
BlockType block = getNearestBlock(color); BlockType block = getNearestBlock(color);
TextureUtil.BiomeColor biome = getNearestBiome(color); TextureUtil.BiomeColor biome = getNearestBiome(color);
int blockColor = getColor(block); int blockColor = getColor(block);
blockAndBiomeIdOutput[0] = block.getInternalId(); blockAndBiomeIdOutput[0] = block.getDefaultState().getOrdinalChar();
blockAndBiomeIdOutput[1] = biome.id; blockAndBiomeIdOutput[1] = biome.id;
if (colorDistance(biome.grassCombined, color) - biomePriority > colorDistance(blockColor, if (colorDistance(biome.grassCombined, color) - biomePriority > colorDistance(blockColor,
color)) { color)) {

Datei anzeigen

@ -235,11 +235,6 @@ public class WorldWrapper extends AbstractWorld {
return parent.getBlock(position); return parent.getBlock(position);
} }
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return parent.getLazyBlock(position);
}
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
return parent.getFullBlock(position); return parent.getFullBlock(position);

Datei anzeigen

@ -42,7 +42,6 @@ import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.FastWorldEditExtent; import com.boydti.fawe.object.extent.FastWorldEditExtent;
@ -61,6 +60,7 @@ import com.boydti.fawe.object.mask.ResettableMask;
import com.boydti.fawe.object.pattern.ExistingPattern; import com.boydti.fawe.object.pattern.ExistingPattern;
import com.boydti.fawe.object.progress.ChatProgressTracker; import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker; import com.boydti.fawe.object.progress.DefaultProgressTracker;
import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.ExtentTraverser; import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.MaskTraverser; import com.boydti.fawe.util.MaskTraverser;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
@ -79,28 +79,18 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent; import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent; import com.sk89q.worldedit.extent.MaskingExtent;
import com.sk89q.worldedit.extent.cache.LastAccessExtentCache;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
import com.sk89q.worldedit.extent.reorder.ChunkBatchingExtent;
import com.sk89q.worldedit.extent.reorder.MultiStageReorder;
import com.sk89q.worldedit.extent.validation.BlockChangeLimiter;
import com.sk89q.worldedit.extent.validation.DataValidatorExtent;
import com.sk89q.worldedit.extent.world.BlockQuirkExtent;
import com.sk89q.worldedit.extent.world.ChunkLoadingExtent;
import com.sk89q.worldedit.extent.world.FastModeExtent;
import com.sk89q.worldedit.extent.world.SurvivalModeExtent; import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter; import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer; import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.ForestGenerator; import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator; import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.BlockMaskBuilder; import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
import com.sk89q.worldedit.function.mask.BlockStateMask;
import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.BoundedHeightMask; import com.sk89q.worldedit.function.mask.BoundedHeightMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
@ -116,7 +106,6 @@ import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.function.util.RegionOffset; import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DirectionalVisitor; import com.sk89q.worldedit.function.visitor.DirectionalVisitor;
import com.sk89q.worldedit.function.visitor.DownwardVisitor; import com.sk89q.worldedit.function.visitor.DownwardVisitor;
@ -127,12 +116,10 @@ import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.function.visitor.RegionVisitor; import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.history.UndoContext; import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.history.change.BlockChange; import com.sk89q.worldedit.history.change.BlockChange;
import com.sk89q.worldedit.history.changeset.BlockOptimizedHistory;
import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException; import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException;
import com.sk89q.worldedit.internal.expression.runtime.RValue; import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
@ -142,7 +129,6 @@ import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector2; import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.interpolation.Interpolation;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation; import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node; import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.math.noise.RandomNoise;
@ -159,21 +145,30 @@ import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.collection.DoubleArrayList;
import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.SimpleWorld; import com.sk89q.worldedit.world.SimpleWorld;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.*; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockID;
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;
import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
@ -204,19 +199,19 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
BEFORE_CHANGE BEFORE_CHANGE
} }
private World world; private final World world;
private String worldName; private final String worldName;
private FaweQueue queue; private final FaweQueue queue;
private boolean wrapped; private final boolean wrapped;
private boolean fastMode; private final boolean fastMode;
private AbstractDelegateExtent extent; private final AbstractDelegateExtent extent;
private HistoryExtent history; private final HistoryExtent history;
private AbstractDelegateExtent bypassHistory; private final AbstractDelegateExtent bypassHistory;
private AbstractDelegateExtent bypassAll; private final AbstractDelegateExtent bypassAll;
private FaweLimit originalLimit; private final FaweLimit originalLimit;
private FaweLimit limit; private final FaweLimit limit;
private FawePlayer player; private final FawePlayer player;
private FaweChangeSet changeTask; private final FaweChangeSet changeTask;
private MutableBlockVector3 mutablebv = new MutableBlockVector3(); private MutableBlockVector3 mutablebv = new MutableBlockVector3();
@ -249,7 +244,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (event == null) { if (event == null) {
event = new EditSessionEvent(world, player == null ? null : (player.getPlayer()), -1, null); event = new EditSessionEvent(world, player == null ? null : (player.getPlayer()), -1, null);
} }
event.setEditSession(this);
if (player == null && event.getActor() != null) { if (player == null && event.getActor() != null) {
player = FawePlayer.wrap(event.getActor()); player = FawePlayer.wrap(event.getActor());
} }
@ -393,7 +387,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT); this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT);
} }
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY); this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
setExtent(this.extent); }
public EditSession(EditSessionBuilder builder) {
super(builder.)
} }
/** /**
@ -496,15 +493,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return bypassHistory; return bypassHistory;
} }
public Extent getExtent() {
return extent;
}
public void setExtent(AbstractDelegateExtent extent) {
this.extent = extent;
new ExtentTraverser(this).setNext(extent);
}
/** /**
* Get the FawePlayer or null * Get the FawePlayer or null
* *
@ -1057,17 +1045,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return queue.getOpacity(x, y, z); return queue.getOpacity(x, y, z);
} }
@Override
public BlockState getLazyBlock(final BlockVector3 position) {
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
public BlockState getLazyBlock(int x, int y, int z) {
return extent.getLazyBlock(x, y, z);
}
public BlockState getBlock(int x, int y, int z) { public BlockState getBlock(int x, int y, int z) {
return getLazyBlock(x, y, z); return extent.getBlock(x, y, z);
} }
@Override @Override
@ -1085,7 +1064,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* *
* @param position the position * @param position the position
* @return the block type * @return the block type
* @deprecated Use {@link #getLazyBlock(BlockVector3)} or {@link #getBlock(BlockVector3)} * @deprecated Use {@link #getBlock(BlockVector3)} or {@link #getBlock(BlockVector3)}
*/ */
@Deprecated @Deprecated
public BlockType getBlockType(final BlockVector3 position) { public BlockType getBlockType(final BlockVector3 position) {
@ -1099,7 +1078,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @param z the Z coordinate * @param z the Z coordinate
* @param minY minimal height * @param minY minimal height
* @param maxY maximal height * @param maxY maximal height
* @param filter a mask of blocks to consider, or null to consider any solid (movement-blocking) block
* @return height of highest block found or 'minY' * @return height of highest block found or 'minY'
*/ */
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) { public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
@ -2918,11 +2896,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* Generate a shape for the given expression. * Generate a shape for the given expression.
* *
* @param region the region to generate the shape in * @param region the region to generate the shape in
* @param zero the coordinate origin for x/y/z variables
* @param unit the scale of the x/y/z/ variables
* @param pattern the default material to make the shape from
* @param expressionString the expression defining the shape
* @param hollow whether the shape should be hollow
* @return number of blocks changed * @return number of blocks changed
* @throws ExpressionException * @throws ExpressionException
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException
@ -3433,8 +3406,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
CompoundTag nbt = block.getNbtData(); CompoundTag nbt = block.getNbtData();
if (nbt != null) { if (nbt != null) {
if (nbt.containsKey("items")) { if (nbt.containsKey("items")) {
block.setNbtData(null); return setBlock(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), block.toBlockState().toBaseBlock());
return setBlock(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), block);
} }
} }
return false; return false;

Datei anzeigen

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

Datei anzeigen

@ -49,7 +49,7 @@ public class GravityBrush implements Brush {
for (int z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) { for (int z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
int freeSpot = startCheckY; int freeSpot = startCheckY;
for (int y = startCheckY; y <= endY; y++) { for (int y = startCheckY; y <= endY; y++) {
BlockStateHolder block = editSession.getLazyBlock(x, y, z); BlockStateHolder block = editSession.getBlock(x, y, z);
if (!block.getBlockType().getMaterial().isAir()) { if (!block.getBlockType().getMaterial().isAir()) {
if (y != freeSpot) { if (y != freeSpot) {
editSession.setBlock(x, y, z, EditSession.nullBlock); editSession.setBlock(x, y, z, EditSession.nullBlock);

Datei anzeigen

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

Datei anzeigen

@ -22,8 +22,6 @@ package com.sk89q.worldedit.extent;
import com.boydti.fawe.jnbt.anvil.generator.GenBase; import com.boydti.fawe.jnbt.anvil.generator.GenBase;
import com.boydti.fawe.jnbt.anvil.generator.Resource; import com.boydti.fawe.jnbt.anvil.generator.Resource;
import com.boydti.fawe.object.extent.LightingExtent; import com.boydti.fawe.object.extent.LightingExtent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -41,29 +39,40 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List;
public class AbstractDelegateExtent implements LightingExtent { import static com.google.common.base.Preconditions.checkNotNull;
private transient final Extent extent;
protected MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0);
/** public class AbstractDelegateExtent implements Extent, LightingExtent {
* Create a new instance. private final Extent extent;
*
* @param extent the extent public AbstractDelegateExtent(Extent parent) {
*/ this.extent = parent;
public AbstractDelegateExtent(Extent extent) {
checkNotNull(extent);
this.extent = extent;
} }
public int getSkyLight(int x, int y, int z) { /**
if (extent instanceof LightingExtent) { * Get the extent.
return ((LightingExtent) extent).getSkyLight(x, y, z); *
} * @return the extent
return 0; */
public final Extent getExtent() {
return extent;
}
/*
Bounds
*/
@Override
public BlockVector3 getMinimumPoint() {
return extent.getMinimumPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return extent.getMaximumPoint();
} }
@Override @Override
@ -71,11 +80,40 @@ public class AbstractDelegateExtent implements LightingExtent {
return extent.getMaxY(); return extent.getMaxY();
} }
/*
Input + Output
*/
@Override @Override
public BlockType getBlockType(BlockVector3 position) { public BlockState getBlock(int x, int y, int z) {
return extent.getBlockType(position); return extent.getBlock(x, y, z);
} }
@Override
public BaseBlock getFullBlock(int x, int y, int z) {
return extent.getFullBlock(x, y, z);
}
@Override
public BiomeType getBiome(int x, int z) {
return extent.getBiome(x, z);
}
@Override
public boolean setBiome(int x, int z, BiomeType biome) {
return extent.setBiome(x, z, biome);
}
/*
Light
*/
public int getSkyLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getSkyLight(x, y, z);
}
return 0;
}
public int getBlockLight(int x, int y, int z) { public int getBlockLight(int x, int y, int z) {
if (extent instanceof LightingExtent) { if (extent instanceof LightingExtent) {
@ -88,7 +126,7 @@ public class AbstractDelegateExtent implements LightingExtent {
if (extent instanceof LightingExtent) { if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getOpacity(x, y, z); return ((LightingExtent) extent).getOpacity(x, y, z);
} }
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightOpacity(); return getBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
} }
@Override @Override
@ -103,164 +141,20 @@ public class AbstractDelegateExtent implements LightingExtent {
if (extent instanceof LightingExtent) { if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBrightness(x, y, z); return ((LightingExtent) extent).getBrightness(x, y, z);
} }
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightValue(); return getBlock(x, y, z).getBlockType().getMaterial().getLightValue();
} }
/** /*
* Get the extent. Generic
*
* @return the extent
*/ */
public Extent getExtent() {
return extent;
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return extent.getLazyBlock(mutable.setComponents(x, y, z));
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return extent.getLazyBlock(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return setBlock(mutable.setComponents(x, y, z), block);
}
public BlockState getBlock(BlockVector3 position) {
return extent.getBlock(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return extent.getFullBlock(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
return extent.setBlock(location, block);
}
@Override
@Nullable
public Entity createEntity(Location location, BaseEntity entity) {
return extent.createEntity(location, entity);
}
@Override
public List<? extends Entity> getEntities() {
return extent.getEntities();
}
@Override
public List<? extends Entity> getEntities(Region region) {
return extent.getEntities(region);
}
@Override
public BiomeType getBiome(BlockVector2 position) {
return extent.getBiome(position);
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
return extent.setBiome(position, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return extent.setBiome(x, y, z, biome);
}
@Override
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
return extent.getHighestTerrainBlock(x, z, minY, maxY);
}
@Override
public BlockVector3 getMinimumPoint() {
return extent.getMinimumPoint();
}
@Override
public BlockVector3 getMaximumPoint() {
return extent.getMaximumPoint();
}
protected Operation commitBefore() {
return null;
}
@Override @Override
public String toString() { public String toString() {
return super.toString() + ":" + extent.toString(); return super.toString() + ":" + extent.toString();
} }
@Override protected Operation commitBefore() {
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) { return null;
return extent.getNearestSurfaceLayer(x, z, y, 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 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);
}
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 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 @Override
@ -279,6 +173,4 @@ public class AbstractDelegateExtent implements LightingExtent {
return null; return null;
} }
} }
} }

Datei anzeigen

@ -117,33 +117,11 @@ public interface Extent extends InputExtent, OutputExtent {
return null; 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) { default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY) {
maxY = Math.min(maxY, Math.max(0, maxY)); maxY = Math.min(maxY, Math.max(0, maxY));
minY = Math.max(0, minY); minY = Math.max(0, minY);
for (int y = maxY; y >= minY; --y) { for (int y = maxY; y >= minY; --y) {
BlockState block = getLazyBlock(x, y, z); BlockState block = getBlock(x, y, z);
if (block.getBlockType().getMaterial().isMovementBlocker()) { if (block.getBlockType().getMaterial().isMovementBlocker()) {
return y; return y;
} }
@ -167,20 +145,20 @@ public interface Extent extends InputExtent, OutputExtent {
int clearanceBelow = y - minY; int clearanceBelow = y - minY;
int clearance = Math.min(clearanceAbove, clearanceBelow); int clearance = Math.min(clearanceAbove, clearanceBelow);
BlockState block = getLazyBlock(x, y, z); BlockState block = getBlock(x, y, z);
boolean state = !block.getBlockType().getMaterial().isMovementBlocker(); boolean state = !block.getBlockType().getMaterial().isMovementBlocker();
int data1 = PropertyGroup.LEVEL.get(block); int data1 = PropertyGroup.LEVEL.get(block);
int data2 = data1; int data2 = data1;
int offset = state ? 0 : 1; int offset = state ? 0 : 1;
for (int d = 0; d <= clearance; d++) { for (int d = 0; d <= clearance; d++) {
int y1 = y + d; int y1 = y + d;
block = getLazyBlock(x, y1, z); block = getBlock(x, y1, z);
if (!block.getBlockType().getMaterial().isMovementBlocker() != state) { if (!block.getBlockType().getMaterial().isMovementBlocker() != state) {
return ((y1 - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data1)); return ((y1 - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data1));
} }
data1 = PropertyGroup.LEVEL.get(block); data1 = PropertyGroup.LEVEL.get(block);
int y2 = y - d; int y2 = y - d;
block = getLazyBlock(x, y2, z); block = getBlock(x, y2, z);
if (!block.getBlockType().getMaterial().isMovementBlocker() != state) { if (!block.getBlockType().getMaterial().isMovementBlocker() != state) {
return ((y2 + offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2)); return ((y2 + offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2));
} }
@ -189,7 +167,7 @@ public interface Extent extends InputExtent, OutputExtent {
if (clearanceAbove != clearanceBelow) { if (clearanceAbove != clearanceBelow) {
if (clearanceAbove < clearanceBelow) { if (clearanceAbove < clearanceBelow) {
for (int layer = y - clearance - 1; layer >= minY; layer--) { 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) { if (!block.getBlockType().getMaterial().isMovementBlocker() != state) {
int data = (state ? PropertyGroup.LEVEL.get(block) : data1); int data = (state ? PropertyGroup.LEVEL.get(block) : data1);
return ((layer + offset) << 4) + 0; return ((layer + offset) << 4) + 0;
@ -198,7 +176,7 @@ public interface Extent extends InputExtent, OutputExtent {
} }
} else { } else {
for (int layer = y + clearance + 1; layer <= maxY; layer++) { 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) { if (!block.getBlockType().getMaterial().isMovementBlocker() != state) {
return ((layer - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2)); return ((layer - offset) << 4) - (15 - (state ? PropertyGroup.LEVEL.get(block) : data2));
} }
@ -254,33 +232,33 @@ public interface Extent extends InputExtent, OutputExtent {
int clearanceAbove = maxY - y; int clearanceAbove = maxY - y;
int clearanceBelow = y - minY; int clearanceBelow = y - minY;
int clearance = Math.min(clearanceAbove, clearanceBelow); int clearance = Math.min(clearanceAbove, clearanceBelow);
BlockStateHolder block = getLazyBlock(x, y, z); BlockStateHolder block = getBlock(x, y, z);
boolean state = !block.getBlockType().getMaterial().isMovementBlocker(); boolean state = !block.getBlockType().getMaterial().isMovementBlocker();
int offset = state ? 0 : 1; int offset = state ? 0 : 1;
for (int d = 0; d <= clearance; d++) { for (int d = 0; d <= clearance; d++) {
int y1 = y + 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; if (!block.getMaterial().isMovementBlocker() != state && block.getBlockType() != BlockTypes.__RESERVED__) return y1 - offset;
int y2 = y - d; 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 (!block.getMaterial().isMovementBlocker() != state && block.getBlockType() != BlockTypes.__RESERVED__) return y2 + offset;
} }
if (clearanceAbove != clearanceBelow) { if (clearanceAbove != clearanceBelow) {
if (clearanceAbove < clearanceBelow) { if (clearanceAbove < clearanceBelow) {
for (int layer = y - clearance - 1; layer >= minY; layer--) { 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; if (!block.getMaterial().isMovementBlocker() != state && block.getBlockType() != BlockTypes.__RESERVED__) return layer + offset;
} }
} else { } else {
for (int layer = y + clearance + 1; layer <= maxY; layer++) { 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; if (!block.getMaterial().isMovementBlocker() != state && block.getBlockType() != BlockTypes.__RESERVED__) return layer - offset;
} }
} }
} }
int result = state ? failedMin : failedMax; int result = state ? failedMin : failedMax;
if(result > 0 && !ignoreAir) { if(result > 0 && !ignoreAir) {
block = getLazyBlock(x, result, z); block = getBlock(x, result, z);
return block.getBlockType().getMaterial().isAir() ? -1 : result; return block.getBlockType().getMaterial().isAir() ? -1 : result;
} }
return result; return result;
@ -296,7 +274,7 @@ public interface Extent extends InputExtent, OutputExtent {
} }
} }
default public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException { default void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
spawnResource(region, new SchemGen(mask, this, clipboards, rotate), rarity, 1); spawnResource(region, new SchemGen(mask, this, clipboards, rotate), rarity, 1);
} }
@ -320,11 +298,11 @@ public interface Extent extends InputExtent, OutputExtent {
return (pt.containedWithin(min, max)); return (pt.containedWithin(min, max));
} }
default public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException { default void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
spawnResource(region, new OreGen(this, mask, material, size, minY, maxY), rarity, frequency); spawnResource(region, new OreGen(this, mask, material, size, minY, maxY), rarity, frequency);
} }
default public void addOres(Region region, Mask mask) throws WorldEditException { default void addOres(Region region, Mask mask) throws WorldEditException {
addOre(region, mask, BlockTypes.DIRT.getDefaultState(), 33, 10, 100, 0, 255); addOre(region, mask, BlockTypes.DIRT.getDefaultState(), 33, 10, 100, 0, 255);
addOre(region, mask, BlockTypes.GRAVEL.getDefaultState(), 33, 8, 100, 0, 255); addOre(region, mask, BlockTypes.GRAVEL.getDefaultState(), 33, 8, 100, 0, 255);
addOre(region, mask, BlockTypes.ANDESITE.getDefaultState(), 33, 10, 100, 0, 79); addOre(region, mask, BlockTypes.ANDESITE.getDefaultState(), 33, 10, 100, 0, 79);

Datei anzeigen

@ -22,6 +22,8 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; 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.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
@ -46,42 +48,31 @@ public interface InputExtent {
* @param position position of the block * @param position position of the block
* @return the block * @return the block
*/ */
BlockState getBlock(BlockVector3 position); default BlockState getBlock(BlockVector3 position) {
return getBlock(position.getX(), position.getY(), position.getZ());
}
default BlockState getBlock(int x, int y, int z) {
return getBlock(MutableBlockVector3.get(x, y, z));
}
default BlockType getBlockType(BlockVector3 position) { default BlockType getBlockType(BlockVector3 position) {
return getBlock(position).getBlockType(); return getBlock(position).getBlockType();
} }
/**
* Get a lazy, immutable snapshot of the block at the given location that only
* immediately contains information about the block's type (and metadata).
*
* <p>Further information (such as NBT data) will be available <strong>by the
* time of access</strong>. Therefore, it is not recommended that
* this method is used if the world is being simulated at the time of
* call. If the block needs to be stored for future use, then this method should
* definitely not be used. Moreover, the block that is returned is immutable (or
* should be), and therefore modifications should not be attempted on it. If a
* modifiable copy is required, then the block should be cloned.</p>
*
* <p>This method exists because it is sometimes important to inspect the block
* at a given location, but {@link #getBlock(Vector)} may be too expensive in
* the underlying implementation. It is also not possible to implement
* caching if the returned object is mutable, so this methods allows caching
* implementations to be used.</p>
*
* @param position position of the block
* @return the block
*/
BlockState getLazyBlock(BlockVector3 position);
/** /**
* Get a immutable snapshot of the block at the given location. * Get a immutable snapshot of the block at the given location.
* *
* @param position position of the block * @param position position of the block
* @return the block * @return the block
*/ */
BaseBlock getFullBlock(BlockVector3 position); default BaseBlock getFullBlock(BlockVector3 position) {
return getFullBlock(position.getX(), position.getY(), position.getZ());
}
default BaseBlock getFullBlock(int x, int y, int z) {
return getFullBlock(MutableBlockVector3.get(x, y, z));
}
/** /**
* Get the biome at the given location. * Get the biome at the given location.
@ -92,6 +83,11 @@ public interface InputExtent {
* @param position the (x, z) location to check the biome at * @param position the (x, z) location to check the biome at
* @return the biome at the location * @return the biome at the location
*/ */
BiomeType getBiome(BlockVector2 position); default BiomeType getBiome(BlockVector2 position) {
return getBiome(position.getX(), position.getZ());
}
default BiomeType getBiome(int x, int z) {
return getBiome(MutableBlockVector2.get(x, z));
}
} }

Datei anzeigen

@ -23,6 +23,8 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; 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.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder; 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) * @return true if the block was successfully set (return value may not be accurate)
* @throws WorldEditException thrown on an error * @throws WorldEditException thrown on an error
*/ */
<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. * Set the biome.
@ -59,7 +67,13 @@ public interface OutputExtent {
* @param biome the biome to set to * @param biome the biome to set to
* @return true if the biome was successfully set (return value may not be accurate) * @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 * Return an {@link Operation} that should be called to tie up loose ends

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.mask; package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.minecraft.util.commands.Link; import com.sk89q.minecraft.util.commands.Link;
import com.sk89q.worldedit.command.UtilityCommands; import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -42,6 +43,8 @@ public interface Mask {
*/ */
boolean test(BlockVector3 vector); boolean test(BlockVector3 vector);
// boolean test(FilterBlock block);
/** /**
* Get the 2D version of this mask if one exists. * Get the 2D version of this mask if one exists.
* *

Datei anzeigen

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

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.minecraft.util.commands.Link; import com.sk89q.minecraft.util.commands.Link;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.UtilityCommands; import com.sk89q.worldedit.command.UtilityCommands;
@ -26,23 +27,12 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
/** /**
* Returns a {@link BlockStateHolder} for a given position. * Returns a {@link BlockStateHolder} for a given position.
*/ */
@Link(clazz = UtilityCommands.class, value = "patterns") @Link(clazz = UtilityCommands.class, value = "patterns")
public interface Pattern{ public interface Pattern {
// @Override
// default BaseBlock next(BlockVector3 position) {
// return new BaseBlock(apply(position));
// }
//
// @Override
// default BaseBlock next(int x, int y, int z) {
// return new BaseBlock(apply(BlockVector3.at(x, y, z)));
// }
/** /**
* Return a {@link BlockStateHolder} for the given position. * Return a {@link BlockStateHolder} for the given position.
@ -55,4 +45,10 @@ public interface Pattern{
default boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { default boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, apply(get)); return extent.setBlock(set, apply(get));
} }
// void apply(FilterBlock block);
default void apply(FilterBlock block) {
apply((BlockVector3) block).apply(block);
}
} }

Datei anzeigen

@ -1,23 +1,19 @@
package com.sk89q.worldedit.function.visitor; package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.example.MappedFaweQueue; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArraySet; import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue;
/** /**
* A chunk based search algorithm * A chunk based search algorithm
@ -58,15 +54,15 @@ public class ScanChunk {
private final RegionFunction function; private final RegionFunction function;
private final BlockVector3[] directions; private final BlockVector3[] directions;
private final Long2ObjectOpenHashMap<long[][]> visited; private final Long2ObjectOpenHashMap<long[][]> visits;
private final Long2ObjectOpenHashMap<char[]> queues; private final Long2ObjectOpenHashMap<char[][]> queues;
public ScanChunk(final RegionFunction function) { public ScanChunk(final RegionFunction function) {
this.function = function; this.function = function;
this.directions = DEFAULT_DIRECTIONS; this.directions = DEFAULT_DIRECTIONS;
this.queues = new Long2ObjectOpenHashMap<>(); this.queues = new Long2ObjectOpenHashMap<>();
this.visited = new Long2ObjectOpenHashMap<>(); this.visits = new Long2ObjectOpenHashMap<>();
} }
public static final long pairInt(int x, int y) { public static final long pairInt(int x, int y) {
@ -77,7 +73,7 @@ public class ScanChunk {
int X = x >> 4; int X = x >> 4;
int Z = z >> 4; int Z = z >> 4;
long pair = pairInt(X, Z); long pair = pairInt(X, Z);
long[][] chunk = visited.get(pair); long[][] chunk = visits.get(pair);
if (chunk == null) return false; if (chunk == null) return false;
int layer = y >> 4; int layer = y >> 4;
long[] section = chunk[layer]; long[] section = chunk[layer];
@ -87,7 +83,7 @@ public class ScanChunk {
public void start(int x, int y, int z) { public void start(int x, int y, int z) {
if (!isVisited(x, y, z)) { if (!isVisited(x, y, z)) {
queue(x, y, z); push(x, y, z);
visit(x, y, z); visit(x, y, z);
} }
} }
@ -96,45 +92,240 @@ public class ScanChunk {
int X = x >> 4; int X = x >> 4;
int Z = z >> 4; int Z = z >> 4;
long pair = pairInt(X, Z); long pair = pairInt(X, Z);
long[][] chunk = visited.get(pair); long[][] arrs = visits.get(pair);
if (chunk == null) { if (arrs == null) {
visited.put(pair, chunk = new long[16][]); visits.put(pair, arrs = new long[16][]);
} }
int layer = y >> 4; int layer = y >> 4;
long[] section = chunk[layer]; long[] section = arrs[layer];
if (section == null) { if (section == null) {
chunk[layer] = section = new long[64]; arrs[layer] = section = new long[64];
} }
set(section, getLocalIndex(x & 15, y & 15, z & 15)); set(section, getLocalIndex(x & 15, y & 15, z & 15));
} }
public void queue(int x, int y, int z) { 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 X = x >> 4;
int Z = z >> 4; int Z = z >> 4;
long pair = pairInt(X, Z); long pair = pairInt(X, Z);
char[] queue = queues.get(pair); int layer = y >> 4;
if (queue == null) { char[] section = getOrCreateQueue(pair, layer);
queue = queues.put(pair, queue = new char[MAX_QUEUE + 2]); push(section, x & 15, y & 15, z & 15);
queue[0] = 2; }
queue[1] = 2;
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;
} }
if (queue[1] >= queue.length) {
queue[1] = 2;
}
queue[queue[1]++] = getLocalIndex(x & 15, y, z & 15);
} }
public void process() { public void process() {
LongArraySet set = new LongArraySet(); LongArraySet set = new LongArraySet();
while (!queues.isEmpty()) { while (!queues.isEmpty()) {
ObjectIterator<Long2ObjectMap.Entry<char[]>> iter = queues.long2ObjectEntrySet().fastIterator(); // ObjectIterator<Long2ObjectMap.Entry<char[][]>> iter = queues.long2ObjectEntrySet().fastIterator();
Long2ObjectMap.Entry<char[]> entry = iter.next(); // Long2ObjectMap.Entry<char[][]> entry = iter.next();
long index = entry.getLongKey(); // long index = entry.getLongKey();
int X = MathMan.unpairIntX(index); // int X = MathMan.unpairIntX(index);
int Z = MathMan.unpairIntY(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) { public void set(long[] bits, int i) {
bits[i >> 6] |= (1L << (i & 0x3F)); bits[i >> 6] |= (1L << (i & 0x3F));
} }
@ -144,7 +335,7 @@ public class ScanChunk {
} }
public char getLocalIndex(int x, int y, int z) { public char getLocalIndex(int x, int y, int z) {
return (char) (y + (x << 8) + (z << 12)); return (char) (x + (z << 4) + (y << 8));
} }

Datei anzeigen

@ -29,58 +29,36 @@ import java.util.Comparator;
/** /**
* An immutable 3-dimensional vector. * An immutable 3-dimensional vector.
*/ */
public class BlockVector3 { public abstract class BlockVector3 {
public static final BlockVector3 ZERO = new BlockVector3(0, 0, 0); public static final BlockVector3 ZERO = new BlockVector3Imp(0, 0, 0);
public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0); public static final BlockVector3 UNIT_X = new BlockVector3Imp(1, 0, 0);
public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0); public static final BlockVector3 UNIT_Y = new BlockVector3Imp(0, 1, 0);
public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1); public static final BlockVector3 UNIT_Z = new BlockVector3Imp(0, 0, 1);
public static final BlockVector3 ONE = new BlockVector3(1, 1, 1); public static final BlockVector3 ONE = new BlockVector3Imp(1, 1, 1);
public static BlockVector3 at(double x, double y, double z) { public static BlockVector3 at(double x, double y, double z) {
return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z)); return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
} }
public static BlockVector3 at(int x, int y, int z) { public static BlockVector3 at(int x, int y, int z) {
return new BlockVector3(x, y, z); return new BlockVector3Imp(x, y, z);
} }
// thread-safe initialization idiom static final Comparator<BlockVector3> YZX_ORDER = (a, b) -> ComparisonChain.start()
private static final class YzxOrderComparator { .compare(a.getY(), b.getY())
private static final Comparator<BlockVector3> YZX_ORDER = (a, b) -> { .compare(a.getZ(), b.getZ())
return ComparisonChain.start() .compare(a.getX(), b.getX())
.compare(a.y, b.y) .result();
.compare(a.z, b.z)
.compare(a.x, b.x)
.result();
};
}
/** /**
* Returns a comparator that sorts vectors first by Y, then Z, then X. * Returns a comparator that sorts vectors first by Y, then Z, then X.
* *
* <p> * <p>
* Useful for sorting by chunk block storage order. * Useful for sorting by chunk block storage order.
*/ */
public static Comparator<BlockVector3> sortByCoordsYzx() { public static Comparator<BlockVector3> sortByCoordsYzx() {
return YzxOrderComparator.YZX_ORDER; return YZX_ORDER;
}
protected int x, y, z;
protected BlockVector3(){}
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
protected BlockVector3(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
} }
public MutableBlockVector3 setComponents(double x, double y, double z) { public MutableBlockVector3 setComponents(double x, double y, double z) {
@ -92,27 +70,27 @@ public class BlockVector3 {
} }
public MutableBlockVector3 mutX(double x) { public MutableBlockVector3 mutX(double x) {
return new MutableBlockVector3((int) x, y, z); return new MutableBlockVector3((int) x, getY(), getZ());
} }
public MutableBlockVector3 mutY(double y) { public MutableBlockVector3 mutY(double y) {
return new MutableBlockVector3(x, (int) y, z); return new MutableBlockVector3(getX(), (int) y, getZ());
} }
public MutableBlockVector3 mutZ(double z) { public MutableBlockVector3 mutZ(double z) {
return new MutableBlockVector3(x, y, (int) z); return new MutableBlockVector3(getX(), getY(), (int) z);
} }
public MutableBlockVector3 mutX(int x) { public MutableBlockVector3 mutX(int x) {
return new MutableBlockVector3(x, y, z); return new MutableBlockVector3(x, getY(), getZ());
} }
public MutableBlockVector3 mutY(int y) { public MutableBlockVector3 mutY(int y) {
return new MutableBlockVector3(x, y, z); return new MutableBlockVector3(getX(), y, getZ());
} }
public MutableBlockVector3 mutZ(int z) { public MutableBlockVector3 mutZ(int z) {
return new MutableBlockVector3(x, y, z); return new MutableBlockVector3(getX(), getY(), z);
} }
/** /**
@ -120,9 +98,7 @@ public class BlockVector3 {
* *
* @return the x coordinate * @return the x coordinate
*/ */
public int getX() { public abstract int getX();
return x;
}
/** /**
* Get the X coordinate. * Get the X coordinate.
@ -130,7 +106,7 @@ public class BlockVector3 {
* @return the x coordinate * @return the x coordinate
*/ */
public int getBlockX() { public int getBlockX() {
return x; return getX();
} }
/** /**
@ -140,7 +116,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 withX(int x) { public BlockVector3 withX(int x) {
return BlockVector3.at(x, y, z); return BlockVector3.at(x, getY(), getZ());
} }
/** /**
@ -148,9 +124,7 @@ public class BlockVector3 {
* *
* @return the y coordinate * @return the y coordinate
*/ */
public int getY() { public abstract int getY();
return y;
}
/** /**
* Get the Y coordinate. * Get the Y coordinate.
@ -158,7 +132,7 @@ public class BlockVector3 {
* @return the y coordinate * @return the y coordinate
*/ */
public int getBlockY() { public int getBlockY() {
return y; return getY();
} }
/** /**
@ -168,7 +142,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 withY(int y) { public BlockVector3 withY(int y) {
return BlockVector3.at(x, y, z); return BlockVector3.at(getX(), y, getZ());
} }
/** /**
@ -176,9 +150,7 @@ public class BlockVector3 {
* *
* @return the z coordinate * @return the z coordinate
*/ */
public int getZ() { public abstract int getZ();
return z;
}
/** /**
* Get the Z coordinate. * Get the Z coordinate.
@ -186,7 +158,7 @@ public class BlockVector3 {
* @return the z coordinate * @return the z coordinate
*/ */
public int getBlockZ() { public int getBlockZ() {
return z; return getZ();
} }
/** /**
@ -196,7 +168,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 withZ(int z) { public BlockVector3 withZ(int z) {
return BlockVector3.at(x, y, z); return BlockVector3.at(getX(), getY(), z);
} }
/** /**
@ -206,7 +178,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 add(BlockVector3 other) { public BlockVector3 add(BlockVector3 other) {
return add(other.x, other.y, other.z); return add(other.getX(), other.getY(), other.getZ());
} }
/** /**
@ -218,7 +190,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 add(int x, int y, int z) { public BlockVector3 add(int x, int y, int z) {
return BlockVector3.at(this.x + x, this.y + y, this.z + z); return BlockVector3.at(this.getX() + x, this.getY() + y, this.getZ() + z);
} }
/** /**
@ -229,12 +201,12 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 add(BlockVector3... others) { public BlockVector3 add(BlockVector3... others) {
int newX = x, newY = y, newZ = z; int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) { for (BlockVector3 other : others) {
newX += other.x; newX += other.getX();
newY += other.y; newY += other.getY();
newZ += other.z; newZ += other.getZ();
} }
return BlockVector3.at(newX, newY, newZ); return BlockVector3.at(newX, newY, newZ);
@ -248,7 +220,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 subtract(BlockVector3 other) { public BlockVector3 subtract(BlockVector3 other) {
return subtract(other.x, other.y, other.z); return subtract(other.getX(), other.getY(), other.getZ());
} }
/** /**
@ -261,7 +233,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 subtract(int x, int y, int z) { public BlockVector3 subtract(int x, int y, int z) {
return BlockVector3.at(this.x - x, this.y - y, this.z - z); return BlockVector3.at(this.getX() - x, this.getY() - y, this.getZ() - z);
} }
/** /**
@ -272,12 +244,12 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 subtract(BlockVector3... others) { public BlockVector3 subtract(BlockVector3... others) {
int newX = x, newY = y, newZ = z; int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) { for (BlockVector3 other : others) {
newX -= other.x; newX -= other.getX();
newY -= other.y; newY -= other.getY();
newZ -= other.z; newZ -= other.getZ();
} }
return BlockVector3.at(newX, newY, newZ); return BlockVector3.at(newX, newY, newZ);
@ -290,7 +262,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 multiply(BlockVector3 other) { public BlockVector3 multiply(BlockVector3 other) {
return multiply(other.x, other.y, other.z); return multiply(other.getX(), other.getY(), other.getZ());
} }
/** /**
@ -302,7 +274,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 multiply(int x, int y, int z) { public BlockVector3 multiply(int x, int y, int z) {
return BlockVector3.at(this.x * x, this.y * y, this.z * z); return BlockVector3.at(this.getX() * x, this.getY() * y, this.getZ() * z);
} }
/** /**
@ -312,12 +284,12 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 multiply(BlockVector3... others) { public BlockVector3 multiply(BlockVector3... others) {
int newX = x, newY = y, newZ = z; int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) { for (BlockVector3 other : others) {
newX *= other.x; newX *= other.getX();
newY *= other.y; newY *= other.getY();
newZ *= other.z; newZ *= other.getZ();
} }
return BlockVector3.at(newX, newY, newZ); return BlockVector3.at(newX, newY, newZ);
@ -340,7 +312,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 divide(BlockVector3 other) { public BlockVector3 divide(BlockVector3 other) {
return divide(other.x, other.y, other.z); return divide(other.getX(), other.getY(), other.getZ());
} }
/** /**
@ -352,7 +324,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 divide(int x, int y, int z) { public BlockVector3 divide(int x, int y, int z) {
return BlockVector3.at(this.x / x, this.y / y, this.z / z); return BlockVector3.at(this.getX() / x, this.getY() / y, this.getZ() / z);
} }
/** /**
@ -380,7 +352,7 @@ public class BlockVector3 {
* @return length, squared * @return length, squared
*/ */
public int lengthSq() { public int lengthSq() {
return x * x + y * y + z * z; return getX() * getX() + getY() * getY() + getZ() * getZ();
} }
/** /**
@ -400,9 +372,9 @@ public class BlockVector3 {
* @return distance * @return distance
*/ */
public int distanceSq(BlockVector3 other) { public int distanceSq(BlockVector3 other) {
int dx = other.x - x; int dx = other.getX() - getX();
int dy = other.y - y; int dy = other.getY() - getY();
int dz = other.z - z; int dz = other.getZ() - getZ();
return dx * dx + dy * dy + dz * dz; return dx * dx + dy * dy + dz * dz;
} }
@ -414,9 +386,9 @@ public class BlockVector3 {
*/ */
public BlockVector3 normalize() { public BlockVector3 normalize() {
double len = length(); double len = length();
double x = this.x / len; double x = this.getX() / len;
double y = this.y / len; double y = this.getY() / len;
double z = this.z / len; double z = this.getZ() / len;
return BlockVector3.at(x, y, z); return BlockVector3.at(x, y, z);
} }
@ -427,7 +399,7 @@ public class BlockVector3 {
* @return the dot product of this and the other vector * @return the dot product of this and the other vector
*/ */
public double dot(BlockVector3 other) { public double dot(BlockVector3 other) {
return x * other.x + y * other.y + z * other.z; return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
} }
/** /**
@ -437,10 +409,10 @@ public class BlockVector3 {
* @return the cross product of this and the other vector * @return the cross product of this and the other vector
*/ */
public BlockVector3 cross(BlockVector3 other) { public BlockVector3 cross(BlockVector3 other) {
return new BlockVector3( return new BlockVector3Imp(
y * other.z - z * other.y, getY() * other.getZ() - getZ() * other.getY(),
z * other.x - x * other.z, getZ() * other.getX() - getX() * other.getZ(),
x * other.y - y * other.x getX() * other.getY() - getY() * other.getX()
); );
} }
@ -452,7 +424,7 @@ public class BlockVector3 {
* @return true if the vector is contained * @return true if the vector is contained
*/ */
public boolean containedWithin(BlockVector3 min, BlockVector3 max) { public boolean containedWithin(BlockVector3 min, BlockVector3 max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z; return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max.getZ();
} }
/** /**
@ -464,11 +436,11 @@ public class BlockVector3 {
*/ */
public BlockVector3 clampY(int min, int max) { public BlockVector3 clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum"); checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) { if (getY() < min) {
return BlockVector3.at(x, min, z); return BlockVector3.at(getX(), min, getZ());
} }
if (y > max) { if (getY() > max) {
return BlockVector3.at(x, max, z); return BlockVector3.at(getX(), max, getZ());
} }
return this; return this;
} }
@ -512,7 +484,7 @@ public class BlockVector3 {
* @return a new vector * @return a new vector
*/ */
public BlockVector3 abs() { public BlockVector3 abs() {
return BlockVector3.at(Math.abs(x), Math.abs(y), Math.abs(z)); return BlockVector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ()));
} }
/** /**
@ -528,8 +500,8 @@ public class BlockVector3 {
*/ */
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) { public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle); angle = Math.toRadians(angle);
double x = this.x - aboutX; double x = this.getX() - aboutX;
double z = this.z - aboutZ; double z = this.getZ() - aboutZ;
double cos = Math.cos(angle); double cos = Math.cos(angle);
double sin = Math.sin(angle); double sin = Math.sin(angle);
double x2 = x * cos - z * sin; double x2 = x * cos - z * sin;
@ -537,7 +509,7 @@ public class BlockVector3 {
return BlockVector3.at( return BlockVector3.at(
x2 + aboutX + translateX, x2 + aboutX + translateX,
y, getY(),
z2 + aboutZ + translateZ z2 + aboutZ + translateZ
); );
} }
@ -583,10 +555,10 @@ public class BlockVector3 {
* @return minimum * @return minimum
*/ */
public BlockVector3 getMinimum(BlockVector3 v2) { public BlockVector3 getMinimum(BlockVector3 v2) {
return new BlockVector3( return new BlockVector3Imp(
Math.min(x, v2.x), Math.min(getX(), v2.getX()),
Math.min(y, v2.y), Math.min(getY(), v2.getY()),
Math.min(z, v2.z) Math.min(getZ(), v2.getZ())
); );
} }
@ -597,10 +569,10 @@ public class BlockVector3 {
* @return maximum * @return maximum
*/ */
public BlockVector3 getMaximum(BlockVector3 v2) { public BlockVector3 getMaximum(BlockVector3 v2) {
return new BlockVector3( return new BlockVector3Imp(
Math.max(x, v2.x), Math.max(getX(), v2.getX()),
Math.max(y, v2.y), Math.max(getY(), v2.getY()),
Math.max(z, v2.z) Math.max(getZ(), v2.getZ())
); );
} }
@ -610,31 +582,34 @@ public class BlockVector3 {
* @return a new {@link BlockVector2} * @return a new {@link BlockVector2}
*/ */
public BlockVector2 toBlockVector2() { public BlockVector2 toBlockVector2() {
return BlockVector2.at(x, z); return BlockVector2.at(getX(), getZ());
} }
public Vector3 toVector3() { public Vector3 toVector3() {
return Vector3.at(x, y, z); return Vector3.at(getX(), getY(), getZ());
} }
@Override @Override
public boolean equals(Object obj) { public final boolean equals(Object obj) {
if (!(obj instanceof BlockVector3)) { if (!(obj instanceof BlockVector3)) {
return false; return false;
} }
BlockVector3 other = (BlockVector3) obj; return equals((BlockVector3) obj);
return other.x == this.x && other.y == this.y && other.z == this.z; }
public final boolean equals(BlockVector3 other) {
return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ();
} }
@Override @Override
public int hashCode() { public int hashCode() {
return (x ^ (z << 12)) ^ (y << 24); return (getX() ^ (getZ() << 12)) ^ (getY() << 24);
} }
@Override @Override
public String toString() { public String toString() {
return "(" + x + ", " + y + ", " + z + ")"; return "(" + getX() + ", " + getY() + ", " + getZ() + ")";
} }
} }

Datei anzeigen

@ -0,0 +1,87 @@
/*
* 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 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 String toString() {
return "(" + getX() + ", " + getY() + ", " + getZ() + ")";
}
}

Datei anzeigen

@ -9,6 +9,14 @@ public class MutableBlockVector3 extends BlockVector3 {
} }
}; };
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) { public static MutableBlockVector3 get(int x, int y, int z) {
return MUTABLE_CACHE.get().setComponents(x, y, z); return MUTABLE_CACHE.get().setComponents(x, y, z);
} }
@ -16,15 +24,19 @@ public class MutableBlockVector3 extends BlockVector3 {
public MutableBlockVector3() {} public MutableBlockVector3() {}
public MutableBlockVector3(BlockVector3 other) { public MutableBlockVector3(BlockVector3 other) {
super(other.getX(), other.getY(), other.getZ()); this(other.getX(), other.getY(), other.getZ());
} }
public MutableBlockVector3 setComponents(BlockVector3 other) { public MutableBlockVector3 setComponents(BlockVector3 other) {
return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ()); return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ());
} }
private int x,y,z;
public MutableBlockVector3(int x, int y, int z) { public MutableBlockVector3(int x, int y, int z) {
super(x, y, z); this.x = x;
this.y = y;
this.z = z;
} }
@Override @Override
@ -35,6 +47,21 @@ public class MutableBlockVector3 extends BlockVector3 {
return this; return this;
} }
@Override
public final int getX() {
return x;
}
@Override
public final int getY() {
return y;
}
@Override
public final int getZ() {
return z;
}
@Override @Override
public MutableBlockVector3 mutX(double x) { public MutableBlockVector3 mutX(double x) {
this.x = (int) x; this.x = (int) x;

Datei anzeigen

@ -91,11 +91,6 @@ public abstract class AbstractWorld implements World {
return false; return false;
} }
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
@Override @Override
public boolean queueBlockBreakEffect(Platform server, BlockVector3 position, BlockType blockType, double priority) { public boolean queueBlockBreakEffect(Platform server, BlockVector3 position, BlockType blockType, double priority) {
if (taskId == -1) { if (taskId == -1) {

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.world.block; package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
@ -47,9 +48,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class BaseBlock implements BlockStateHolder<BaseBlock> { public class BaseBlock implements BlockStateHolder<BaseBlock> {
private final BlockState blockState; private final BlockState blockState;
private final CompoundTag nbtData;
@Nullable
protected CompoundTag nbtData;
@Deprecated @Deprecated
public BaseBlock() { public BaseBlock() {
@ -83,6 +82,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock> {
public BaseBlock(BlockState blockState) { public BaseBlock(BlockState blockState) {
this.blockState = blockState; this.blockState = blockState;
nbtData = null;
} }
/** /**
@ -157,7 +157,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock> {
@Override @Override
public void setNbtData(@Nullable CompoundTag nbtData) { public void setNbtData(@Nullable CompoundTag nbtData) {
this.nbtData = nbtData; throw new UnsupportedOperationException("Immutable");
} }
/** /**
@ -202,7 +202,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock> {
} }
@Override @Override
public int getOrdinal() { public final int getOrdinal() {
return blockState.getOrdinal(); return blockState.getOrdinal();
} }
@ -227,6 +227,10 @@ public class BaseBlock implements BlockStateHolder<BaseBlock> {
} }
} }
public BlockState toBlockState() {
return blockState;
}
@Override @Override
public int hashCode() { public int hashCode() {
return getOrdinal(); return getOrdinal();
@ -246,7 +250,12 @@ public class BaseBlock implements BlockStateHolder<BaseBlock> {
return extent.setBlock(set, this); return extent.setBlock(set, this);
} }
@Override @Override
public void apply(FilterBlock block) {
block.setFullBlock(this);
}
@Override
public boolean hasNbtData() { public boolean hasNbtData() {
return this.nbtData != null; return this.nbtData != null;
} }

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.world.block; package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.command.SuggestInputParseException; import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.object.string.MutableCharSequence; import com.boydti.fawe.object.string.MutableCharSequence;
import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.StringMan;
@ -62,7 +63,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
this.internalId = internalId; this.internalId = internalId;
this.ordinal = ordinal; this.ordinal = ordinal;
this.ordinalChar = (char) ordinal; this.ordinalChar = (char) ordinal;
this.emptyBaseBlock = new BaseBlock(this); this.emptyBaseBlock = new ImmutableBaseBlock(this);
} }
/** /**
@ -218,6 +219,11 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return extent.setBlock(set, this); return extent.setBlock(set, this);
} }
@Override
public final void apply(FilterBlock block) {
block.setOrdinal(ordinal);
}
@Override @Override
public BaseBlock apply(BlockVector3 position) { public BaseBlock apply(BlockVector3 position) {
return this.toBaseBlock(); return this.toBaseBlock();
@ -333,7 +339,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
} }
@Override @Override
public int getOrdinal() { public final int getOrdinal() {
return this.ordinal; return this.ordinal;
} }

Datei anzeigen

@ -21,6 +21,7 @@ package com.sk89q.worldedit.world.block;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -45,7 +46,7 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class BlockType implements FawePattern { public final class BlockType implements FawePattern {
private final String id; private final String id;
private final BlockTypes.Settings settings; private final BlockTypes.Settings settings;
@ -179,7 +180,7 @@ public class BlockType implements FawePattern {
* *
* @return The default state * @return The default state
*/ */
public BlockState getDefaultState() { public final BlockState getDefaultState() {
return this.settings.defaultState; return this.settings.defaultState;
} }
@ -306,6 +307,11 @@ public class BlockType implements FawePattern {
return this.getDefaultState().toBaseBlock(); return this.getDefaultState().toBaseBlock();
} }
@Override
public final void apply(FilterBlock block) {
block.setOrdinal(getDefaultState().getOrdinal());
}
public Mask toMask(Extent extent) { public Mask toMask(Extent extent) {
return new SingleBlockTypeMask(extent, this); return new SingleBlockTypeMask(extent, this);
} }

Datei anzeigen

@ -0,0 +1,28 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.jnbt.CompoundTag;
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 final void apply(FilterBlock block) {
block.setOrdinal(getOrdinal());
}
}