Use expression for brush radius

This commit is contained in:
Jesse Boyd 2018-08-22 02:58:10 +10:00
commit 43531a0da0
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
8 changed files with 126 additions and 45 deletions

View File

@ -194,6 +194,29 @@ public class FawePrimitiveBinding extends BindingHelper {
return v; return v;
} }
@BindingMatch(type = { Expression.class },
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Expression getExpression(ArgumentStack context) throws ParameterException, ExpressionException {
String input = context.next();
try {
return new Expression(Double.parseDouble(input));
} catch (NumberFormatException e1) {
try {
Expression expression = Expression.compile(input);
expression.optimize();
return expression;
} catch (EvaluationException e) {
throw new ParameterException(String.format(
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
} catch (ExpressionException e) {
throw new ParameterException(String.format(
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
}
}
}
/** /**
* Gets a type from a {@link ArgumentStack}. * Gets a type from a {@link ArgumentStack}.
* *

View File

@ -16,6 +16,10 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.Constant;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.ProcessedCallable; import com.sk89q.worldedit.util.command.ProcessedCallable;
@ -26,6 +30,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkNotNull;
public class BrushSettings { public class BrushSettings {
public enum SettingType { public enum SettingType {
BRUSH, BRUSH,
@ -45,7 +51,7 @@ public class BrushSettings {
private Mask sourceMask = null; private Mask sourceMask = null;
private ResettableExtent transform = null; private ResettableExtent transform = null;
private Pattern material; private Pattern material;
private double size = 1; private Expression size = new Expression(1);
private Set<String> permissions; private Set<String> permissions;
private ScrollAction scrollAction; private ScrollAction scrollAction;
private String lastWorld; private String lastWorld;
@ -78,7 +84,12 @@ public class BrushSettings {
bs.permissions.addAll((Collection<? extends String>) settings.get(SettingType.PERMISSIONS.name())); bs.permissions.addAll((Collection<? extends String>) settings.get(SettingType.PERMISSIONS.name()));
} }
if (settings.containsKey(SettingType.SIZE.name())) { if (settings.containsKey(SettingType.SIZE.name())) {
bs.size = (double) settings.get(SettingType.SIZE.name()); try {
bs.size = Expression.compile((String) settings.getOrDefault(SettingType.SIZE.name(), -1));
bs.size.optimize();
} catch (ExpressionException e) {
throw new RuntimeException(e);
}
} }
ParserContext parserContext = new ParserContext(); ParserContext parserContext = new ParserContext();
@ -140,7 +151,7 @@ public class BrushSettings {
transform = null; transform = null;
material = null; material = null;
scrollAction = null; scrollAction = null;
size = 1; size = new Expression(1);
permissions.clear(); permissions.clear();
constructor.clear(); constructor.clear();
return this; return this;
@ -184,16 +195,21 @@ public class BrushSettings {
return this; return this;
} }
public BrushSettings setSize(double size) { public BrushSettings setSize(Expression size) {
checkNotNull(size);
this.size = size; this.size = size;
if (size == -1) { if (size.getRoot() instanceof Constant && ((Constant) size.getRoot()).getValue() == -1) {
constructor.remove(SettingType.SIZE); constructor.remove(SettingType.SIZE);
} else { } else {
constructor.put(SettingType.SIZE, size); constructor.put(SettingType.SIZE, size.toString());
} }
return this; return this;
} }
public BrushSettings setSize(double size) {
return setSize(new Expression(size));
}
public BrushSettings setScrollAction(ScrollAction scrollAction) { public BrushSettings setScrollAction(ScrollAction scrollAction) {
if (scrollAction == null) constructor.remove(SettingType.SCROLL_ACTION); if (scrollAction == null) constructor.remove(SettingType.SCROLL_ACTION);
this.scrollAction = scrollAction; this.scrollAction = scrollAction;
@ -245,7 +261,15 @@ public class BrushSettings {
} }
public double getSize() { public double getSize() {
return size; try {
return size.evaluate();
} catch (EvaluationException e) {
throw new RuntimeException(e);
}
}
public Expression getSizeExpression() {
return this.size;
} }
public Set<String> getPermissions() { public Set<String> getPermissions() {

View File

@ -21,7 +21,7 @@ public class CommandBrush implements Brush {
private final String command; private final String command;
public CommandBrush(String command, double radius) { public CommandBrush(String command) {
this.command = command.charAt(0) == '/' ? "/" + command : command; this.command = command.charAt(0) == '/' ? "/" + command : command;
} }

View File

@ -22,6 +22,9 @@ package com.sk89q.worldedit;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.runtime.Constant;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
@ -338,6 +341,15 @@ public class WorldEdit {
} }
} }
public void checkMaxBrushRadius(Expression radius) throws MaxBrushRadiusException {
if (getConfiguration().maxBrushRadius > 0) {
RValue r = radius.getRoot();
if (r instanceof Constant && ((Constant) r).getValue() > getConfiguration().maxBrushRadius) {
throw new MaxBrushRadiusException();
}
}
}
/** /**
* Get a file relative to the defined working directory. If the specified * Get a file relative to the defined working directory. If the specified
* path is absolute, then the working directory is not used. * path is absolute, then the working directory is not used.

View File

@ -48,6 +48,7 @@ import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask; import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.command.InvalidUsageException; import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Range;
@ -88,7 +89,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.blendball") @CommandPermissions("worldedit.brush.blendball")
public BrushSettings blendBallBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings blendBallBrush(Player player, LocalSession session, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, new BlendBall()).setSize(radius); return set(session, context, new BlendBall()).setSize(radius);
} }
@ -102,7 +103,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.erode") @CommandPermissions("worldedit.brush.erode")
public BrushSettings erodeBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings erodeBrush(Player player, LocalSession session, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, new ErodeBrush()).setSize(radius); return set(session, context, new ErodeBrush()).setSize(radius);
} }
@ -116,7 +117,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.pull") @CommandPermissions("worldedit.brush.pull")
public BrushSettings pullBrush(Player player, LocalSession session, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings pullBrush(Player player, LocalSession session, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, new RaiseBrush()).setSize(radius); return set(session, context, new RaiseBrush()).setSize(radius);
} }
@ -131,7 +132,7 @@ public class BrushCommands extends BrushProcessor {
max = 2 max = 2
) )
@CommandPermissions("worldedit.brush.sphere") @CommandPermissions("worldedit.brush.sphere")
public BrushSettings circleBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings circleBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, new CircleBrush(player)).setSize(radius).setFill(fill); return set(session, context, new CircleBrush(player)).setSize(radius).setFill(fill);
} }
@ -147,7 +148,7 @@ public class BrushCommands extends BrushProcessor {
max = 3 max = 3
) )
@CommandPermissions("worldedit.brush.recursive") @CommandPermissions("worldedit.brush.recursive")
public BrushSettings recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("5") double radius, @Switch('d') boolean depthFirst, CommandContext context) throws WorldEditException { public BrushSettings recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("5") Expression radius, @Switch('d') boolean depthFirst, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new RecurseBrush(depthFirst)) new RecurseBrush(depthFirst))
@ -170,7 +171,7 @@ public class BrushCommands extends BrushProcessor {
max = 2 max = 2
) )
@CommandPermissions("worldedit.brush.line") @CommandPermissions("worldedit.brush.line")
public BrushSettings lineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat, CommandContext context) throws WorldEditException { public BrushSettings lineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") Expression radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new LineBrush(shell, select, flat)) new LineBrush(shell, select, flat))
@ -191,7 +192,7 @@ public class BrushCommands extends BrushProcessor {
max = 2 max = 2
) )
@CommandPermissions("worldedit.brush.spline") @CommandPermissions("worldedit.brush.spline")
public BrushSettings splineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("25") double radius, CommandContext context) throws WorldEditException { public BrushSettings splineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("25") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius)); player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
return set(session, context, return set(session, context,
@ -229,7 +230,7 @@ public class BrushCommands extends BrushProcessor {
max = 3 max = 3
) )
@CommandPermissions("worldedit.brush.spline") @CommandPermissions("worldedit.brush.spline")
public BrushSettings catenaryBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("1.2") @Range(min=1) double lengthFactor, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('d') boolean facingDirection, CommandContext context) throws WorldEditException { public BrushSettings catenaryBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("1.2") @Range(min=1) double lengthFactor, @Optional("0") Expression radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('d') boolean facingDirection, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new CatenaryBrush(shell, select, facingDirection, lengthFactor)) new CatenaryBrush(shell, select, facingDirection, lengthFactor))
@ -247,7 +248,7 @@ public class BrushCommands extends BrushProcessor {
max = 6 max = 6
) )
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0, @CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
public BrushSettings surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality, CommandContext context) throws WorldEditException { public BrushSettings surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") Expression radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality, CommandContext context) throws WorldEditException {
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius)); player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius));
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
@ -288,9 +289,8 @@ public class BrushCommands extends BrushProcessor {
max = 2 max = 2
) )
@CommandPermissions("worldedit.brush.sphere") @CommandPermissions("worldedit.brush.sphere")
public BrushSettings sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") @Range(min=0) double radius, @Switch('h') boolean hollow, @Switch('f') boolean falling, CommandContext context) throws WorldEditException { public BrushSettings sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") @Range(min=0) Expression radius, @Switch('h') boolean hollow, @Switch('f') boolean falling, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
Brush brush; Brush brush;
if (hollow) { if (hollow) {
brush = new HollowSphereBrush(); brush = new HollowSphereBrush();
@ -326,7 +326,7 @@ public class BrushCommands extends BrushProcessor {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.shatter") @CommandPermissions("worldedit.brush.shatter")
public BrushSettings shatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("10") double radius, @Optional("10") int count, CommandContext context) throws WorldEditException { public BrushSettings shatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("10") Expression radius, @Optional("10") int count, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new ShatterBrush(count)) new ShatterBrush(count))
@ -347,7 +347,7 @@ public class BrushCommands extends BrushProcessor {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.stencil") @CommandPermissions("worldedit.brush.stencil")
public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException { public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
InputStream stream = getHeightmapStream(image); InputStream stream = getHeightmapStream(image);
HeightBrush brush; HeightBrush brush;
@ -378,7 +378,7 @@ public class BrushCommands extends BrushProcessor {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.stencil") @CommandPermissions("worldedit.brush.stencil")
public BrushSettings imageBrush(Player player, EditSession editSession, LocalSession session, @Optional("5") double radius, FawePrimitiveBinding.ImageUri imageUri, @Optional("1") @Range(min=Double.MIN_NORMAL) final double yscale, @Switch('a') boolean alpha, @Switch('f') boolean fadeOut, CommandContext context) throws WorldEditException, IOException, ParameterException { public BrushSettings imageBrush(Player player, EditSession editSession, LocalSession session, @Optional("5") Expression radius, FawePrimitiveBinding.ImageUri imageUri, @Optional("1") @Range(min=Double.MIN_NORMAL) final double yscale, @Switch('a') boolean alpha, @Switch('f') boolean fadeOut, CommandContext context) throws WorldEditException, IOException, ParameterException {
BufferedImage image = imageUri.load(); BufferedImage image = imageUri.load();
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
if (yscale != 1) { if (yscale != 1) {
@ -407,7 +407,7 @@ public class BrushCommands extends BrushProcessor {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.surface") @CommandPermissions("worldedit.brush.surface")
public BrushSettings surfaceBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings surfaceBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, new SurfaceSphereBrush()).setFill(fill).setSize(radius); return set(session, context, new SurfaceSphereBrush()).setFill(fill).setSize(radius);
} }
@ -425,7 +425,7 @@ public class BrushCommands extends BrushProcessor {
max = 4 max = 4
) )
@CommandPermissions("worldedit.brush.scatter") @CommandPermissions("worldedit.brush.scatter")
public BrushSettings scatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("5") double points, @Optional("1") double distance, @Switch('o') boolean overlay, CommandContext context) throws WorldEditException { public BrushSettings scatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, @Optional("5") double points, @Optional("1") double distance, @Switch('o') boolean overlay, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
Brush brush; Brush brush;
if (overlay) { if (overlay) {
@ -451,7 +451,7 @@ public class BrushCommands extends BrushProcessor {
max = 4 max = 4
) )
@CommandPermissions("worldedit.brush.populateschematic") @CommandPermissions("worldedit.brush.populateschematic")
public BrushSettings scatterSchemBrush(Player player, EditSession editSession, LocalSession session, Mask mask, String clipboard, @Optional("30") double radius, @Optional("50") double density, @Switch('r') boolean rotate, CommandContext context) throws WorldEditException { public BrushSettings scatterSchemBrush(Player player, EditSession editSession, LocalSession session, Mask mask, String clipboard, @Optional("30") Expression radius, @Optional("50") double density, @Switch('r') boolean rotate, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
@ -486,7 +486,7 @@ public class BrushCommands extends BrushProcessor {
max = 999 max = 999
) )
@CommandPermissions("worldedit.brush.layer") @CommandPermissions("worldedit.brush.layer")
public BrushSettings surfaceLayer(Player player, EditSession editSession, LocalSession session, double radius, CommandContext args, CommandContext context) throws WorldEditException, InvalidUsageException { public BrushSettings surfaceLayer(Player player, EditSession editSession, LocalSession session, Expression radius, CommandContext args, CommandContext context) throws WorldEditException, InvalidUsageException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
ParserContext parserContext = new ParserContext(); ParserContext parserContext = new ParserContext();
parserContext.setActor(player); parserContext.setActor(player);
@ -526,7 +526,7 @@ public class BrushCommands extends BrushProcessor {
max = 5 max = 5
) )
@CommandPermissions("worldedit.brush.splatter") @CommandPermissions("worldedit.brush.splatter")
public BrushSettings splatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("1") double points, @Optional("5") double recursion, @Optional("true") boolean solid, CommandContext context) throws WorldEditException { public BrushSettings splatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, @Optional("1") double points, @Optional("5") double recursion, @Optional("true") boolean solid, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new SplatterBrush((int) points, (int) recursion, solid)) new SplatterBrush((int) points, (int) recursion, solid))
@ -547,7 +547,7 @@ public class BrushCommands extends BrushProcessor {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.scattercommand") @CommandPermissions("worldedit.brush.scattercommand")
public BrushSettings scatterCommandBrush(Player player, EditSession editSession, LocalSession session, double radius, double points, double distance, CommandContext args, CommandContext context) throws WorldEditException { public BrushSettings scatterCommandBrush(Player player, EditSession editSession, LocalSession session, Expression radius, double points, double distance, CommandContext args, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
new ScatterCommand((int) points, (int) distance, args.getJoinedStrings(3))) new ScatterCommand((int) points, (int) distance, args.getJoinedStrings(3)))
@ -567,7 +567,7 @@ public class BrushCommands extends BrushProcessor {
) )
@CommandPermissions("worldedit.brush.cylinder") @CommandPermissions("worldedit.brush.cylinder")
public BrushSettings cylinderBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, public BrushSettings cylinderBrush(Player player, EditSession editSession, LocalSession session, Pattern fill,
@Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException { @Optional("2") Expression radius, @Optional("1") int height, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
getWorldEdit().checkMaxBrushRadius(height); getWorldEdit().checkMaxBrushRadius(height);
@ -619,7 +619,7 @@ public class BrushCommands extends BrushProcessor {
) )
@CommandPermissions("worldedit.brush.smooth") @CommandPermissions("worldedit.brush.smooth")
public BrushSettings smoothBrush(Player player, LocalSession session, EditSession editSession, public BrushSettings smoothBrush(Player player, LocalSession session, EditSession editSession,
@Optional("2") double radius, @Optional("4") int iterations, CommandContext context) throws WorldEditException { @Optional("2") Expression radius, @Optional("4") int iterations, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
@ -640,7 +640,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.ex") @CommandPermissions("worldedit.brush.ex")
public BrushSettings extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, CommandContext context) throws WorldEditException { public BrushSettings extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") Expression radius, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
Pattern fill = BlockTypes.AIR.getDefaultState(); Pattern fill = BlockTypes.AIR.getDefaultState();
@ -664,7 +664,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.gravity") @CommandPermissions("worldedit.brush.gravity")
public BrushSettings gravityBrush(Player player, LocalSession session, @Optional("5") double radius, @Switch('h') boolean fromMaxY, CommandContext context) throws WorldEditException { public BrushSettings gravityBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Switch('h') boolean fromMaxY, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
return set(session, context, return set(session, context,
@ -688,7 +688,7 @@ public class BrushCommands extends BrushProcessor {
max = 4 max = 4
) )
@CommandPermissions("worldedit.brush.height") @CommandPermissions("worldedit.brush.height")
public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context); return terrainBrush(player, session, radius, image, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
} }
@ -706,7 +706,7 @@ public class BrushCommands extends BrushProcessor {
max = 4 max = 4
) )
@CommandPermissions("worldedit.brush.height") @CommandPermissions("worldedit.brush.height")
public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context); return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context);
} }
@ -723,11 +723,11 @@ public class BrushCommands extends BrushProcessor {
max = 4 max = 4
) )
@CommandPermissions("worldedit.brush.height") @CommandPermissions("worldedit.brush.height")
public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") double radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException {
return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context); return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context);
} }
private BrushSettings terrainBrush(Player player, LocalSession session, double radius, String image, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException { private BrushSettings terrainBrush(Player player, LocalSession session, Expression radius, String image, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
InputStream stream = getHeightmapStream(image); InputStream stream = getHeightmapStream(image);
HeightBrush brush; HeightBrush brush;
@ -798,7 +798,7 @@ public class BrushCommands extends BrushProcessor {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.copy") @CommandPermissions("worldedit.brush.copy")
public BrushSettings copy(Player player, LocalSession session, @Optional("5") double radius, @Switch('r') boolean randomRotate, @Switch('a') boolean autoRotate, CommandContext context) throws WorldEditException { public BrushSettings copy(Player player, LocalSession session, @Optional("5") Expression radius, @Switch('r') boolean randomRotate, @Switch('a') boolean autoRotate, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius); getWorldEdit().checkMaxBrushRadius(radius);
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius)); player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
@ -820,10 +820,10 @@ public class BrushCommands extends BrushProcessor {
max = 99 max = 99
) )
@CommandPermissions("worldedit.brush.command") @CommandPermissions("worldedit.brush.command")
public BrushSettings command(Player player, LocalSession session, double radius, CommandContext args, CommandContext context) throws WorldEditException { public BrushSettings command(Player player, LocalSession session, Expression radius, CommandContext args, CommandContext context) throws WorldEditException {
String cmd = args.getJoinedStrings(1); String cmd = args.getJoinedStrings(1);
return set(session, context, return set(session, context,
new CommandBrush(cmd, radius)) new CommandBrush(cmd))
.setSize(radius); .setSize(radius);
} }

View File

@ -26,6 +26,7 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
@ -116,17 +117,14 @@ public class ToolUtilCommands {
@Command( @Command(
aliases = { "size" }, aliases = { "size" },
usage = "[pattern]", usage = "[size]",
desc = "Set the brush size", desc = "Set the brush size",
min = 1, min = 1,
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.options.size") @CommandPermissions("worldedit.brush.options.size")
public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void size(Player player, LocalSession session, EditSession editSession, Expression radius) throws WorldEditException {
int radius = args.getInteger(0);
we.checkMaxBrushRadius(radius); we.checkMaxBrushRadius(radius);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius);
player.print("Brush size set."); player.print("Brush size set.");
} }

View File

@ -23,6 +23,7 @@ import com.google.gson.reflect.TypeToken;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.*; import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.command.tool.brush.Brush;
@ -351,6 +352,15 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
this.getContext().setSize(radius); this.getContext().setSize(radius);
} }
/**
* Set the set brush size.
*
* @param radius a radius
*/
public void setSize(Expression radius) {
this.getContext().setSize(radius);
}
/** /**
* Get the set brush range. * Get the set brush range.
* *
@ -476,7 +486,9 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
} }
try { try {
new PatternTraverser(current).reset(editSession); new PatternTraverser(current).reset(editSession);
brush.build(editSession, target, current.getMaterial(), current.getSize()); double size = current.getSize();
WorldEdit.getInstance().checkMaxBrushRadius(size);
brush.build(editSession, target, current.getMaterial(), size);
} catch (WorldEditException e) { } catch (WorldEditException e) {
player.printError("Max blocks change limit reached."); // Never happens player.printError("Max blocks change limit reached."); // Never happens
} finally { } finally {

View File

@ -80,6 +80,11 @@ public class Expression {
return new Expression(expression, variableNames); return new Expression(expression, variableNames);
} }
public Expression(double constant) {
variableNames = null;
root = new Constant(0, constant);
}
private Expression(String expression, String... variableNames) throws ExpressionException { private Expression(String expression, String... variableNames) throws ExpressionException {
this(Lexer.tokenize(expression), variableNames); this(Lexer.tokenize(expression), variableNames);
} }
@ -106,6 +111,9 @@ public class Expression {
} }
public double evaluate(double... values) throws EvaluationException { public double evaluate(double... values) throws EvaluationException {
if (root instanceof Constant) {
return root.getValue();
}
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
Variable var = variableArray[i]; Variable var = variableArray[i];
var.value = values[i]; var.value = values[i];
@ -124,6 +132,10 @@ public class Expression {
root = root.optimize(); root = root.optimize();
} }
public RValue getRoot() {
return root;
}
@Override @Override
public String toString() { public String toString() {
return root.toString(); return root.toString();