Biome pattern! #biome:<biome> (possibly buggy)

This commit is contained in:
Jesse Boyd 2017-03-12 02:38:56 +11:00
parent 71fab26845
commit 8c4ed29edb
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
33 changed files with 821 additions and 184 deletions

View File

@ -51,6 +51,7 @@ import com.sk89q.worldedit.command.WorldEditCommands;
import com.sk89q.worldedit.command.composition.SelectionCommand;
import com.sk89q.worldedit.command.tool.AreaPickaxe;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.FloodFillTool;
import com.sk89q.worldedit.command.tool.LongRangeBuildTool;
import com.sk89q.worldedit.command.tool.RecursivePickaxe;
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
@ -70,6 +71,8 @@ import com.sk89q.worldedit.extent.clipboard.io.SchematicReader;
import com.sk89q.worldedit.extent.clipboard.io.SchematicWriter;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.FuzzyBlockMask;
@ -101,6 +104,7 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
import com.sk89q.worldedit.session.PasteBuilder;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.session.request.Request;
@ -110,7 +114,6 @@ import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
@ -408,6 +411,7 @@ public class Fawe {
ClipboardFormat.inject(); // Optimizations + new formats + api
PasteBuilder.inject(); // Optimizations
// Brushes/Tools
FloodFillTool.inject();
GravityBrush.inject(); // Fix for instant placement assumption
LongRangeBuildTool.inject();
AreaPickaxe.inject(); // Fixes
@ -449,7 +453,9 @@ public class Fawe {
// Block
BaseBlock.inject(); // Optimizations
// Pattern
ArbitraryShape.inject(); // Optimizations + update from legacy code
Pattern.inject(); // Simplify API
com.sk89q.worldedit.patterns.Pattern.inject(); // Simplify API
Patterns.inject(); // Optimizations (reduce object creation)
RandomPattern.inject(); // Optimizations
ClipboardPattern.inject(); // Optimizations
@ -467,6 +473,8 @@ public class Fawe {
MaskUnion.inject(); // Optimizations
// Operations
Operations.inject(); // Optimizations
ExtentBlockCopy.inject(); // Optimizations
BlockReplace.inject(); // Optimizations + Features
ForwardExtentCopy.inject(); // Fixes + optimizations
ChangeSetExecutor.inject(); // Optimizations
// BlockData

View File

@ -5,7 +5,6 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
public class LineBrush implements Brush, ResettableTool {
@ -24,7 +23,7 @@ public class LineBrush implements Brush, ResettableTool {
pos1 = position;
return;
}
editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat);
editSession.drawLine(pattern, pos1, position, size, !shell, flat);
if (!select) {
pos1 = null;
return;

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.object.brush;
import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.mask.AdjacentAnyMask;
import com.boydti.fawe.object.pattern.BiomePattern;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
@ -31,7 +32,13 @@ public class SplatterBrush extends ScatterBrush {
public void apply(final EditSession editSession, final LocalBlockVectorSet placed, final Vector position, Pattern p, double size) throws MaxChangedBlocksException {
final Pattern finalPattern;
if (solid) {
finalPattern = new BlockPattern(p.apply(position));
Pattern tmp;
try {
tmp = new BlockPattern(p.apply(position));
} catch (BiomePattern.BiomePatternException ignore) {
tmp = ignore.getPattern();
}
finalPattern = tmp;
} else {
finalPattern = p;
}

View File

@ -17,7 +17,6 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.transform.AffineTransform;
import java.util.ArrayList;
@ -140,7 +139,7 @@ public class SplineBrush implements Brush {
int index = (int) (i * listSize / (double) (numSplines));
currentSpline.add(points.get(index));
}
editSession.drawSpline(Patterns.wrap(pattern), currentSpline, 0, 0, 0, 10, 0, true);
editSession.drawSpline(pattern, currentSpline, 0, 0, 0, 10, 0, true);
}
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s());
if (visualization) {

View File

@ -16,6 +16,6 @@ public class PatternTransform extends ResettableExtent {
@Override
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
return super.setBlock(location, pattern.apply(location));
return pattern.apply(getExtent(), location);
}
}

View File

@ -0,0 +1,49 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.biome.BaseBiome;
public class BiomePattern extends ExistingPattern {
private final BaseBiome biome;
private BiomePatternException exception;
public BiomePattern(Extent extent, BaseBiome biome) {
super(extent);
this.biome = biome;
this.exception = new BiomePatternException();
}
@Override
public BaseBlock apply(Vector position) {
throw exception;
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
return extent.setBiome(new Vector2D(position.getBlockX(), position.getBlockZ()), biome);
}
public class BiomePatternException extends RuntimeException {
public BiomePatternException() {
super("Haha, you failed Empire92! Should've done things properly instead of some hacky AF biome pattern.\nHey, you! The one reading this stacktrace, can you do me a favor and report this on GitHub so I can get around to fixing it?");
}
public BiomePattern getPattern() {
return BiomePattern.this;
}
public BaseBiome getBiome() {
return biome;
}
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
}

View File

@ -1,7 +1,9 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import java.util.Arrays;
@ -25,4 +27,13 @@ public class Linear3DBlockPattern extends AbstractPattern {
}
return patternsArray[index].apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
int index = (position.getBlockX() + position.getBlockY() + position.getBlockZ()) % patternsArray.length;
if (index < 0) {
index += patternsArray.length;
}
return patternsArray[index].apply(extent, position);
}
}

View File

@ -1,7 +1,9 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import java.util.Arrays;
@ -26,6 +28,14 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat
return patternsArray[index++].apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
if (index == patternsArray.length) {
index = 0;
}
return patternsArray[index++].apply(extent, position);
}
@Override
public void reset() {
index = 0;

View File

@ -1,7 +1,9 @@
package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -31,4 +33,13 @@ public class MaskedPattern extends AbstractPattern {
}
return secondaryPattern.apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
patternExtent.setTarget(position);
if (mask.test(position)) {
return patternExtent.getAndResetTarget(extent, position);
}
return secondaryPattern.apply(extent, position);
}
}

View File

@ -2,7 +2,9 @@ package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -22,4 +24,11 @@ public class NoXPattern extends AbstractPattern {
mutable.mutZ((pos.getZ()));
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector pos) throws WorldEditException {
mutable.mutY((pos.getY()));
mutable.mutZ((pos.getZ()));
return pattern.apply(extent, mutable);
}
}

