mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-12-01 07:03:52 +01:00
Masking changes
Add light related masks - #opacity - #brightness - #blocklight - #skylight - #light - #nolight - #haslight Add mask tab completion Add source masks - `/gsmask` and `/smask` - Masking the source instead of the destination (e.g. with //paste) - if there is no source, the current block/extent will be used
This commit is contained in:
parent
bde4749e2c
commit
30700559db
44
core/src/main/java/com/boydti/fawe/command/MaskBinding.java
Normal file
44
core/src/main/java/com/boydti/fawe/command/MaskBinding.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.boydti.fawe.command;
|
||||||
|
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
|
import com.boydti.fawe.util.StringMan;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||||
|
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MaskBinding extends FaweBinding {
|
||||||
|
private final WorldEdit worldEdit;
|
||||||
|
|
||||||
|
public MaskBinding(WorldEdit worldEdit) {
|
||||||
|
super(worldEdit);
|
||||||
|
this.worldEdit = worldEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getSuggestions(ParameterData parameter, String prefix) {
|
||||||
|
int index = prefix.lastIndexOf(",");
|
||||||
|
String start = index != -1 ? prefix.substring(0, index) : "";
|
||||||
|
String current = index != -1 ? prefix.substring(index) : prefix;
|
||||||
|
if (current.isEmpty()) {
|
||||||
|
return MainUtil.prepend(start, Arrays.asList(DefaultMaskParser.ALL_MASKS));
|
||||||
|
}
|
||||||
|
if (current.startsWith("#") || current.startsWith("=")) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (StringMan.isAlphanumeric(current.charAt(0) + "")) {
|
||||||
|
String[] split2 = current.split(":");
|
||||||
|
if (split2.length == 2 || current.endsWith(":")) {
|
||||||
|
start = (start.isEmpty() ? split2[0] : start + " " + split2[0]) + ":";
|
||||||
|
current = split2.length == 2 ? split2[1] : "";
|
||||||
|
return MainUtil.prepend(start, MainUtil.filter(current, BundledBlockData.getInstance().getBlockStates(split2[0])));
|
||||||
|
}
|
||||||
|
List<String> blocks = BundledBlockData.getInstance().getBlockNames(split2[0]);
|
||||||
|
return MainUtil.prepend(start, blocks);
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
@ -50,6 +50,8 @@ public enum BBC {
|
|||||||
|
|
||||||
MASK_DISABLED("Global mask disabled", "WorldEdit.General"),
|
MASK_DISABLED("Global mask disabled", "WorldEdit.General"),
|
||||||
MASK("Global mask set", "WorldEdit.General"),
|
MASK("Global mask set", "WorldEdit.General"),
|
||||||
|
SOURCE_MASK_DISABLED("Global source mask disabled", "WorldEdit.General"),
|
||||||
|
SOURCE_MASK("Global source mask set", "WorldEdit.General"),
|
||||||
TRANSFORM_DISABLED("Global transform disabled", "WorldEdit.General"),
|
TRANSFORM_DISABLED("Global transform disabled", "WorldEdit.General"),
|
||||||
TRANSFORM("Global transform set", "WorldEdit.General"),
|
TRANSFORM("Global transform set", "WorldEdit.General"),
|
||||||
|
|
||||||
@ -85,6 +87,7 @@ public enum BBC {
|
|||||||
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
||||||
SELECTION_NONE("Make a region selection first", "WorldEdit.Selection"),
|
SELECTION_NONE("Make a region selection first", "WorldEdit.Selection"),
|
||||||
|
|
||||||
|
BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"),
|
||||||
BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
|
BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
|
||||||
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
||||||
BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "WorldEdit.Brush"),
|
BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "WorldEdit.Brush"),
|
||||||
@ -110,6 +113,8 @@ public enum BBC {
|
|||||||
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
BRUSH_RANGE("Brush size set", "WorldEdit.Brush"),
|
||||||
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"),
|
||||||
BRUSH_MASK("Brush mask set", "WorldEdit.Brush"),
|
BRUSH_MASK("Brush mask set", "WorldEdit.Brush"),
|
||||||
|
BRUSH_SOURCE_MASK_DISABLED("Brush source mask disabled", "WorldEdit.Brush"),
|
||||||
|
BRUSH_SOURCE_MASK("Brush source mask set", "WorldEdit.Brush"),
|
||||||
BRUSH_TRANSFORM_DISABLED("Brush transform disabled", "WorldEdit.Brush"),
|
BRUSH_TRANSFORM_DISABLED("Brush transform disabled", "WorldEdit.Brush"),
|
||||||
BRUSH_TRANSFORM("Brush transform set", "WorldEdit.Brush"),
|
BRUSH_TRANSFORM("Brush transform set", "WorldEdit.Brush"),
|
||||||
BRUSH_MATERIAL("Brush material set", "WorldEdit.Brush"),
|
BRUSH_MATERIAL("Brush material set", "WorldEdit.Brush"),
|
||||||
|
@ -30,6 +30,7 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
|||||||
protected static int MAX_RANGE = 500;
|
protected static int MAX_RANGE = 500;
|
||||||
protected int range = -1;
|
protected int range = -1;
|
||||||
private Mask mask = null;
|
private Mask mask = null;
|
||||||
|
private Mask sourceMask = null;
|
||||||
private ResettableExtent transform = null;
|
private ResettableExtent transform = null;
|
||||||
private DoubleActionBrush brush = null;
|
private DoubleActionBrush brush = null;
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -69,6 +70,15 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filter.
|
||||||
|
*
|
||||||
|
* @return the filter
|
||||||
|
*/
|
||||||
|
public Mask getSourceMask() {
|
||||||
|
return sourceMask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the block filter used for identifying blocks to replace.
|
* Set the block filter used for identifying blocks to replace.
|
||||||
*
|
*
|
||||||
@ -78,6 +88,15 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
|||||||
this.mask = filter;
|
this.mask = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the block filter used for identifying blocks to replace.
|
||||||
|
*
|
||||||
|
* @param filter the filter to set
|
||||||
|
*/
|
||||||
|
public void setSourceMask(Mask filter) {
|
||||||
|
this.sourceMask = filter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the brush.
|
* Set the brush.
|
||||||
*
|
*
|
||||||
@ -178,6 +197,19 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
|||||||
editSession.setMask(newMask);
|
editSession.setMask(newMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sourceMask != null) {
|
||||||
|
Mask existingMask = editSession.getSourceMask();
|
||||||
|
|
||||||
|
if (existingMask == null) {
|
||||||
|
editSession.setSourceMask(sourceMask);
|
||||||
|
} else if (existingMask instanceof MaskIntersection) {
|
||||||
|
((MaskIntersection) existingMask).add(sourceMask);
|
||||||
|
} else {
|
||||||
|
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||||
|
newMask.add(sourceMask);
|
||||||
|
editSession.setSourceMask(newMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
editSession.addTransform(transform);
|
editSession.addTransform(transform);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,31 @@ public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFa
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLight(int x, int y, int z) {
|
||||||
|
return queue.getLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int x, int y, int z) {
|
||||||
|
return queue.getEmmittedLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return queue.getSkyLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBrightness(int x, int y, int z) {
|
||||||
|
return queue.getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity(int x, int y, int z) {
|
||||||
|
return queue.getOpacity(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity createEntity(final Location loc, final BaseEntity entity) {
|
public Entity createEntity(final Location loc, final BaseEntity entity) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.boydti.fawe.object.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
|
||||||
|
public interface LightingExtent extends Extent {
|
||||||
|
int getLight(int x, int y, int z);
|
||||||
|
int getSkyLight(int x, int y, int z);
|
||||||
|
int getBlockLight(int x, int y, int z);
|
||||||
|
int getOpacity(int x, int y, int z);
|
||||||
|
int getBrightness(int x, int y, int z);
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.boydti.fawe.object.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public class SourceMaskExtent extends TemporalExtent {
|
||||||
|
private Mask mask;
|
||||||
|
private Vector mutable = new Vector();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mask.
|
||||||
|
*
|
||||||
|
* @return the mask
|
||||||
|
*/
|
||||||
|
public Mask getMask() {
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mask.
|
||||||
|
*
|
||||||
|
* @param mask a mask
|
||||||
|
*/
|
||||||
|
public void setMask(Mask mask) {
|
||||||
|
checkNotNull(mask);
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceMaskExtent(Extent extent, Mask mask) {
|
||||||
|
super(extent);
|
||||||
|
checkNotNull(mask);
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
|
||||||
|
set((int) location.x, (int) location.y, (int) location.z, block);
|
||||||
|
return mask.test(location) && super.setBlock(location, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||||
|
set(x, y, z, block);
|
||||||
|
mutable.x = x;
|
||||||
|
mutable.y = y;
|
||||||
|
mutable.z = z;
|
||||||
|
return mask.test(mutable) && super.setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.boydti.fawe.object.extent;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.Vector2D;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||||
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
|
|
||||||
|
public class TemporalExtent extends AbstractDelegateExtent {
|
||||||
|
private int x,y,z = Integer.MAX_VALUE;
|
||||||
|
private BaseBlock block = EditSession.nullBlock;
|
||||||
|
|
||||||
|
private int bx,bz = Integer.MAX_VALUE;
|
||||||
|
private BaseBiome biome = EditSession.nullBiome;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*
|
||||||
|
* @param extent the extent
|
||||||
|
*/
|
||||||
|
public TemporalExtent(Extent extent) {
|
||||||
|
super(extent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void set(int x, int y, int z, BaseBlock block) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int x, int z, BaseBiome biome) {
|
||||||
|
this.bx = x;
|
||||||
|
this.bz = z;
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBrightness(int x, int y, int z) {
|
||||||
|
if (this.x == x && this.y == y && this.z == z) {
|
||||||
|
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(this.block.getId());
|
||||||
|
if (block == null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.min(15, block.getLightValue());
|
||||||
|
}
|
||||||
|
return super.getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getBlock(Vector position) {
|
||||||
|
if (position.x == x && position.y == y && position.z == z) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
return super.getBlock(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getLazyBlock(Vector position) {
|
||||||
|
if (position.x == x && position.y == y && position.z == z) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
return super.getLazyBlock(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getLazyBlock(int x, int y, int z) {
|
||||||
|
if (this.x == x && this.y == y && this.z == z) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
return super.getLazyBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBiome getBiome(Vector2D position) {
|
||||||
|
if (position.getX() == bx && position.getZ() == bz) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
return super.getBiome(position);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BlockLightMask implements Mask {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final int min,max;
|
||||||
|
|
||||||
|
public BlockLightMask(Extent extent, int min, int max) {
|
||||||
|
this.extent = extent;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Vector vector) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
int light = ((LightingExtent) extent).getBlockLight((int) vector.x, (int) vector.y, (int) vector.z);
|
||||||
|
return light >= min && light <= max;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BrightnessMask implements Mask {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final int min,max;
|
||||||
|
|
||||||
|
public BrightnessMask(Extent extent, int min, int max) {
|
||||||
|
this.extent = extent;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Vector vector) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
int light = ((LightingExtent) extent).getBrightness((int) vector.x, (int) vector.y, (int) vector.z);
|
||||||
|
return light >= min && light <= max;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class LightMask implements Mask {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final int min,max;
|
||||||
|
|
||||||
|
public LightMask(Extent extent, int min, int max) {
|
||||||
|
this.extent = extent;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Vector vector) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
int light = ((LightingExtent) extent).getLight((int) vector.x, (int) vector.y, (int) vector.z);
|
||||||
|
return light >= min && light <= max;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class OpacityMask implements Mask {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final int min,max;
|
||||||
|
|
||||||
|
public OpacityMask(Extent extent, int min, int max) {
|
||||||
|
this.extent = extent;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Vector vector) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
int light = ((LightingExtent) extent).getOpacity((int) vector.x, (int) vector.y, (int) vector.z);
|
||||||
|
return light >= min && light <= max;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class SkyLightMask implements Mask {
|
||||||
|
|
||||||
|
private final Extent extent;
|
||||||
|
private final int min,max;
|
||||||
|
|
||||||
|
public SkyLightMask(Extent extent, int min, int max) {
|
||||||
|
this.extent = extent;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Vector vector) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
int light = ((LightingExtent) extent).getSkyLight((int) vector.x, (int) vector.y, (int) vector.z);
|
||||||
|
return light >= min && light <= max;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.schematic;
|
|||||||
|
|
||||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
@ -12,6 +13,7 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
|||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
@ -114,6 +116,12 @@ public class Schematic {
|
|||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
copy.setTransform(transform);
|
copy.setTransform(transform);
|
||||||
}
|
}
|
||||||
|
Mask sourceMask = editSession.getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(extent);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
editSession.setSourceMask(null);
|
||||||
|
}
|
||||||
if (!pasteAir) {
|
if (!pasteAir) {
|
||||||
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,12 @@ import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
|
|||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
import com.boydti.fawe.object.extent.FastWorldEditExtent;
|
||||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.boydti.fawe.object.extent.NullExtent;
|
import com.boydti.fawe.object.extent.NullExtent;
|
||||||
import com.boydti.fawe.object.extent.ProcessedWEExtent;
|
import com.boydti.fawe.object.extent.ProcessedWEExtent;
|
||||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||||
import com.boydti.fawe.object.extent.SlowExtent;
|
import com.boydti.fawe.object.extent.SlowExtent;
|
||||||
|
import com.boydti.fawe.object.extent.SourceMaskExtent;
|
||||||
import com.boydti.fawe.object.mask.ResettableMask;
|
import com.boydti.fawe.object.mask.ResettableMask;
|
||||||
import com.boydti.fawe.object.progress.DefaultProgressTracker;
|
import com.boydti.fawe.object.progress.DefaultProgressTracker;
|
||||||
import com.boydti.fawe.util.ExtentTraverser;
|
import com.boydti.fawe.util.ExtentTraverser;
|
||||||
@ -155,7 +157,7 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
|||||||
* {@link Extent}s that are chained together. For example, history is logged
|
* {@link Extent}s that are chained together. For example, history is logged
|
||||||
* using the {@link ChangeSetExtent}.</p>
|
* using the {@link ChangeSetExtent}.</p>
|
||||||
*/
|
*/
|
||||||
public class EditSession extends AbstractWorld implements HasFaweQueue {
|
public class EditSession extends AbstractWorld implements HasFaweQueue, LightingExtent {
|
||||||
/**
|
/**
|
||||||
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
|
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
|
||||||
* determine which {@link Extent}s should be bypassed.
|
* determine which {@link Extent}s should be bypassed.
|
||||||
@ -592,6 +594,16 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
|||||||
return maskingExtent != null ? maskingExtent.get().getMask() : null;
|
return maskingExtent != null ? maskingExtent.get().getMask() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mask.
|
||||||
|
*
|
||||||
|
* @return mask, may be null
|
||||||
|
*/
|
||||||
|
public Mask getSourceMask() {
|
||||||
|
ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser(this.extent).find(SourceMaskExtent.class);
|
||||||
|
return maskingExtent != null ? maskingExtent.get().getMask() : null;
|
||||||
|
}
|
||||||
|
|
||||||
public void addTransform(ResettableExtent transform) {
|
public void addTransform(ResettableExtent transform) {
|
||||||
if (transform == null) {
|
if (transform == null) {
|
||||||
ExtentTraverser<AbstractDelegateExtent> traverser = new ExtentTraverser(this.extent).find(ResettableExtent.class);
|
ExtentTraverser<AbstractDelegateExtent> traverser = new ExtentTraverser(this.extent).find(ResettableExtent.class);
|
||||||
@ -607,6 +619,29 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mask.
|
||||||
|
*
|
||||||
|
* @param mask mask or null
|
||||||
|
*/
|
||||||
|
public void setSourceMask(Mask mask) {
|
||||||
|
if (mask == null) {
|
||||||
|
mask = Masks.alwaysTrue();
|
||||||
|
} else {
|
||||||
|
new MaskTraverser(mask).reset(this);
|
||||||
|
}
|
||||||
|
ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser(this.extent).find(SourceMaskExtent.class);
|
||||||
|
if (maskingExtent != null && maskingExtent.get() != null) {
|
||||||
|
Mask oldMask = maskingExtent.get().getMask();
|
||||||
|
if (oldMask instanceof ResettableMask) {
|
||||||
|
((ResettableMask) oldMask).reset();
|
||||||
|
}
|
||||||
|
maskingExtent.get().setMask(mask);
|
||||||
|
} else if (mask != Masks.alwaysTrue()) {
|
||||||
|
this.extent = new SourceMaskExtent(this.extent, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a mask.
|
* Set a mask.
|
||||||
*
|
*
|
||||||
@ -792,6 +827,31 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
|||||||
return this.extent.setBiome(position, biome);
|
return this.extent.setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLight(int x, int y, int z) {
|
||||||
|
return queue.getLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int x, int y, int z) {
|
||||||
|
return queue.getEmmittedLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return queue.getSkyLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBrightness(int x, int y, int z) {
|
||||||
|
return queue.getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity(int x, int y, int z) {
|
||||||
|
return queue.getOpacity(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getLazyBlock(final Vector position) {
|
public BaseBlock getLazyBlock(final Vector position) {
|
||||||
if (position.y > maxY || position.y < 0) {
|
if (position.y > maxY || position.y < 0) {
|
||||||
@ -1794,6 +1854,12 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
|||||||
final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to);
|
final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to);
|
||||||
copy.setRepetitions(count);
|
copy.setRepetitions(count);
|
||||||
copy.setTransform(new AffineTransform().translate(dir.multiply(size)));
|
copy.setTransform(new AffineTransform().translate(dir.multiply(size)));
|
||||||
|
Mask sourceMask = getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(EditSession.this);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
setSourceMask(null);
|
||||||
|
}
|
||||||
if (!copyAir) {
|
if (!copyAir) {
|
||||||
copy.setSourceMask(new ExistingBlockMask(EditSession.this));
|
copy.setSourceMask(new ExistingBlockMask(EditSession.this));
|
||||||
}
|
}
|
||||||
@ -1844,6 +1910,12 @@ public class EditSession extends AbstractWorld implements HasFaweQueue {
|
|||||||
copy.setTransform(new AffineTransform().translate(dir.multiply(distance)));
|
copy.setTransform(new AffineTransform().translate(dir.multiply(distance)));
|
||||||
copy.setSourceFunction(remove); // Remove
|
copy.setSourceFunction(remove); // Remove
|
||||||
copy.setRemovingEntities(true);
|
copy.setRemovingEntities(true);
|
||||||
|
Mask sourceMask = getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(EditSession.this);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
setSourceMask(null);
|
||||||
|
}
|
||||||
if (!copyAir) {
|
if (!copyAir) {
|
||||||
copy.setSourceMask(new ExistingBlockMask(EditSession.this));
|
copy.setSourceMask(new ExistingBlockMask(EditSession.this));
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ public class LocalSession {
|
|||||||
private transient int cuiVersion = -1;
|
private transient int cuiVersion = -1;
|
||||||
private transient boolean fastMode = false;
|
private transient boolean fastMode = false;
|
||||||
private transient Mask mask;
|
private transient Mask mask;
|
||||||
|
private transient Mask sourceMask;
|
||||||
private ResettableExtent transform = null;
|
private ResettableExtent transform = null;
|
||||||
private transient TimeZone timezone = TimeZone.getDefault();
|
private transient TimeZone timezone = TimeZone.getDefault();
|
||||||
|
|
||||||
@ -1238,6 +1239,9 @@ public class LocalSession {
|
|||||||
if (mask != null) {
|
if (mask != null) {
|
||||||
editSession.setMask(mask);
|
editSession.setMask(mask);
|
||||||
}
|
}
|
||||||
|
if (sourceMask != null) {
|
||||||
|
editSession.setSourceMask(sourceMask);
|
||||||
|
}
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
editSession.addTransform(transform);
|
editSession.addTransform(transform);
|
||||||
}
|
}
|
||||||
@ -1272,6 +1276,15 @@ public class LocalSession {
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mask.
|
||||||
|
*
|
||||||
|
* @return mask, may be null
|
||||||
|
*/
|
||||||
|
public Mask getSourceMask() {
|
||||||
|
return sourceMask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a mask.
|
* Set a mask.
|
||||||
*
|
*
|
||||||
@ -1281,6 +1294,15 @@ public class LocalSession {
|
|||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mask.
|
||||||
|
*
|
||||||
|
* @param mask mask or null
|
||||||
|
*/
|
||||||
|
public void setSourceMask(Mask mask) {
|
||||||
|
this.sourceMask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a mask.
|
* Set a mask.
|
||||||
*
|
*
|
||||||
@ -1291,6 +1313,16 @@ public class LocalSession {
|
|||||||
setMask(mask != null ? Masks.wrap(mask) : null);
|
setMask(mask != null ? Masks.wrap(mask) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a mask.
|
||||||
|
*
|
||||||
|
* @param mask mask or null
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void setSourceMask(com.sk89q.worldedit.masks.Mask mask) {
|
||||||
|
setSourceMask(mask != null ? Masks.wrap(mask) : null);
|
||||||
|
}
|
||||||
|
|
||||||
public ResettableExtent getTransform() {
|
public ResettableExtent getTransform() {
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import com.boydti.fawe.object.RunnableVal2;
|
|||||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.util.ImgurUtility;
|
import com.boydti.fawe.util.ImgurUtility;
|
||||||
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
@ -141,6 +142,12 @@ public class ClipboardCommands {
|
|||||||
|
|
||||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||||
|
Mask sourceMask = editSession.getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(editSession);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
editSession.setSourceMask(null);
|
||||||
|
}
|
||||||
if (mask != null && mask != Masks.alwaysTrue()) {
|
if (mask != null && mask != Masks.alwaysTrue()) {
|
||||||
copy.setSourceMask(mask);
|
copy.setSourceMask(mask);
|
||||||
}
|
}
|
||||||
@ -173,6 +180,12 @@ public class ClipboardCommands {
|
|||||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||||
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
|
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
|
||||||
|
Mask sourceMask = editSession.getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(editSession);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
editSession.setSourceMask(null);
|
||||||
|
}
|
||||||
if (mask != null) {
|
if (mask != null) {
|
||||||
copy.setSourceMask(mask);
|
copy.setSourceMask(mask);
|
||||||
}
|
}
|
||||||
@ -253,7 +266,7 @@ public class ClipboardCommands {
|
|||||||
@Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
|
@Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
|
||||||
@Switch('s') boolean selectPasted) throws WorldEditException {
|
@Switch('s') boolean selectPasted) throws WorldEditException {
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
if (holder.getTransform().isIdentity()) {
|
if (holder.getTransform().isIdentity() && editSession.getSourceMask() == null) {
|
||||||
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
|
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class GeneralCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/gmask", "gmask" },
|
aliases = { "/gmask", "gmask", "globalmask", "/globalmask" },
|
||||||
usage = "[mask]",
|
usage = "[mask]",
|
||||||
desc = "Set the global mask",
|
desc = "Set the global mask",
|
||||||
min = 0,
|
min = 0,
|
||||||
@ -124,6 +124,30 @@ public class GeneralCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = { "/gsmask", "gsmask", "globalsourcemask", "/globalsourcemask" },
|
||||||
|
usage = "[mask]",
|
||||||
|
desc = "Set the global source mask",
|
||||||
|
min = 0,
|
||||||
|
max = -1
|
||||||
|
)
|
||||||
|
@CommandPermissions("worldedit.global-mask")
|
||||||
|
public void gsmask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException {
|
||||||
|
if (context == null || context.argsLength() == 0) {
|
||||||
|
session.setSourceMask((Mask) null);
|
||||||
|
BBC.SOURCE_MASK_DISABLED.send(player);
|
||||||
|
} else {
|
||||||
|
ParserContext parserContext = new ParserContext();
|
||||||
|
parserContext.setActor(player);
|
||||||
|
parserContext.setWorld(player.getWorld());
|
||||||
|
parserContext.setSession(session);
|
||||||
|
parserContext.setExtent(editSession);
|
||||||
|
Mask mask = worldEdit.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||||
|
session.setSourceMask(mask);
|
||||||
|
BBC.SOURCE_MASK.send(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/gtransform", "gtransform" },
|
aliases = { "/gtransform", "gtransform" },
|
||||||
usage = "[transform]",
|
usage = "[transform]",
|
||||||
|
@ -577,11 +577,15 @@ public class RegionCommands {
|
|||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
public void regenerateChunk(Player player, LocalSession session, EditSession editSession, @Selection Region region) throws WorldEditException {
|
public void regenerateChunk(Player player, LocalSession session, EditSession editSession, @Selection Region region) throws WorldEditException {
|
||||||
Mask mask = session.getMask();
|
Mask mask = session.getMask();
|
||||||
|
Mask sourceMask = session.getSourceMask();
|
||||||
try {
|
try {
|
||||||
session.setMask((Mask) null);
|
session.setMask((Mask) null);
|
||||||
|
session.setSourceMask((Mask) null);
|
||||||
player.getWorld().regenerate(region, editSession);
|
player.getWorld().regenerate(region, editSession);
|
||||||
} finally {
|
} finally {
|
||||||
session.setMask(mask);
|
session.setMask(mask);
|
||||||
|
session.setSourceMask(mask);
|
||||||
|
|
||||||
}
|
}
|
||||||
BBC.COMMAND_REGEN.send(player);
|
BBC.COMMAND_REGEN.send(player);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class ToolUtilCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "mask" },
|
aliases = { "mask", "/mask" },
|
||||||
usage = "[mask]",
|
usage = "[mask]",
|
||||||
desc = "Set the brush mask",
|
desc = "Set the brush mask",
|
||||||
min = 0,
|
min = 0,
|
||||||
@ -71,6 +71,7 @@ public class ToolUtilCommands {
|
|||||||
public void mask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException {
|
public void mask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException {
|
||||||
Tool tool = session.getTool(player.getItemInHand());
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
if (tool == null) {
|
if (tool == null) {
|
||||||
|
player.print(BBC.BRUSH_NONE.f());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (context == null || context.argsLength() == 0) {
|
if (context == null || context.argsLength() == 0) {
|
||||||
@ -96,6 +97,43 @@ public class ToolUtilCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = { "smask", "/smask", "/sourcemask", "sourcemask" },
|
||||||
|
usage = "[mask]",
|
||||||
|
desc = "Set the brush mask",
|
||||||
|
min = 0,
|
||||||
|
max = -1
|
||||||
|
)
|
||||||
|
@CommandPermissions("worldedit.brush.options.mask")
|
||||||
|
public void smask(Player player, LocalSession session, EditSession editSession, @Optional CommandContext context) throws WorldEditException {
|
||||||
|
Tool tool = session.getTool(player.getItemInHand());
|
||||||
|
if (tool == null) {
|
||||||
|
player.print(BBC.BRUSH_NONE.f());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (context == null || context.argsLength() == 0) {
|
||||||
|
if (tool instanceof BrushTool) {
|
||||||
|
((BrushTool) tool).setSourceMask(null);
|
||||||
|
} else if (tool instanceof DoubleActionBrushTool) {
|
||||||
|
((DoubleActionBrushTool) tool).setMask(null);
|
||||||
|
}
|
||||||
|
BBC.BRUSH_SOURCE_MASK_DISABLED.send(player);
|
||||||
|
} else {
|
||||||
|
ParserContext parserContext = new ParserContext();
|
||||||
|
parserContext.setActor(player);
|
||||||
|
parserContext.setWorld(player.getWorld());
|
||||||
|
parserContext.setSession(session);
|
||||||
|
parserContext.setExtent(editSession);
|
||||||
|
Mask mask = we.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||||
|
if (tool instanceof BrushTool) {
|
||||||
|
((BrushTool) tool).setSourceMask(mask);
|
||||||
|
} else if (tool instanceof DoubleActionBrushTool) {
|
||||||
|
((DoubleActionBrushTool) tool).setSourceMask(mask);
|
||||||
|
}
|
||||||
|
BBC.BRUSH_SOURCE_MASK.send(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "transform" },
|
aliases = { "transform" },
|
||||||
usage = "[transform]",
|
usage = "[transform]",
|
||||||
|
@ -29,6 +29,7 @@ public class BrushTool implements TraceTool {
|
|||||||
protected static int MAX_RANGE = 500;
|
protected static int MAX_RANGE = 500;
|
||||||
protected int range = -1;
|
protected int range = -1;
|
||||||
private Mask mask = null;
|
private Mask mask = null;
|
||||||
|
private Mask sourceMask = null;
|
||||||
private ResettableExtent transform = null;
|
private ResettableExtent transform = null;
|
||||||
private Brush brush = new SphereBrush();
|
private Brush brush = new SphereBrush();
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -77,6 +78,24 @@ public class BrushTool implements TraceTool {
|
|||||||
this.mask = filter;
|
this.mask = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filter.
|
||||||
|
*
|
||||||
|
* @return the filter
|
||||||
|
*/
|
||||||
|
public Mask getSourceMask() {
|
||||||
|
return sourceMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the block filter used for identifying blocks to replace.
|
||||||
|
*
|
||||||
|
* @param filter the filter to set
|
||||||
|
*/
|
||||||
|
public void setSourceMask(Mask filter) {
|
||||||
|
this.sourceMask = filter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the brush.
|
* Set the brush.
|
||||||
*
|
*
|
||||||
@ -178,6 +197,19 @@ public class BrushTool implements TraceTool {
|
|||||||
editSession.setMask(newMask);
|
editSession.setMask(newMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sourceMask != null) {
|
||||||
|
Mask existingMask = editSession.getMask();
|
||||||
|
|
||||||
|
if (existingMask == null) {
|
||||||
|
editSession.setSourceMask(sourceMask);
|
||||||
|
} else if (existingMask instanceof MaskIntersection) {
|
||||||
|
((MaskIntersection) existingMask).add(sourceMask);
|
||||||
|
} else {
|
||||||
|
MaskIntersection newMask = new MaskIntersection(existingMask);
|
||||||
|
newMask.add(sourceMask);
|
||||||
|
editSession.setSourceMask(newMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
editSession.addTransform(transform);
|
editSession.addTransform(transform);
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,16 @@
|
|||||||
package com.sk89q.worldedit.extension.factory;
|
package com.sk89q.worldedit.extension.factory;
|
||||||
|
|
||||||
import com.boydti.fawe.command.FaweParser;
|
import com.boydti.fawe.command.FaweParser;
|
||||||
import com.boydti.fawe.object.mask.AdjacentMask;
|
import com.boydti.fawe.command.SuggestInputParseException;
|
||||||
import com.boydti.fawe.object.mask.AngleMask;
|
import com.boydti.fawe.object.mask.*;
|
||||||
import com.boydti.fawe.object.mask.CustomMask;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.object.mask.DataMask;
|
import com.boydti.fawe.util.StringMan;
|
||||||
import com.boydti.fawe.object.mask.IdDataMask;
|
|
||||||
import com.boydti.fawe.object.mask.IdMask;
|
|
||||||
import com.boydti.fawe.object.mask.RadiusMask;
|
|
||||||
import com.boydti.fawe.object.mask.WallMask;
|
|
||||||
import com.boydti.fawe.object.mask.XAxisMask;
|
|
||||||
import com.boydti.fawe.object.mask.YAxisMask;
|
|
||||||
import com.boydti.fawe.object.mask.ZAxisMask;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.IncompleteRegionException;
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.mask.BiomeMask2D;
|
import com.sk89q.worldedit.function.mask.BiomeMask2D;
|
||||||
@ -27,6 +19,7 @@ import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
|||||||
import com.sk89q.worldedit.function.mask.ExpressionMask;
|
import com.sk89q.worldedit.function.mask.ExpressionMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||||
|
import com.sk89q.worldedit.function.mask.MaskUnion;
|
||||||
import com.sk89q.worldedit.function.mask.Masks;
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
import com.sk89q.worldedit.function.mask.NoiseFilter;
|
import com.sk89q.worldedit.function.mask.NoiseFilter;
|
||||||
import com.sk89q.worldedit.function.mask.OffsetMask;
|
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||||
@ -58,16 +51,24 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
|
|
||||||
public static final String[] EXPRESSION_MASK = new String[] { "=<expression>" };
|
public static final String[] EXPRESSION_MASK = new String[] { "=<expression>" };
|
||||||
|
|
||||||
public static final String[] BLOCK_MASK = new String[] { "<block>" };
|
public static final String[] BLOCK_MASK = new String[] { "<blocks>" };
|
||||||
|
|
||||||
public static final String[] SIMPLE_MASK = new String[] {
|
public static final String[] SIMPLE_MASK = new String[] {
|
||||||
"#existing", "#solid", "#dregion", "#dselection", "#dsel", "#selection", "#region", "#sel", "#xaxis", "#yaxis", "#zaxis", "#id", "#data", "#wall", "#surface",
|
"#nolight", "#haslight", "#existing", "#solid", "#dregion", "#dselection", "#dsel", "#selection", "#region", "#sel", "#xaxis", "#yaxis", "#zaxis", "#id", "#data", "#wall", "#surface",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final String[] MISC_PATTERNS = new String[] {
|
public static final String[] DELEGATE_MASKS = new String[] {
|
||||||
"hand", "pos1",
|
"#offset:", "#light:", "#blocklight:", "#skylight:", "#brightness:", "#opacity:"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final String[] CHARACTER_MASKS= new String[] {
|
||||||
|
"/", "{", "|", "~", ">", "<", "$", "%", "=", "!",
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final String[] HASHTAG_MASKS = MainUtil.joinArrayGeneric(SIMPLE_MASK, DELEGATE_MASKS);
|
||||||
|
|
||||||
|
public static final String[] ALL_MASKS = MainUtil.joinArrayGeneric(EXPRESSION_MASK, BLOCK_MASK, SIMPLE_MASK, DELEGATE_MASKS, CHARACTER_MASKS);
|
||||||
|
|
||||||
public DefaultMaskParser(WorldEdit worldEdit) {
|
public DefaultMaskParser(WorldEdit worldEdit) {
|
||||||
super(worldEdit);
|
super(worldEdit);
|
||||||
}
|
}
|
||||||
@ -111,19 +112,83 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mask getBlockMaskComponent(List<Mask> masks, String component, ParserContext context) throws InputParseException {
|
public Mask catchSuggestion(String currentInput, List<Mask> masks, String nextInput, ParserContext context) throws InputParseException {
|
||||||
|
try {
|
||||||
|
return getBlockMaskComponent(masks, nextInput, context);
|
||||||
|
} catch (SuggestInputParseException e) {
|
||||||
|
e.prepend(currentInput.substring(0, currentInput.length() - nextInput.length()));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mask getBlockMaskComponent(List<Mask> masks, String input, ParserContext context) throws InputParseException {
|
||||||
Extent extent = Request.request().getExtent();
|
Extent extent = Request.request().getExtent();
|
||||||
|
|
||||||
final char firstChar = component.charAt(0);
|
final char firstChar = input.charAt(0);
|
||||||
switch (firstChar) {
|
switch (firstChar) {
|
||||||
case '#':
|
case '#':
|
||||||
int colon = component.indexOf(':');
|
int colon = input.indexOf(':');
|
||||||
|
String component = input;
|
||||||
if (colon != -1) {
|
if (colon != -1) {
|
||||||
String rest = component.substring(colon + 1);
|
|
||||||
component = component.substring(0, colon);
|
component = component.substring(0, colon);
|
||||||
masks.add(getBlockMaskComponent(masks, rest, context));
|
String rest = input.substring(colon + 1);
|
||||||
|
switch (component.toLowerCase()) {
|
||||||
|
case "#light":
|
||||||
|
case "#skylight":
|
||||||
|
case "#blocklight":
|
||||||
|
case "#emittedlight":
|
||||||
|
case "#opacity":
|
||||||
|
case "#brightness":
|
||||||
|
String[] split = rest.split(":");
|
||||||
|
if (split.length < 2) {
|
||||||
|
throw new SuggestInputParseException(input, component + ":<min>:<max>");
|
||||||
|
} else if (split.length > 2) {
|
||||||
|
masks.add(catchSuggestion(input, masks, StringMan.join(Arrays.copyOfRange(split, 2, split.length), ":"), context));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
||||||
|
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
||||||
|
switch (component.toLowerCase()) {
|
||||||
|
case "#light":
|
||||||
|
return new LightMask(extent, y1, y2);
|
||||||
|
case "#skylight":
|
||||||
|
return new SkyLightMask(extent, y1, y2);
|
||||||
|
case "#blocklight":
|
||||||
|
case "#emittedlight":
|
||||||
|
return new BlockLightMask(extent, y1, y2);
|
||||||
|
case "#opacity":
|
||||||
|
return new OpacityMask(extent, y1, y2);
|
||||||
|
case "#brightness":
|
||||||
|
return new BrightnessMask(extent, y1, y2);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new SuggestInputParseException(input, component + ":<min>:<max>");
|
||||||
|
}
|
||||||
|
case "#~":
|
||||||
|
case "#rel":
|
||||||
|
case "#relative":
|
||||||
|
case "#offset":
|
||||||
|
try {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<mask>");
|
||||||
|
int x = (int) Expression.compile(split3.get(0)).evaluate();
|
||||||
|
int y = (int) Expression.compile(split3.get(1)).evaluate();
|
||||||
|
int z = (int) Expression.compile(split3.get(2)).evaluate();
|
||||||
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
|
Mask mask = catchSuggestion(input, masks, rest, context);
|
||||||
|
return new OffsetMask(mask, new Vector(x, y, z));
|
||||||
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
throw new SuggestInputParseException(null, "#offset:<dx>:<dy>:<dz>:<mask>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mask mask = catchSuggestion(input, masks, rest, context);
|
||||||
|
masks.add(mask);
|
||||||
}
|
}
|
||||||
switch (component.toLowerCase()) {
|
switch (component.toLowerCase()) {
|
||||||
|
case "#haslight":
|
||||||
|
return new LightMask(extent, 1, Integer.MAX_VALUE);
|
||||||
|
case "#nolight":
|
||||||
|
return new LightMask(extent, 0, 0);
|
||||||
case "#existing":
|
case "#existing":
|
||||||
return new ExistingBlockMask(extent);
|
return new ExistingBlockMask(extent);
|
||||||
case "#solid":
|
case "#solid":
|
||||||
@ -160,38 +225,38 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
masks.add(new ExistingBlockMask(extent));
|
masks.add(new ExistingBlockMask(extent));
|
||||||
return new AdjacentMask(extent, Arrays.asList(new BaseBlock(0)), 1, 8);
|
return new AdjacentMask(extent, Arrays.asList(new BaseBlock(0)), 1, 8);
|
||||||
default:
|
default:
|
||||||
throw new NoMatchException("Unrecognized mask '" + component + "'");
|
throw new SuggestInputParseException(input, HASHTAG_MASKS);
|
||||||
}
|
}
|
||||||
case '\\':
|
case '\\':
|
||||||
case '/': {
|
case '/': {
|
||||||
String[] split = component.substring(1).split(",");
|
String[] split = input.substring(1).split(":");
|
||||||
if (split.length != 2) {
|
if (split.length != 2) {
|
||||||
throw new InputParseException("Unknown angle '" + component + "' (not in form `/#,#`)");
|
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
||||||
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
||||||
return new AngleMask(extent, y1, y2);
|
return new AngleMask(extent, y1, y2);
|
||||||
} catch (NumberFormatException | ExpressionException e) {
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
throw new InputParseException("Unknown angle '" + component + "' (not in form `/#,#`)");
|
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '{': {
|
case '{': {
|
||||||
String[] split = component.substring(1).split(",");
|
String[] split = input.substring(1).split(":");
|
||||||
if (split.length != 2) {
|
if (split.length != 2) {
|
||||||
throw new InputParseException("Unknown range '" + component + "' (not in form `{#,#`)");
|
throw new SuggestInputParseException(input, "{<min-radius>:<max-radius>");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
||||||
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
||||||
return new RadiusMask(y1, y2);
|
return new RadiusMask(y1, y2);
|
||||||
} catch (NumberFormatException | ExpressionException e) {
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
throw new InputParseException("Unknown range '" + component + "' (not in form `{#,#`)");
|
throw new SuggestInputParseException(input, "{<min-radius>:<max-radius>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '|':
|
case '|':
|
||||||
case '~': {
|
case '~': {
|
||||||
String[] split = component.substring(1).split("=");
|
String[] split = input.substring(1).split("=");
|
||||||
ParserContext tempContext = new ParserContext(context);
|
ParserContext tempContext = new ParserContext(context);
|
||||||
tempContext.setRestricted(false);
|
tempContext.setRestricted(false);
|
||||||
tempContext.setPreferringWildcard(true);
|
tempContext.setPreferringWildcard(true);
|
||||||
@ -206,19 +271,19 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstChar == '~') {
|
if (firstChar == '~') {
|
||||||
return new AdjacentMask(extent, worldEdit.getBlockFactory().parseFromListInput(component.substring(1), tempContext), requiredMin, requiredMax);
|
return new AdjacentMask(extent, worldEdit.getBlockFactory().parseFromListInput(input.substring(1), tempContext), requiredMin, requiredMax);
|
||||||
} else {
|
} else {
|
||||||
return new WallMask(extent, worldEdit.getBlockFactory().parseFromListInput(component.substring(1), tempContext), requiredMin, requiredMax);
|
return new WallMask(extent, worldEdit.getBlockFactory().parseFromListInput(input.substring(1), tempContext), requiredMin, requiredMax);
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException | ExpressionException e) {
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
throw new InputParseException("Unknown adjacent mask '" + component + "' (not in form `~<ids>[=count]`)");
|
throw new SuggestInputParseException(input, "~<blocks>=<amount>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '>':
|
case '>':
|
||||||
case '<':
|
case '<':
|
||||||
Mask submask;
|
Mask submask;
|
||||||
if (component.length() > 1) {
|
if (input.length() > 1) {
|
||||||
submask = getBlockMaskComponent(masks, component.substring(1), context);
|
submask = getBlockMaskComponent(masks, input.substring(1), context);
|
||||||
} else {
|
} else {
|
||||||
submask = new ExistingBlockMask(extent);
|
submask = new ExistingBlockMask(extent);
|
||||||
}
|
}
|
||||||
@ -227,58 +292,80 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
|
|
||||||
case '$':
|
case '$':
|
||||||
Set<BaseBiome> biomes = new HashSet<BaseBiome>();
|
Set<BaseBiome> biomes = new HashSet<BaseBiome>();
|
||||||
String[] biomesList = component.substring(1).split(",");
|
String[] biomesList = input.substring(1).split(",");
|
||||||
BiomeRegistry biomeRegistry = context.requireWorld().getWorldData().getBiomeRegistry();
|
BiomeRegistry biomeRegistry = context.requireWorld().getWorldData().getBiomeRegistry();
|
||||||
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
||||||
for (String biomeName : biomesList) {
|
for (String biomeName : biomesList) {
|
||||||
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry);
|
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry);
|
||||||
if (biome == null) {
|
if (biome == null) {
|
||||||
throw new InputParseException("Unknown biome '" + biomeName + "'");
|
throw new SuggestInputParseException(input, "$<biome>");
|
||||||
}
|
}
|
||||||
biomes.add(biome);
|
biomes.add(biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes));
|
return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes));
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
try {
|
try {
|
||||||
double i = Math.abs(Expression.compile(component.substring(1)).evaluate());
|
double i = Math.abs(Expression.compile(input.substring(1)).evaluate());
|
||||||
return new NoiseFilter(new RandomNoise(), (i) / 100);
|
return new NoiseFilter(new RandomNoise(), (i) / 100);
|
||||||
} catch (NumberFormatException | ExpressionException e) {
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
throw new InputParseException("Unknown percentage '" + component.substring(1) + "'");
|
throw new SuggestInputParseException(input, "%<percent>");
|
||||||
}
|
}
|
||||||
case '=':
|
case '=':
|
||||||
try {
|
try {
|
||||||
Expression exp = Expression.compile(component.substring(1), "x", "y", "z");
|
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
|
||||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
|
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
|
||||||
Request.request().getEditSession(), Vector.ONE, Vector.ZERO);
|
Request.request().getEditSession(), Vector.ONE, Vector.ZERO);
|
||||||
exp.setEnvironment(env);
|
exp.setEnvironment(env);
|
||||||
return new ExpressionMask(exp);
|
return new ExpressionMask(exp);
|
||||||
} catch (ExpressionException e) {
|
} catch (ExpressionException e) {
|
||||||
throw new InputParseException("Invalid expression: " + e.getMessage());
|
throw new SuggestInputParseException(input, "=<expression>");
|
||||||
}
|
}
|
||||||
|
|
||||||
case '!':
|
case '!':
|
||||||
if (component.length() > 1) {
|
if (input.length() > 1) {
|
||||||
return Masks.negate(getBlockMaskComponent(masks, component.substring(1), context));
|
return Masks.negate(getBlockMaskComponent(masks, input.substring(1), context));
|
||||||
}
|
}
|
||||||
|
throw new SuggestInputParseException(input, "!<mask>");
|
||||||
default:
|
default:
|
||||||
for (CustomMask mask : customMasks) {
|
for (CustomMask mask : customMasks) {
|
||||||
if (mask.accepts(component)) {
|
if (mask.accepts(input)) {
|
||||||
try {
|
try {
|
||||||
Constructor<? extends CustomMask> constructor = mask.getClass().getDeclaredConstructor(List.class, String.class, ParserContext.class);
|
Constructor<? extends CustomMask> constructor = mask.getClass().getDeclaredConstructor(List.class, String.class, ParserContext.class);
|
||||||
return constructor.newInstance(masks, component, context);
|
return constructor.newInstance(masks, input, context);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
List<String> split = split(input, ',');
|
||||||
ParserContext tempContext = new ParserContext(context);
|
if (split.size() == 1) {
|
||||||
tempContext.setRestricted(false);
|
ParserContext tempContext = new ParserContext(context);
|
||||||
tempContext.setPreferringWildcard(true);
|
tempContext.setRestricted(false);
|
||||||
return new BlockMask(extent, worldEdit.getBlockFactory().parseFromListInput(component, tempContext));
|
tempContext.setPreferringWildcard(true);
|
||||||
|
return new BlockMask(extent, worldEdit.getBlockFactory().parseFromListInput(input, tempContext));
|
||||||
|
}
|
||||||
|
HashSet<BaseBlock> blocks = new HashSet<BaseBlock>();
|
||||||
|
ArrayList<Mask> maskUnion = new ArrayList<Mask>();
|
||||||
|
for (String elem : split) {
|
||||||
|
ArrayList<Mask> list = new ArrayList<Mask>();
|
||||||
|
list.add(catchSuggestion(input, list, elem, context));
|
||||||
|
if (list.size() == 1) {
|
||||||
|
Mask mask = list.get(0);
|
||||||
|
if (mask instanceof BlockMask) {
|
||||||
|
blocks.addAll(((BlockMask) mask).getBlocks());
|
||||||
|
} else {
|
||||||
|
maskUnion.add(mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!blocks.isEmpty()) {
|
||||||
|
maskUnion.add(new BlockMask(extent, blocks));
|
||||||
|
}
|
||||||
|
if (maskUnion.size() == 1) {
|
||||||
|
return maskUnion.get(0);
|
||||||
|
}
|
||||||
|
return new MaskUnion(maskUnion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +145,10 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
case "#offset":
|
case "#offset":
|
||||||
try {
|
try {
|
||||||
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<pattern>");
|
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
int x = (int) Expression.compile(split3.get(0)).evaluate();
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
int y = (int) Expression.compile(split3.get(1)).evaluate();
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
int z = (int) Expression.compile(split3.get(2)).evaluate();
|
||||||
rest = StringMan.join(split3.subList(3, split3.size() - 1), ":");
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
return new OffsetPattern(pattern, x, y, z);
|
return new OffsetPattern(pattern, x, y, z);
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
@ -160,7 +160,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
rest = StringMan.join(split3.subList(3, split3.size() - 1), ":");
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
return new SurfaceRandomOffsetPattern(pattern, x, y, z);
|
return new SurfaceRandomOffsetPattern(pattern, x, y, z);
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
@ -173,7 +173,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
rest = StringMan.join(split3.subList(3, split3.size() - 1), ":");
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
return new SolidRandomOffsetPattern(pattern, x, y, z);
|
return new SolidRandomOffsetPattern(pattern, x, y, z);
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
@ -187,7 +187,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
rest = StringMan.join(split3.subList(3, split3.size() - 1), ":");
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
return new RandomOffsetPattern(pattern, x, y, z);
|
return new RandomOffsetPattern(pattern, x, y, z);
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.extension.platform;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.command.AnvilCommands;
|
import com.boydti.fawe.command.AnvilCommands;
|
||||||
|
import com.boydti.fawe.command.MaskBinding;
|
||||||
import com.boydti.fawe.command.PatternBinding;
|
import com.boydti.fawe.command.PatternBinding;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -130,6 +131,7 @@ public final class CommandManager {
|
|||||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||||
|
|
||||||
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
|
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
|
||||||
|
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
|
||||||
|
|
||||||
builder.addInvokeListener(new LegacyCommandsHandler());
|
builder.addInvokeListener(new LegacyCommandsHandler());
|
||||||
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
|
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
|
||||||
|
@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extent;
|
package com.sk89q.worldedit.extent;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
@ -30,6 +32,7 @@ import com.sk89q.worldedit.function.operation.OperationQueue;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -39,7 +42,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
/**
|
/**
|
||||||
* A base class for {@link Extent}s that merely passes extents onto another.
|
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDelegateExtent implements Extent {
|
public abstract class AbstractDelegateExtent implements LightingExtent {
|
||||||
|
|
||||||
private final Extent extent;
|
private final Extent extent;
|
||||||
|
|
||||||
@ -53,6 +56,50 @@ public abstract class AbstractDelegateExtent implements Extent {
|
|||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
return ((LightingExtent) extent).getSkyLight(x, y, z);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockLight(int x, int y, int z) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
return ((LightingExtent) extent).getBlockLight(x, y, z);
|
||||||
|
}
|
||||||
|
return getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOpacity(int x, int y, int z) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
return ((LightingExtent) extent).getOpacity(x, y, z);
|
||||||
|
}
|
||||||
|
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(getLazyBlock(x, y, z).getId());
|
||||||
|
if (block == null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.min(15, block.getLightOpacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLight(int x, int y, int z) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
return ((LightingExtent) extent).getLight(x, y, z);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBrightness(int x, int y, int z) {
|
||||||
|
if (extent instanceof LightingExtent) {
|
||||||
|
return ((LightingExtent) extent).getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(getLazyBlock(x, y, z).getId());
|
||||||
|
if (block == null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.min(15, block.getLightValue());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the extent.
|
* Get the extent.
|
||||||
*
|
*
|
||||||
|
@ -23,18 +23,21 @@ import com.boydti.fawe.config.Settings;
|
|||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||||
|
import com.boydti.fawe.object.extent.LightingExtent;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -48,7 +51,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
* Stores block data as a multi-dimensional array of {@link BaseBlock}s and
|
* Stores block data as a multi-dimensional array of {@link BaseBlock}s and
|
||||||
* other data as lists or maps.
|
* other data as lists or maps.
|
||||||
*/
|
*/
|
||||||
public class BlockArrayClipboard implements Clipboard {
|
public class BlockArrayClipboard implements Clipboard, LightingExtent {
|
||||||
|
|
||||||
private Region region;
|
private Region region;
|
||||||
public FaweClipboard IMP;
|
public FaweClipboard IMP;
|
||||||
@ -57,6 +60,7 @@ public class BlockArrayClipboard implements Clipboard {
|
|||||||
private int my;
|
private int my;
|
||||||
private int mz;
|
private int mz;
|
||||||
private Vector origin;
|
private Vector origin;
|
||||||
|
private Vector mutable = new Vector();
|
||||||
|
|
||||||
public BlockArrayClipboard(Region region) {
|
public BlockArrayClipboard(Region region) {
|
||||||
checkNotNull(region);
|
checkNotNull(region);
|
||||||
@ -227,4 +231,43 @@ public class BlockArrayClipboard implements Clipboard {
|
|||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
return BlockArrayClipboard.class;
|
return BlockArrayClipboard.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLight(int x, int y, int z) {
|
||||||
|
return getBlockLight(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLight(int x, int y, int z) {
|
||||||
|
return getBrightness(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity(int x, int y, int z) {
|
||||||
|
mutable.x = x;
|
||||||
|
mutable.y = y;
|
||||||
|
mutable.z = z;
|
||||||
|
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(getBlock(mutable).getId());
|
||||||
|
if (block == null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.min(15, block.getLightOpacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBrightness(int x, int y, int z) {
|
||||||
|
mutable.x = x;
|
||||||
|
mutable.y = y;
|
||||||
|
mutable.z = z;
|
||||||
|
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(getBlock(mutable).getId());
|
||||||
|
if (block == null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.min(15, block.getLightValue());
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,11 +19,14 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.session;
|
package com.sk89q.worldedit.session;
|
||||||
|
|
||||||
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
@ -97,6 +100,14 @@ public class PasteBuilder {
|
|||||||
}
|
}
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), targetExtent, to);
|
ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), targetExtent, to);
|
||||||
copy.setTransform(transform);
|
copy.setTransform(transform);
|
||||||
|
if (targetExtent instanceof EditSession) {
|
||||||
|
Mask sourceMask = ((EditSession) targetExtent).getSourceMask();
|
||||||
|
if (sourceMask != null) {
|
||||||
|
new MaskTraverser(sourceMask).reset(extent);
|
||||||
|
copy.setSourceMask(sourceMask);
|
||||||
|
((EditSession) targetExtent).setSourceMask(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ignoreAirBlocks) {
|
if (ignoreAirBlocks) {
|
||||||
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user