Search in sources :

Example 6 with Expression

use of com.sk89q.worldedit.internal.expression.Expression 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 7 with Expression

use of com.sk89q.worldedit.internal.expression.Expression 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)

Aggregations

Expression (com.sk89q.worldedit.internal.expression.Expression)7 ExpressionException (com.sk89q.worldedit.internal.expression.ExpressionException)5 WorldEditExpressionEnvironment (com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment)4 InputParseException (com.sk89q.worldedit.extension.input.InputParseException)2 EvaluationException (com.sk89q.worldedit.internal.expression.EvaluationException)2 ExpressionTimeoutException (com.sk89q.worldedit.internal.expression.ExpressionTimeoutException)2 IOException (java.io.IOException)2 ExpressionPattern (com.fastasyncworldedit.core.function.pattern.ExpressionPattern)1 MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)1 MutableVector3 (com.fastasyncworldedit.core.math.MutableVector3)1 CommandPermissions (com.sk89q.worldedit.command.util.CommandPermissions)1 ExpressionMask (com.sk89q.worldedit.function.mask.ExpressionMask)1 Variable (com.sk89q.worldedit.internal.expression.LocalSlot.Variable)1 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)1 Vector3 (com.sk89q.worldedit.math.Vector3)1 ArbitraryBiomeShape (com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape)1 ArbitraryShape (com.sk89q.worldedit.regions.shape.ArbitraryShape)1 SessionOwner (com.sk89q.worldedit.session.SessionOwner)1 BiomeType (com.sk89q.worldedit.world.biome.BiomeType)1 BaseBlock (com.sk89q.worldedit.world.block.BaseBlock)1