Added a few new things using block states.

* `//set ##*tag` sets all states in the tag (not just default state per type)
* `//set ^type` is a pattern changing block type but copying all valid existing states
* `//set ^[prop=val,...]` sets the property `prop` to `val` wherever the existing block has that property
* `//set ^type[prop=val,...]` does both of the above
Those work anywhere a pattern is taken, of course.

* The mask syntax `^[prop=val]` matches blocks with the property `prop` set to `val`, or blocks that don't have the property at all.
* The mask syntax `^=[prop=val]` only matches blocks that have the property.
Those work anywhere a mask is taken, of course. (`//mask`, `//gmask`, `//replace`, etc)

The `//drain` command now takes `-w` flag that removes the waterlogged state from blocks (in addition to removing water, as before).
This commit is contained in:
wizjany
2019-02-12 16:39:09 -05:00
parent 1ae0e88b63
commit 88014b18a3
19 changed files with 711 additions and 49 deletions

View File

@ -53,6 +53,7 @@ import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.BlockStateMask;
import com.sk89q.worldedit.function.mask.BoundedHeightMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
@ -68,6 +69,7 @@ import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
@ -115,7 +117,9 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@ -125,8 +129,6 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* An {@link Extent} that handles history, {@link BlockBag}s, change limits,
* block re-ordering, and much more. Most operations in WorldEdit use this class.
@ -1283,15 +1285,38 @@ public class EditSession implements Extent, AutoCloseable {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(BlockVector3 origin, double radius) throws MaxChangedBlocksException {
return drainArea(origin, radius, false);
}
/**
* Drain nearby pools of water or lava, optionally removed waterlogged states from blocks.
*
* @param origin the origin to drain from, which will search a 3x3 area
* @param radius the radius of the removal, where a value should be 0 or greater
* @param waterlogged true to make waterlogged blocks non-waterlogged as well
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(BlockVector3 origin, double radius, boolean waterlogged) throws MaxChangedBlocksException {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
MaskIntersection mask = new MaskIntersection(
new BoundedHeightMask(0, getWorld().getMaxY()),
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
getWorld().createLiquidMask());
waterlogged ? new MaskUnion(
getWorld().createLiquidMask(),
new BlockStateMask(this, new HashMap<String, String>() {{
put("waterlogged", "true");
}}, true))
: getWorld().createLiquidMask());
BlockReplace replace = new BlockReplace(this, new BlockPattern(BlockTypes.AIR.getDefaultState()));
BlockReplace replace;
if (waterlogged) {
replace = new BlockReplace(this, new WaterloggedRemover(this));
} else {
replace = new BlockReplace(this, new BlockPattern(BlockTypes.AIR.getDefaultState()));
}
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace);
// Around the origin in a 3x3 block
@ -2197,7 +2222,7 @@ public class EditSession implements Extent, AutoCloseable {
try {
if (expression.evaluate(scaled.getX(), scaled.getZ()) <= 0) {
return null; // TODO should return OUTSIDE? seems to cause issues otherwise, workedaround for now
return null;
}
// TODO: Allow biome setting via a script variable (needs BiomeType<->int mapping)