mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-11-19 10:25:00 +00:00
Added query{,Abs,Rel}(x,y,z,typevar,datavar) to the expression parser.
This commit is contained in:
parent
eba1114b39
commit
8badb09399
@ -2808,10 +2808,15 @@ public class EditSession {
|
|||||||
final RValue typeVariable = expression.getVariable("type", false);
|
final RValue typeVariable = expression.getVariable("type", false);
|
||||||
final RValue dataVariable = expression.getVariable("data", false);
|
final RValue dataVariable = expression.getVariable("data", false);
|
||||||
|
|
||||||
|
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
|
||||||
|
expression.setEnvironment(environment);
|
||||||
|
|
||||||
final ArbitraryShape shape = new ArbitraryShape(region) {
|
final ArbitraryShape shape = new ArbitraryShape(region) {
|
||||||
@Override
|
@Override
|
||||||
protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) {
|
protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) {
|
||||||
final Vector scaled = new Vector(x, y, z).subtract(zero).divide(unit);
|
final Vector current = new Vector(x, y, z);
|
||||||
|
environment.setCurrentBlock(current);
|
||||||
|
final Vector scaled = current.subtract(zero).divide(unit);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getType(), defaultMaterial.getData()) <= 0) {
|
if (expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getType(), defaultMaterial.getData()) <= 0) {
|
||||||
@ -2837,7 +2842,8 @@ public class EditSession {
|
|||||||
final RValue y = expression.getVariable("y", false);
|
final RValue y = expression.getVariable("y", false);
|
||||||
final RValue z = expression.getVariable("z", false);
|
final RValue z = expression.getVariable("z", false);
|
||||||
|
|
||||||
Vector zero2 = zero.add(0.5, 0.5, 0.5);
|
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
|
||||||
|
expression.setEnvironment(environment);
|
||||||
|
|
||||||
final DoubleArrayList<BlockVector, BaseBlock> queue = new DoubleArrayList<BlockVector, BaseBlock>(false);
|
final DoubleArrayList<BlockVector, BaseBlock> queue = new DoubleArrayList<BlockVector, BaseBlock>(false);
|
||||||
|
|
||||||
@ -2848,13 +2854,11 @@ public class EditSession {
|
|||||||
// transform
|
// transform
|
||||||
expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ());
|
expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ());
|
||||||
|
|
||||||
final Vector sourceScaled = new Vector(x.getValue(), y.getValue(), z.getValue());
|
final BlockVector sourcePosition = environment.toWorld(scaled.getX(), scaled.getY(), scaled.getZ());
|
||||||
|
|
||||||
// unscale, unoffset, round-nearest
|
|
||||||
final BlockVector sourcePosition = sourceScaled.multiply(unit).add(zero2).toBlockPoint();
|
|
||||||
|
|
||||||
// read block from world
|
// read block from world
|
||||||
BaseBlock material = new BaseBlock(world.getBlockType(sourcePosition), world.getBlockData(sourcePosition));
|
// TODO: use getBlock here once the reflection is out of the way
|
||||||
|
final BaseBlock material = new BaseBlock(world.getBlockType(sourcePosition), world.getBlockData(sourcePosition));
|
||||||
|
|
||||||
// queue operation
|
// queue operation
|
||||||
queue.put(position, material);
|
queue.put(position, material);
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.expression.runtime.ExpressionEnvironment;
|
||||||
|
|
||||||
|
class WorldEditExpressionEnvironment implements ExpressionEnvironment {
|
||||||
|
private final Vector unit;
|
||||||
|
private final Vector zero2;
|
||||||
|
private Vector current = new Vector();
|
||||||
|
private EditSession editSession;
|
||||||
|
|
||||||
|
public WorldEditExpressionEnvironment(EditSession editSession, Vector unit, Vector zero) {
|
||||||
|
this.editSession = editSession;
|
||||||
|
this.unit = unit;
|
||||||
|
this.zero2 = zero.add(0.5, 0.5, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockVector toWorld(double x, double y, double z) {
|
||||||
|
// unscale, unoffset, round-nearest
|
||||||
|
return new Vector(x, y, z).multiply(unit).add(zero2).toBlockPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector toWorldRel(double x, double y, double z) {
|
||||||
|
return current.add(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockType(double x, double y, double z) {
|
||||||
|
return editSession.getBlockType(toWorld(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockData(double x, double y, double z) {
|
||||||
|
return editSession.getBlockData(toWorld(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockTypeAbs(double x, double y, double z) {
|
||||||
|
return editSession.getBlockType(new Vector(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockDataAbs(double x, double y, double z) {
|
||||||
|
return editSession.getBlockData(new Vector(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockTypeRel(double x, double y, double z) {
|
||||||
|
return editSession.getBlockType(toWorldRel(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockDataRel(double x, double y, double z) {
|
||||||
|
return editSession.getBlockData(toWorldRel(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentBlock(Vector current) {
|
||||||
|
this.current = current;
|
||||||
|
}
|
||||||
|
}
|
@ -24,9 +24,12 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.expression.lexer.Lexer;
|
import com.sk89q.worldedit.expression.lexer.Lexer;
|
||||||
import com.sk89q.worldedit.expression.lexer.tokens.Token;
|
import com.sk89q.worldedit.expression.lexer.tokens.Token;
|
||||||
import com.sk89q.worldedit.expression.parser.Parser;
|
import com.sk89q.worldedit.expression.parser.Parser;
|
||||||
|
import com.sk89q.worldedit.expression.runtime.ExpressionEnvironment;
|
||||||
import com.sk89q.worldedit.expression.runtime.Constant;
|
import com.sk89q.worldedit.expression.runtime.Constant;
|
||||||
import com.sk89q.worldedit.expression.runtime.EvaluationException;
|
import com.sk89q.worldedit.expression.runtime.EvaluationException;
|
||||||
import com.sk89q.worldedit.expression.runtime.Functions;
|
import com.sk89q.worldedit.expression.runtime.Functions;
|
||||||
@ -43,7 +46,7 @@ import com.sk89q.worldedit.expression.runtime.Variable;
|
|||||||
* Arithmetic: +, -, *, /, % (modulo), ^ (power), - (unary), --, ++ (prefix only)
|
* Arithmetic: +, -, *, /, % (modulo), ^ (power), - (unary), --, ++ (prefix only)
|
||||||
* Comparison: <=, >=, >, <, ==, !=, ~= (near)
|
* Comparison: <=, >=, >, <, ==, !=, ~= (near)
|
||||||
*
|
*
|
||||||
* Supported functions: abs, acos, asin, atan, atan2, cbrt, ceil, cos, cosh, exp, floor, ln, log, log10, max, max, min, min, rint, round, sin, sinh, sqrt, tan, tanh
|
* Supported functions: abs, acos, asin, atan, atan2, cbrt, ceil, cos, cosh, exp, floor, ln, log, log10, max, max, min, min, rint, round, sin, sinh, sqrt, tan, tanh and more. (See the Functions class or the wiki)
|
||||||
*
|
*
|
||||||
* Constants: e, pi
|
* Constants: e, pi
|
||||||
*
|
*
|
||||||
@ -65,6 +68,7 @@ public class Expression {
|
|||||||
private final String[] variableNames;
|
private final String[] variableNames;
|
||||||
private RValue root;
|
private RValue root;
|
||||||
private final Functions functions = new Functions();
|
private final Functions functions = new Functions();
|
||||||
|
private ExpressionEnvironment environment;
|
||||||
|
|
||||||
public static Expression compile(String expression, String... variableNames) throws ExpressionException {
|
public static Expression compile(String expression, String... variableNames) throws ExpressionException {
|
||||||
return new Expression(expression, variableNames);
|
return new Expression(expression, variableNames);
|
||||||
@ -157,4 +161,12 @@ public class Expression {
|
|||||||
public Functions getFunctions() {
|
public Functions getFunctions() {
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExpressionEnvironment getEnvironment() {
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnvironment(ExpressionEnvironment environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.sk89q.worldedit.expression.runtime;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a way to access blocks in a world. Has to accept non-rounded coordinates.
|
||||||
|
*/
|
||||||
|
public interface ExpressionEnvironment {
|
||||||
|
int getBlockType(double x, double y, double z);
|
||||||
|
int getBlockData(double x, double y, double z);
|
||||||
|
int getBlockTypeAbs(double x, double y, double z);
|
||||||
|
int getBlockDataAbs(double x, double y, double z);
|
||||||
|
int getBlockTypeRel(double x, double y, double z);
|
||||||
|
int getBlockDataRel(double x, double y, double z);
|
||||||
|
}
|
@ -375,4 +375,60 @@ public final class Functions {
|
|||||||
public static double randint(RValue max) throws EvaluationException {
|
public static double randint(RValue max) throws EvaluationException {
|
||||||
return random.nextInt((int) Math.floor(max.getValue()));
|
return random.nextInt((int) Math.floor(max.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static double queryInternal(LValue type, LValue data, double typeId, double dataValue) throws EvaluationException {
|
||||||
|
// Compare to input values and determine return value
|
||||||
|
final double ret = typeId == type.getValue() && typeId == type.getValue() ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
type.assign(typeId);
|
||||||
|
data.assign(dataValue);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Dynamic
|
||||||
|
public static double query(RValue x, RValue y, RValue z, LValue type, LValue data) throws EvaluationException {
|
||||||
|
final double xp = x.getValue();
|
||||||
|
final double yp = y.getValue();
|
||||||
|
final double zp = z.getValue();
|
||||||
|
|
||||||
|
final ExpressionEnvironment environment = Expression.getInstance().getEnvironment();
|
||||||
|
|
||||||
|
// Read values from world
|
||||||
|
final double typeId = environment.getBlockType(xp, yp, zp);
|
||||||
|
final double dataValue = environment.getBlockData(xp, yp, zp);
|
||||||
|
|
||||||
|
return queryInternal(type, data, typeId, dataValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Dynamic
|
||||||
|
public static double queryAbs(RValue x, RValue y, RValue z, LValue type, LValue data) throws EvaluationException {
|
||||||
|
final double xp = x.getValue();
|
||||||
|
final double yp = y.getValue();
|
||||||
|
final double zp = z.getValue();
|
||||||
|
|
||||||
|
final ExpressionEnvironment environment = Expression.getInstance().getEnvironment();
|
||||||
|
|
||||||
|
// Read values from world
|
||||||
|
final double typeId = environment.getBlockTypeAbs(xp, yp, zp);
|
||||||
|
final double dataValue = environment.getBlockDataAbs(xp, yp, zp);
|
||||||
|
|
||||||
|
return queryInternal(type, data, typeId, dataValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Dynamic
|
||||||
|
public static double queryRel(RValue x, RValue y, RValue z, LValue type, LValue data) throws EvaluationException {
|
||||||
|
final double xp = x.getValue();
|
||||||
|
final double yp = y.getValue();
|
||||||
|
final double zp = z.getValue();
|
||||||
|
|
||||||
|
final ExpressionEnvironment environment = Expression.getInstance().getEnvironment();
|
||||||
|
|
||||||
|
// Read values from world
|
||||||
|
final double typeId = environment.getBlockTypeRel(xp, yp, zp);
|
||||||
|
final double dataValue = environment.getBlockDataRel(xp, yp, zp);
|
||||||
|
|
||||||
|
return queryInternal(type, data, typeId, dataValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user