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;
}
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;
}
Aggregations