Make masks more stateless

This commit is contained in:
Jesse Boyd
2020-01-04 10:11:13 +00:00
parent 9efdd886c5
commit 88a95221a8
98 changed files with 617 additions and 468 deletions

View File

@ -16,11 +16,8 @@ public abstract class AbstractFilterBlock extends FilterBlock {
public abstract BaseBlock getFullBlock();
public abstract void setFullBlock(BaseBlock block);
public abstract BlockVector3 getPosition();
@Override
public Extent getExtent() {
return this;
}
public abstract Extent getExtent();
@Override
public int getX() {

View File

@ -19,9 +19,7 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock {
private final int yOffset;
private final int width, length;
private int x, z, index;
private char ordinal;
// TODO use in CFI
public ArrayFilterBlock(Extent extent, char[] blocks, byte[] heights, int width, int length,
int yOffset) {
super(extent);
@ -32,18 +30,16 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock {
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);
}
}
public void init(int x, int z, int index) {
this.x = x;
this.z = z;
this.index = index;
}
@Override
public int getOrdinal() {
return ordinal;
return blocks[index];
}
@Override
@ -53,7 +49,7 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock {
@Override
public BlockState getBlock() {
return BlockTypesCache.states[ordinal];
return BlockTypesCache.states[getOrdinal()];
}
@Override

View File

@ -32,4 +32,9 @@ public class ExtentFilterBlock extends AbstractFilterBlock {
public BlockVector3 getPosition() {
return pos;
}
@Override
public Extent getExtent() {
return extent;
}
}

View File

@ -0,0 +1,39 @@
package com.boydti.fawe.beta.implementation.filter.block;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import javax.annotation.Nullable;
public class MultiFilterBlock extends DelegateFilterBlock {
private final FilterBlock[] blocks;
private final int length;
public MultiFilterBlock(FilterBlock... blocks) {
super(blocks[0]);
this.blocks = blocks;
this.length = blocks.length;
}
@Override
public void setOrdinal(int ordinal) {
for (int i = 0; i < length; i++) blocks[i].setOrdinal(ordinal);
}
@Override
public void setBlock(BlockState state) {
for (int i = 0; i < length; i++) blocks[i].setBlock(state);
}
@Override
public void setFullBlock(BaseBlock block) {
for (int i = 0; i < length; i++) blocks[i].setFullBlock(block);
}
@Override
public void setNbtData(@Nullable CompoundTag nbtData) {
for (int i = 0; i < length; i++) blocks[i].setNbtData(nbtData);
}
}

View File

@ -1,32 +0,0 @@
package com.boydti.fawe.beta.implementation.filter.block;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
public class VectorSingleFilterBlock extends AbstractSingleFilterBlock {
private final BlockVector3 mutable;
public VectorSingleFilterBlock(BlockVector3 mutable) {
this.mutable = mutable;
}
public VectorSingleFilterBlock init(BaseBlock block) {
super.init(block);
return this;
}
@Override
public int getX() {
return mutable.getX();
}
@Override
public int getY() {
return mutable.getY();
}
@Override
public int getZ() {
return mutable.getZ();
}
}

View File

@ -456,7 +456,7 @@ public class CFICommands {
for (int typeId : tu.getValidBlockIds()) {
BlockType type = BlockTypes.get(typeId);
extent.init(0, 0, 0, type.getDefaultState().toBaseBlock());
if (mask.test(extent)) {
if (mask.test(extent, extent)) {
blocks.add(type);
}
}

View File

@ -1,6 +1,8 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.config.Caption;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.boydti.fawe.object.brush.visualization.VisualExtent;
import com.boydti.fawe.object.clipboard.ResizableClipboardBuilder;
@ -64,11 +66,11 @@ public class CopyPastaBrush implements Brush, ResettableTool {
}
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
final int minY = position.getBlockY();
mask = new AbstractDelegateMask(mask) {
mask = new DelegateExtentMask(editSession, mask) {
@Override
public boolean test(BlockVector3 vector) {
if (super.test(vector) && vector.getBlockY() >= minY) {
BaseBlock block = editSession.getFullBlock(vector);
public boolean test(Extent extent, BlockVector3 vector) {
if (super.test(extent, vector) && vector.getBlockY() >= minY) {
BaseBlock block = vector.getFullBlock(editSession);
if (!block.getBlockType().getMaterial().isAir()) {
builder.add(vector, BlockTypes.AIR.getDefaultState().toBaseBlock(), block);
return true;
@ -78,7 +80,7 @@ public class CopyPastaBrush implements Brush, ResettableTool {
}
};
// Add origin
mask.test(position);
mask.test(editSession, position);
RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction(), (int) size);
visitor.visit(position);
Operations.completeBlindly(visitor);

View File

@ -8,6 +8,7 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -86,11 +87,11 @@ public class ImageBrush implements Brush {
float pitch = loc.getPitch();
AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX((pitch - 90) % 360).inverse();
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
RecursiveVisitor visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
private final MutableVector3 mutable = new MutableVector3();
@Override
public boolean test(BlockVector3 vector) {
if (solid.test(vector)) {
public boolean test(Extent extent, BlockVector3 vector) {
if (solid.test(extent, vector)) {
int dx = vector.getBlockX() - cx;
int dy = vector.getBlockY() - cy;
int dz = vector.getBlockZ() - cz;

View File

@ -6,7 +6,10 @@ import com.boydti.fawe.object.mask.RadiusMask;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -34,34 +37,42 @@ public class LayerBrush implements Brush {
final AdjacentAnyMask adjacent = new AdjacentAnyMask(new BlockMask(editSession).add(BlockTypes.AIR, BlockTypes.CAVE_AIR, BlockTypes.VOID_AIR));
final SolidBlockMask solid = new SolidBlockMask(editSession);
final RadiusMask radius = new RadiusMask(0, (int) size);
visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), function -> true);
visitor = new RecursiveVisitor(new Mask() {
@Override
public boolean test(Extent extent, BlockVector3 vector) {
return solid.test(extent, vector) && radius.test(extent, vector) && adjacent.test(extent, vector);
}
}, function -> true);
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);
BlockVectorSet visited = visitor.getVisited();
visitor = new RecursiveVisitor(pos -> {
int depth = visitor.getDepth() + 1;
if (depth > 1) {
boolean found = false;
BlockState previous = layers[depth - 1];
BlockState previous2 = layers[depth - 2];
for (BlockVector3 dir : BreadthFirstSearch.DEFAULT_DIRECTIONS) {
mutable.setComponents(pos.getBlockX() + dir.getBlockX(), pos.getBlockY() + dir.getBlockY(), pos.getBlockZ() + dir.getBlockZ());
if (visitor.isVisited(mutable) && editSession.getBlock(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous) {
mutable.setComponents(pos.getBlockX() + dir.getBlockX() * 2, pos.getBlockY() + dir.getBlockY() * 2, pos.getBlockZ() + dir.getBlockZ() * 2);
if (visitor.isVisited(mutable) && editSession.getBlock(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous2) {
found = true;
break;
} else {
return false;
visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
@Override
public boolean test(Extent extent, BlockVector3 pos) {
int depth = visitor.getDepth() + 1;
if (depth > 1) {
boolean found = false;
BlockState previous = layers[depth - 1];
BlockState previous2 = layers[depth - 2];
for (BlockVector3 dir : BreadthFirstSearch.DEFAULT_DIRECTIONS) {
mutable.setComponents(pos.getBlockX() + dir.getBlockX(), pos.getBlockY() + dir.getBlockY(), pos.getBlockZ() + dir.getBlockZ());
if (visitor.isVisited(mutable) && editSession.getBlock(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous) {
mutable.setComponents(pos.getBlockX() + dir.getBlockX() * 2, pos.getBlockY() + dir.getBlockY() * 2, pos.getBlockZ() + dir.getBlockZ() * 2);
if (visitor.isVisited(mutable) && editSession.getBlock(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous2) {
found = true;
break;
} else {
return false;
}
}
}
if (!found) {
return false;
}
}
if (!found) {
return false;
}
return !adjacent.test(extent, pos);
}
return !adjacent.test(pos);
}, pos -> {
int depth = visitor.getDepth();
BlockStateHolder currentPattern = layers[depth];

View File

@ -6,6 +6,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.operation.Operations;
@ -27,6 +28,8 @@ public class RecurseBrush implements Brush {
Mask mask = editSession.getMask();
if (mask == null) {
mask = Masks.alwaysTrue();
} else {
mask = mask.withExtent(editSession);
}
final int radius = (int) size;
BlockStateHolder block = editSession.getBlock(position);
@ -42,7 +45,7 @@ public class RecurseBrush implements Brush {
@Override
public boolean isVisitable(BlockVector3 from, BlockVector3 to) {
int y = to.getBlockY();
return y < maxY && radMask.test(to) && super.isVisitable(from, to);
return y < maxY && radMask.test(editSession, to) && super.isVisitable(from, to);
}
};
visitor.visit(position);

View File

@ -8,7 +8,11 @@ import com.boydti.fawe.object.mask.SurfaceMask;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskUnion;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -50,7 +54,7 @@ public class ScatterBrush implements Brush {
final int distance = Math.min((int) size, this.distance);
RecursiveVisitor visitor = new RecursiveVisitor(vector -> radius.test(vector) && surface.test(vector), function -> true);
RecursiveVisitor visitor = new RecursiveVisitor(new MaskUnion(radius, surface).withExtent(editSession), function -> true);
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);
@ -87,11 +91,11 @@ public class ScatterBrush implements Brush {
}
public boolean canApply(EditSession editSession, BlockVector3 pos) {
return mask.test(pos);
return mask.test(editSession, pos);
}
public BlockVector3 getDirection(BlockVector3 pt) {
return surface.direction(pt);
public BlockVector3 getDirection(Extent extent, BlockVector3 pt) {
return surface.direction(extent, pt);
}
public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws MaxChangedBlocksException {

View File

@ -16,7 +16,7 @@ public class ScatterOverlayBrush extends ScatterBrush {
int x = pt.getBlockX();
int y = pt.getBlockY();
int z = pt.getBlockZ();
BlockVector3 dir = getDirection(pt);
BlockVector3 dir = getDirection(editSession, pt);
editSession.setBlock(x + dir.getBlockX(), y + dir.getBlockY(), z + dir.getBlockZ(), p);
}
}

View File

@ -76,7 +76,7 @@ public class ShatterBrush extends ScatterBrush {
int dSqr = (dx * dx) + (dy * dy) + (dz * dz);
if (dSqr <= radius2) {
BlockVector3 bv = mutable.setComponents(x2, y2, z2);
if (surfaceTest.test(bv) && finalMask.test(bv)) {
if (surfaceTest.test(editSession, bv) && finalMask.test(editSession, bv)) {
// (collision) If it's visited and part of another frontier, set the block
if (!placed.add(x2, y2, z2)) {
if (!frontierVisited.contains(x2, y2, z2)) {

View File

@ -5,6 +5,9 @@ import com.boydti.fawe.object.mask.SurfaceMask;
import com.boydti.fawe.object.pattern.BiomePattern;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
@ -40,14 +43,17 @@ public class SplatterBrush extends ScatterBrush {
final int size2 = (int) (size * size);
SurfaceMask surface = new SurfaceMask(editSession);
RecursiveVisitor visitor = new RecursiveVisitor(vector -> {
double dist = vector.distanceSq(position);
if (dist < size2 && !placed.contains(vector) && ThreadLocalRandom.current().nextInt(5) < 2
&& surface.test(vector)) {
placed.add(vector);
return true;
RecursiveVisitor visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
@Override
public boolean test(Extent extent, BlockVector3 vector) {
double dist = vector.distanceSq(position);
if (dist < size2 && !placed.contains(vector) && ThreadLocalRandom.current().nextInt(5) < 2
&& surface.test(extent, vector)) {
placed.add(vector);
return true;
}
return false;
}
return false;
}, vector -> editSession.setBlock(vector, finalPattern), recursion);
visitor.setMaxBranch(2);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.FaweCache;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.boydti.fawe.object.brush.visualization.VisualExtent;
import com.boydti.fawe.object.mask.IdMask;
@ -52,6 +53,7 @@ public class SplineBrush implements Brush, ResettableTool {
} else {
mask = new MaskIntersection(mask, new IdMask(editSession));
}
mask = mask.withExtent(editSession);
boolean visualization = editSession.getExtent() instanceof VisualExtent;
if (visualization && positionSets.isEmpty()) {
return;

View File

@ -5,7 +5,9 @@ import com.boydti.fawe.object.mask.AdjacentAnyMask;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
@ -61,10 +63,10 @@ public class StencilBrush extends HeightBrush {
AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX(pitch - 90).inverse();
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
RecursiveVisitor visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
private final MutableVector3 mutable = new MutableVector3();
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
if (solid.test(vector)) {
int dx = vector.getBlockX() - cx;
int dy = vector.getBlockY() - cy;

View File

@ -5,6 +5,8 @@ import com.boydti.fawe.object.mask.SurfaceMask;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.function.mask.MaskUnion;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -20,7 +22,7 @@ public class SurfaceSphereBrush implements Brush {
SurfaceMask surface = new SurfaceMask(editSession);
final SolidBlockMask solid = new SolidBlockMask(editSession);
final RadiusMask radius = new RadiusMask(0, (int) size);
RecursiveVisitor visitor = new RecursiveVisitor(vector -> surface.test(vector) && radius.test(vector), vector -> editSession.setBlock(vector, pattern));
RecursiveVisitor visitor = new RecursiveVisitor(new MaskUnion(surface, radius).withExtent(editSession), vector -> editSession.setBlock(vector, pattern));
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);

View File

@ -7,6 +7,10 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.filter.block.AbstractFilterBlock;
import com.boydti.fawe.beta.implementation.filter.block.ArrayFilterBlock;
import com.boydti.fawe.beta.implementation.filter.block.MultiFilterBlock;
import com.boydti.fawe.beta.implementation.filter.block.SingleFilterBlock;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.beta.implementation.blocks.FallbackChunkGet;
import com.boydti.fawe.jnbt.anvil.MCAChunk;
@ -34,6 +38,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
@ -54,6 +59,7 @@ import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -552,7 +558,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights[index] & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
int newHeight = table.average(x, z, index);
setLayerHeightRaw(index, newHeight);
}
@ -607,7 +613,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}
mutable.mutX(x);
mutable.mutY(y);
if (!mask.test(mutable)) {
if (!mask.test(this, mutable)) {
continue;
}
if (placed.containsRadius(x, z, distance)) {
@ -654,7 +660,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}
mutable.mutX(x);
mutable.mutY(y);
if (!mask.test(mutable)) {
if (!mask.test(this, mutable)) {
continue;
}
if (placed.containsRadius(x, z, distance)) {
@ -1066,7 +1072,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
if (mask != null) {
mutable.mutX(z);
mutable.mutY(heights.getByte(index) & 0xFF);
if (!mask.test(mutable)) continue;
if (!mask.test(this, mutable)) continue;
}
if (imgMask != null) {
int height = imgMask.getRGB(x, z) & 0xFF;
@ -1181,7 +1187,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
for (int x = 0; x < getWidth(); x++, index++) {
mutable.mutX(x);
mutable.mutY(heights.getByte(index) & 0xFF);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
int color = img.getRGB(x, z);
BlockType block = textureUtil.getNearestBlock(color);
if (block != null) {
@ -1254,7 +1260,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
biomes.setByte(index, biomeByte);
}
}
@ -1274,17 +1280,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}
overlay.record(() -> {
char[] overlayArr = overlay.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, overlay.get(), heights.get(), getWidth(), getLength(), 1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int height = img.getRGB(x, z) & 0xFF;
if (height == 255 || height > 0 && !white && ThreadLocalRandom.current()
.nextInt(256) <= height) {
mutable.mutX(x);
mutable.mutY(height);
overlayArr[index] = pattern.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
pattern.apply(this, filter, filter);
}
}
}
@ -1302,17 +1306,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
primitives.modifiedMain = true;
main.record(() -> {
char[] mainArr = main.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int height = img.getRGB(x, z) & 0xFF;
if (height == 255 || height > 0 && !white && ThreadLocalRandom.current()
.nextInt(256) <= height) {
mutable.mutX(x);
mutable.mutY(height);
mainArr[index] = pattern.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
pattern.apply(this, filter, filter);
}
}
}
@ -1328,17 +1330,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
floor.record(() -> {
char[] floorArr = floor.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int height = img.getRGB(x, z) & 0xFF;
if (height == 255 || height > 0 && !white && ThreadLocalRandom.current()
.nextInt(256) <= height) {
mutable.mutX(x);
mutable.mutY(height);
floorArr[index] = pattern.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
pattern.apply(this, filter, filter);
}
}
}
@ -1355,20 +1355,20 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
primitives.modifiedMain = true;
main.record(() -> floor.record(() -> {
char[] floorArr = floor.get();
char[] mainArr = main.get();
ArrayFilterBlock filterFloor = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 0);
ArrayFilterBlock filterMain = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int height = img.getRGB(x, z) & 0xFF;
if (height == 255 || height > 0 && !white && ThreadLocalRandom.current()
.nextInt(256) <= height) {
mutable.mutX(x);
mutable.mutY(height);
char combined = pattern.apply(mutable).getOrdinalChar();
mainArr[index] = combined;
floorArr[index] = combined;
filterFloor.init(x, z, index);
filterMain.init(x, z, index);
pattern.apply(this, filterFloor, filterFloor);
pattern.apply(this, filterMain, filterMain);
}
}
}
@ -1380,19 +1380,20 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
if (pattern instanceof BlockStateHolder) {
setOverlay(mask, ((BlockStateHolder) pattern).getOrdinalChar());
} else {
int index = 0;
if (overlay == null) overlay = new DifferentialArray<>(new char[getArea()]);
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
overlay.setInt(index, pattern.apply(mutable).getOrdinalChar());
overlay.record(() -> {
ArrayFilterBlock filter = new ArrayFilterBlock(this, overlay.get(), heights.get(), getWidth(), getLength(), 1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < getWidth(); x++, index++) {
filter.init(x, z, index);
if (mask.test(this, filter)) {
pattern.apply(this, filter, filter);
}
}
}
}
});
}
}
@ -1400,18 +1401,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
if (pattern instanceof BlockStateHolder) {
setFloor(mask, ((BlockStateHolder) pattern).getOrdinalChar());
} else {
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
floor.setInt(index, pattern.apply(mutable).getOrdinalChar());
floor.record(() -> {
ArrayFilterBlock filter = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 0);
int index = 0;
for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < getWidth(); x++, index++) {
filter.init(x, z, index);
if (mask.test(this, filter)) {
pattern.apply(this, filter, filter);
}
}
}
}
});
}
}
@ -1419,19 +1420,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
if (pattern instanceof BlockStateHolder) {
setMain(mask, ((BlockStateHolder) pattern).getOrdinalChar());
} else {
primitives.modifiedMain = true;
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
main.setInt(index, pattern.apply(mutable).getOrdinalChar());
main.record(() -> {
ArrayFilterBlock filter = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
primitives.modifiedMain = true;
int index = 0;
for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < getWidth(); x++, index++) {
if (mask.test(this, filter)) {
pattern.apply(this, filter, filter);
}
}
}
}
});
}
}
@ -1439,21 +1439,25 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
if (pattern instanceof BlockStateHolder) {
setColumn(mask, ((BlockStateHolder) pattern).getOrdinalChar());
} else {
primitives.modifiedMain = true;
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
int combined = pattern.apply(mutable).getOrdinalChar();
floor.setInt(index, combined);
main.setInt(index, combined);
floor.record(() -> main.record(() -> {
ArrayFilterBlock floorFilter = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 0);
ArrayFilterBlock mainFilter = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
primitives.modifiedMain = true;
int index = 0;
for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < getWidth(); x++, index++) {
floorFilter.init(x, z, index);
mainFilter.init(x, z, index);
if (mask.test(this, mainFilter)) {
pattern.apply(this, mainFilter, mainFilter);
}
if (mask.test(this, floorFilter)) {
pattern.apply(this, floorFilter, floorFilter);
}
}
}
}
}));
}
}
@ -1466,15 +1470,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
setFloor(((BlockStateHolder) value).getOrdinalChar());
} else {
floor.record(() -> {
char[] floorArr = floor.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 0);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
floorArr[index] = value.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
value.apply(this, filter, filter);
}
}
});
@ -1486,18 +1487,15 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
setColumn(((BlockStateHolder) value).getOrdinalChar());
} else {
main.record(() -> floor.record(() -> {
char[] floorArr = floor.get();
char[] mainArr = main.get();
ArrayFilterBlock floorFilter = new ArrayFilterBlock(this, floor.get(), heights.get(), getWidth(), getLength(), 0);
ArrayFilterBlock mainFilter = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
char combined = value.apply(mutable).getOrdinalChar();
mainArr[index] = combined;
floorArr[index] = combined;
floorFilter.init(x, z, index);
mainFilter.init(x, z, index);
value.apply(this, floorFilter, floorFilter);
value.apply(this, mainFilter, mainFilter);
}
}
}));
@ -1509,15 +1507,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
setMain(((BlockStateHolder) value).getOrdinalChar());
} else {
main.record(() -> {
char[] mainArr = main.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, main.get(), heights.get(), getWidth(), getLength(), -1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
mainArr[index] = value.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
value.apply(this, filter, filter);
}
}
});
@ -1530,15 +1525,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
setOverlay(((BlockStateHolder) value).getOrdinalChar());
} else {
overlay.record(() -> {
char[] overlayArr = overlay.get();
ArrayFilterBlock filter = new ArrayFilterBlock(this, overlay.get(), heights.get(), getWidth(), getLength(), 1);
int index = 0;
for (int z = 0; z < getLength(); z++) {
mutable.mutZ(z);
for (int x = 0; x < getWidth(); x++, index++) {
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
overlayArr[index] = value.apply(mutable).getOrdinalChar();
filter.init(x, z, index);
value.apply(this, filter, filter);
}
}
});
@ -1758,7 +1750,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
overlay.setInt(index, combined);
}
}
@ -1773,7 +1765,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
floor.setInt(index, combined);
}
}
@ -1789,7 +1781,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
main.setInt(index, combined);
}
}
@ -1805,7 +1797,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int y = heights.getByte(index) & 0xFF;
mutable.mutX(x);
mutable.mutY(y);
if (mask.test(mutable)) {
if (mask.test(this, mutable)) {
floor.setInt(index, combined);
main.setInt(index, combined);
}

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.beta.implementation.filter.block.AbstractFilterBlock;
import com.boydti.fawe.jnbt.streamer.IntValueReader;
import com.google.common.collect.ForwardingIterator;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.visitor.Order;
import com.sk89q.worldedit.math.BlockVector3;
@ -111,5 +112,10 @@ public abstract class LinearClipboard extends SimpleClipboard implements Clipboa
public BlockVector3 getPosition() {
return position;
}
@Override
public Extent getExtent() {
return LinearClipboard.this;
}
}
}

View File

@ -294,14 +294,14 @@ public final class DifferentialArray<T> implements DifferentialCollection<T> {
dataInts[index] = value;
}
// public void setChar(int index, char value) {
// changed = true;
// try {
// changesChars[index] += dataChars[index] - value;
// } catch (NullPointerException ignore) {
// changes = (T) (changesChars = new char[dataChars.length]);
// changesChars[index] += dataChars[index] - value;
// }
// dataChars[index] = value;
// }
public void setChar(int index, char value) {
changed = true;
try {
changesChars[index] += dataChars[index] - value;
} catch (NullPointerException ignore) {
changes = (T) (changesChars = new char[dataChars.length]);
changesChars[index] += dataChars[index] - value;
}
dataChars[index] = value;
}
}

View File

@ -11,8 +11,20 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
public class SourceMaskExtent extends TemporalExtent {
private Mask mask;
private Extent get;
private MutableBlockVector3 mutable = new MutableBlockVector3();
public SourceMaskExtent(Extent extent, Mask mask) {
this(extent, extent, mask);
}
public SourceMaskExtent(Extent get, Extent set, Mask mask) {
super(set);
checkNotNull(get);
checkNotNull(mask);
this.get = get;
this.mask = mask;
}
/**
* Get the mask.
@ -33,16 +45,10 @@ public class SourceMaskExtent extends TemporalExtent {
this.mask = mask;
}
public SourceMaskExtent(Extent extent, Mask mask) {
super(extent);
checkNotNull(mask);
this.mask = mask;
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
set(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block);
return mask.test(location) && super.setBlock(location, block);
return mask.test(get, location) && super.setBlock(location, block);
}
@Override
@ -51,6 +57,6 @@ public class SourceMaskExtent extends TemporalExtent {
mutable.mutX(x);
mutable.mutY(y);
mutable.mutZ(z);
return mask.test(mutable) && super.setBlock(x, y, z, block);
return mask.test(get, mutable) && super.setBlock(x, y, z, block);
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.function.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Mask2D;
@ -24,9 +25,20 @@ public class AbstractDelegateMask extends AbstractMask {
return mask.test(vector);
}
@Override
public boolean test(Extent extent, BlockVector3 pos) {
return mask.test(extent, pos);
}
@Nullable
@Override
public Mask2D toMask2D() {
return mask.toMask2D();
}
@Override
public Mask withExtent(Extent extent) {
mask.withExtent(extent);
return this;
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
@ -11,7 +12,7 @@ import com.sk89q.worldedit.math.MutableBlockVector3;
public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
private final CachedMask mask;
private transient MutableBlockVector3 mutable = new MutableBlockVector3();
private final MutableBlockVector3 mutable;
public AdjacentAnyMask(Mask mask) {
this.mask = CachedMask.cache(mask);
@ -20,7 +21,7 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
@Override
public void reset() {
mutable = new MutableBlockVector3();
mutable.setComponents(0, 0, 0);
}
public CachedMask getParentMask() {
@ -28,53 +29,28 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 v) {
int x = v.getBlockX();
int y = v.getBlockY();
int z = v.getBlockZ();
if (mask.test(x + 1, y, z)) {
return true;
}
if (mask.test(x - 1, y, z)) {
return true;
}
if (mask.test(x, y, z + 1)) {
return true;
}
if (mask.test(x, y, z - 1)) {
return true;
}
if (y < 256 && mask.test(x, y + 1, z)) {
return true;
}
if (y > 0 && mask.test(x, y - 1, z)) {
return true;
}
return false;
public boolean test(Extent extent, BlockVector3 v) {
return direction(extent, v) != null;
}
public BlockVector3 direction(BlockVector3 v) {
public BlockVector3 direction(Extent extent, BlockVector3 v) {
int x = v.getBlockX();
int y = v.getBlockY();
int z = v.getBlockZ();
if (mask.test(x + 1, y, z)) {
mutable.setComponents(1, 0, 0);
}else
if (mask.test(x - 1, y, z)) {
mutable.setComponents(-1, 0, 0);
}else
if (mask.test(x, y, z + 1)) {
mutable.setComponents(0, 0, 1);
}else
if (mask.test(x, y, z - 1)) {
mutable.setComponents(0, 0, -1);
}else
if (y < 256 && mask.test(x, y + 1, z)) {
mutable.setComponents(0, 1, 0);
}else
if (y > 0 && mask.test(x, y - 1, z)) {
mutable.setComponents(0, -1, 0);
if (mask.test(extent, x + 1, y, z)) {
return mutable.setComponents(1, 0, 0);
}else if (mask.test(extent, x - 1, y, z)) {
return mutable.setComponents(-1, 0, 0);
}else if (mask.test(extent, x, y, z + 1)) {
return mutable.setComponents(0, 0, 1);
}else if (mask.test(extent, x, y, z - 1)) {
return mutable.setComponents(0, 0, -1);
}else if (y < 256 && mask.test(extent, x, y + 1, z)) {
return mutable.setComponents(0, 1, 0);
}else if (y > 0 && mask.test(extent, x, y - 1, z)) {
return mutable.setComponents(0, -1, 0);
} else {
return null;
}
return (mutable.getX() == 0 && mutable.getY() == 0 && mutable.getZ() == 0) ? null : mutable;
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
@ -18,41 +19,41 @@ public class AdjacentMask extends AbstractMask {
}
@Override
public boolean test(BlockVector3 bv) {
public boolean test(Extent extent, BlockVector3 bv) {
v.setComponents(bv);
int count = 0;
double x = bv.getX();
double y = bv.getY();
double z = bv.getZ();
v.mutX(x + 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutX(x);
return true;
}
v.mutX(x - 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutX(x);
return true;
}
v.mutX(x);
v.mutY(y + 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutY(y);
return true;
}
v.mutY(y - 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutY(y);
return true;
}
v.mutY(y);
v.mutZ(z + 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutZ(z);
return true;
}
v.mutZ(z - 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutZ(z);
return true;
}

View File

@ -58,8 +58,8 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
protected transient boolean foundY;
protected transient boolean lastValue;
public int getHeight(int x, int y, int z) {
// return getExtent().getNearestSurfaceTerrainBlock(x, z, y, 0, maxY);
public int getHeight(Extent extent, int x, int y, int z) {
// return extent.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY);
try {
int rx = x - cacheBotX + 16;
int rz = z - cacheBotZ + 16;
@ -80,7 +80,7 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
}
int result = cacheHeights[index] & 0xFF;
if (y > result) {
cacheHeights[index] = (byte) (result = lastY = getExtent().getNearestSurfaceTerrainBlock(x, z, lastY, 0, maxY));
cacheHeights[index] = (byte) (result = lastY = extent.getNearestSurfaceTerrainBlock(x, z, lastY, 0, maxY));
}
return result;
} catch (Throwable e) {
@ -89,72 +89,72 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
}
}
protected boolean testSlope(int x, int y, int z) {
protected boolean testSlope(Extent extent, int x, int y, int z) {
double slope;
boolean aboveMin;
lastY = y;
slope = Math.abs(getHeight(x + distance, y, z) - getHeight(x -distance, y, z)) * ADJACENT_MOD;
slope = Math.abs(getHeight(extent, x + distance, y, z) - getHeight(extent, x -distance, y, z)) * ADJACENT_MOD;
if (checkFirst) {
if (slope >= min) {
return lastValue = true;
}
slope = Math.max(slope, Math.abs(getHeight(x, y, z + distance) - getHeight(x, y, z - distance)) * ADJACENT_MOD);
slope = Math.max(slope, Math.abs(getHeight(x + distance, y, z + distance) - getHeight(x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(x - distance, y, z + distance) - getHeight(x + distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance)) * ADJACENT_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x + distance, y, z + distance) - getHeight(extent, x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x - distance, y, z + distance) - getHeight(extent, x + distance, y, z - distance)) * DIAGONAL_MOD);
return lastValue = (slope >= min);
} else {
slope = Math.max(slope, Math.abs(getHeight(x, y, z + distance) - getHeight(x, y, z - distance)) * ADJACENT_MOD);
slope = Math.max(slope, Math.abs(getHeight(x + distance, y, z + distance) - getHeight(x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(x - distance, y, z + distance) - getHeight(x + distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance)) * ADJACENT_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x + distance, y, z + distance) - getHeight(extent, x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(getHeight(extent, x - distance, y, z + distance) - getHeight(extent, x + distance, y, z - distance)) * DIAGONAL_MOD);
return lastValue = (slope >= min && slope <= max);
}
}
public boolean adjacentAir(BlockVector3 v) {
public boolean adjacentAir(Extent extent, BlockVector3 v) {
int x = v.getBlockX();
int y = v.getBlockY();
int z = v.getBlockZ();
if (!mask.test(x + 1, y, z)) {
if (!mask.test(extent, x + 1, y, z)) {
return true;
}
if (!mask.test(x - 1, y, z)) {
if (!mask.test(extent, x - 1, y, z)) {
return true;
}
if (!mask.test(x, y, z + 1)) {
if (!mask.test(extent, x, y, z + 1)) {
return true;
}
if (!mask.test(x, y, z - 1)) {
if (!mask.test(extent, x, y, z - 1)) {
return true;
}
if (y < 255 && !mask.test(x, y + 1, z)) {
if (y < 255 && !mask.test(extent, x, y + 1, z)) {
return true;
}
if (y > 0 && !mask.test(x, y - 1, z)) {
if (y > 0 && !mask.test(extent, x, y - 1, z)) {
return true;
}
return false;
}
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
int x = vector.getBlockX();
int y = vector.getBlockY();
int z = vector.getBlockZ();
if ((lastX == (lastX = x) & lastZ == (lastZ = z))) {
int height = getHeight(x, y, z);
int height = getHeight(extent, x, y, z);
if (y <= height) return overlay ? (lastValue && y == height) : lastValue;
}
if (!mask.test(x, y, z)) {
if (!mask.test(extent, x, y, z)) {
return false;
}
if (overlay) {
if (y < 255 && !mask.test(x, y + 1, z)) return lastValue = false;
} else if (!adjacentAir(vector)) {
if (y < 255 && !mask.test(extent, x, y + 1, z)) return lastValue = false;
} else if (!adjacentAir(extent, vector)) {
return false;
}
return testSlope(x, y, z);
return testSlope(extent, x, y, z);
}
}

View File

@ -22,8 +22,8 @@ public class BiomeMask extends AbstractExtentMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
BlockVector2 pos = mutable.setComponents(vector.getBlockX(), vector.getBlockZ());
return getExtent().getBiome(pos).getId() == biome.getId();
return extent.getBiome(pos).getId() == biome.getId();
}
}

View File

@ -16,8 +16,7 @@ public class BlockLightMask extends AbstractExtentMask {
}
@Override
public boolean test(BlockVector3 vector) {
Extent extent = getExtent();
public boolean test(Extent extent, BlockVector3 vector) {
if (extent instanceof LightingExtent) {
int light = ((LightingExtent) extent).getBlockLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
return light >= min && light <= max;

View File

@ -16,8 +16,7 @@ public class BrightnessMask extends AbstractExtentMask {
}
@Override
public boolean test(BlockVector3 vector) {
Extent extent = getExtent();
public boolean test(Extent extent, BlockVector3 vector) {
if (extent instanceof LightingExtent) {
int light = ((LightingExtent) extent).getBrightness(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
return light >= min && light <= max;

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.object.mask;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
@ -41,21 +42,21 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
return test(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
public boolean test(Extent extent, BlockVector3 vector) {
return test(extent, vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
}
public boolean test(int x, int y, int z) {
public boolean test(Extent extent, int x, int y, int z) {
try {
boolean check = cache_checked.add(x, y, z);
if (!check) {
return cache_results.contains(x, y, z);
}
boolean result = getMask().test(mutable.setComponents(x, y, z));
boolean result = getMask().test(extent, mutable.setComponents(x, y, z));
if (result) cache_results.add(x, y, z);
return result;
} catch (UnsupportedOperationException ignore) {
boolean result = getMask().test(mutable.setComponents(x, y, z));
boolean result = getMask().test(extent, mutable.setComponents(x, y, z));
if (y < 0 || y > 255) return result;
resetCache();
cache_checked.setOffset(x, z);

View File

@ -13,8 +13,7 @@ public class DataMask extends AbstractExtentMask implements ResettableMask {
private transient int data = -1;
@Override
public boolean test(BlockVector3 vector) {
Extent extent = getExtent();
public boolean test(Extent extent, BlockVector3 vector) {
if (data != -1) {
return extent.getBlock(vector).getInternalPropertiesId() == data;
} else {

View File

@ -8,28 +8,28 @@ public class ExtremaMask extends AngleMask {
}
@Override
protected boolean testSlope(int x, int y, int z) {
protected boolean testSlope(Extent extent, int x, int y, int z) {
double slope, tmp;
boolean aboveMin;
lastY = y;
int base = getHeight(x, y, z);
int base = getHeight(extent, x, y, z);
slope = get(base, x, y, z, 1, 0, distance) * ADJACENT_MOD;
slope = getHeight(extent, base, x, y, z, 1, 0, distance) * ADJACENT_MOD;
tmp = get(base, x, y, z, 0, 1, distance) * ADJACENT_MOD;
tmp = getHeight(extent, base, x, y, z, 0, 1, distance) * ADJACENT_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = get(base, x, y, z, 1, 1, distance) * DIAGONAL_MOD;
tmp = getHeight(extent, base, x, y, z, 1, 1, distance) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = get(base, x, y, z, 1, -1, distance) * DIAGONAL_MOD;
tmp = getHeight(extent, base, x, y, z, 1, -1, distance) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
return lastValue = (slope > min && slope < max);
}
private int get(int base, int x, int y, int z, int OX, int OZ, int iterations) {
private int getHeight(Extent extent, int base, int x, int y, int z, int OX, int OZ, int iterations) {
int sign = 0;
int lastHeight1 = base;
int lastHeight2 = base;
@ -40,8 +40,8 @@ public class ExtremaMask extends AngleMask {
int z1 = z + coz;
int x2 = x - cox;
int z2 = z - coz;
int height1 = getHeight(x1, y, z1);
int height2 = getHeight(x2, y, z2);
int height1 = getHeight(extent, x1, y, z1);
int height2 = getHeight(extent, x2, y, z2);
int diff1 = height1 - lastHeight1;
int diff2 = height2 - lastHeight2;
int sign1 = Integer.signum(diff1);

View File

@ -12,8 +12,7 @@ public class IdDataMask extends AbstractExtentMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
Extent extent = getExtent();
public boolean test(Extent extent, BlockVector3 vector) {
if (combined != -1) {
return extent.getBlock(vector).getInternalId() == combined;
} else {

View File

@ -13,8 +13,7 @@ public class IdMask extends AbstractExtentMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
Extent extent = getExtent();
public boolean test(Extent extent, BlockVector3 vector) {
if (id != -1) {
return extent.getBlock(vector).getInternalBlockTypeId() == id;
} else {

View File

@ -16,9 +16,9 @@ public class LightMask extends AbstractExtentMask {
}
@Override
public boolean test(BlockVector3 vector) {
if (getExtent() instanceof LightingExtent) {
int light = ((LightingExtent) getExtent()).getLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
public boolean test(Extent extent, BlockVector3 vector) {
if (extent instanceof LightingExtent) {
int light = ((LightingExtent) extent).getLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
return light >= min && light <= max;
}
return false;

View File

@ -21,7 +21,7 @@ public class MaskedTargetBlock extends TargetBlock {
Location lastBlock = null;
while (getNextBlock() != null) {
Location current = getCurrentBlock();
if (!mask.test(current.toBlockPoint())) {
if (!mask.test(world, current.toBlockPoint())) {
if (searchForLastBlock) {
lastBlock = current;
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) {

View File

@ -16,9 +16,9 @@ public class OpacityMask extends AbstractExtentMask {
}
@Override
public boolean test(BlockVector3 vector) {
if (getExtent() instanceof LightingExtent) {
int light = ((LightingExtent) getExtent()).getOpacity(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
public boolean test(Extent extent, BlockVector3 vector) {
if (extent instanceof LightingExtent) {
int light = ((LightingExtent) extent).getOpacity(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
return light >= min && light <= max;
}
return false;

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -12,7 +13,7 @@ public class PlaneMask extends AbstractMask implements ResettableMask {
private transient int originX = Integer.MAX_VALUE, originY = Integer.MAX_VALUE, originZ = Integer.MAX_VALUE;
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
switch (mode) {
case -1:
originX = vector.getBlockX();

View File

@ -9,23 +9,23 @@ public class ROCAngleMask extends AngleMask {
}
@Override
protected boolean testSlope(int x, int y, int z) {
protected boolean testSlope(Extent extent, int x, int y, int z) {
double tmp;
lastY = y;
int base = getHeight(x, y, z);
int base = getHeight(extent, x, y, z);
double slope =
(getHeight(x + distance, y, z) - base - (base - getHeight(x - distance, y, z)))
(getHeight(extent, x + distance, y, z) - base - (base - getHeight(extent, x - distance, y, z)))
* ADJACENT_MOD;
tmp = (getHeight(x, y, z + distance) - base - (base - getHeight(x, y, z - distance))) * ADJACENT_MOD;
tmp = (getHeight(extent, x, y, z + distance) - base - (base - getHeight(extent, x, y, z - distance))) * ADJACENT_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = (getHeight(x + distance, y, z + distance) - base - (base - getHeight(x - distance, y,
tmp = (getHeight(extent, x + distance, y, z + distance) - base - (base - getHeight(extent, x - distance, y,
z - distance))) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = (getHeight(x - distance, y, z + distance) - base - (base - getHeight(x + distance, y,
tmp = (getHeight(extent, x - distance, y, z + distance) - base - (base - getHeight(extent, x + distance, y,
z - distance))) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -19,7 +20,7 @@ public class RadiusMask extends AbstractMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 to) {
public boolean test(Extent extent, BlockVector3 to) {
if (pos == null) {
pos = to.toImmutable();
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
import java.util.SplittableRandom;
@ -14,7 +15,7 @@ public class RandomMask extends AbstractMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
return random.nextInt() <= threshold;
}

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.object.mask;
import com.boydti.fawe.object.random.SimplexNoise;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -14,7 +15,7 @@ public class SimplexMask extends AbstractMask {
}
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
double value = SimplexNoise.noise(vector.getBlockX() * scale, vector.getBlockY() * scale, vector.getBlockZ() * scale);
return value >= min && value <= max;
}

View File

@ -17,9 +17,9 @@ public class SkyLightMask extends AbstractExtentMask {
}
@Override
public boolean test(BlockVector3 vector) {
if (getExtent() instanceof LightingExtent) {
int light = ((LightingExtent) getExtent())
public boolean test(Extent extent, BlockVector3 vector) {
if (extent instanceof LightingExtent) {
int light = ((LightingExtent) extent)
.getSkyLight(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
return light >= min && light <= max;
}

View File

@ -20,7 +20,7 @@ public class SolidPlaneMask extends SolidBlockMask implements ResettableMask {
}
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
switch (mode) {
case -1:
if (!super.test(vector)) {
@ -30,7 +30,6 @@ public class SolidPlaneMask extends SolidBlockMask implements ResettableMask {
originY = vector.getBlockY();
originZ = vector.getBlockZ();
mode = 0;
Extent extent = getExtent();
if (!extent.getBlock(mutable.setComponents(originX - 1, originY, originZ)).getMaterial().isAir() && !extent.getBlock(mutable.setComponents(originX + 1, originY, originZ)).getMaterial().isAir()) {
mode &= 1;
}

View File

@ -19,7 +19,7 @@ public class SurfaceMask extends AdjacentAnyMask {
}
@Override
public boolean test(BlockVector3 v) {
return !getParentMask().test(v.getBlockX(), v.getBlockY(), v.getBlockZ()) && super.test(v);
public boolean test(Extent extent, BlockVector3 v) {
return !getParentMask().test(extent, v.getBlockX(), v.getBlockY(), v.getBlockZ()) && super.test(extent, v);
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
@ -18,30 +19,30 @@ public class WallMask extends AbstractMask {
}
@Override
public boolean test(BlockVector3 bv) {
public boolean test(Extent extent, BlockVector3 bv) {
v.setComponents(bv);
int count = 0;
double x = v.getX();
double y = v.getY();
double z = v.getZ();
v.mutX(x + 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutX(x);
return true;
}
v.mutX(x - 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutX(x);
return true;
}
v.mutX(x);
v.mutZ(z + 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutZ(z);
return true;
}
v.mutZ(z - 1);
if (mask.test(v) && ++count == min && max >= 8) {
if (mask.test(extent, v) && ++count == min && max >= 8) {
v.mutZ(z);
return true;
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -11,7 +12,7 @@ public class XAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {
layer = vector.getBlockX();
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -11,7 +12,7 @@ public class YAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {
layer = vector.getBlockY();
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.math.BlockVector3;
@ -11,7 +12,7 @@ public class ZAxisMask extends AbstractMask implements ResettableMask {
private transient int layer = -1;
@Override
public boolean test(BlockVector3 vector) {
public boolean test(Extent extent, BlockVector3 vector) {
if (layer == -1) {
layer = vector.getBlockZ();
}

View File

@ -20,7 +20,6 @@ public class MaskedPattern extends AbstractPattern {
this.secondary = secondary;
}
@Override
public BaseBlock apply(BlockVector3 position) {
if (mask.test(position)) {
@ -31,7 +30,7 @@ public class MaskedPattern extends AbstractPattern {
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
if (mask.test(get)) {
if (mask.test(extent, get)) {
return primary.apply(extent, get, set);
}
return secondary.apply(extent, get, set);

View File

@ -5,6 +5,8 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.DelegateExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
@ -42,7 +44,7 @@ public class FuzzyRegion extends AbstractRegion {
}
public void select(int x, int y, int z) {
RecursiveVisitor search = new RecursiveVisitor(mask, new RegionFunction() {
RecursiveVisitor search = new RecursiveVisitor(mask.withExtent(extent), new RegionFunction() {
@Override
public boolean apply(BlockVector3 p) throws WorldEditException {
setMinMax(p.getBlockX(), p.getBlockY(), p.getBlockZ());

View File

@ -375,7 +375,7 @@ public class TextureUtil implements TextureHolder {
for (int typeId : tu.getValidBlockIds()) {
BlockType block = BlockTypes.get(typeId);
extent.init(0, 0, 0, block.getDefaultState().toBaseBlock());
if (mask.test(extent)) {
if (mask.test(extent, extent)) {
blocks.add(block);
}
}