View File

@ -2,7 +2,9 @@ package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -22,4 +24,11 @@ public class NoYPattern extends AbstractPattern {
mutable.mutZ((pos.getZ()));
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector pos) throws WorldEditException {
mutable.mutX((pos.getX()));
mutable.mutZ((pos.getZ()));
return pattern.apply(extent, mutable);
}
}

View File

@ -2,7 +2,9 @@ package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -22,4 +24,11 @@ public class NoZPattern extends AbstractPattern {
mutable.mutY((pos.getY()));
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector pos) throws WorldEditException {
mutable.mutX((pos.getX()));
mutable.mutY((pos.getY()));
return pattern.apply(extent, mutable);
}
}

View File

@ -2,7 +2,9 @@ package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -26,4 +28,12 @@ public class OffsetPattern extends AbstractPattern {
mutable.mutZ((position.getZ() + dz));
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
mutable.mutX((position.getX() + dx));
mutable.mutY((position.getY() + dy));
mutable.mutZ((position.getZ() + dz));
return pattern.apply(extent, mutable);
}
}

View File

@ -67,6 +67,16 @@ public class PatternExtent extends AbstractPattern implements Extent {
this.target = vector;
}
public boolean getAndResetTarget(Extent extent, Vector position) throws WorldEditException {
BaseBlock result = block;
if (result != null) {
block = null;
return extent.setBlock(position, result);
} else {
return pattern.apply(extent, target);
}
}
public BaseBlock getAndResetTarget() {
BaseBlock result = block;
if (result != null) {
@ -107,4 +117,9 @@ public class PatternExtent extends AbstractPattern implements Extent {
public BaseBlock apply(Vector position) {
return pattern.apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
return pattern.apply(extent, position);
}
}

View File

@ -3,7 +3,9 @@ package com.boydti.fawe.object.pattern;
import com.boydti.fawe.object.PseudoRandom;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -31,4 +33,12 @@ public class RandomOffsetPattern extends AbstractPattern {
mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
return pattern.apply(extent, mutable);
}
}

View File

@ -2,7 +2,9 @@ package com.boydti.fawe.object.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -28,6 +30,17 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter
return pattern.apply(mutable);
}
@Override
public boolean apply(Extent extent, Vector pos) throws WorldEditException {
if (origin == null) {
origin = new Vector(pos);
}
mutable.mutX((pos.getX() - origin.getX()));
mutable.mutY((pos.getY() - origin.getY()));
mutable.mutZ((pos.getZ() - origin.getZ()));
return pattern.apply(extent, mutable);
}
@Override
public void reset() {
origin = null;

View File

@ -4,8 +4,10 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.PseudoRandom;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -46,4 +48,17 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
return pattern.apply(position);
}
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
BaseBlock block = pattern.apply(mutable);
if (solid[FaweCache.getCombined(block)]) {
return pattern.apply(extent, mutable);
} else {
return pattern.apply(extent, position);
}
}
}

View File

@ -4,8 +4,10 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.PseudoRandom;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -48,4 +50,19 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern {
}
return pattern.apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
mutable.mutX((position.getX() + r.nextInt(dx2) - dx));
mutable.mutY((position.getY() + r.nextInt(dy2) - dy));
mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz));
BaseBlock block = pattern.apply(mutable);
if (solid[FaweCache.getCombined(block)]) {
mutable.mutY(mutable.getY() + 1);
if (!solid[FaweCache.getCombined(pattern.apply(mutable))]) {
return pattern.apply(extent, mutable);
}
}
return pattern.apply(extent, position);
}
}

View File

