diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java index e0f147028..0c5696b8e 100644 --- a/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -686,6 +686,9 @@ public class LocalSession { new EditSession(player.isPlayer() ? player.getWorld() : null, getBlockChangeLimit(), blockBag); editSession.setFastMode(fastMode); + if (mask != null) { + mask.prepare(this, player, null); + } editSession.setMask(mask); return editSession; diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java index 827d4ec98..da4de3b79 100644 --- a/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -600,6 +600,10 @@ public class WorldEdit { case '#': if (component.equalsIgnoreCase("#existing")) { return new ExistingBlockMask(); + } else if (component.equalsIgnoreCase("#dregion") + || component.equalsIgnoreCase("#dselection") + || component.equalsIgnoreCase("#dsel")) { + return new DynamicRegionMask(); } else if (component.equalsIgnoreCase("#selection") || component.equalsIgnoreCase("#region") || component.equalsIgnoreCase("#sel")) { diff --git a/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java b/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java index 6331a7591..c25621f17 100644 --- a/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/BiomeTypeMask.java @@ -5,6 +5,8 @@ import java.util.Set; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; public class BiomeTypeMask implements Mask { @@ -19,6 +21,9 @@ public class BiomeTypeMask implements Mask { this.biomes = biomes; } + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + } + public boolean matches(EditSession editSession, Vector pos) { BiomeType biome = editSession.getWorld().getBiome(pos.toVector2D()); return biomes.contains(biome); diff --git a/src/main/java/com/sk89q/worldedit/masks/BlockTypeMask.java b/src/main/java/com/sk89q/worldedit/masks/BlockTypeMask.java index b3ebfe3fc..ce2ed7c52 100644 --- a/src/main/java/com/sk89q/worldedit/masks/BlockTypeMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/BlockTypeMask.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.masks; import java.util.HashSet; import java.util.Set; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; /** @@ -49,6 +51,9 @@ public class BlockTypeMask implements Mask { types.add(type); } + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + } + public boolean matches(EditSession editSession, Vector pos) { return types.contains(editSession.getBlockType(pos)); } diff --git a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java index 4bb5e070a..fa618a81d 100644 --- a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.masks; import java.util.ArrayList; import java.util.List; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; public class CombinedMask implements Mask { @@ -51,6 +53,12 @@ public class CombinedMask implements Mask { return masks.contains(mask); } + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + for (Mask mask : masks) { + mask.prepare(session, player, target); + } + } + public boolean matches(EditSession editSession, Vector pos) { for (Mask mask : masks) { if (!mask.matches(editSession, pos)) { diff --git a/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java b/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java new file mode 100644 index 000000000..c7cec61d3 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java @@ -0,0 +1,26 @@ +package com.sk89q.worldedit.masks; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.regions.Region; + +public class DynamicRegionMask implements Mask { + + private Region region; + + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + try { + region = session.getSelection(player.getWorld()); + } catch (IncompleteRegionException exc) { + region = null; + } + } + + @Override + public boolean matches(EditSession editSession, Vector pos) { + return region == null || region.contains(pos); + } +} diff --git a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java index 3f4827b95..cd5be8199 100644 --- a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java @@ -20,10 +20,16 @@ package com.sk89q.worldedit.masks; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockID; public class ExistingBlockMask implements Mask { + + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + } + public boolean matches(EditSession editSession, Vector pos) { return editSession.getBlockType(pos) != BlockID.AIR; } diff --git a/src/main/java/com/sk89q/worldedit/masks/Mask.java b/src/main/java/com/sk89q/worldedit/masks/Mask.java index d1ac39766..322ffdb72 100644 --- a/src/main/java/com/sk89q/worldedit/masks/Mask.java +++ b/src/main/java/com/sk89q/worldedit/masks/Mask.java @@ -20,6 +20,8 @@ package com.sk89q.worldedit.masks; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; /** @@ -29,6 +31,16 @@ import com.sk89q.worldedit.Vector; * @author sk89q */ public interface Mask { + + /** + * Called one time before each edit session. + * + * @param session + * @param player + * @param target target of the brush, null if not a brush mask + */ + public void prepare(LocalSession session, LocalPlayer player, Vector target); + /** * Given a block position, this method returns true if the block at * that position matches the filter. Block information is not provided diff --git a/src/main/java/com/sk89q/worldedit/masks/RegionMask.java b/src/main/java/com/sk89q/worldedit/masks/RegionMask.java index f949b01a5..18cad9683 100644 --- a/src/main/java/com/sk89q/worldedit/masks/RegionMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/RegionMask.java @@ -20,6 +20,8 @@ package com.sk89q.worldedit.masks; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.regions.Region; @@ -31,6 +33,9 @@ public class RegionMask implements Mask { this.region = region.clone(); } + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + } + public boolean matches(EditSession editSession, Vector pos) { return region.contains(pos); } diff --git a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java index 5d5b339b5..f8a3a3815 100644 --- a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java +++ b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java @@ -23,6 +23,8 @@ import java.util.HashSet; import java.util.Set; import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockID; @@ -44,6 +46,9 @@ public class UnderOverlayMask implements Mask { this.ids.addAll(ids); } + public void prepare(LocalSession session, LocalPlayer player, Vector target) { + } + public boolean matches(EditSession editSession, Vector pos) { int id = editSession.getBlock(pos.setY(pos.getBlockY() + (overlay ? -1 : 1))).getType(); return ids.isEmpty() ? id != BlockID.AIR : ids.contains(id); diff --git a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java b/src/main/java/com/sk89q/worldedit/tools/BrushTool.java index 121242118..100036e2f 100644 --- a/src/main/java/com/sk89q/worldedit/tools/BrushTool.java +++ b/src/main/java/com/sk89q/worldedit/tools/BrushTool.java @@ -178,6 +178,7 @@ public class BrushTool implements TraceTool { EditSession editSession = session.createEditSession(player); if (mask != null) { + mask.prepare(session, player, target); Mask existingMask = editSession.getMask(); if (existingMask == null) { editSession.setMask(mask);