Search in sources :

Example 1 with Variable

use of com.sk89q.worldedit.internal.expression.LocalSlot.Variable in project FastAsyncWorldEdit by IntellectualSites.

the class EditSession method makeShape.

/**
 * Generate a shape for the given expression.
 *
 * @param region           the region to generate the shape in
 * @param zero             the coordinate origin for x/y/z variables
 * @param unit             the scale of the x/y/z/ variables
 * @param pattern          the default material to make the shape from
 * @param expressionString the expression defining the shape
 * @param hollow           whether the shape should be hollow
 * @param timeout          the time, in milliseconds, to wait for each expression evaluation before halting it. -1 to disable
 * @return number of blocks changed
 * @throws ExpressionException       if there is a problem with the expression
 * @throws MaxChangedBlocksException if the maximum block change limit is exceeded
 */
public int makeShape(final Region region, final Vector3 zero, final Vector3 unit, final Pattern pattern, final String expressionString, final boolean hollow, final int timeout) throws ExpressionException, MaxChangedBlocksException {
    final Expression expression = Expression.compile(expressionString, "x", "y", "z", "type", "data");
    expression.optimize();
    final Variable typeVariable = expression.getSlots().getVariable("type").orElseThrow(IllegalStateException::new);
    final Variable dataVariable = expression.getSlots().getVariable("data").orElseThrow(IllegalStateException::new);
    final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
    expression.setEnvironment(environment);
    final int[] timedOut = { 0 };
    final ArbitraryShape shape = new ArbitraryShape(region) {

        @Override
        protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) {
            final Vector3 current = Vector3.at(x, y, z);
            environment.setCurrentBlock(current);
            final Vector3 scaled = current.subtract(zero).divide(unit);
            try {
                int[] legacy = LegacyMapper.getInstance().getLegacyFromBlock(defaultMaterial.toImmutableState());
                int typeVar = 0;
                int dataVar = 0;
                if (legacy != null) {
                    typeVar = legacy[0];
                    if (legacy.length > 1) {
                        dataVar = legacy[1];
                    }
                }
                if (expression.evaluate(new double[] { scaled.getX(), scaled.getY(), scaled.getZ(), typeVar, dataVar }, timeout) <= 0) {
                    return null;
                }
                int newType = (int) typeVariable.getValue();
                int newData = (int) dataVariable.getValue();
                if (newType != typeVar || newData != dataVar) {
                    BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(newType, newData);
                    return state == null ? defaultMaterial : state.toBaseBlock();
                } else {
                    return defaultMaterial;
                }
            } catch (ExpressionTimeoutException e) {
                timedOut[0] = timedOut[0] + 1;
                return null;
            } catch (Exception e) {
                LOGGER.warn("Failed to create shape", e);
                return null;
            }
        }
    };
    int changed = shape.generate(this, pattern, hollow);
    if (timedOut[0] > 0) {
        throw new ExpressionTimeoutException(String.format("%d blocks changed. %d blocks took too long to evaluate (increase with //timeout).", changed, timedOut[0]));
    }
    return changed;
}
Also used : ArbitraryShape(com.sk89q.worldedit.regions.shape.ArbitraryShape) Variable(com.sk89q.worldedit.internal.expression.LocalSlot.Variable) BlockState(com.sk89q.worldedit.world.block.BlockState) WorldEditExpressionEnvironment(com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment) Expression(com.sk89q.worldedit.internal.expression.Expression) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) MutableVector3(com.fastasyncworldedit.core.math.MutableVector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) ExpressionTimeoutException(com.sk89q.worldedit.internal.expression.ExpressionTimeoutException) BaseBlock(com.sk89q.worldedit.world.block.BaseBlock) ExpressionException(com.sk89q.worldedit.internal.expression.ExpressionException) EvaluationException(com.sk89q.worldedit.internal.expression.EvaluationException) IOException(java.io.IOException) ExpressionTimeoutException(com.sk89q.worldedit.internal.expression.ExpressionTimeoutException)

Example 2 with Variable

use of com.sk89q.worldedit.internal.expression.LocalSlot.Variable in project FastAsyncWorldEdit by IntellectualSites.

the class EditSession method deformRegion.

/**
 * Internal version of {@link EditSession#deformRegion(Region, Vector3, Vector3, String, int)}.
 *
 * <p>
 * The Expression class is subject to change. Expressions should be provided via the string overload.
 * </p>
 */
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final Expression expression, final int timeout) throws ExpressionException, MaxChangedBlocksException {
    final Variable x = expression.getSlots().getVariable("x").orElseThrow(IllegalStateException::new);
    final Variable y = expression.getSlots().getVariable("y").orElseThrow(IllegalStateException::new);
    final Variable z = expression.getSlots().getVariable("z").orElseThrow(IllegalStateException::new);
    final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
    expression.setEnvironment(environment);
    // FAWE start
    final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
    RegionVisitor visitor = new RegionVisitor(region, position -> {
        try {
            // offset, scale
            final Vector3 scaled = position.toVector3().subtract(zero).divide(unit);
            // transform
            expression.evaluate(new double[] { scaled.getX(), scaled.getY(), scaled.getZ() }, timeout);
            int xv = (int) (x.getValue() * unit.getX() + zero2.getX());
            int yv = (int) (y.getValue() * unit.getY() + zero2.getY());
            int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ());
            BlockState get;
            if (yv >= minY && yv <= maxY) {
                get = getBlock(xv, yv, zv);
            } else {
                get = BlockTypes.AIR.getDefaultState();
            }
            // read block from world
            return setBlock(position, get);
        } catch (EvaluationException e) {
            throw new RuntimeException(e);
        }
    }, this);
    Operations.completeBlindly(visitor);
    changes += visitor.getAffected();
    return changes;
// FAWE end
}
Also used : Variable(com.sk89q.worldedit.internal.expression.LocalSlot.Variable) RegionVisitor(com.sk89q.worldedit.function.visitor.RegionVisitor) FlatRegionVisitor(com.sk89q.worldedit.function.visitor.FlatRegionVisitor) BlockState(com.sk89q.worldedit.world.block.BlockState) WorldEditExpressionEnvironment(com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) MutableVector3(com.fastasyncworldedit.core.math.MutableVector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) EvaluationException(com.sk89q.worldedit.internal.expression.EvaluationException)

Aggregations

MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)2 MutableVector3 (com.fastasyncworldedit.core.math.MutableVector3)2 EvaluationException (com.sk89q.worldedit.internal.expression.EvaluationException)2 Variable (com.sk89q.worldedit.internal.expression.LocalSlot.Variable)2 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)2 Vector3 (com.sk89q.worldedit.math.Vector3)2 WorldEditExpressionEnvironment (com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment)2 BlockState (com.sk89q.worldedit.world.block.BlockState)2 FlatRegionVisitor (com.sk89q.worldedit.function.visitor.FlatRegionVisitor)1 RegionVisitor (com.sk89q.worldedit.function.visitor.RegionVisitor)1 Expression (com.sk89q.worldedit.internal.expression.Expression)1 ExpressionException (com.sk89q.worldedit.internal.expression.ExpressionException)1 ExpressionTimeoutException (com.sk89q.worldedit.internal.expression.ExpressionTimeoutException)1 ArbitraryShape (com.sk89q.worldedit.regions.shape.ArbitraryShape)1 BaseBlock (com.sk89q.worldedit.world.block.BaseBlock)1 IOException (java.io.IOException)1