@ -52,7 +52,6 @@ import com.boydti.fawe.object.extent.ProcessedWEExtent;
import com.boydti.fawe.object.extent.ResettableExtent;
import com.boydti.fawe.object.extent.SlowExtent;
import com.boydti.fawe.object.extent.SourceMaskExtent;
import com.boydti.fawe.object.function.block.LegacyBlockReplace;
import com.boydti.fawe.object.mask.ResettableMask;
import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker;
@ -98,6 +97,7 @@ import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
@ -116,8 +116,6 @@ import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
@ -1111,7 +1109,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
public boolean setBlock(int x, int y, int z, Pattern pattern) {
this.changes++;
try {
return this.extent.setBlock(x, y, z, pattern.next(x, y, z));
return this.extent.setBlock(x, y, z, pattern.apply(x, y, z));
} catch (WorldEditException e) {
throw new RuntimeException("Unexpected exception", e);
}
@ -1131,31 +1129,19 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
}
}
/**
* Sets the block at a position, subject to both history and block re-ordering.
*
* @param position the position
* @param pattern a pattern to use
* @return Whether the block changed -- not entirely dependable
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
@SuppressWarnings("deprecation")
public boolean setBlock(final Vector position, final Pattern pattern) throws MaxChangedBlocksException {
return this.setBlockFast(position, pattern.next(position));
this.changes++;
try {
return pattern.apply(this.extent, position);
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
/**
* Set blocks that are in a set of positions and return the number of times
* that the block set calls returned true.
*
* @param vset a set of positions
* @param pattern the pattern
* @return the number of changed blocks
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
@SuppressWarnings("deprecation")
private int setBlocks(final Set<Vector> vset, final Pattern pattern) throws MaxChangedBlocksException {
RegionVisitor visitor = new RegionVisitor(vset, new LegacyBlockReplace(extent, pattern), this);
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(extent, pattern), this);
Operations.completeBlindly(visitor);
changes += visitor.getAffected();
return changes;
@ -1431,7 +1417,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
*/
@SuppressWarnings("deprecation")
public int fillXZ(final Vector origin, final BaseBlock block, final double radius, final int depth, final boolean recursive) throws MaxChangedBlocksException {
return this.fillXZ(origin, new SingleBlockPattern(block), radius, depth, recursive);
return this.fillXZ(origin, new BlockPattern(block), radius, depth, recursive);
}
/**
@ -1456,7 +1442,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
(origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
// Want to replace blocks
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
// Pick how we're going to visit blocks
RecursiveVisitor visitor;
@ -1514,7 +1500,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
(origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
// Want to replace blocks
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
// Pick how we're going to visit blocks
RecursiveVisitor visitor;
@ -1549,7 +1535,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final Region region = new CuboidRegion(this.getWorld(), // Causes clamping of Y range
position.add(-apothem + 1, 0, -apothem + 1), position.add(apothem - 1, height - 1, apothem - 1));
final Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
final Pattern pattern = new BlockPattern(new BaseBlock(BlockID.AIR));
return this.setBlocks(region, pattern);
}
@ -1570,7 +1556,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final Region region = new CuboidRegion(this.getWorld(), // Causes clamping of Y range
position.add(-apothem + 1, 0, -apothem + 1), position.add(apothem - 1, -height + 1, apothem - 1));
final Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
final Pattern pattern = new BlockPattern(new BaseBlock(BlockID.AIR));
return this.setBlocks(region, pattern);
}
@ -1592,7 +1578,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1);
final Region region = new CuboidRegion(this.getWorld(), // Causes clamping of Y range
position.add(adjustment.multiply(-1)), position.add(adjustment));
final Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
final Pattern pattern = new BlockPattern(new BaseBlock(BlockID.AIR));
return this.replaceBlocks(region, mask, pattern);
}
@ -1643,7 +1629,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
}
try {
if (hasExtraExtents()) {
RegionVisitor visitor = new RegionVisitor(region, new LegacyBlockReplace(extent, new SingleBlockPattern(block)), this);
RegionVisitor visitor = new RegionVisitor(region, new BlockReplace(extent, new BlockPattern(block)), this);
Operations.completeBlindly(visitor);
this.changes += visitor.getAffected();
} else {
@ -1662,6 +1648,10 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
return changes;
}
public int setBlocks(final Region region, final com.sk89q.worldedit.patterns.Pattern pattern) throws MaxChangedBlocksException {
return setBlocks(region, Patterns.wrap(pattern));
}
/**
* Sets all the blocks inside a region to a given pattern.
*
@ -1677,7 +1667,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
if (pattern instanceof BlockPattern) {
return setBlocks(region, ((BlockPattern) pattern).getBlock());
}
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
final RegionVisitor visitor = new RegionVisitor(region, replace, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
@ -1700,9 +1690,11 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
// return changes = region.getArea();
// }
// TODO fast replace
return this.replaceBlocks(region, filter, new SingleBlockPattern(replacement));
return this.replaceBlocks(region, filter, new BlockPattern(replacement));
}
/**
* Replaces all the blocks matching a given filter, within a given region, to a block
* returned by a given pattern.
@ -1741,7 +1733,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
checkNotNull(region);
checkNotNull(mask);
checkNotNull(pattern);
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
final RegionMaskingFilter filter = new RegionMaskingFilter(mask, replace);
final RegionVisitor visitor = new RegionVisitor(region, filter, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
Operations.completeBlindly(visitor);
@ -1779,7 +1771,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
*/
@SuppressWarnings("deprecation")
public int makeCuboidFaces(final Region region, final BaseBlock block) throws MaxChangedBlocksException {
return this.makeCuboidFaces(region, new SingleBlockPattern(block));
return this.makeCuboidFaces(region, new BlockPattern(block));
}
/**
@ -1811,7 +1803,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
@SuppressWarnings("deprecation")
public int makeFaces(final Region region, final Pattern pattern) throws MaxChangedBlocksException {
public int makeFaces(final Region region, final Pattern pattern) throws WorldEditException {
checkNotNull(region);
checkNotNull(pattern);
@ -1833,7 +1825,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
*/
@SuppressWarnings("deprecation")
public int makeCuboidWalls(final Region region, final BaseBlock block) throws MaxChangedBlocksException {
return this.makeCuboidWalls(region, new SingleBlockPattern(block));
return this.makeCuboidWalls(region, new BlockPattern(block));
}
/**
@ -1866,7 +1858,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
@SuppressWarnings("deprecation")
public int makeWalls(final Region region, final Pattern pattern) throws MaxChangedBlocksException {
public int makeWalls(final Region region, final Pattern pattern) throws WorldEditException {
checkNotNull(region);
checkNotNull(pattern);
@ -1877,7 +1869,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final int maxY = region.getMaximumPoint().getBlockY();
final ArbitraryShape shape = new RegionShape(region) {
@Override
protected BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
public BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
if ((y > maxY) || (y < minY)) {
// Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region
return defaultMaterial;
@ -1903,7 +1895,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
public int overlayCuboidBlocks(final Region region, final BaseBlock block) throws MaxChangedBlocksException {
checkNotNull(block);
return this.overlayCuboidBlocks(region, new SingleBlockPattern(block));
return this.overlayCuboidBlocks(region, new BlockPattern(block));
}
/**
@ -1919,7 +1911,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
public int overlayCuboidBlocks(final Region region, final Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
final BlockReplace replace = new BlockReplace(EditSession.this, Patterns.wrap(pattern));
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
final RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), offset);
final LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
@ -2819,7 +2811,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final ArbitraryShape shape = new ArbitraryShape(region) {
@Override
protected BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
public BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
final Vector current = new Vector(x, y, z);
environment.setCurrentBlock(current);
final Vector scaled = current.subtract(zero).divide(unit);
@ -2837,7 +2829,11 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
}
};
return shape.generate(this, pattern, hollow);
try {
return shape.generate(this, pattern, hollow);
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
public int deformRegion(final Region region, final Vector zero, final Vector unit, final String expressionString) throws ExpressionException, MaxChangedBlocksException {
@ -2941,15 +2937,21 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
outside.addAll(newOutside);
}
outer: for (final BlockVector position : region) {
for (final Vector recurseDirection : this.recurseDirections) {
final BlockVector neighbor = position.add(recurseDirection).toBlockVector();
try {
outer:
for (final BlockVector position : region) {
for (final Vector recurseDirection : this.recurseDirections) {
final BlockVector neighbor = position.add(recurseDirection).toBlockVector();
if (outside.contains(neighbor)) {
continue outer;
if (outside.contains(neighbor)) {
continue outer;
}
}
this.changes++;
pattern.apply(this.extent, position);
}
this.setBlockFast(position, pattern.next(position));
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
return changes;
@ -3068,7 +3070,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final int tipy = (int) Math.round(tipv.getY());
final int tipz = (int) Math.round(tipv.getZ());
if (radius == 0) {
setBlock(tipx, tipy, tipz, pattern.next(tipx, tipy, tipz));
setBlock(tipx, tipy, tipz, pattern.apply(tipx, tipy, tipz));
} else {
vset.add(new Vector(tipx, tipy, tipz));
}

View File

@ -31,7 +31,6 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.regions.Region;
@ -123,7 +122,7 @@ public class GenerationCommands {
worldEdit.checkMaxRadius(height);
Vector pos = session.getPlacementPosition(player);
int affected = editSession.makeCylinder(pos, Patterns.wrap(pattern), radiusX, radiusZ, height, !hollow);
int affected = editSession.makeCylinder(pos, pattern, radiusX, radiusZ, height, !hollow);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -188,7 +187,7 @@ public class GenerationCommands {
pos = pos.add(0, radiusY, 0);
}
int affected = editSession.makeSphere(pos, Patterns.wrap(pattern), radiusX, radiusY, radiusZ, !hollow);
int affected = editSession.makeSphere(pos, pattern, radiusX, radiusY, radiusZ, !hollow);
player.findFreePosition();
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -249,7 +248,7 @@ public class GenerationCommands {
public void pyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow) throws WorldEditException, ParameterException {
Vector pos = session.getPlacementPosition(player);
worldEdit.checkMaxRadius(size);
int affected = editSession.makePyramid(pos, Patterns.wrap(pattern), size, !hollow);
int affected = editSession.makePyramid(pos, pattern, size, !hollow);
player.findFreePosition();
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -312,7 +311,7 @@ public class GenerationCommands {
}
try {
final int affected = editSession.makeShape(region, zero, unit, Patterns.wrap(pattern), expression, hollow);
final int affected = editSession.makeShape(region, zero, unit, pattern, expression, hollow);
player.findFreePosition();
BBC.VISITOR_BLOCK.send(player, affected);
} catch (ExpressionException e) {

View File

@ -50,7 +50,6 @@ import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Selection;
@ -251,7 +250,7 @@ public class RegionCommands {
CuboidRegion cuboidregion = (CuboidRegion) region;
Vector pos1 = cuboidregion.getPos1();
Vector pos2 = cuboidregion.getPos2();
int blocksChanged = editSession.drawLine(Patterns.wrap(pattern), pos1, pos2, thickness, !shell);
int blocksChanged = editSession.drawLine(pattern, pos1, pos2, thickness, !shell);
BBC.VISITOR_BLOCK.send(player, blocksChanged);
}
@ -284,7 +283,7 @@ public class RegionCommands {
ConvexPolyhedralRegion cpregion = (ConvexPolyhedralRegion) region;
List<Vector> vectors = new ArrayList<Vector>(cpregion.getVertices());
int blocksChanged = editSession.drawSpline(Patterns.wrap(pattern), vectors, 0, 0, 0, 10, thickness, !shell);
int blocksChanged = editSession.drawSpline(pattern, vectors, 0, 0, 0, 10, thickness, !shell);
BBC.VISITOR_BLOCK.send(player, blocksChanged);
}
@ -303,7 +302,7 @@ public class RegionCommands {
if (from == null) {
from = new ExistingBlockMask(editSession);
}
int affected = editSession.replaceBlocks(region, from, Patterns.wrap(to));
int affected = editSession.replaceBlocks(region, from, to);
BBC.VISITOR_BLOCK.send(player, affected);
if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) BBC.TIP_REPLACE_ID.or(BBC.TIP_REPLACE_LIGHT, BBC.TIP_REPLACE_MARKER, BBC.TIP_TAB_COMPLETE).send(player);
}
@ -322,7 +321,7 @@ public class RegionCommands {
if (from == null) {
from = new ExistingBlockMask(editSession);
}
int affected = editSession.replaceBlocks(region, from, Patterns.wrap(to));
int affected = editSession.replaceBlocks(region, from, to);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -340,7 +339,7 @@ public class RegionCommands {
if (to instanceof BlockPattern) {
affected = editSession.setBlocks(selection, ((BlockPattern) to).getBlock());
} else {
affected = editSession.setBlocks(selection, Patterns.wrap(to));
affected = editSession.setBlocks(selection, to);
}
if (affected != 0) {
BBC.OPERATION.send(player, affected);
@ -358,7 +357,7 @@ public class RegionCommands {
@CommandPermissions("worldedit.region.overlay")
@Logging(REGION)
public void overlay(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
int affected = editSession.overlayCuboidBlocks(region, Patterns.wrap(pattern));
int affected = editSession.overlayCuboidBlocks(region, pattern);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -372,7 +371,7 @@ public class RegionCommands {
@Logging(REGION)
@CommandPermissions("worldedit.region.center")
public void center(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
int affected = editSession.center(region, Patterns.wrap(pattern));
int affected = editSession.center(region, pattern);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -400,7 +399,7 @@ public class RegionCommands {
@CommandPermissions("worldedit.region.walls")
@Logging(REGION)
public void walls(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
int affected = editSession.makeCuboidWalls(region, Patterns.wrap(pattern));
int affected = editSession.makeCuboidWalls(region, pattern);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -414,7 +413,7 @@ public class RegionCommands {
@CommandPermissions("worldedit.region.faces")
@Logging(REGION)
public void faces(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
int affected = editSession.makeCuboidFaces(region, Patterns.wrap(pattern));
int affected = editSession.makeCuboidFaces(region, pattern);
BBC.VISITOR_BLOCK.send(player, affected);
}
@ -650,7 +649,7 @@ public class RegionCommands {
@Optional("0") @Range(min = 0) int thickness,
@Optional("air") Pattern pattern) throws WorldEditException {
int affected = editSession.hollowOutRegion(region, thickness, Patterns.wrap(pattern));
int affected = editSession.hollowOutRegion(region, thickness, pattern);
BBC.VISITOR_BLOCK.send(player, affected);
}

View File

@ -39,7 +39,7 @@ import com.sk89q.worldedit.command.tool.LongRangeBuildTool;
import com.sk89q.worldedit.command.tool.QueryTool;
import com.sk89q.worldedit.command.tool.TreePlanter;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.command.parametric.Optional;
@ -150,17 +150,13 @@ public class ToolCommands {
max = 2
)
@CommandPermissions("worldedit.tool.flood-fill")
public void floodFill(Player player, LocalSession session, CommandContext args) throws WorldEditException {
public void floodFill(Player player, LocalSession session, Pattern pattern, double range) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
int range = args.getInteger(1);
if (range > config.maxSuperPickaxeSize) {
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
return;
}
Pattern pattern = we.getBlockPattern(player, args.getString(0));
session.setTool(new FloodFillTool(range, pattern), player);
session.setTool(new FloodFillTool((int) range, pattern), player);
BBC.TOOL_FLOOD_FILL.send(player, ItemType.toHeldName(player.getItemInHand()));
}

View File

@ -24,9 +24,17 @@ import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.google.common.base.Joiner;
import com.google.common.util.concurrent.AtomicDouble;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.*;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.command.util.CreatureButcher;
import com.sk89q.worldedit.command.util.EntityRemover;
@ -36,13 +44,15 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
@ -51,6 +61,7 @@ import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.util.formatting.StyledFragment;
@ -58,13 +69,16 @@ import com.sk89q.worldedit.util.formatting.component.Code;
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
import com.sk89q.worldedit.world.World;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
/**
@ -87,21 +101,14 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.fill")
@Logging(PLACEMENT)
public void fill(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
Pattern pattern = we.getBlockPattern(player, args.getString(0));
double radius = Math.max(1, args.getDouble(1));
public void fill(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
we.checkMaxRadius(radius);
int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : 1;
Vector pos = session.getPlacementPosition(player);
int affected = 0;
if (pattern instanceof SingleBlockPattern) {
affected = editSession.fillXZ(pos,
((SingleBlockPattern) pattern).getBlock(),
radius, depth, false);
if (pattern instanceof BlockPattern) {
affected = editSession.fillXZ(pos, ((BlockPattern) pattern).getBlock(), radius, (int) depth, false);
} else {
affected = editSession.fillXZ(pos, pattern, radius, depth, false);
affected = editSession.fillXZ(pos, pattern, radius, (int) depth, false);
}
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
}
@ -115,21 +122,14 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.fill.recursive")
@Logging(PLACEMENT)
public void fillr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
Pattern pattern = we.getBlockPattern(player, args.getString(0));
double radius = Math.max(1, args.getDouble(1));
public void fillr(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
we.checkMaxRadius(radius);
int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : Integer.MAX_VALUE;
Vector pos = session.getPlacementPosition(player);
int affected = 0;
if (pattern instanceof SingleBlockPattern) {
affected = editSession.fillXZ(pos,
((SingleBlockPattern) pattern).getBlock(),
radius, depth, true);
if (pattern instanceof BlockPattern) {
affected = editSession.fillXZ(pos, ((BlockPattern) pattern).getBlock(), radius, (int) depth, true);
} else {
affected = editSession.fillXZ(pos, pattern, radius, depth, true);
affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
}
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
}
@ -143,9 +143,7 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.drain")
@Logging(PLACEMENT)
public void drain(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
double radius = Math.max(0, args.getDouble(0));
public void drain(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
we.checkMaxRadius(radius);
int affected = editSession.drainArea(
session.getPlacementPosition(player), radius);
@ -161,9 +159,7 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.fixlava")
@Logging(PLACEMENT)
public void fixLava(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
double radius = Math.max(0, args.getDouble(0));
public void fixLava(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(
session.getPlacementPosition(player), radius, 10, 11);
@ -179,9 +175,7 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.fixwater")
@Logging(PLACEMENT)
public void fixWater(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
double radius = Math.max(0, args.getDouble(0));
public void fixWater(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(
session.getPlacementPosition(player), radius, 8, 9);
@ -197,15 +191,9 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.removeabove")
@Logging(PLACEMENT)
public void removeAbove(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1;
public void removeAbove(Player player, LocalSession session, EditSession editSession, @Optional("1") double size, @Optional("256") double height) throws WorldEditException {
we.checkMaxRadius(size);
World world = player.getWorld();
int height = args.argsLength() > 1 ? Math.min((world.getMaxY() + 1), args.getInteger(1) + 2) : (world.getMaxY() + 1);
int affected = editSession.removeAbove(
session.getPlacementPosition(player), size, height);
int affected = editSession.removeAbove(session.getPlacementPosition(player), (int) size, (int) height);
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
}
@ -218,14 +206,9 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.removebelow")
@Logging(PLACEMENT)
public void removeBelow(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : 1;
public void removeBelow(Player player, LocalSession session, EditSession editSession, @Optional("1") double size, @Optional("256") double height) throws WorldEditException {
we.checkMaxRadius(size);
World world = player.getWorld();
int height = args.argsLength() > 1 ? Math.min((world.getMaxY() + 1), args.getInteger(1) + 2) : (world.getMaxY() + 1);
int affected = editSession.removeBelow(session.getPlacementPosition(player), size, height);
int affected = editSession.removeBelow(session.getPlacementPosition(player), (int) size, (int) height);
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
}
@ -238,13 +221,9 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.removenear")
@Logging(PLACEMENT)
public void removeNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
BaseBlock block = we.getBlock(player, args.getString(0), true);
int size = Math.max(1, args.getInteger(1, 50));
public void removeNear(Player player, LocalSession session, EditSession editSession, BaseBlock block, @Optional("50") double size) throws WorldEditException {
we.checkMaxRadius(size);
int affected = editSession.removeNear(session.getPlacementPosition(player), block.getType(), size);
int affected = editSession.removeNear(session.getPlacementPosition(player), block.getId(), (int) size);
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
}
@ -258,31 +237,17 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.replacenear")
@Logging(PLACEMENT)
public void replaceNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
int size = Math.max(1, args.getInteger(0));
int affected;
Set<BaseBlock> from;
Pattern to;
if (args.argsLength() == 2) {
from = null;
to = we.getBlockPattern(player, args.getString(1));
} else {
from = we.getBlocks(player, args.getString(1), true, !args.hasFlag('f'));
to = we.getBlockPattern(player, args.getString(2));
public void replaceNear(Player player, LocalSession session, EditSession editSession, double size, @Optional Mask from, Pattern to) throws WorldEditException {
if (from == null) {
from = new ExistingBlockMask(editSession);
}
Vector base = session.getPlacementPosition(player);
Vector min = base.subtract(size, size, size);
Vector max = base.add(size, size, size);
Region region = new CuboidRegion(player.getWorld(), min, max);
if (to instanceof SingleBlockPattern) {
affected = editSession.replaceBlocks(region, from, ((SingleBlockPattern) to).getBlock());
} else {
affected = editSession.replaceBlocks(region, from, to);
}
player.print(BBC.getPrefix() + affected + " block(s) have been replaced.");
int affected = editSession.replaceBlocks(region, from, to);
BBC.VISITOR_BLOCK.send(player, affected);
}
@Command(

View File

@ -0,0 +1,117 @@
/*
* 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.command.tool;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import java.util.HashSet;
import java.util.Set;
/**
* A tool that flood fills blocks.
*/
public class FloodFillTool implements BlockTool {
private int range;
private Pattern pattern;
public FloodFillTool(int range, com.sk89q.worldedit.patterns.Pattern pattern) {
this(range, (Pattern) pattern);
}
public FloodFillTool(int range, Pattern pattern) {
this.range = range;
this.pattern = pattern;
}
@Override
public boolean canUse(Actor player) {
return player.hasPermission("worldedit.tool.flood-fill");
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
World world = (World) clicked.getExtent();
int initialType = world.getBlockType(clicked.toVector());
if (initialType == BlockID.AIR) {
return true;
}
if (initialType == BlockID.BEDROCK && !player.canDestroyBedrock()) {
return true;
}
EditSession editSession = session.createEditSession(player);
try {
recurse(server, editSession, world, clicked.toVector().toBlockVector(),
clicked.toVector(), range, initialType, new HashSet<BlockVector>());
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
return true;
}
private void recurse(Platform server, EditSession editSession, World world, BlockVector pos, Vector origin, int size, int initialType,
Set<BlockVector> visited) throws WorldEditException {
if (origin.distance(pos) > size || visited.contains(pos)) {
return;
}
visited.add(pos);
if (editSession.getBlock(pos).getType() == initialType) {
editSession.setBlock(pos, pattern);
} else {
return;
}
recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(),
origin, size, initialType, visited);
}
public static Class<?> inject() {
return FloodFillTool.class;
}
}

