Search in sources :

Example 1 with WorldEditExpressionEnvironment

use of com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment in project FastAsyncWorldEdit by IntellectualSites.

the class ExpressionMaskParser method parseFromInput.

@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
    if (!input.startsWith("=")) {
        return null;
    }
    // FAWE start - richer parsing
    if (input.charAt(1) == '[') {
        int end = input.lastIndexOf(']');
        if (end == -1) {
            return null;
        }
        input = input.substring(2, end);
    } else {
        input = input.substring(1);
    }
    try {
        // FAWE start - richer parsing
        Expression exp = Expression.compile(input, "x", "y", "z");
        // FAWE end
        WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(context.requireExtent(), Vector3.ONE, Vector3.ZERO);
        exp.setEnvironment(env);
        if (context.getActor() != null) {
            SessionOwner owner = context.getActor();
            IntSupplier timeout = () -> WorldEdit.getInstance().getSessionManager().get(owner).getTimeout();
            return new ExpressionMask(exp, timeout);
        }
        return new ExpressionMask(exp);
    } catch (ExpressionException e) {
        throw new InputParseException(Caption.of("worldedit.error.parser.invalid-expression", TextComponent.of(e.getMessage())));
    }
}
Also used : InputParseException(com.sk89q.worldedit.extension.input.InputParseException) WorldEditExpressionEnvironment(com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment) Expression(com.sk89q.worldedit.internal.expression.Expression) IntSupplier(java.util.function.IntSupplier) SessionOwner(com.sk89q.worldedit.session.SessionOwner) ExpressionException(com.sk89q.worldedit.internal.expression.ExpressionException) ExpressionMask(com.sk89q.worldedit.function.mask.ExpressionMask)

Example 2 with WorldEditExpressionEnvironment

use of com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment in project FastAsyncWorldEdit by IntellectualSites.

the class ExpressionPatternParser method parseFromSimpleInput.

@Override
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
    try {
        Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
        WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(context.requireExtent(), Vector3.ONE, Vector3.ZERO);
        exp.setEnvironment(env);
        return new ExpressionPattern(exp);
    } catch (ExpressionException e) {
        throw new InputParseException(Caption.of("worldedit.error.parser.invalid-expression", TextComponent.of(e.getMessage())));
    }
}
Also used : InputParseException(com.sk89q.worldedit.extension.input.InputParseException) WorldEditExpressionEnvironment(com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment) Expression(com.sk89q.worldedit.internal.expression.Expression) ExpressionPattern(com.fastasyncworldedit.core.function.pattern.ExpressionPattern) ExpressionException(com.sk89q.worldedit.internal.expression.ExpressionException)

Example 3 with WorldEditExpressionEnvironment

use of com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment in project FastAsyncWorldEdit by IntellectualSites.

the class EditSession method makeBiomeShape.

public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType, final String expressionString, final boolean hollow, final int timeout) throws ExpressionException {
    final Expression expression = Expression.compile(expressionString, "x", "y", "z");
    expression.optimize();
    final EditSession editSession = this;
    final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(editSession, unit, zero);
    expression.setEnvironment(environment);
    AtomicInteger timedOut = new AtomicInteger();
    final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {

        @Override
        protected BiomeType getBiome(int x, int y, int z, BiomeType defaultBiomeType) {
            environment.setCurrentBlock(x, y, z);
            double scaledX = (x - zero.getX()) / unit.getX();
            double scaledY = (y - zero.getY()) / unit.getY();
            double scaledZ = (z - zero.getZ()) / unit.getZ();
            try {
                if (expression.evaluate(new double[] { scaledX, scaledY, scaledZ }, timeout) <= 0) {
                    return null;
                }
                // TODO: Allow biome setting via a script variable (needs BiomeType<->int mapping)
                return defaultBiomeType;
            } catch (ExpressionTimeoutException e) {
                timedOut.getAndIncrement();
                return null;
            } catch (Exception e) {
                LOGGER.warn("Failed to create shape", e);
                return null;
            }
        }
    };
    int changed = shape.generate(this, biomeType, hollow);
    if (timedOut.get() > 0) {
        throw new ExpressionTimeoutException(String.format("%d biomes changed. %d biomes took too long to evaluate (increase time with //timeout)", changed, timedOut.get()));
    }
    return changed;
}
Also used : BiomeType(com.sk89q.worldedit.world.biome.BiomeType) WorldEditExpressionEnvironment(com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment) Expression(com.sk89q.worldedit.internal.expression.Expression) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArbitraryBiomeShape(com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape) ExpressionTimeoutException(com.sk89q.worldedit.internal.expression.ExpressionTimeoutException) 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 4 with WorldEditExpressionEnvironment

use of com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment 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 5 with WorldEditExpressionEnvironment

use of com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment 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

WorldEditExpressionEnvironment (com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment)5 Expression (com.sk89q.worldedit.internal.expression.Expression)4 ExpressionException (com.sk89q.worldedit.internal.expression.ExpressionException)4 EvaluationException (com.sk89q.worldedit.internal.expression.EvaluationException)3 MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)2 MutableVector3 (com.fastasyncworldedit.core.math.MutableVector3)2 InputParseException (com.sk89q.worldedit.extension.input.InputParseException)2 ExpressionTimeoutException (com.sk89q.worldedit.internal.expression.ExpressionTimeoutException)2 Variable (com.sk89q.worldedit.internal.expression.LocalSlot.Variable)2 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)2 Vector3 (com.sk89q.worldedit.math.Vector3)2 BlockState (com.sk89q.worldedit.world.block.BlockState)2 IOException (java.io.IOException)2 ExpressionPattern (com.fastasyncworldedit.core.function.pattern.ExpressionPattern)1 ExpressionMask (com.sk89q.worldedit.function.mask.ExpressionMask)1 FlatRegionVisitor (com.sk89q.worldedit.function.visitor.FlatRegionVisitor)1 RegionVisitor (com.sk89q.worldedit.function.visitor.RegionVisitor)1 ArbitraryBiomeShape (com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape)1 ArbitraryShape (com.sk89q.worldedit.regions.shape.ArbitraryShape)1 SessionOwner (com.sk89q.worldedit.session.SessionOwner)1