Search in sources :

Example 6 with ExpressionException

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

the class GenerationCommands method generate.

@Command(name = "/generate", aliases = { "/gen", "/g" }, desc = "Generates a shape according to a formula.", descFooter = "For details, see https://ehub.to/we/expr")
@CommandPermissions("worldedit.generation.shape")
@Logging(ALL)
@Confirm(Confirm.Processor.REGION)
public int generate(Actor actor, LocalSession session, EditSession editSession, @Selection Region region, @Arg(desc = "The pattern of blocks to set") Pattern pattern, @Arg(desc = "Expression to test block placement locations and set block type", variable = true) List<String> expression, @Switch(name = 'h', desc = "Generate a hollow shape") boolean hollow, @Switch(name = 'r', desc = "Use the game's coordinate origin") boolean useRawCoords, @Switch(name = 'o', desc = "Use the placement's coordinate origin") boolean offset, @Switch(name = 'c', desc = "Use the selection's center as origin") boolean offsetCenter) throws WorldEditException {
    final Vector3 zero;
    Vector3 unit;
    if (useRawCoords) {
        zero = Vector3.ZERO;
        unit = Vector3.ONE;
    } else if (offset) {
        zero = session.getPlacementPosition(actor).toVector3();
        unit = Vector3.ONE;
    } else if (offsetCenter) {
        final Vector3 min = region.getMinimumPoint().toVector3();
        final Vector3 max = region.getMaximumPoint().toVector3();
        zero = max.add(min).multiply(0.5);
        unit = Vector3.ONE;
    } else {
        final Vector3 min = region.getMinimumPoint().toVector3();
        final Vector3 max = region.getMaximumPoint().toVector3();
        zero = max.add(min).multiply(0.5);
        unit = max.subtract(zero);
        if (unit.getX() == 0) {
            unit = unit.withX(1.0);
        }
        if (unit.getY() == 0) {
            unit = unit.withY(1.0);
        }
        if (unit.getZ() == 0) {
            unit = unit.withZ(1.0);
        }
    }
    final Vector3 unit1 = unit;
    try {
        final int affected = editSession.makeShape(region, zero, unit1, pattern, String.join(" ", expression), hollow, session.getTimeout());
        if (actor instanceof Player) {
            ((Player) actor).findFreePosition();
        }
        actor.print(Caption.of("worldedit.generate.created", TextComponent.of(affected)));
        return affected;
    } catch (ExpressionException e) {
        actor.printError(TextComponent.of(e.getMessage()));
        return 0;
    }
}
Also used : Player(com.sk89q.worldedit.entity.Player) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) ExpressionException(com.sk89q.worldedit.internal.expression.ExpressionException) Logging(com.sk89q.worldedit.command.util.Logging) Command(org.enginehub.piston.annotation.Command) Confirm(com.sk89q.worldedit.command.util.annotation.Confirm) CommandPermissions(com.sk89q.worldedit.command.util.CommandPermissions)

Example 7 with ExpressionException

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

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

Aggregations

ExpressionException (com.sk89q.worldedit.internal.expression.ExpressionException)8 Expression (com.sk89q.worldedit.internal.expression.Expression)5 CommandPermissions (com.sk89q.worldedit.command.util.CommandPermissions)4 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)4 Vector3 (com.sk89q.worldedit.math.Vector3)4 WorldEditExpressionEnvironment (com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment)4 Command (org.enginehub.piston.annotation.Command)4 Logging (com.sk89q.worldedit.command.util.Logging)3 Confirm (com.sk89q.worldedit.command.util.annotation.Confirm)3 Preload (com.sk89q.worldedit.command.util.annotation.Preload)2 Player (com.sk89q.worldedit.entity.Player)2 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 ExpressionMask (com.sk89q.worldedit.function.mask.ExpressionMask)1 Variable (com.sk89q.worldedit.internal.expression.LocalSlot.Variable)1