View File

@ -24,6 +24,10 @@ import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.ArrayList;
import java.util.List;
@ -104,6 +108,13 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
case "#data": {
return new DataPattern(Request.request().getEditSession(), catchSuggestion(input, rest, context));
}
case "#biome": {
World world = context.getWorld();
BiomeRegistry biomeRegistry = world.getWorldData().getBiomeRegistry();
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, rest, biomeRegistry);
return new BiomePattern(Request.request().getEditSession(), biome);
}
case "#~":
case "#r":
case "#relative":

View File

@ -0,0 +1,61 @@
/*
* 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.function.block;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Replaces blocks with a given pattern.
*/
public class BlockReplace implements RegionFunction {
private final Extent extent;
private Pattern pattern;
/**
* Create a new instance.
*
* @param extent an extent
* @param pattern a pattern
*/
public BlockReplace(Extent extent, Pattern pattern) {
checkNotNull(extent);
checkNotNull(pattern);
this.extent = extent;
this.pattern = pattern;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
return pattern.apply(extent, position);
}
public static Class<?> inject() {
return BlockReplace.class;
}
}

View File

@ -117,4 +117,8 @@ public class ExtentBlockCopy implements RegionFunction {
return state;
}
public static Class<?> inject() {
return ExtentBlockCopy.class;
}
}

