Some new brushes
Scatter - Set a pattern at random points on a surface ScatterCommand - Runs a command at random points on a surface Splatter - Recursively set blocks at random points on a surface
This commit is contained in:
parent
fb76ff4ea0
commit
d765b24b27
@ -5,7 +5,6 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -14,29 +13,6 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
public List<String> split(String input, char delim) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
int start = 0;
|
||||
int bracket = 0;
|
||||
boolean inQuotes = false;
|
||||
for (int current = 0; current < input.length(); current++) {
|
||||
char currentChar = input.charAt(current);
|
||||
boolean atLastChar = (current == input.length() - 1);
|
||||
if (!atLastChar && (bracket > 0 || (currentChar == '{' && ++bracket > 0) || (current == '}' && --bracket <= 0))) continue;
|
||||
if (currentChar == '\"') inQuotes = !inQuotes; // toggle state
|
||||
if(atLastChar) result.add(input.substring(start));
|
||||
else if (currentChar == delim && !inQuotes) {
|
||||
String toAdd = input.substring(start, current);
|
||||
if (toAdd.startsWith("\"")) {
|
||||
toAdd = toAdd.substring(1, toAdd.length() - 1);
|
||||
}
|
||||
result.add(toAdd);
|
||||
start = current + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public T catchSuggestion(String currentInput, String nextInput, ParserContext context) throws InputParseException {
|
||||
try {
|
||||
return parseFromInput(nextInput, context);
|
||||
@ -47,7 +23,7 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
}
|
||||
|
||||
public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
||||
List<String> remainder = split(input, ':');
|
||||
List<String> remainder = StringMan.split(input, ':');
|
||||
int len = remainder.size();
|
||||
if (len != expected.length - 1) {
|
||||
if (len <= expected.length - 1 && len != 0) {
|
||||
|
@ -121,6 +121,7 @@ public enum BBC {
|
||||
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
||||
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2. Note: Use the blend brush if you want to smooth overhangs or caves.).", "WorldEdit.Brush"),
|
||||
BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_SCATTER("Scatter brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
||||
BRUSH_SHATTER("Shatter brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
||||
BRUSH_STENCIL("Stencil brush equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_LINE("Line brush shape equipped (%s0).", "WorldEdit.Brush"),
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
||||
import com.boydti.fawe.wrappers.PlayerWrapper;
|
||||
import com.boydti.fawe.wrappers.SilentPlayerWrapper;
|
||||
@ -15,25 +16,25 @@ import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandBrush implements Brush {
|
||||
|
||||
private final String command;
|
||||
private final int radius;
|
||||
|
||||
public CommandBrush(String command, double radius) {
|
||||
this.command = command;
|
||||
this.radius = (int) radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
int radius = (int) size;
|
||||
CuboidRegionSelector selector = new CuboidRegionSelector(editSession.getWorld(), position.subtract(radius, radius, radius), position.add(radius, radius, radius));
|
||||
String replaced = command.replace("{x}", position.getBlockX() + "")
|
||||
.replace("{y}", position.getBlockY() + "")
|
||||
.replace("{z}", position.getBlockZ() + "")
|
||||
.replace("{y}", Integer.toString(position.getBlockY()))
|
||||
.replace("{z}", Integer.toString(position.getBlockZ()))
|
||||
.replace("{world}", editSession.getQueue().getWorldName())
|
||||
.replace("{size}", radius + "");
|
||||
.replace("{size}", Integer.toString(radius));
|
||||
|
||||
FawePlayer fp = editSession.getPlayer();
|
||||
Player player = fp.getPlayer();
|
||||
@ -45,7 +46,7 @@ public class CommandBrush implements Brush {
|
||||
}
|
||||
fp.setSelection(selector);
|
||||
PlayerWrapper wePlayer = new SilentPlayerWrapper(new LocationMaskedPlayerWrapper(player, new Location(player.getExtent(), position)));
|
||||
String[] cmds = replaced.split(";");
|
||||
List<String> cmds = StringMan.split(replaced, ';');
|
||||
for (String cmd : cmds) {
|
||||
CommandEvent event = new CommandEvent(wePlayer, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
|
@ -0,0 +1,91 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
||||
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ScatterBrush implements Brush {
|
||||
|
||||
private final int count;
|
||||
private final int distance;
|
||||
private Mask mask;
|
||||
|
||||
public ScatterBrush(int count, int distance) {
|
||||
this.count = count;
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
// pick a bunch of random points
|
||||
// expand randomly from them
|
||||
this.mask = editSession.getMask();
|
||||
if (this.mask == null) {
|
||||
this.mask = Masks.alwaysTrue();
|
||||
}
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
final RadiusMask radius = new RadiusMask(0, (int) size);
|
||||
|
||||
final int distance = Math.min((int) size, this.distance);
|
||||
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), function -> true);
|
||||
visitor.visit(position);
|
||||
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
|
||||
Operations.completeBlindly(visitor);
|
||||
BlockVectorSet visited = visitor.getVisited();
|
||||
int length = visited.size();
|
||||
|
||||
LocalBlockVectorSet placed = new LocalBlockVectorSet();
|
||||
int maxFails = 1000;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index = PseudoRandom.random.nextInt(length);
|
||||
Vector pos = visited.get(index);
|
||||
if (pos != null && canApply(editSession, pos)) {
|
||||
int x = pos.getBlockX();
|
||||
int y = pos.getBlockY();
|
||||
int z = pos.getBlockZ();
|
||||
if (placed.containsRadius(x, y, z, distance)) {
|
||||
if (maxFails-- <= 0) {
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
placed.add(x, y, z);
|
||||
apply(editSession, placed, pos, pattern, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canApply(EditSession editSession, Vector pos) {
|
||||
return mask.test(pos);
|
||||
}
|
||||
|
||||
public void apply(EditSession editSession, LocalBlockVectorSet placed, Vector pt, Pattern p, double size) throws MaxChangedBlocksException {
|
||||
editSession.setBlock(pt, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
||||
import com.boydti.fawe.wrappers.PlayerWrapper;
|
||||
import com.boydti.fawe.wrappers.SilentPlayerWrapper;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.util.List;
|
||||
|
||||
public class ScatterCommand extends ScatterBrush{
|
||||
private final String command;
|
||||
|
||||
public ScatterCommand(int count, int distance, String command) {
|
||||
super(count, distance);
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(EditSession editSession, LocalBlockVectorSet placed, Vector position, Pattern p, double size) throws MaxChangedBlocksException {
|
||||
int radius = getDistance();
|
||||
CuboidRegionSelector selector = new CuboidRegionSelector(editSession.getWorld(), position.subtract(radius, radius, radius), position.add(radius, radius, radius));
|
||||
String replaced = command.replace("{x}", position.getBlockX() + "")
|
||||
.replace("{y}", Integer.toString(position.getBlockY()))
|
||||
.replace("{z}", Integer.toString(position.getBlockZ()))
|
||||
.replace("{world}", editSession.getQueue().getWorldName())
|
||||
.replace("{size}", Integer.toString(radius));
|
||||
|
||||
FawePlayer fp = editSession.getPlayer();
|
||||
Player player = fp.getPlayer();
|
||||
fp.setSelection(selector);
|
||||
PlayerWrapper wePlayer = new SilentPlayerWrapper(new LocationMaskedPlayerWrapper(player, new Location(player.getExtent(), position)));
|
||||
List<String> cmds = StringMan.split(replaced, ';');
|
||||
for (String cmd : cmds) {
|
||||
CommandEvent event = new CommandEvent(wePlayer, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
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.visitor.RecursiveVisitor;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SplatterBrush extends ScatterBrush {
|
||||
private final boolean solid;
|
||||
private final int recursion;
|
||||
|
||||
public SplatterBrush(int count, int distance, boolean solid) {
|
||||
super(count, 1);
|
||||
this.recursion = distance;
|
||||
this.solid = solid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final EditSession editSession, final LocalBlockVectorSet placed, final Vector position, Pattern p, double size) throws MaxChangedBlocksException {
|
||||
final Pattern finalPattern;
|
||||
if (solid) {
|
||||
finalPattern = new BlockPattern(p.apply(position));
|
||||
} else {
|
||||
finalPattern = p;
|
||||
}
|
||||
final int size2 = (int) (size * size);
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
double dist = vector.distanceSq(position);
|
||||
if (!placed.contains(vector) && (PseudoRandom.random.random(5) < 2) && solid.test(vector) && adjacent.test(vector)) {
|
||||
placed.add(vector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, new RegionFunction() {
|
||||
@Override
|
||||
public boolean apply(Vector vector) throws WorldEditException {
|
||||
return editSession.setBlock(vector, finalPattern);
|
||||
}
|
||||
}, recursion, editSession);
|
||||
visitor.setMaxBranch(2);
|
||||
visitor.setDirections(Arrays.asList(visitor.DIAGONAL_DIRECTIONS));
|
||||
visitor.visit(position);
|
||||
Operations.completeBlindly(visitor);
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ package com.boydti.fawe.object.brush;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.brush.heightmap.HeightMap;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -45,11 +44,10 @@ public class StencilBrush extends HeightBrush {
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
RegionMask region = new RegionMask(new CuboidRegion(position.subtract(size, size, size), position.add(size, size, size)));
|
||||
final RadiusMask radius = new RadiusMask(0, size);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
if (solid.test(vector) && radius.test(vector)) {
|
||||
if (solid.test(vector) && region.test(vector)) {
|
||||
int dx = vector.getBlockX() - cx;
|
||||
int dy = vector.getBlockY() - cy;
|
||||
int dz = vector.getBlockZ() - cz;
|
||||
|
@ -32,6 +32,31 @@ public class BlockVectorSet extends AbstractCollection<Vector> implements Set<Ve
|
||||
return size;
|
||||
}
|
||||
|
||||
public Vector get(int index) {
|
||||
int count = 0;
|
||||
ObjectIterator<Int2ObjectMap.Entry<LocalBlockVectorSet>> iter = localSets.int2ObjectEntrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Int2ObjectMap.Entry<LocalBlockVectorSet> entry = iter.next();
|
||||
LocalBlockVectorSet set = entry.getValue();
|
||||
int size = set.size();
|
||||
int newSize = count + size;
|
||||
if (newSize > index) {
|
||||
int localIndex = index - count;
|
||||
Vector pos = set.getIndex(localIndex);
|
||||
if (pos != null) {
|
||||
int pair = entry.getIntKey();
|
||||
int cx = MathMan.unpairX(pair);
|
||||
int cz = MathMan.unpairY(pair);
|
||||
pos.mutX((cx << 11) + pos.getBlockX());
|
||||
pos.mutZ((cz << 11) + pos.getBlockZ());
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
count = newSize;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (Int2ObjectMap.Entry<LocalBlockVectorSet> entry : localSets.int2ObjectEntrySet()) {
|
||||
|
@ -61,6 +61,9 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
||||
}
|
||||
|
||||
public boolean containsRadius(int x, int y, int z, int radius) {
|
||||
if (radius <= 0) {
|
||||
return contains(x, y, z);
|
||||
}
|
||||
int length = radius * 2;
|
||||
if (size() < length * length * length) {
|
||||
int index = -1;
|
||||
@ -97,6 +100,28 @@ public class LocalBlockVectorSet implements Set<Vector> {
|
||||
this.offsetZ = z;
|
||||
}
|
||||
|
||||
public Vector getIndex(int getIndex) {
|
||||
int size = size();
|
||||
if (getIndex > size) {
|
||||
return null;
|
||||
}
|
||||
int index = -1;
|
||||
for (int i = 0; i < getIndex; i++) {
|
||||
index = set.nextSetBit(index + 1);
|
||||
}
|
||||
if (index != -1) {
|
||||
int b1 = (index & 0xFF);
|
||||
int b2 = ((byte) (index >> 8)) & 0x7F;
|
||||
int b3 = ((byte)(index >> 15)) & 0xFF;
|
||||
int b4 = ((byte) (index >> 23)) & 0xFF;
|
||||
int x = offsetX + (((b3 + ((MathMan.unpair8x(b2)) << 8)) << 21) >> 21);
|
||||
int y = b1;
|
||||
int z = offsetZ + (((b4 + ((MathMan.unpair8y(b2)) << 8)) << 21) >> 21);
|
||||
return MutableBlockVector.get(x, y, z);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Vector> iterator() {
|
||||
return new Iterator<Vector>() {
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
@ -30,6 +32,29 @@ public class StringMan {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static List<String> split(String input, char delim) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
int start = 0;
|
||||
int bracket = 0;
|
||||
boolean inQuotes = false;
|
||||
for (int current = 0; current < input.length(); current++) {
|
||||
char currentChar = input.charAt(current);
|
||||
boolean atLastChar = (current == input.length() - 1);
|
||||
if (!atLastChar && (bracket > 0 || (currentChar == '{' && ++bracket > 0) || (current == '}' && --bracket <= 0))) continue;
|
||||
if (currentChar == '\"') inQuotes = !inQuotes; // toggle state
|
||||
if(atLastChar) result.add(input.substring(start));
|
||||
else if (currentChar == delim && !inQuotes) {
|
||||
String toAdd = input.substring(start, current);
|
||||
if (toAdd.startsWith("\"")) {
|
||||
toAdd = toAdd.substring(1, toAdd.length() - 1);
|
||||
}
|
||||
result.add(toAdd);
|
||||
start = current + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int intersection(final Set<String> options, final String[] toCheck) {
|
||||
int count = 0;
|
||||
for (final String check : toCheck) {
|
||||
|
@ -34,7 +34,10 @@ import com.boydti.fawe.object.brush.HeightBrush;
|
||||
import com.boydti.fawe.object.brush.LineBrush;
|
||||
import com.boydti.fawe.object.brush.RaiseBrush;
|
||||
import com.boydti.fawe.object.brush.RecurseBrush;
|
||||
import com.boydti.fawe.object.brush.ScatterBrush;
|
||||
import com.boydti.fawe.object.brush.ScatterCommand;
|
||||
import com.boydti.fawe.object.brush.ShatterBrush;
|
||||
import com.boydti.fawe.object.brush.SplatterBrush;
|
||||
import com.boydti.fawe.object.brush.SplineBrush;
|
||||
import com.boydti.fawe.object.brush.StencilBrush;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
@ -537,7 +540,8 @@ public class BrushCommands {
|
||||
desc = "Use a height map to paint a surface",
|
||||
help =
|
||||
"Chooses the stencil brush.\n" +
|
||||
"The -w flag will only apply at maximum saturation",
|
||||
"The -w flag will only apply at maximum saturation\n" +
|
||||
"The -r flag will apply random rotation",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@ -561,6 +565,62 @@ public class BrushCommands {
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_STENCIL.f(radius));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "scatter" },
|
||||
usage = "<pattern> [radius=5] [points=5] [distance=1]",
|
||||
desc = "Scatter blocks on a surface",
|
||||
help =
|
||||
"Chooses the scatter brush.",
|
||||
min = 1,
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.scatter")
|
||||
public void scatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("5") double points, @Optional("1") double distance) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new ScatterBrush((int) points, (int) distance), "worldedit.brush.scatter", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "splatter" },
|
||||
usage = "<pattern> [radius=5] [seeds=1] [recursion=5] [solid=true]",
|
||||
desc = "Splatter blocks on a surface",
|
||||
help =
|
||||
"Chooses the Splatter brush.",
|
||||
min = 1,
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.splatter")
|
||||
public void splatterBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius, @Optional("1") double points, @Optional("5") double recursion, @Optional("true") boolean solid) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new SplatterBrush((int) points, (int) recursion, solid), "worldedit.brush.splatter", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "scmd", "scattercmd", "scattercommand", "scommand" },
|
||||
usage = "<scatter-radius> <points> <cmd-radius=1> <cmd1;cmd2...>",
|
||||
desc = "Scatter commands on a surface",
|
||||
help =
|
||||
"Chooses the scatter command brush.",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.scattercommand")
|
||||
public void scatterCommandBrush(Player player, EditSession editSession, LocalSession session, double radius, double points, double distance, CommandContext args) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new ScatterCommand((int) points, (int) distance, args.getJoinedStrings(3)), "worldedit.brush.scattercommand", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SCATTER.f(radius, points));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "cylinder", "cyl", "c" },
|
||||
usage = "<block> [radius] [height]",
|
||||
@ -822,7 +882,7 @@ public class BrushCommands {
|
||||
max = 99
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.command")
|
||||
public void command(Player player, LocalSession session, @Optional("5") double radius, CommandContext args) throws WorldEditException {
|
||||
public void command(Player player, LocalSession session, double radius, CommandContext args) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
String cmd = args.getJoinedStrings(1);
|
||||
tool.setBrush(new CommandBrush(cmd, radius), "worldedit.brush.copy", player);
|
||||
|
@ -90,13 +90,13 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
List<Mask> masks = new ArrayList<Mask>();
|
||||
|
||||
for (String component : split(input, ' ')) {
|
||||
for (String component : StringMan.split(input, ' ')) {
|
||||
if (component.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
HashSet<BaseBlock> blocks = new HashSet<BaseBlock>();
|
||||
List<Mask> masksUnion = new ArrayList<Mask>();
|
||||
for (String elem : split(component, ',')) {
|
||||
for (String elem : StringMan.split(component, ',')) {
|
||||
ArrayList<Mask> list = new ArrayList<Mask>();
|
||||
list.add(catchSuggestion(input, list, elem, context));
|
||||
if (list.size() == 1) {
|
||||
|
@ -197,7 +197,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
case "#l":
|
||||
case "#linear": {
|
||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
for (String token : split(rest, ',')) {
|
||||
for (String token : StringMan.split(rest, ',')) {
|
||||
patterns.add(catchSuggestion(input, token, context));
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
@ -208,7 +208,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
case "#l3d":
|
||||
case "#linear3d": {
|
||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
for (String token : split(rest, ',')) {
|
||||
for (String token : StringMan.split(rest, ',')) {
|
||||
patterns.add(catchSuggestion(input, token, context));
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
@ -250,7 +250,7 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
case "<block>":
|
||||
throw new SuggestInputParseException(input, BundledBlockData.getInstance().getBlockNames());
|
||||
}
|
||||
List<String> items = split(input, ',');
|
||||
List<String> items = StringMan.split(input, ',');
|
||||
if (items.size() == 1) {
|
||||
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items.get(0), context));
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
@ -60,6 +60,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
private BlockVectorSet queue;
|
||||
private final int maxDepth;
|
||||
private int affected = 0;
|
||||
private int maxBranch = Integer.MAX_VALUE;
|
||||
|
||||
public BreadthFirstSearch(final RegionFunction function) {
|
||||
this(function, Integer.MAX_VALUE);
|
||||
@ -118,6 +119,10 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
return visited.contains(pos);
|
||||
}
|
||||
|
||||
public void setMaxBranch(int maxBranch) {
|
||||
this.maxBranch = maxBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
MutableBlockVector mutable = new MutableBlockVector();
|
||||
@ -151,7 +156,8 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
}
|
||||
for (Vector from : queue) {
|
||||
if (function.apply(from)) affected++;
|
||||
for (IntegerTrio direction : dirs) {
|
||||
for (int i = 0, j = 0; i < dirs.length && j < maxBranch; i++) {
|
||||
IntegerTrio direction = dirs[i];
|
||||
int y = from.getBlockY() + direction.y;
|
||||
if (y < 0 || y >= 256) {
|
||||
continue;
|
||||
@ -163,6 +169,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
mutable2.mutY(y);
|
||||
mutable2.mutZ(z);
|
||||
if (isVisitable(from, mutable2)) {
|
||||
j++;
|
||||
visited.add(x, y, z);
|
||||
tempQueue.add(x, y, z);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user