diff --git a/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java b/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java index e611f93b7..fa2cdf163 100644 --- a/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java +++ b/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java @@ -29,6 +29,7 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.BiomeMask2D; import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.mask.ExpressionMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.function.mask.Masks; @@ -36,6 +37,7 @@ import com.sk89q.worldedit.function.mask.NoiseFilter; import com.sk89q.worldedit.function.mask.OffsetMask; import com.sk89q.worldedit.function.mask.RegionMask; import com.sk89q.worldedit.function.mask.SolidBlockMask; +import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.session.request.Request; @@ -140,6 +142,13 @@ class DefaultMaskParser extends InputParser { int i = Integer.parseInt(component.substring(1)); return new NoiseFilter(new RandomNoise(), ((double) i) / 100); + case '=': + try { + return new ExpressionMask(component.substring(1)); + } catch (ExpressionException e) { + throw new InputParseException("Invalid expression: " + e.getMessage()); + } + case '!': if (component.length() > 1) { return Masks.negate(getBlockMaskComponent(masks, component.substring(1), context)); diff --git a/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java b/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java new file mode 100644 index 000000000..ef0a02d01 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java @@ -0,0 +1,77 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.function.mask; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; + +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A mask that evaluates an expression. + * + *

Expressions are evaluated as {@code true} if they return a value + * greater than {@code 0}.

+ */ +public class ExpressionMask extends AbstractMask { + + private final Expression expression; + + /** + * Create a new instance. + * + * @param expression the expression + * @throws ExpressionException thrown if there is an error with the expression + */ + public ExpressionMask(String expression) throws ExpressionException { + checkNotNull(expression); + this.expression = Expression.compile(expression, "x", "y", "z"); + } + + /** + * Create a new instance. + * + * @param expression the expression + */ + public ExpressionMask(Expression expression) { + checkNotNull(expression); + this.expression = expression; + } + + @Override + public boolean test(Vector vector) { + try { + return expression.evaluate(vector.getX(), vector.getY(), vector.getZ()) > 0; + } catch (EvaluationException e) { + return false; + } + } + + @Nullable + @Override + public Mask2D toMask2D() { + return new ExpressionMask2D(expression); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java new file mode 100644 index 000000000..52fc28c57 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java @@ -0,0 +1,63 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.function.mask; + +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ExpressionMask2D extends AbstractMask2D { + + private final Expression expression; + + /** + * Create a new instance. + * + * @param expression the expression + * @throws ExpressionException thrown if there is an error with the expression + */ + public ExpressionMask2D(String expression) throws ExpressionException { + checkNotNull(expression); + this.expression = Expression.compile(expression, "x", "z"); + } + + /** + * Create a new instance. + * + * @param expression the expression + */ + public ExpressionMask2D(Expression expression) { + checkNotNull(expression); + this.expression = expression; + } + + @Override + public boolean test(Vector2D vector) { + try { + return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0; + } catch (EvaluationException e) { + return false; + } + } + +}