View File

@ -20,12 +20,7 @@ public class BlockPattern extends AbstractPattern {
}
@Override
public BaseBlock next(int x, int y, int z) {
return block;
}
@Override
public BaseBlock next(Vector position) {
public BaseBlock apply(int x, int y, int z) {
return block;
}

View File

@ -21,12 +21,14 @@ package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
/**
* Returns a {@link BaseBlock} for a given position.
*/
public interface Pattern extends com.sk89q.worldedit.patterns.Pattern {
public interface Pattern {
/**
* Return a {@link BaseBlock} for the given position.
@ -36,14 +38,12 @@ public interface Pattern extends com.sk89q.worldedit.patterns.Pattern {
*/
BaseBlock apply(Vector position);
@Override
default BaseBlock next(Vector position) {
return apply(position);
default BaseBlock apply(int x, int y, int z) {
return apply(MutableBlockVector.get(x, y, z));
}
@Override
default BaseBlock next(int x, int y, int z) {
return apply(MutableBlockVector.get(x, y, z));
default boolean apply(Extent extent,Vector position) throws WorldEditException {
return extent.setBlock(position, apply(position));
}
public static Class<Pattern> inject() {

View File

@ -4,9 +4,6 @@ import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Utility methods related to {@link Pattern}s.
*/
@ -22,16 +19,7 @@ public final class Patterns {
* @return a new-style pattern
*/
public static Pattern wrap(final com.sk89q.worldedit.patterns.Pattern pattern) {
if (pattern instanceof Pattern) {
return (Pattern) pattern;
}
checkNotNull(pattern);
return new Pattern() {
@Override
public BaseBlock apply(Vector position) {
return pattern.next(position);
}
};
return pattern;
}
/**
@ -41,7 +29,9 @@ public final class Patterns {
* @return an old-style pattern
*/
public static com.sk89q.worldedit.patterns.Pattern wrap(final Pattern pattern) {
checkNotNull(pattern);
if (pattern instanceof com.sk89q.worldedit.patterns.Pattern) {
return (com.sk89q.worldedit.patterns.Pattern) pattern;
}
return new com.sk89q.worldedit.patterns.Pattern() {
private MutableBlockVector mutable = new MutableBlockVector(0, 0, 0);
@Override
@ -62,5 +52,4 @@ public final class Patterns {
public static Class<?> inject() {
return Patterns.class;
}
}

View File

@ -2,7 +2,9 @@ package com.sk89q.worldedit.function.pattern;
import com.boydti.fawe.object.collection.RandomCollection;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -40,6 +42,11 @@ public class RandomPattern extends AbstractPattern {
return collection.next().apply(position);
}
@Override
public boolean apply(Extent extent, Vector position) throws WorldEditException {
return collection.next().apply(extent, position);
}
private static class Chance {
private Pattern pattern;
private double chance;

View File

@ -0,0 +1,70 @@
/*
* 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.patterns;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
/**
* @deprecated See {@link com.sk89q.worldedit.function.pattern.Pattern}
*/
@Deprecated
public interface Pattern extends com.sk89q.worldedit.function.pattern.Pattern{
/**
* Get a block for a position. This return value of this method does
* not have to be consistent for the same position.
*
* @param position the position where a block is needed
* @return a block
*/
public BaseBlock next(Vector position);
@Override
default boolean apply(Extent extent, Vector position) throws WorldEditException {
return extent.setBlock(position, apply(position));
}
@Override
default BaseBlock apply(Vector position) {
return next(position);
}
@Override
default BaseBlock apply(int x, int y, int z) {
return next(x, y, z);
}
/**
* Get a block for a position. This return value of this method does
* not have to be consistent for the same position.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @return a block
*/
public BaseBlock next(int x, int y, int z);
public static Class<?> inject() {
return Pattern.class;
}
}

View File

@ -0,0 +1,221 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.shape;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.regions.Region;
/**
* Generates solid and hollow shapes according to materials returned by the
* {@link #getMaterial} method.
*/
public abstract class ArbitraryShape {
public final Region extent;
private int cacheOffsetX;
private int cacheOffsetY;
private int cacheOffsetZ;
@SuppressWarnings("FieldCanBeLocal")
private int cacheSizeX;
private int cacheSizeY;
private int cacheSizeZ;
public ArbitraryShape(Region extent) {
this.extent = extent;
Vector min = extent.getMinimumPoint();
Vector max = extent.getMaximumPoint();
cacheOffsetX = min.getBlockX() - 1;
cacheOffsetY = min.getBlockY() - 1;
cacheOffsetZ = min.getBlockZ() - 1;
cacheSizeX = (int) (max.getX() - cacheOffsetX + 2);
cacheSizeY = (int) (max.getY() - cacheOffsetY + 2);
cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2);
cache = new short[cacheSizeX * cacheSizeY * cacheSizeZ];
}
public Region getExtent() {
return extent;
}
/**
* Cache entries:
* 0 = unknown
* -1 = outside
* -2 = inside but type and data 0
* > 0 = inside, value = (type | (data << 8)), not handling data < 0
*/
private final short[] cache;
/**
* Override this function to specify the shape to generate.
*
* @param x X coordinate to be queried
* @param y Y coordinate to be queried
* @param z Z coordinate to be queried
* @param defaultMaterial The material returned by the pattern for the current block.
* @return material to place or null to not place anything.
*/
public abstract BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial);
private BaseBlock getMaterialCached(int x, int y, int z, Pattern pattern) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
final short cacheEntry = cache[index];
switch (cacheEntry) {
case 0:
// unknown, fetch material
final BaseBlock material = getMaterial(x, y, z, pattern.apply(new BlockVector(x, y, z)));
if (material == null) {
// outside
cache[index] = -1;
return null;
}
short newCacheEntry = (short) (material.getType() | ((material.getData() + 1) << 8));
if (newCacheEntry == 0) {
// type and data 0
newCacheEntry = -2;
}
cache[index] = newCacheEntry;
return material;
case -1:
// outside
return null;
case -2:
// type and data 0
return new BaseBlock(0, 0);
}
return new BaseBlock(cacheEntry & 255, ((cacheEntry >> 8) - 1) & 15);
}
private boolean isInsideCached(int x, int y, int z, Pattern pattern) {
final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
switch (cache[index]) {
case 0:
// unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape
return getMaterialCached(x, y, z, pattern) != null;
case -1:
// outside
return false;
default:
// inside
return true;
}
}
@Deprecated
public int generate(EditSession editSession, com.sk89q.worldedit.patterns.Pattern pattern, boolean hollow) throws WorldEditException {
return generate(editSession, Patterns.wrap(pattern), hollow);
}
/**
* Generates the shape.
*
* @param editSession The EditSession to use.
* @param pattern The pattern to generate default materials from.
* @param hollow Specifies whether to generate a hollow shape.
* @return number of affected blocks.
* @throws MaxChangedBlocksException
*/
public int generate(EditSession editSession, Pattern pattern, boolean hollow) throws WorldEditException {
int affected = 0;
for (BlockVector position : getExtent()) {
int x = position.getBlockX();
int y = position.getBlockY();
int z = position.getBlockZ();
if (!hollow) {
final BaseBlock material = getMaterial(x, y, z, pattern.apply(position));
if (material != null && editSession.setBlock(position, material)) {
++affected;
}
continue;
}
final BaseBlock material = getMaterialCached(x, y, z, pattern);
if (material == null) {
continue;
}
boolean draw = false;
do {
if (!isInsideCached(x + 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x - 1, y, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z + 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y, z - 1, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y + 1, z, pattern)) {
draw = true;
break;
}
if (!isInsideCached(x, y - 1, z, pattern)) {
draw = true;
break;
}
} while (false);
if (!draw) {
continue;
}
if (editSession.setBlock(position, material)) {
++affected;
}
}
return affected;
}
public static Class<?> inject() {
return ArbitraryShape.class;
}
}