Change mask, pattern and transform syntax
This commit is contained in:
parent
1e31827c9f
commit
69f4b7abd6
@ -60,6 +60,7 @@ import com.sk89q.worldedit.command.util.EntityRemover;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultBlockParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
@ -190,6 +191,10 @@ public class Fawe {
|
||||
private VisualQueue visualQueue;
|
||||
private Updater updater;
|
||||
private TextureUtil textures;
|
||||
private DefaultTransformParser transformParser;
|
||||
|
||||
// @Deprecated
|
||||
// private boolean isJava8 = MainUtil.getJavaVersion() >= 1.8;
|
||||
|
||||
/**
|
||||
* Get the implementation specific class
|
||||
@ -273,6 +278,7 @@ public class Fawe {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
transformParser = new DefaultTransformParser(getWorldEdit());
|
||||
visualQueue = new VisualQueue();
|
||||
WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers());
|
||||
WEManager.IMP.managers.add(new PlotSquaredFeature());
|
||||
@ -283,7 +289,7 @@ public class Fawe {
|
||||
|
||||
TaskManager.IMP.repeat(timer, 1);
|
||||
|
||||
if (Settings.IMP.UPDATE && isJava8()) {
|
||||
if (Settings.IMP.UPDATE) {
|
||||
// Delayed updating
|
||||
updater = new Updater();
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@ -309,10 +315,13 @@ public class Fawe {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isJava8 = MainUtil.getJavaVersion() >= 1.8;
|
||||
// @Deprecated
|
||||
// public boolean isJava8() {
|
||||
// return isJava8;
|
||||
// }
|
||||
|
||||
public boolean isJava8() {
|
||||
return isJava8;
|
||||
public DefaultTransformParser getTransformParser() {
|
||||
return transformParser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,14 +10,12 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.mask.CustomMask;
|
||||
import com.boydti.fawe.object.schematic.Schematic;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
@ -26,15 +24,12 @@ import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
@ -42,7 +37,6 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.File;
|
||||
@ -60,7 +54,6 @@ import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
@ -94,26 +87,48 @@ public class FaweAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom mask for use in e.g //mask #id:<input>
|
||||
* @param name The mask id
|
||||
* @param mask The mask class
|
||||
* Add a custom mask for use in e.g {@literal //mask #id:<input>}
|
||||
* @see com.sk89q.worldedit.command.MaskCommands
|
||||
* @param methods The class with a bunch of mask methods
|
||||
* @return true if the mask was registered
|
||||
*/
|
||||
public static boolean registerMask(String name, Class<? extends CustomMask> mask) {
|
||||
public static boolean registerMasks(Object methods) {
|
||||
DefaultMaskParser parser = getParser(DefaultMaskParser.class);
|
||||
if (parser != null) parser.register(methods);
|
||||
return parser != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom material for use in e.g {@literal //material #id:<input>}
|
||||
* @see com.sk89q.worldedit.command.PatternCommands
|
||||
* @param methods The class with a bunch of pattern methods
|
||||
* @return true if the mask was registered
|
||||
*/
|
||||
public static boolean registerPatterns(Object methods) {
|
||||
HashTagPatternParser parser = getParser(HashTagPatternParser.class);
|
||||
if (parser != null) parser.register(methods);
|
||||
return parser != null;
|
||||
}
|
||||
|
||||
public static <T> T getParser(Class<T> parserClass) {
|
||||
try {
|
||||
Field field = AbstractFactory.class.getDeclaredField("parsers");
|
||||
field.setAccessible(true);
|
||||
List<InputParser> parsers = (List<InputParser>) field.get(WorldEdit.getInstance().getMaskFactory());
|
||||
ArrayList<InputParser> parsers = new ArrayList<>();
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getMaskFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getBlockFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getItemFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getPatternFactory()));
|
||||
for (InputParser parser : parsers) {
|
||||
if (parser instanceof DefaultMaskParser) {
|
||||
((DefaultMaskParser) parser).addMask(name, mask);
|
||||
return true;
|
||||
if (parserClass.isAssignableFrom(parser.getClass())) {
|
||||
return (T) parser;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,7 +166,7 @@ public class FaweAPI {
|
||||
* - The WorldEdit EditSession can do a lot more<br>
|
||||
* Remember to enqueue it when you're done!<br>
|
||||
* @see com.boydti.fawe.object.FaweQueue#enqueue()
|
||||
* @param worldName The name of the world
|
||||
* @param world The name of the world
|
||||
* @param autoqueue If it should start dispatching before you enqueue it.
|
||||
* @return
|
||||
*/
|
||||
|
@ -5,8 +5,11 @@ 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.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class FaweParser<T> extends InputParser<T> {
|
||||
protected FaweParser(WorldEdit worldEdit) {
|
||||
@ -37,4 +40,83 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
|
||||
protected static class ParseEntry {
|
||||
public boolean and;
|
||||
public String input;
|
||||
|
||||
public ParseEntry(String input, boolean type) {
|
||||
this.input = input;
|
||||
this.and = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return input + " | " + and;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Map.Entry<ParseEntry, List<String>>> parse(String command) throws InputParseException {
|
||||
List<Map.Entry<ParseEntry, List<String>>> keys = new ArrayList<>();
|
||||
List<String> args = new ArrayList<>();
|
||||
int len = command.length();
|
||||
String current = null;
|
||||
int end = -1;
|
||||
for (int i = 0; i < len; i++) {
|
||||
boolean newEntry = i == 0;
|
||||
boolean prefix = false;
|
||||
boolean or = false;
|
||||
char c = command.charAt(i);
|
||||
if (i < end) continue;
|
||||
switch (c) {
|
||||
case '&':
|
||||
or = true;
|
||||
case ',': {
|
||||
prefix = true;
|
||||
if (current == null) {
|
||||
throw new InputParseException("Duplicate separator");
|
||||
}
|
||||
newEntry = true;
|
||||
break;
|
||||
}
|
||||
case '[': {
|
||||
int depth = 0;
|
||||
end = len;
|
||||
loop:
|
||||
for (int j = i + 1; j < len; j++) {
|
||||
char c2 = command.charAt(j);
|
||||
switch (c2) {
|
||||
case '[':
|
||||
depth++;
|
||||
continue;
|
||||
case ']':
|
||||
if (depth-- <= 0) {
|
||||
end = j;
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
String arg = command.substring(i + 1, end);
|
||||
args.add(arg);
|
||||
// start
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newEntry) {
|
||||
int index = StringMan.indexOf(command, i + 1, '[', '&', ',');
|
||||
if (index < 0) index = len;
|
||||
end = index;
|
||||
current = command.substring(i + (prefix ? 1 : 0), end);
|
||||
args = new ArrayList<>();
|
||||
ParseEntry entry = new ParseEntry(current, or);
|
||||
keys.add(new AbstractMap.SimpleEntry<ParseEntry, List<String>>(entry, args));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < keys.size() - 1; i++) { // Apply greedy and
|
||||
if (keys.get(i + 1).getKey().and) {
|
||||
keys.get(i).getKey().and = true;
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,15 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
|
||||
@ -11,6 +21,7 @@ import com.sk89q.worldedit.util.command.parametric.BindingBehavior;
|
||||
import com.sk89q.worldedit.util.command.parametric.BindingHelper;
|
||||
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.lang.annotation.Annotation;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -50,6 +61,32 @@ public class FawePrimitiveBinding extends BindingHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link com.sk89q.worldedit.extent.Extent} from a {@link ArgumentStack}.
|
||||
*
|
||||
* @param context the context
|
||||
* @return an extent
|
||||
* @throws ParameterException on other error
|
||||
*/
|
||||
@BindingMatch(type = ResettableExtent.class,
|
||||
behavior = BindingBehavior.PROVIDES)
|
||||
public ResettableExtent getResettableExtent(ArgumentStack context) throws ParameterException, InputParseException {
|
||||
String input = context.next();
|
||||
if (input.equalsIgnoreCase("#null")) return new NullExtent();
|
||||
DefaultTransformParser parser = Fawe.get().getTransformParser();
|
||||
Actor actor = context.getContext().getLocals().get(Actor.class);
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(context.getContext().getLocals().get(Actor.class));
|
||||
if (actor instanceof Entity) {
|
||||
Extent extent = ((Entity) actor).getExtent();
|
||||
if (extent instanceof World) {
|
||||
parserContext.setWorld((World) extent);
|
||||
}
|
||||
}
|
||||
parserContext.setSession(WorldEdit.getInstance().getSessionManager().get(actor));
|
||||
return parser.parseFromInput(input, parserContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link ArgumentStack}.
|
||||
*
|
||||
|
@ -1,13 +1,8 @@
|
||||
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 {
|
||||
@ -20,25 +15,25 @@ public class MaskBinding extends FaweBinding {
|
||||
|
||||
@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);
|
||||
}
|
||||
// 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<>();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
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 PatternBinding extends FaweBinding {
|
||||
@ -19,31 +15,32 @@ public class PatternBinding extends FaweBinding {
|
||||
|
||||
@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(HashTagPatternParser.ALL_PATTERNS));
|
||||
}
|
||||
if (current.startsWith("#") || current.startsWith("=")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if ("hand".startsWith(prefix)) {
|
||||
return MainUtil.prepend(start, Arrays.asList("hand"));
|
||||
}
|
||||
if ("pos1".startsWith(prefix)) {
|
||||
return MainUtil.prepend(start, Arrays.asList("pos1"));
|
||||
}
|
||||
if (current.contains("|")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
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<>();
|
||||
// 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(HashTagPatternParser.ALL_PATTERNS));
|
||||
// }
|
||||
// if (current.startsWith("#") || current.startsWith("=")) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// if ("hand".startsWith(prefix)) {
|
||||
// return MainUtil.prepend(start, Arrays.asList("hand"));
|
||||
// }
|
||||
// if ("pos1".startsWith(prefix)) {
|
||||
// return MainUtil.prepend(start, Arrays.asList("pos1"));
|
||||
// }
|
||||
// if (current.contains("|")) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -217,13 +217,14 @@ public enum BBC {
|
||||
|
||||
COMMAND_INVALID_SYNTAX("The command was not used properly (no more help available).", "WorldEdit.Command"),
|
||||
|
||||
HELP_SUGGEST("&7Couldn't find %s0. Maybe try one of &c%s1 &7?", "WorldEdit.Help"),
|
||||
HELP_HEADER_CATEGORIES("Command Types", "WorldEdit.Help"),
|
||||
HELP_HEADER_SUBCOMMANDS("Subcommands", "WorldEdit.Help"),
|
||||
HELP_HEADER_COMMAND("&cHelp for: &7%s0", "WorldEdit.Help"),
|
||||
HELP_ITEM_ALLOWED("&a%s0&8 - &7%s1", "WorldEdit.Help"),
|
||||
HELP_ITEM_DENIED("&c%s0&8 - &7%s1", "WorldEdit.Help"),
|
||||
HELP_HEADER("Help: page %s0/%s1", "WorldEdit.Help"),
|
||||
HELP_HEADER_FOOTER("&7Use: &8//help [type|command] [#]&7\n&7Wiki: https://git.io/vSKE5", "WorldEdit.Help"),
|
||||
HELP_HEADER_FOOTER("&7Use: &8//help [type|command|search] [#]&7\n&7Wiki: https://git.io/vSKE5", "WorldEdit.Help"),
|
||||
|
||||
PROGRESS_MESSAGE("%s1/%s0 (%s2%) @%s3cps %s4s left", "Progress"),
|
||||
PROGRESS_FINISHED("[ Done! ]", "Progress"),
|
||||
@ -292,14 +293,14 @@ public enum BBC {
|
||||
TIP_FAST("&7Tip: Set fast and without undo using &c//fast", "Tips"),
|
||||
TIP_CANCEL("&7Tip: You can &c//cancel &7an edit in progress", "Tips"),
|
||||
TIP_MASK("&7Tip: Set a global destination mask with &c/gmask", "Tips"),
|
||||
TIP_MASK_ANGLE("Tip: Replace upward slopes of 3-20 blocks using&c //replace /-20:-3 bedrock", "Tips"),
|
||||
TIP_SET_LINEAR("&7Tip: Set blocks linearly with&c //set #l3d:wood,bedrock", "Tips"),
|
||||
TIP_SURFACE_SPREAD("&7Tip: Spread a flat surface with&c //set #surfacespread:5:0:5:#existing", "Tips"),
|
||||
TIP_MASK_ANGLE("Tip: Replace upward slopes of 3-20 blocks using&c //replace /[-20][-3] bedrock", "Tips"),
|
||||
TIP_SET_LINEAR("&7Tip: Set blocks linearly with&c //set #l3d[wood,bedrock]", "Tips"),
|
||||
TIP_SURFACE_SPREAD("&7Tip: Spread a flat surface with&c //set #surfacespread[5][0][5][#existing]", "Tips"),
|
||||
TIP_SET_HAND("&7Tip: Use your current hand with &c//set hand", "Tips"),
|
||||
|
||||
// replace
|
||||
TIP_REPLACE_ID("&7Tip: Replace only the block id:&c //replace woodenstair #id:cobblestair", "Tips"),
|
||||
TIP_REPLACE_LIGHT("Tip: Remove light sources with&c //replace #brightness:1:15 0", "Tips"),
|
||||
TIP_REPLACE_ID("&7Tip: Replace only the block id:&c //replace woodenstair #id[cobblestair]", "Tips"),
|
||||
TIP_REPLACE_LIGHT("Tip: Remove light sources with&c //replace #brightness[1][15] 0", "Tips"),
|
||||
TIP_TAB_COMPLETE("Tip: The replace command supports tab completion", "Tips"),
|
||||
|
||||
// clipboard
|
||||
@ -322,7 +323,7 @@ public enum BBC {
|
||||
TIP_BRUSH_MASK("&7Tip: Set a brush destination mask with &c/mask", "Tips"),
|
||||
TIP_BRUSH_MASK_SOURCE("&7Tip: Set a brush source mask with &c/smask", "Tips"),
|
||||
TIP_BRUSH_TRANSFORM("&7Tip: Set a brush transform with &c/transform", "Tips"),
|
||||
TIP_BRUSH_RELATIVE("&7Tip: Use a relative clipboard pattern with //br sphere #~:#copy", "Tips"),
|
||||
TIP_BRUSH_RELATIVE("&7Tip: Use a relative clipboard pattern with //br sphere #~[#copy]", "Tips"),
|
||||
TIP_BRUSH_COMMAND("&7Tip: Try the command brush &c//br cmd <radius> <cmd1;cmd2>", "Tips"),
|
||||
|
||||
// regen
|
||||
@ -419,10 +420,10 @@ public enum BBC {
|
||||
if (args[i] == null) {
|
||||
continue;
|
||||
}
|
||||
m = m.replaceAll("%s" + i, args[i].toString());
|
||||
m = m.replace("%s" + i, args[i].toString());
|
||||
}
|
||||
if (args.length > 0) {
|
||||
m = m.replaceAll("%s", args[0].toString());
|
||||
m = m.replace("%s", args[0].toString());
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
@ -30,11 +30,11 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
|
||||
public static Command translate(final Command command) {
|
||||
public static Command translate(Class clazz, final Command command) {
|
||||
if (cmdConfig == null || command instanceof TranslatedCommand) {
|
||||
return command;
|
||||
}
|
||||
return new TranslatedCommand(command);
|
||||
return new TranslatedCommand(clazz.getSimpleName(), command);
|
||||
}
|
||||
|
||||
public static String getAlias(String command) {
|
||||
@ -53,12 +53,17 @@ public class Commands {
|
||||
private final String help;
|
||||
private final Command command;
|
||||
|
||||
public TranslatedCommand(Command command) {
|
||||
public TranslatedCommand(String clazz, Command command) {
|
||||
String id = command.aliases()[0];
|
||||
ConfigurationSection commands = cmdConfig.getConfigurationSection(id);
|
||||
ConfigurationSection commands;
|
||||
if (cmdConfig.contains(clazz + "." + id) || !cmdConfig.contains(id)) {
|
||||
commands = cmdConfig.getConfigurationSection(clazz + "." + id);
|
||||
} else {
|
||||
commands = cmdConfig.getConfigurationSection(id);
|
||||
}
|
||||
boolean set = false;
|
||||
if (commands == null) {
|
||||
set = (commands = cmdConfig.createSection(id)) != null;
|
||||
set = (commands = cmdConfig.createSection(clazz + "." + id)) != null;
|
||||
}
|
||||
|
||||
HashMap<String, Object> options = new HashMap<>();
|
||||
|
@ -18,7 +18,6 @@ import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
@ -87,7 +86,8 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> exte
|
||||
@Override
|
||||
public void optimize() {
|
||||
final ForkJoinPool pool = TaskManager.IMP.getPublicForkJoinPool();
|
||||
if (Fawe.get().isJava8()) {
|
||||
// if (Fawe.get().isJava8())
|
||||
{
|
||||
map.forEachChunk(new RunnableVal<FaweChunk>() {
|
||||
@Override
|
||||
public void run(final FaweChunk chunk) {
|
||||
@ -100,21 +100,22 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> exte
|
||||
}
|
||||
});
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
final ArrayList<Runnable> tasks = new ArrayList<Runnable>(map.size());
|
||||
map.forEachChunk(new RunnableVal<FaweChunk>() {
|
||||
@Override
|
||||
public void run(final FaweChunk chunk) {
|
||||
tasks.add(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.optimize();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
TaskManager.IMP.parallel(tasks);
|
||||
}
|
||||
// else {
|
||||
// final ArrayList<Runnable> tasks = new ArrayList<Runnable>(map.size());
|
||||
// map.forEachChunk(new RunnableVal<FaweChunk>() {
|
||||
// @Override
|
||||
// public void run(final FaweChunk chunk) {
|
||||
// tasks.add(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// chunk.optimize();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// TaskManager.IMP.parallel(tasks);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
@ -372,7 +372,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
biomes[index] = biome;
|
||||
}
|
||||
}
|
||||
@ -496,7 +496,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(height);
|
||||
overlay[index] = (char) pattern.apply(mutable).getCombined();
|
||||
@ -517,7 +517,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(height);
|
||||
main[index] = (char) pattern.apply(mutable).getCombined();
|
||||
@ -537,7 +537,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(height);
|
||||
floor[index] = (char) pattern.apply(mutable).getCombined();
|
||||
@ -558,7 +558,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(height);
|
||||
char combined = (char) pattern.apply(mutable).getCombined();
|
||||
@ -1063,7 +1063,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
main[index] = combined;
|
||||
}
|
||||
}
|
||||
@ -1076,7 +1076,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
floor[index] = combined;
|
||||
}
|
||||
}
|
||||
@ -1090,7 +1090,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
main[index] = combined;
|
||||
floor[index] = combined;
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* @Deprecated use ThreadLocalRandom instead
|
||||
*/
|
||||
public class PseudoRandom {
|
||||
|
||||
public static PseudoRandom random = new PseudoRandom();
|
||||
|
||||
private long state;
|
||||
@ -32,7 +35,7 @@ public class PseudoRandom {
|
||||
}
|
||||
|
||||
public double nextDouble() {
|
||||
return Math.max(0, Math.min(1, Math.abs((double) nextLong() / Long.MAX_VALUE)));
|
||||
return 0x1.0p-63 * (((nextLong()) & 0x7FFFFFFFFFFFFFFFl));
|
||||
}
|
||||
|
||||
public int random(final int n) {
|
||||
|
@ -12,6 +12,7 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
@ -33,7 +34,7 @@ public class LayerBrush implements Brush {
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern ignore, double size) throws MaxChangedBlocksException {
|
||||
final FaweQueue queue = editSession.getQueue();
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(new BlockMask(editSession, new BaseBlock(0)));
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
final RadiusMask radius = new RadiusMask(0, (int) size);
|
||||
visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), function -> true);
|
||||
|
@ -1,19 +1,17 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
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.boydti.fawe.object.mask.SurfaceMask;
|
||||
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;
|
||||
@ -25,7 +23,7 @@ public class ScatterBrush implements Brush {
|
||||
private final int count;
|
||||
private final int distance;
|
||||
private Mask mask;
|
||||
private AdjacentAnyMask adjacent;
|
||||
private AdjacentAnyMask surface;
|
||||
|
||||
public ScatterBrush(int count, int distance) {
|
||||
this.count = count;
|
||||
@ -46,18 +44,12 @@ public class ScatterBrush implements Brush {
|
||||
if (this.mask == null) {
|
||||
this.mask = Masks.alwaysTrue();
|
||||
}
|
||||
this.adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
for (int id = 0; id < 256; id++) {
|
||||
if (FaweCache.canPassThrough(id, 0)) {
|
||||
adjacent.add(new BaseBlock(id, -1));
|
||||
}
|
||||
}
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
surface = new SurfaceMask(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);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(vector -> radius.test(vector) && surface.test(vector), function -> true);
|
||||
visitor.visit(position);
|
||||
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
|
||||
Operations.completeBlindly(visitor);
|
||||
@ -67,7 +59,6 @@ public class ScatterBrush implements Brush {
|
||||
length = 1;
|
||||
visited.add(position);
|
||||
}
|
||||
|
||||
LocalBlockVectorSet placed = new LocalBlockVectorSet();
|
||||
int maxFails = 1000;
|
||||
for (int i = 0; i < count; i++) {
|
||||
@ -98,7 +89,7 @@ public class ScatterBrush implements Brush {
|
||||
}
|
||||
|
||||
public Vector getDirection(Vector pt) {
|
||||
return adjacent.direction(pt);
|
||||
return surface.direction(pt);
|
||||
}
|
||||
|
||||
public void apply(EditSession editSession, LocalBlockVectorSet placed, Vector pt, Pattern p, double size) throws MaxChangedBlocksException {
|
||||
|
@ -2,13 +2,12 @@ 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.boydti.fawe.object.mask.SurfaceMask;
|
||||
import com.boydti.fawe.object.pattern.BiomePattern;
|
||||
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;
|
||||
@ -43,14 +42,14 @@ public class SplatterBrush extends ScatterBrush {
|
||||
finalPattern = p;
|
||||
}
|
||||
final int size2 = (int) (size * size);
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
SurfaceMask surface = new SurfaceMask(editSession);
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
double dist = vector.distanceSq(position);
|
||||
if (dist < size2 && !placed.contains(vector) && (PseudoRandom.random.random(5) < 2) && solid.test(vector) && adjacent.test(vector)) {
|
||||
if (dist < size2 && !placed.contains(vector) && (PseudoRandom.random.random(5) < 2) && surface.test(vector)) {
|
||||
placed.add(vector);
|
||||
return true;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
@ -45,7 +46,7 @@ public class StencilBrush extends HeightBrush {
|
||||
map.setSize(size);
|
||||
int cutoff = onlyWhite ? maxY : 0;
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, solid.getInverseBlocks());
|
||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(Masks.negate(solid));
|
||||
RegionMask region = new RegionMask(new CuboidRegion(position.subtract(size, size, size), position.add(size, size, size)));
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
|
||||
@Override
|
||||
|
@ -1,15 +1,11 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.boydti.fawe.object.mask.SurfaceMask;
|
||||
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;
|
||||
@ -20,19 +16,10 @@ import java.util.Arrays;
|
||||
public class SurfaceSphereBrush implements Brush {
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
Mask mask = editSession.getMask();
|
||||
if (mask == null) {
|
||||
mask = Masks.alwaysTrue();
|
||||
}
|
||||
AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
for (int id = 0; id < 256; id++) {
|
||||
if (FaweCache.canPassThrough(id, 0)) {
|
||||
adjacent.add(new BaseBlock(id, -1));
|
||||
}
|
||||
}
|
||||
SurfaceMask surface = new SurfaceMask(editSession);
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
final RadiusMask radius = new RadiusMask(0, (int) size);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), vector -> editSession.setBlock(vector, pattern));
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(vector -> radius.test(vector) && surface.test(vector), vector -> editSession.setBlock(vector, pattern));
|
||||
visitor.visit(position);
|
||||
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
|
||||
Operations.completeBlindly(visitor);
|
||||
|
@ -1,16 +1,15 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.random.SimpleRandom;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
public class FastRandomCollection<T> extends RandomCollection<T> {
|
||||
private PseudoRandom random = new PseudoRandom();
|
||||
private T[] values;
|
||||
|
||||
public FastRandomCollection(Map<T, Double> weights) {
|
||||
super(weights);
|
||||
public FastRandomCollection(Map<T, Double> weights, SimpleRandom random) {
|
||||
super(weights, random);
|
||||
int max = 0;
|
||||
int[] counts = new int[weights.size()];
|
||||
Double[] weightDoubles = weights.values().toArray(new Double[weights.size()]);
|
||||
@ -39,7 +38,7 @@ public class FastRandomCollection<T> extends RandomCollection<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return values[random.nextInt(values.length)];
|
||||
public T next(int x, int y, int z) {
|
||||
return values[random.nextInt(x, y, z, values.length)];
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,34 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.boydti.fawe.object.random.SimpleRandom;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class RandomCollection<T> {
|
||||
public RandomCollection(Map<T, Double> weights) {}
|
||||
|
||||
public static <T> RandomCollection<T> of(Map<T, Double> weights) {
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public abstract class RandomCollection<T> {
|
||||
protected SimpleRandom random;
|
||||
|
||||
public RandomCollection(Map<T, Double> weights, SimpleRandom random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public static <T> RandomCollection<T> of(Map<T, Double> weights, SimpleRandom random) {
|
||||
try {
|
||||
return new FastRandomCollection<>(weights);
|
||||
return new FastRandomCollection<>(weights, random);
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
return new SimpleRandomCollection<>(weights);
|
||||
return new SimpleRandomCollection<>(weights, random);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract T next();
|
||||
public void setRandom(SimpleRandom random) {
|
||||
checkNotNull(random);
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public SimpleRandom getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
public abstract T next(int x, int y, int z);
|
||||
}
|
||||
|
@ -1,23 +1,20 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.boydti.fawe.object.random.SimpleRandom;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class SimpleRandomCollection<E> extends RandomCollection<E> {
|
||||
|
||||
private final NavigableMap<Double, E> map = new TreeMap<Double, E>();
|
||||
private final Random random;
|
||||
private double total = 0;
|
||||
|
||||
public SimpleRandomCollection(Map<E, Double> weights) {
|
||||
super(weights);
|
||||
this.random = new Random();
|
||||
public SimpleRandomCollection(Map<E, Double> weights, SimpleRandom random) {
|
||||
super(weights, random);
|
||||
for (Map.Entry<E, Double> entry : weights.entrySet()) {
|
||||
add(entry.getValue(), entry.getKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void add(double weight, E result) {
|
||||
@ -26,8 +23,7 @@ public class SimpleRandomCollection<E> extends RandomCollection<E> {
|
||||
map.put(total, result);
|
||||
}
|
||||
|
||||
public E next() {
|
||||
double value = random.nextDouble() * total;
|
||||
return map.ceilingEntry(value).getValue();
|
||||
public E next(int x, int y, int z) {
|
||||
return map.ceilingEntry(random.nextDouble(x, y, z)).getValue();
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
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.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class ClipboardExtent extends ResettableExtent {
|
||||
|
||||
private final Clipboard clipboard;
|
||||
private final Vector origin;
|
||||
private final boolean ignoreAir;
|
||||
private Extent extent;
|
||||
|
||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
public ClipboardExtent(Extent parent, Clipboard clipboard, boolean ignoreAir) {
|
||||
super(parent);
|
||||
checkNotNull(clipboard);
|
||||
this.extent = parent;
|
||||
this.clipboard = clipboard;
|
||||
this.origin = clipboard.getOrigin();
|
||||
this.ignoreAir = ignoreAir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector to, BaseBlock block) throws WorldEditException {
|
||||
Region region = clipboard.getRegion();
|
||||
ForwardExtentCopy copy = new ForwardExtentCopy(clipboard, clipboard.getRegion(), clipboard.getOrigin(), extent, to);
|
||||
if (ignoreAir) {
|
||||
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||
}
|
||||
Operations.completeLegacy(copy);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(y);
|
||||
mutable.mutZ(z);
|
||||
return setBlock(mutable, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
this.extent = extent;
|
||||
return super.setExtent(extent);
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.boydti.fawe.object.mask.CustomMask;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
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.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.NullExtent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Parses mask input strings.
|
||||
*/
|
||||
public class DefaultTransformParser extends InputParser<ResettableExtent> {
|
||||
|
||||
public DefaultTransformParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
private static CustomMask[] customMasks = new CustomMask[0];
|
||||
|
||||
public void addMask(CustomMask mask) {
|
||||
checkNotNull(mask);
|
||||
List<CustomMask> list = new ArrayList<>(Arrays.asList(customMasks));
|
||||
list.add(mask);
|
||||
customMasks = list.toArray(new CustomMask[list.size()]);
|
||||
}
|
||||
|
||||
public List<CustomMask> getCustomMasks() {
|
||||
return Arrays.asList(customMasks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
Extent extent = new NullExtent();
|
||||
for (String component : input.split(" ")) {
|
||||
if (component.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
extent = getTansformComponent(extent, component, context);
|
||||
}
|
||||
if (extent instanceof ResettableExtent) {
|
||||
return (ResettableExtent) extent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ResettableExtent getTansformComponent(Extent parent, String component, ParserContext context) throws InputParseException {
|
||||
final char firstChar = component.charAt(0);
|
||||
switch (firstChar) {
|
||||
case '#':
|
||||
int colon = component.indexOf(':');
|
||||
if (colon != -1) {
|
||||
String rest = component.substring(colon + 1);
|
||||
switch (component.substring(0, colon).toLowerCase()) {
|
||||
case "#pattern": {
|
||||
Pattern pattern = worldEdit.getPatternFactory().parseFromInput(rest, context);
|
||||
return new PatternTransform(parent, pattern);
|
||||
}
|
||||
case "#offset": {
|
||||
try {
|
||||
String[] split2 = component.split(":");
|
||||
double x = Math.abs(Expression.compile(split2[1]).evaluate());
|
||||
double y = Math.abs(Expression.compile(split2[2]).evaluate());
|
||||
double z = Math.abs(Expression.compile(split2[3]).evaluate());
|
||||
rest = rest.substring(Math.min(rest.length(), split2[1].length() + split2[2].length() + split2[3].length() + 3));
|
||||
if (!rest.isEmpty()) {
|
||||
parent = parseFromInput(rest, context);
|
||||
}
|
||||
return new OffsetExtent(parent, (int) x, (int) y, (int) z);
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new InputParseException("The correct format is #offset:<dx>:<dy>:<dz>");
|
||||
}
|
||||
}
|
||||
case "#scale": {
|
||||
try {
|
||||
String[] split2 = component.split(":");
|
||||
double x = Math.abs(Expression.compile(split2[1]).evaluate());
|
||||
double y = Math.abs(Expression.compile(split2[2]).evaluate());
|
||||
double z = Math.abs(Expression.compile(split2[3]).evaluate());
|
||||
rest = rest.substring(Math.min(rest.length(), split2[1].length() + split2[2].length() + split2[3].length() + 3));
|
||||
if (!rest.isEmpty()) {
|
||||
parent = parseFromInput(rest, context);
|
||||
}
|
||||
return new ScaleTransform(parent, x, y, z);
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new InputParseException("The correct format is #scale:<dx>:<dy>:<dz>");
|
||||
}
|
||||
}
|
||||
case "#rotate": {
|
||||
try {
|
||||
String[] split2 = component.split(":");
|
||||
double x = (Expression.compile(split2[1]).evaluate());
|
||||
double y = (Expression.compile(split2[2]).evaluate());
|
||||
double z = (Expression.compile(split2[3]).evaluate());
|
||||
rest = rest.substring(Math.min(rest.length(), split2[1].length() + split2[2].length() + split2[3].length() + 3));
|
||||
if (!rest.isEmpty()) {
|
||||
parent = parseFromInput(rest, context);
|
||||
}
|
||||
ExtentTraverser traverser = new ExtentTraverser(parent).find(TransformExtent.class);
|
||||
BlockTransformExtent affine = (TransformExtent) (traverser != null ? traverser.get() : null);
|
||||
if (affine == null) {
|
||||
parent = affine = new TransformExtent(parent, context.requireWorld().getWorldData().getBlockRegistry());
|
||||
}
|
||||
AffineTransform transform = (AffineTransform) affine.getTransform();
|
||||
transform = transform.rotateX(x);
|
||||
transform = transform.rotateY(y);
|
||||
transform = transform.rotateZ(z);
|
||||
affine.setTransform(transform);
|
||||
return (ResettableExtent) parent;
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new InputParseException("The correct format is #rotate:<dx>:<dy>:<dz>");
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new NoMatchException("Unrecognized transform '" + component + "'");
|
||||
}
|
||||
} else {
|
||||
switch (component) {
|
||||
case "#clipboard": {
|
||||
LocalSession session = context.requireSession();
|
||||
if (session != null) {
|
||||
try {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
return new ClipboardExtent(parent, clipboard, true);
|
||||
} catch (EmptyClipboardException e) {
|
||||
throw new InputParseException("To use #clipboard, please first copy something to your clipboard");
|
||||
}
|
||||
} else {
|
||||
throw new InputParseException("No session is available, so no clipboard is available");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new NoMatchException("Unrecognized transform '" + component + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return DefaultTransformParser.class;
|
||||
}
|
||||
}
|
@ -11,14 +11,13 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class FaweRegionExtent extends AbstractDelegateExtent {
|
||||
public abstract class FaweRegionExtent extends ResettableExtent {
|
||||
private final FaweLimit limit;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class Linear3DTransform extends SelectTransform {
|
||||
|
||||
private final Collection<ResettableExtent> extents;
|
||||
private final ResettableExtent[] extentsArray;
|
||||
|
||||
public Linear3DTransform(ResettableExtent[] extents) {
|
||||
this.extentsArray = extents;
|
||||
this.extents = Arrays.asList(extents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
for (ResettableExtent cur : extentsArray) {
|
||||
cur.setExtent(extent);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int y, int z) {
|
||||
int index = (x + y + z) % extentsArray.length;
|
||||
if (index < 0) {
|
||||
index += extentsArray.length;
|
||||
}
|
||||
return extentsArray[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int z) {
|
||||
return getExtent(x, 0, z);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class LinearTransform extends SelectTransform {
|
||||
|
||||
private final Collection<ResettableExtent> extents;
|
||||
private final ResettableExtent[] extentsArray;
|
||||
private int index;
|
||||
|
||||
public LinearTransform(ResettableExtent[] extents) {
|
||||
this.extentsArray = extents;
|
||||
this.extents = Arrays.asList(extents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
for (ResettableExtent cur : extentsArray) {
|
||||
cur.setExtent(extent);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int y, int z) {
|
||||
if (index == extentsArray.length) {
|
||||
index = 0;
|
||||
}
|
||||
return extentsArray[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int z) {
|
||||
return getExtent(x, 0, z);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class MultiTransform extends RandomTransform {
|
||||
private AbstractDelegateExtent[] extents;
|
||||
|
||||
public MultiTransform(Collection<ResettableExtent> extents) {
|
||||
for (ResettableExtent extent : extents) add(extent, 1);
|
||||
}
|
||||
|
||||
public MultiTransform() {
|
||||
this.extents = new AbstractDelegateExtent[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ResettableExtent extent, double chance) {
|
||||
super.add(extent, chance);
|
||||
this.extents = getExtents().toArray(new AbstractDelegateExtent[getExtents().size()]);
|
||||
}
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
boolean result = false;
|
||||
for (AbstractDelegateExtent extent : extents) result |= extent.setBlock(x, y, z, block);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
|
||||
boolean result = false;
|
||||
for (AbstractDelegateExtent extent : extents) result |= extent.setBlock(location, block);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome biome) {
|
||||
boolean result = false;
|
||||
for (AbstractDelegateExtent extent : extents) result |= extent.setBiome(position, biome);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
Entity created = null;
|
||||
for (AbstractDelegateExtent extent : extents) created = extent.createEntity(location, entity);
|
||||
return created;
|
||||
}
|
||||
}
|
@ -34,6 +34,16 @@ public class NullExtent extends FaweRegionExtent {
|
||||
this.reason = failReason;
|
||||
}
|
||||
|
||||
public NullExtent() {
|
||||
super(new com.sk89q.worldedit.extent.NullExtent(), FaweLimit.MAX);
|
||||
this.reason = BBC.WORLDEDIT_CANCEL_REASON_MANUAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBiome getBiome(final Vector2D arg0) {
|
||||
throw new FaweException(reason);
|
||||
|
@ -21,21 +21,16 @@ public class OffsetExtent extends ResettableExtent {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome biome) {
|
||||
return super.setBiome(mutable.setComponents(position.getBlockX() + dx, position.getBlockZ() + dz), biome);
|
||||
return getExtent().setBiome(mutable.setComponents(position.getBlockX() + dx, position.getBlockZ() + dz), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException {
|
||||
return super.setBlock(location.getBlockX() + dx, location.getBlockY() + dy, location.getBlockZ() + dz, block);
|
||||
return getExtent().setBlock(location.getBlockX() + dx, location.getBlockY() + dy, location.getBlockZ() + dz, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
return super.setBlock(x + dx, y + dy, z + dz, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
return super.setExtent(extent);
|
||||
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.MutableBlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.SplittableRandom;
|
||||
|
||||
public class RandomOffsetTransform extends ResettableExtent {
|
||||
private final int dx, dy, dz;
|
||||
private final SplittableRandom random;
|
||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||
|
||||
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
|
||||
super(parent);
|
||||
this.dx = dx + 1;
|
||||
this.dy = dy + 1;
|
||||
this.dz = dz + 1;
|
||||
this.random = new SplittableRandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D pos, BaseBiome biome) {
|
||||
int x = pos.getBlockX() + random.nextInt(1 + (dx << 1)) - dx;
|
||||
int z = pos.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz;
|
||||
return super.setBiome(mutable.setComponents(x, z), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector pos, BaseBlock block) throws WorldEditException {
|
||||
int x = pos.getBlockX() + random.nextInt(1 + (dx << 1)) - dx;
|
||||
int y = pos.getBlockY() + random.nextInt(1 + (dy << 1)) - dy;
|
||||
int z = pos.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz;
|
||||
return super.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
x = x + random.nextInt(1 + (dx << 1)) - dx;
|
||||
y = y + random.nextInt(1 + (dy << 1)) - dy;
|
||||
z = z + random.nextInt(1 + (dz << 1)) - dz;
|
||||
return super.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
return super.setExtent(extent);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.boydti.fawe.object.collection.RandomCollection;
|
||||
import com.boydti.fawe.object.random.SimpleRandom;
|
||||
import com.boydti.fawe.object.random.TrueRandom;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Uses a random pattern of a weighted list of patterns.
|
||||
*/
|
||||
public class RandomTransform extends SelectTransform {
|
||||
|
||||
private final SimpleRandom random;
|
||||
private Map<ResettableExtent, Double> weights = new HashMap<>();
|
||||
private RandomCollection<ResettableExtent> collection;
|
||||
private LinkedHashSet<ResettableExtent> extents = new LinkedHashSet<>();
|
||||
|
||||
public RandomTransform() {
|
||||
this(new TrueRandom());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int y, int z) {
|
||||
return collection.next(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDelegateExtent getExtent(int x, int z) {
|
||||
return collection.next(x, 0, z);
|
||||
}
|
||||
|
||||
public RandomTransform(SimpleRandom random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
for (AbstractDelegateExtent current : extents) {
|
||||
if (current instanceof ResettableExtent) {
|
||||
((ResettableExtent) current).setExtent(extent);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pattern to the weight list of patterns.
|
||||
*
|
||||
* <p>The probability for the pattern added is chance / max where max is
|
||||
* the sum of the probabilities of all added patterns.</p>
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param chance the chance, which can be any positive number
|
||||
*/
|
||||
public void add(ResettableExtent extent, double chance) {
|
||||
checkNotNull(extent);
|
||||
weights.put(extent, chance);
|
||||
collection = RandomCollection.of(weights, random);
|
||||
this.extents.add(extent);
|
||||
}
|
||||
|
||||
public Set<ResettableExtent> getExtents() {
|
||||
return extents;
|
||||
}
|
||||
|
||||
public RandomCollection<ResettableExtent> getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return RandomPattern.class;
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.extent;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -14,10 +15,11 @@ public class ResettableExtent extends AbstractDelegateExtent {
|
||||
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
checkNotNull(extent);
|
||||
if (getExtent() instanceof ResettableExtent) {
|
||||
((ResettableExtent) getExtent()).setExtent(extent);
|
||||
Extent next = getExtent();
|
||||
if (!(next instanceof NullExtent) && !(next instanceof World) && next instanceof ResettableExtent) {
|
||||
((ResettableExtent) next).setExtent(extent);
|
||||
} else {
|
||||
new ExtentTraverser(this).setNext(extent);
|
||||
new ExtentTraverser(this).setNext(new AbstractDelegateExtent(extent));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.*;
|
||||
import com.sk89q.worldedit.extent.NullExtent;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class SelectTransform extends ResettableExtent {
|
||||
public SelectTransform() {
|
||||
super(new NullExtent());
|
||||
}
|
||||
|
||||
public abstract AbstractDelegateExtent getExtent(int x, int y, int z);
|
||||
public abstract AbstractDelegateExtent getExtent(int x, int z);
|
||||
|
||||
public Extent getExtent(Vector pos) {
|
||||
return getExtent(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||
}
|
||||
public Extent getExtent(Vector2D pos) {
|
||||
return getExtent(pos.getBlockX(), pos.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
|
||||
return getExtent(x, y, z).setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector position, BaseBlock block) throws WorldEditException {
|
||||
return getExtent(position).setBlock(position, block);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Location position, BaseEntity entity) {
|
||||
return getExtent(position.getBlockX(), position.getBlockY(), position.getBlockZ()).createEntity(position, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome biome) {
|
||||
return getExtent(position).setBiome(position, biome);
|
||||
}
|
||||
}
|
@ -2,25 +2,22 @@ package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
|
||||
/**
|
||||
* Just an optimized version of the Adjacent Mask for single adjacency
|
||||
*/
|
||||
public class AdjacentAnyMask extends BlockMask {
|
||||
|
||||
public class AdjacentAnyMask implements Mask {
|
||||
|
||||
private final Mask mask;
|
||||
private MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
public AdjacentAnyMask(Extent extent, BaseBlock... blocks) {
|
||||
this(extent, Arrays.asList(blocks));
|
||||
public AdjacentAnyMask(Mask mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public AdjacentAnyMask(Extent extent, Collection<BaseBlock> blocks) {
|
||||
super(extent, blocks);
|
||||
public Mask getMask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,19 +26,19 @@ public class AdjacentAnyMask extends BlockMask {
|
||||
int y = v.getBlockY();
|
||||
int z = v.getBlockZ();
|
||||
v.mutY(y + 1);
|
||||
if (super.test(v)) { v.mutY(y); return true; }
|
||||
if (mask.test(v)) { v.mutY(y); return true; }
|
||||
v.mutY(y - 1);
|
||||
if (super.test(v)) { v.mutY(y); return true; }
|
||||
if (mask.test(v)) { v.mutY(y); return true; }
|
||||
v.mutY(y);
|
||||
v.mutX(x + 1);
|
||||
if (super.test(v)) { v.mutX(x); return true; }
|
||||
if (mask.test(v)) { v.mutX(x); return true; }
|
||||
v.mutX(x - 1);
|
||||
if (super.test(v)) { v.mutX(x); return true; }
|
||||
if (mask.test(v)) { v.mutX(x); return true; }
|
||||
v.mutX(x);
|
||||
v.mutZ(z + 1);
|
||||
if (super.test(v)) { v.mutZ(z); return true; }
|
||||
if (mask.test(v)) { v.mutZ(z); return true; }
|
||||
v.mutZ(z - 1);
|
||||
if (super.test(v)) { v.mutZ(z); return true; }
|
||||
if (mask.test(v)) { v.mutZ(z); return true; }
|
||||
v.mutZ(z);
|
||||
return false;
|
||||
}
|
||||
@ -51,19 +48,19 @@ public class AdjacentAnyMask extends BlockMask {
|
||||
int y = v.getBlockY();
|
||||
int z = v.getBlockZ();
|
||||
v.mutY(y + 1);
|
||||
if (super.test(v)) { v.mutY(y); return mutable.setComponents(0, 1, 0); }
|
||||
if (mask.test(v)) { v.mutY(y); return mutable.setComponents(0, 1, 0); }
|
||||
v.mutY(y - 1);
|
||||
if (super.test(v)) { v.mutY(y); return mutable.setComponents(0, -1, 0); }
|
||||
if (mask.test(v)) { v.mutY(y); return mutable.setComponents(0, -1, 0); }
|
||||
v.mutY(y);
|
||||
v.mutX(x + 1);
|
||||
if (super.test(v)) { v.mutX(x); return mutable.setComponents(1, 0, 0); }
|
||||
if (mask.test(v)) { v.mutX(x); return mutable.setComponents(1, 0, 0); }
|
||||
v.mutX(x - 1);
|
||||
if (super.test(v)) { v.mutX(x); return mutable.setComponents(-1, 0, 0); }
|
||||
if (mask.test(v)) { v.mutX(x); return mutable.setComponents(-1, 0, 0); }
|
||||
v.mutX(x);
|
||||
v.mutZ(z + 1);
|
||||
if (super.test(v)) { v.mutZ(z); return mutable.setComponents(0, 0, 1); }
|
||||
if (mask.test(v)) { v.mutZ(z); return mutable.setComponents(0, 0, 1); }
|
||||
v.mutZ(z - 1);
|
||||
if (super.test(v)) { v.mutZ(z); return mutable.setComponents(0, 0, - 1); }
|
||||
if (mask.test(v)) { v.mutZ(z); return mutable.setComponents(0, 0, - 1); }
|
||||
v.mutZ(z);
|
||||
return null;
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import java.util.Collection;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
|
||||
public class AdjacentMask extends BlockMask {
|
||||
public class AdjacentMask implements Mask {
|
||||
private final int min, max;
|
||||
private final Mask mask;
|
||||
|
||||
public AdjacentMask(Extent extent, Collection<BaseBlock> blocks, int requiredMin, int requiredMax) {
|
||||
super(extent, blocks);
|
||||
public AdjacentMask(Mask mask, int requiredMin, int requiredMax) {
|
||||
this.mask = mask;
|
||||
this.min = requiredMin;
|
||||
this.max = requiredMax;
|
||||
}
|
||||
@ -22,19 +20,19 @@ public class AdjacentMask extends BlockMask {
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
v.mutX(x + 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
v.mutX(x - 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
v.mutX(x);
|
||||
v.mutY(y + 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutY(y); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutY(y); return true; }
|
||||
v.mutY(y - 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutY(y); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutY(y); return true; }
|
||||
v.mutY(y);
|
||||
v.mutZ(z + 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
v.mutZ(z - 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
v.mutZ(z);
|
||||
return count >= min && count <= max;
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.MutableBlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
public class BiomeMask extends AbstractExtentMask {
|
||||
private final BaseBiome biome;
|
||||
private MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||
|
||||
public BiomeMask(Extent extent, BaseBiome biome) {
|
||||
super(extent);
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
Vector2D pos = mutable.setComponents(vector.getBlockX(), vector.getBlockZ());
|
||||
return getExtent().getBiome(pos).getId() == biome.getId();
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CustomMask implements Mask {
|
||||
|
||||
/**
|
||||
* Constructor for custom mask
|
||||
* When used in commands, use #custom:<input>
|
||||
* @param masks Any previous masks set (usually from //mask [previous] [thismask]
|
||||
* @param input The input to parse
|
||||
* @param context The context (for extent, player etc)
|
||||
*/
|
||||
public CustomMask(List<Mask> masks, String input, ParserContext context) {
|
||||
try {
|
||||
this.getClass(). getConstructor ( List.class, String.class, ParserContext.class ) ;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException("Constructor for " + getClass() + " must be <init>(List.class, String.class, ParserContext.class)");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract String description();
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||
import java.util.SplittableRandom;
|
||||
|
||||
public class RandomMask extends AbstractMask {
|
||||
private final SplittableRandom random;
|
||||
private final double threshold;
|
||||
|
||||
public RandomMask(double threshold) {
|
||||
this.random = new SplittableRandom();
|
||||
this.threshold = (threshold - 0.5) * Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
return random.nextInt() <= threshold;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.boydti.fawe.object.random.SimplexNoise;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||
|
||||
public class SimplexMask extends AbstractMask {
|
||||
private final double min, max, scale;
|
||||
|
||||
public SimplexMask(double scale, double min, double max) {
|
||||
this.scale = scale;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Vector vector) {
|
||||
double value = SimplexNoise.noise(vector.getBlockX() * scale, vector.getBlockY() * scale, vector.getBlockZ() * scale);
|
||||
return value >= min && value <= max;
|
||||
}
|
||||
}
|
@ -4,20 +4,24 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
|
||||
public class SurfaceMask extends AdjacentAnyMask {
|
||||
private final Extent extent;
|
||||
|
||||
public SurfaceMask(Extent extent) {
|
||||
super(extent);
|
||||
super(new BlockMask(extent, new BaseBlock(0)));
|
||||
BlockMask mask = (BlockMask) getMask();
|
||||
for (int id = 0; id < 256; id++) {
|
||||
if (FaweCache.canPassThrough(id, 0)) {
|
||||
add(new BaseBlock(id, -1));
|
||||
mask.add(new BaseBlock(id, -1));
|
||||
}
|
||||
}
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Vector v) {
|
||||
BaseBlock block = getExtent().getBlock(v);
|
||||
return !test(block.getId()) && super.test(v);
|
||||
return !getMask().test(v) && super.test(v);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import java.util.Collection;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
|
||||
public class WallMask extends BlockMask {
|
||||
public class WallMask implements Mask {
|
||||
private final int min, max;
|
||||
private final Mask mask;
|
||||
|
||||
public WallMask(Extent extent, Collection<BaseBlock> blocks, int requiredMin, int requiredMax) {
|
||||
super(extent, blocks);
|
||||
public WallMask(Mask mask, int requiredMin, int requiredMax) {
|
||||
this.mask = mask;
|
||||
this.min = requiredMin;
|
||||
this.max = requiredMax;
|
||||
}
|
||||
@ -22,14 +20,14 @@ public class WallMask extends BlockMask {
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
v.mutX(x + 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
v.mutX(x - 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutX(x); return true; }
|
||||
v.mutX(x);
|
||||
v.mutZ(z + 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
v.mutZ(z - 1);
|
||||
if (super.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
if (mask.test(v) && ++count == min && max >= 8) { v.mutZ(z); return true; }
|
||||
v.mutZ(z);
|
||||
return count >= min && count <= max;
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
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.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class BufferedPattern2D extends AbstractPattern implements ResettablePattern {
|
||||
private final Pattern pattern;
|
||||
private final LocalBlockVectorSet set = new LocalBlockVectorSet();
|
||||
private final FaweTimer timer;
|
||||
private final long[] actionTime;
|
||||
|
||||
public BufferedPattern2D(FawePlayer fp, Pattern parent) {
|
||||
long[] actionTime = fp.getMeta("lastActionTime");
|
||||
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
||||
this.actionTime = actionTime;
|
||||
this.pattern = parent;
|
||||
this.timer = Fawe.get().getTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
return pattern.apply(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
long now = timer.getTick();
|
||||
try {
|
||||
if (!set.add(setPosition.getBlockX(), 0, setPosition.getBlockZ())) {
|
||||
return false;
|
||||
}
|
||||
return pattern.apply(extent, setPosition, getPosition);
|
||||
} catch (UnsupportedOperationException ignore) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
long now = timer.getTick();
|
||||
if (now - actionTime[1] > 5) {
|
||||
set.clear();
|
||||
}
|
||||
actionTime[1] = actionTime[0];
|
||||
actionTime[0] = now;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
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.pattern.AbstractPattern;
|
||||
@ -16,4 +17,12 @@ public class ExistingPattern extends AbstractPattern {
|
||||
public BaseBlock apply(Vector position) {
|
||||
return extent.getBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector set, Vector get) throws WorldEditException {
|
||||
if (set.getBlockX() == get.getBlockX() && set.getBlockZ() == get.getBlockZ() && set.getBlockY() == get.getBlockY()) {
|
||||
return false;
|
||||
}
|
||||
return extent.setBlock(set, extent.getBlock(get));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package com.boydti.fawe.object.random;
|
||||
|
||||
public interface SimpleRandom {
|
||||
public double nextDouble(int x, int y, int z);
|
||||
|
||||
public default int nextInt(int x, int y, int z, int len) {
|
||||
double val = nextDouble(x, y, z);
|
||||
return (int) (val * len);
|
||||
}
|
||||
}
|
@ -0,0 +1,355 @@
|
||||
package com.boydti.fawe.object.random;
|
||||
/*
|
||||
* A speed-improved simplex noise algorithm for 2D, 3D and 4D in Java.
|
||||
*
|
||||
* Based on example code by Stefan Gustavson (stegu@itn.liu.se).
|
||||
* Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).
|
||||
* Better rank ordering method for 4D by Stefan Gustavson in 2012.
|
||||
*
|
||||
* This could be speeded up even further, but it's useful as it is.
|
||||
*
|
||||
* Version 2012-03-09
|
||||
*
|
||||
* This code was placed in the public domain by its original author,
|
||||
* Stefan Gustavson. You may use it as you see fit, but
|
||||
* attribution is appreciated.
|
||||
*
|
||||
*/
|
||||
|
||||
public class SimplexNoise {
|
||||
private static Grad grad3[] = {new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0),
|
||||
new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1),
|
||||
new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)};
|
||||
|
||||
private static Grad grad4[]= {new Grad(0,1,1,1),new Grad(0,1,1,-1),new Grad(0,1,-1,1),new Grad(0,1,-1,-1),
|
||||
new Grad(0,-1,1,1),new Grad(0,-1,1,-1),new Grad(0,-1,-1,1),new Grad(0,-1,-1,-1),
|
||||
new Grad(1,0,1,1),new Grad(1,0,1,-1),new Grad(1,0,-1,1),new Grad(1,0,-1,-1),
|
||||
new Grad(-1,0,1,1),new Grad(-1,0,1,-1),new Grad(-1,0,-1,1),new Grad(-1,0,-1,-1),
|
||||
new Grad(1,1,0,1),new Grad(1,1,0,-1),new Grad(1,-1,0,1),new Grad(1,-1,0,-1),
|
||||
new Grad(-1,1,0,1),new Grad(-1,1,0,-1),new Grad(-1,-1,0,1),new Grad(-1,-1,0,-1),
|
||||
new Grad(1,1,1,0),new Grad(1,1,-1,0),new Grad(1,-1,1,0),new Grad(1,-1,-1,0),
|
||||
new Grad(-1,1,1,0),new Grad(-1,1,-1,0),new Grad(-1,-1,1,0),new Grad(-1,-1,-1,0)};
|
||||
|
||||
private static short p[] = {151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
|
||||
// To remove the need for index wrapping, double the permutation table length
|
||||
private static short perm[] = new short[512];
|
||||
private static short permMod12[] = new short[512];
|
||||
static {
|
||||
for(int i=0; i<512; i++)
|
||||
{
|
||||
perm[i]=p[i & 255];
|
||||
permMod12[i] = (short)(perm[i] % 12);
|
||||
}
|
||||
}
|
||||
|
||||
// Skewing and unskewing factors for 2, 3, and 4 dimensions
|
||||
private static final double F2 = 0.5*(Math.sqrt(3.0)-1.0);
|
||||
private static final double G2 = (3.0-Math.sqrt(3.0))/6.0;
|
||||
private static final double F3 = 1.0/3.0;
|
||||
private static final double G3 = 1.0/6.0;
|
||||
private static final double F4 = (Math.sqrt(5.0)-1.0)/4.0;
|
||||
private static final double G4 = (5.0-Math.sqrt(5.0))/20.0;
|
||||
|
||||
// This method is a *lot* faster than using (int)Math.floor(x)
|
||||
private static int fastfloor(double x) {
|
||||
int xi = (int)x;
|
||||
return x<xi ? xi-1 : xi;
|
||||
}
|
||||
|
||||
private static double dot(Grad g, double x, double y) {
|
||||
return g.x*x + g.y*y; }
|
||||
|
||||
private static double dot(Grad g, double x, double y, double z) {
|
||||
return g.x*x + g.y*y + g.z*z; }
|
||||
|
||||
private static double dot(Grad g, double x, double y, double z, double w) {
|
||||
return g.x*x + g.y*y + g.z*z + g.w*w; }
|
||||
|
||||
|
||||
// 2D simplex noise
|
||||
public static double noise(double xin, double yin) {
|
||||
double n0, n1, n2; // Noise contributions from the three corners
|
||||
// Skew the input space to determine which simplex cell we're in
|
||||
double s = (xin+yin)*F2; // Hairy factor for 2D
|
||||
int i = fastfloor(xin+s);
|
||||
int j = fastfloor(yin+s);
|
||||
double t = (i+j)*G2;
|
||||
double X0 = i-t; // Unskew the cell origin back to (x,y) space
|
||||
double Y0 = j-t;
|
||||
double x0 = xin-X0; // The x,y distances from the cell origin
|
||||
double y0 = yin-Y0;
|
||||
// For the 2D case, the simplex shape is an equilateral triangle.
|
||||
// Determine which simplex we are in.
|
||||
int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
|
||||
if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
// c = (3-sqrt(3))/6
|
||||
double x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
|
||||
double y1 = y0 - j1 + G2;
|
||||
double x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
|
||||
double y2 = y0 - 1.0 + 2.0 * G2;
|
||||
// Work out the hashed gradient indices of the three simplex corners
|
||||
int ii = i & 255;
|
||||
int jj = j & 255;
|
||||
int gi0 = permMod12[ii+perm[jj]];
|
||||
int gi1 = permMod12[ii+i1+perm[jj+j1]];
|
||||
int gi2 = permMod12[ii+1+perm[jj+1]];
|
||||
// Calculate the contribution from the three corners
|
||||
double t0 = 0.5 - x0*x0-y0*y0;
|
||||
if(t0<0) n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * dot(grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
|
||||
}
|
||||
double t1 = 0.5 - x1*x1-y1*y1;
|
||||
if(t1<0) n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * dot(grad3[gi1], x1, y1);
|
||||
}
|
||||
double t2 = 0.5 - x2*x2-y2*y2;
|
||||
if(t2<0) n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * dot(grad3[gi2], x2, y2);
|
||||
}
|
||||
// Add contributions from each corner to get the final noise value.
|
||||
// The result is scaled to return values in the interval [-1,1].
|
||||
return 70.0 * (n0 + n1 + n2);
|
||||
}
|
||||
|
||||
|
||||
// 3D simplex noise
|
||||
public static double noise(double xin, double yin, double zin) {
|
||||
double n0, n1, n2, n3; // Noise contributions from the four corners
|
||||
// Skew the input space to determine which simplex cell we're in
|
||||
double s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D
|
||||
int i = fastfloor(xin+s);
|
||||
int j = fastfloor(yin+s);
|
||||
int k = fastfloor(zin+s);
|
||||
double t = (i+j+k)*G3;
|
||||
double X0 = i-t; // Unskew the cell origin back to (x,y,z) space
|
||||
double Y0 = j-t;
|
||||
double Z0 = k-t;
|
||||
double x0 = xin-X0; // The x,y,z distances from the cell origin
|
||||
double y0 = yin-Y0;
|
||||
double z0 = zin-Z0;
|
||||
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
|
||||
// Determine which simplex we are in.
|
||||
int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
|
||||
int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
|
||||
if(x0>=y0) {
|
||||
if(y0>=z0)
|
||||
{ i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
|
||||
else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
|
||||
else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
|
||||
}
|
||||
else { // x0<y0
|
||||
if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
|
||||
else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
|
||||
else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
|
||||
}
|
||||
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
|
||||
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
|
||||
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
|
||||
// c = 1/6.
|
||||
double x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
|
||||
double y1 = y0 - j1 + G3;
|
||||
double z1 = z0 - k1 + G3;
|
||||
double x2 = x0 - i2 + 2.0*G3; // Offsets for third corner in (x,y,z) coords
|
||||
double y2 = y0 - j2 + 2.0*G3;
|
||||
double z2 = z0 - k2 + 2.0*G3;
|
||||
double x3 = x0 - 1.0 + 3.0*G3; // Offsets for last corner in (x,y,z) coords
|
||||
double y3 = y0 - 1.0 + 3.0*G3;
|
||||
double z3 = z0 - 1.0 + 3.0*G3;
|
||||
// Work out the hashed gradient indices of the four simplex corners
|
||||
int ii = i & 255;
|
||||
int jj = j & 255;
|
||||
int kk = k & 255;
|
||||
int gi0 = permMod12[ii+perm[jj+perm[kk]]];
|
||||
int gi1 = permMod12[ii+i1+perm[jj+j1+perm[kk+k1]]];
|
||||
int gi2 = permMod12[ii+i2+perm[jj+j2+perm[kk+k2]]];
|
||||
int gi3 = permMod12[ii+1+perm[jj+1+perm[kk+1]]];
|
||||
// Calculate the contribution from the four corners
|
||||
double t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
|
||||
if(t0<0) n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0);
|
||||
}
|
||||
double t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
|
||||
if(t1<0) n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1);
|
||||
}
|
||||
double t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
|
||||
if(t2<0) n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2);
|
||||
}
|
||||
double t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
|
||||
if(t3<0) n3 = 0.0;
|
||||
else {
|
||||
t3 *= t3;
|
||||
n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3);
|
||||
}
|
||||
// Add contributions from each corner to get the final noise value.
|
||||
// The result is scaled to stay just inside [-1,1]
|
||||
return 32.0*(n0 + n1 + n2 + n3);
|
||||
}
|
||||
|
||||
|
||||
// 4D simplex noise, better simplex rank ordering method 2012-03-09
|
||||
public static double noise(double x, double y, double z, double w) {
|
||||
|
||||
double n0, n1, n2, n3, n4; // Noise contributions from the five corners
|
||||
// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
|
||||
double s = (x + y + z + w) * F4; // Factor for 4D skewing
|
||||
int i = fastfloor(x + s);
|
||||
int j = fastfloor(y + s);
|
||||
int k = fastfloor(z + s);
|
||||
int l = fastfloor(w + s);
|
||||
double t = (i + j + k + l) * G4; // Factor for 4D unskewing
|
||||
double X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
|
||||
double Y0 = j - t;
|
||||
double Z0 = k - t;
|
||||
double W0 = l - t;
|
||||
double x0 = x - X0; // The x,y,z,w distances from the cell origin
|
||||
double y0 = y - Y0;
|
||||
double z0 = z - Z0;
|
||||
double w0 = w - W0;
|
||||
// For the 4D case, the simplex is a 4D shape I won't even try to describe.
|
||||
// To find out which of the 24 possible simplices we're in, we need to
|
||||
// determine the magnitude ordering of x0, y0, z0 and w0.
|
||||
// Six pair-wise comparisons are performed between each possible pair
|
||||
// of the four coordinates, and the results are used to rank the numbers.
|
||||
int rankx = 0;
|
||||
int ranky = 0;
|
||||
int rankz = 0;
|
||||
int rankw = 0;
|
||||
if(x0 > y0) rankx++; else ranky++;
|
||||
if(x0 > z0) rankx++; else rankz++;
|
||||
if(x0 > w0) rankx++; else rankw++;
|
||||
if(y0 > z0) ranky++; else rankz++;
|
||||
if(y0 > w0) ranky++; else rankw++;
|
||||
if(z0 > w0) rankz++; else rankw++;
|
||||
int i1, j1, k1, l1; // The integer offsets for the second simplex corner
|
||||
int i2, j2, k2, l2; // The integer offsets for the third simplex corner
|
||||
int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
|
||||
// [rankx, ranky, rankz, rankw] is a 4-vector with the numbers 0, 1, 2 and 3
|
||||
// in some order. We use a thresholding to set the coordinates in turn.
|
||||
// Rank 3 denotes the largest coordinate.
|
||||
i1 = rankx >= 3 ? 1 : 0;
|
||||
j1 = ranky >= 3 ? 1 : 0;
|
||||
k1 = rankz >= 3 ? 1 : 0;
|
||||
l1 = rankw >= 3 ? 1 : 0;
|
||||
// Rank 2 denotes the second largest coordinate.
|
||||
i2 = rankx >= 2 ? 1 : 0;
|
||||
j2 = ranky >= 2 ? 1 : 0;
|
||||
k2 = rankz >= 2 ? 1 : 0;
|
||||
l2 = rankw >= 2 ? 1 : 0;
|
||||
// Rank 1 denotes the second smallest coordinate.
|
||||
i3 = rankx >= 1 ? 1 : 0;
|
||||
j3 = ranky >= 1 ? 1 : 0;
|
||||
k3 = rankz >= 1 ? 1 : 0;
|
||||
l3 = rankw >= 1 ? 1 : 0;
|
||||
// The fifth corner has all coordinate offsets = 1, so no need to compute that.
|
||||
double x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
|
||||
double y1 = y0 - j1 + G4;
|
||||
double z1 = z0 - k1 + G4;
|
||||
double w1 = w0 - l1 + G4;
|
||||
double x2 = x0 - i2 + 2.0*G4; // Offsets for third corner in (x,y,z,w) coords
|
||||
double y2 = y0 - j2 + 2.0*G4;
|
||||
double z2 = z0 - k2 + 2.0*G4;
|
||||
double w2 = w0 - l2 + 2.0*G4;
|
||||
double x3 = x0 - i3 + 3.0*G4; // Offsets for fourth corner in (x,y,z,w) coords
|
||||
double y3 = y0 - j3 + 3.0*G4;
|
||||
double z3 = z0 - k3 + 3.0*G4;
|
||||
double w3 = w0 - l3 + 3.0*G4;
|
||||
double x4 = x0 - 1.0 + 4.0*G4; // Offsets for last corner in (x,y,z,w) coords
|
||||
double y4 = y0 - 1.0 + 4.0*G4;
|
||||
double z4 = z0 - 1.0 + 4.0*G4;
|
||||
double w4 = w0 - 1.0 + 4.0*G4;
|
||||
// Work out the hashed gradient indices of the five simplex corners
|
||||
int ii = i & 255;
|
||||
int jj = j & 255;
|
||||
int kk = k & 255;
|
||||
int ll = l & 255;
|
||||
int gi0 = perm[ii+perm[jj+perm[kk+perm[ll]]]] % 32;
|
||||
int gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]] % 32;
|
||||
int gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]] % 32;
|
||||
int gi3 = perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]] % 32;
|
||||
int gi4 = perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]] % 32;
|
||||
// Calculate the contribution from the five corners
|
||||
double t0 = 0.6 - x0*x0 - y0*y0 - z0*z0 - w0*w0;
|
||||
if(t0<0) n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0);
|
||||
}
|
||||
double t1 = 0.6 - x1*x1 - y1*y1 - z1*z1 - w1*w1;
|
||||
if(t1<0) n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1);
|
||||
}
|
||||
double t2 = 0.6 - x2*x2 - y2*y2 - z2*z2 - w2*w2;
|
||||
if(t2<0) n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2);
|
||||
}
|
||||
double t3 = 0.6 - x3*x3 - y3*y3 - z3*z3 - w3*w3;
|
||||
if(t3<0) n3 = 0.0;
|
||||
else {
|
||||
t3 *= t3;
|
||||
n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3);
|
||||
}
|
||||
double t4 = 0.6 - x4*x4 - y4*y4 - z4*z4 - w4*w4;
|
||||
if(t4<0) n4 = 0.0;
|
||||
else {
|
||||
t4 *= t4;
|
||||
n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4);
|
||||
}
|
||||
// Sum up and scale the result to cover the range [-1,1]
|
||||
return 27.0 * (n0 + n1 + n2 + n3 + n4);
|
||||
}
|
||||
|
||||
// Inner class to speed upp gradient computations
|
||||
// (In Java, array access is a lot slower than member access)
|
||||
private static class Grad
|
||||
{
|
||||
double x, y, z, w;
|
||||
|
||||
Grad(double x, double y, double z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
Grad(double x, double y, double z, double w)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.boydti.fawe.object.random;
|
||||
|
||||
public class SimplexRandom implements SimpleRandom {
|
||||
private final double scale;
|
||||
public SimplexRandom(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble(int x, int y, int z) {
|
||||
return (SimplexNoise.noise(x * scale, y * scale, z * scale) + 1) * 0.5;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.boydti.fawe.object.random;
|
||||
|
||||
import java.util.SplittableRandom;
|
||||
|
||||
public class TrueRandom implements SimpleRandom {
|
||||
private final SplittableRandom r;
|
||||
|
||||
public TrueRandom() {
|
||||
this.r = new SplittableRandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble(int x, int y, int z) {
|
||||
return r.nextDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt(int x, int y, int z, int len) {
|
||||
return r.nextInt(len);
|
||||
}
|
||||
}
|
@ -30,7 +30,9 @@ import com.sk89q.worldedit.command.ClipboardCommands;
|
||||
import com.sk89q.worldedit.command.GeneralCommands;
|
||||
import com.sk89q.worldedit.command.GenerationCommands;
|
||||
import com.sk89q.worldedit.command.HistoryCommands;
|
||||
import com.sk89q.worldedit.command.MaskCommands;
|
||||
import com.sk89q.worldedit.command.NavigationCommands;
|
||||
import com.sk89q.worldedit.command.PatternCommands;
|
||||
import com.sk89q.worldedit.command.RegionCommands;
|
||||
import com.sk89q.worldedit.command.SchematicCommands;
|
||||
import com.sk89q.worldedit.command.ScriptingCommands;
|
||||
@ -40,6 +42,7 @@ import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
||||
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
||||
import com.sk89q.worldedit.command.ToolCommands;
|
||||
import com.sk89q.worldedit.command.ToolUtilCommands;
|
||||
import com.sk89q.worldedit.command.TransformCommands;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.command.WorldEditCommands;
|
||||
import java.io.FileOutputStream;
|
||||
@ -113,6 +116,9 @@ public final class DocumentationPrinter {
|
||||
writePermissionsWikiTable(stream, builder, "/", SnapshotUtilCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/", ScriptingCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/", ChunkCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/masks ", MaskCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/patterns ", PatternCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/transforms ", TransformCommands.class);
|
||||
stream.println();
|
||||
stream.print("#### Uncategorized\n");
|
||||
stream.append("| Aliases | Permission | flags | Usage |\n");
|
||||
|
@ -131,14 +131,16 @@ public class SetQueue {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (pool.getQueuedSubmissionCount() != 0 || pool.getRunningThreadCount() != 0 || pool.getQueuedTaskCount() != 0) {
|
||||
if (Fawe.get().isJava8()) {
|
||||
// if (Fawe.get().isJava8())
|
||||
{
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
pool.shutdown();
|
||||
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
pool = new ForkJoinPool();
|
||||
completer = new ExecutorCompletionService(pool);
|
||||
}
|
||||
// else {
|
||||
// pool.shutdown();
|
||||
// pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
// pool = new ForkJoinPool();
|
||||
// completer = new ExecutorCompletionService(pool);
|
||||
// }
|
||||
}
|
||||
secondLast = System.currentTimeMillis();
|
||||
queue.endSet(parallel);
|
||||
|
@ -32,6 +32,15 @@ public class StringMan {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static int indexOf(String input, int start, char... values) {
|
||||
for (int i = start; i < input.length(); i++){
|
||||
for (char c : values) {
|
||||
if (c == input.charAt(i)) return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<String> split(String input, char delim) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
int start = 0;
|
||||
|
@ -6,7 +6,6 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -61,20 +60,20 @@ public abstract class TaskManager {
|
||||
* @param runnables
|
||||
*/
|
||||
public void parallel(Collection<Runnable> runnables) {
|
||||
if (!Fawe.get().isJava8()) {
|
||||
ExecutorCompletionService c = new ExecutorCompletionService(pool);
|
||||
for (Runnable run : runnables) {
|
||||
c.submit(run, null);
|
||||
}
|
||||
try {
|
||||
for (int i = 0; i < runnables.size(); i++) {
|
||||
c.take();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// if (!Fawe.get().isJava8()) {
|
||||
// ExecutorCompletionService c = new ExecutorCompletionService(pool);
|
||||
// for (Runnable run : runnables) {
|
||||
// c.submit(run, null);
|
||||
// }
|
||||
// try {
|
||||
// for (int i = 0; i < runnables.size(); i++) {
|
||||
// c.take();
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
for (Runnable run : runnables) {
|
||||
pool.submit(run);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.foundation.Block;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
@ -435,6 +437,11 @@ public class BaseBlock extends Block implements TileEntityBlock, Pattern {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
return extent.setBlock(setPosition, this);
|
||||
}
|
||||
|
||||
public static Class<BaseBlock> inject() {
|
||||
return BaseBlock.class;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
@ -45,17 +46,8 @@ import com.boydti.fawe.object.brush.SplineBrush;
|
||||
import com.boydti.fawe.object.brush.StencilBrush;
|
||||
import com.boydti.fawe.object.brush.SurfaceSphereBrush;
|
||||
import com.boydti.fawe.object.brush.SurfaceSpline;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollClipboard;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollMask;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollPattern;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollRange;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollSize;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollTarget;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
@ -80,9 +72,7 @@ import com.sk89q.worldedit.command.tool.brush.SmoothBrush;
|
||||
import com.sk89q.worldedit.command.tool.brush.SphereBrush;
|
||||
import com.sk89q.worldedit.command.util.CreatureButcher;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
@ -91,6 +81,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.command.InvalidUsageException;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import java.io.File;
|
||||
@ -103,9 +94,7 @@ import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* Commands to set brush shape.
|
||||
@ -113,177 +102,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@Command(aliases = { "brush", "br" },
|
||||
desc = "Commands to build and draw from far away. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Brushes)"
|
||||
)
|
||||
public class BrushCommands {
|
||||
public class BrushCommands extends MethodCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param worldEdit reference to WorldEdit
|
||||
*/
|
||||
public BrushCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "primary" },
|
||||
usage = "[brush arguments]",
|
||||
desc = "Set the right click brush",
|
||||
help = "Set the right click brush",
|
||||
min = 1
|
||||
)
|
||||
public void primary(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BaseBlock item = player.getBlockInHand();
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
session.setTool(item.getId(), item.getData(), null, player);
|
||||
String cmd = "brush " + args.getJoinedStrings(0);
|
||||
CommandEvent event = new CommandEvent(player, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
BrushTool newTool = session.getBrushTool(item.getId(), item.getData(), player, false);
|
||||
if (newTool != null && tool != null) {
|
||||
newTool.setSecondary(tool.getSecondary());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "secondary" },
|
||||
usage = "[brush arguments]",
|
||||
desc = "Set the left click brush",
|
||||
help = "Set the left click brush",
|
||||
min = 1
|
||||
)
|
||||
public void secondary(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BaseBlock item = player.getBlockInHand();
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
session.setTool(item.getId(), item.getData(), null, player);
|
||||
String cmd = "brush " + args.getJoinedStrings(0);
|
||||
CommandEvent event = new CommandEvent(player, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
BrushTool newTool = session.getBrushTool(item.getId(), item.getData(), player, false);
|
||||
if (newTool != null && tool != null) {
|
||||
newTool.setPrimary(tool.getPrimary());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "visualize", "visual", "vis" },
|
||||
usage = "[mode]",
|
||||
desc = "Toggle between different visualization modes",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
public void visual(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
VisualMode[] modes = VisualMode.values();
|
||||
VisualMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)];
|
||||
tool.setVisualMode(newMode);
|
||||
BBC.BRUSH_VISUAL_MODE_SET.send(player, newMode);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "target", "tar" },
|
||||
usage = "[mode]",
|
||||
desc = "Toggle between different target modes",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
public void target(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
TargetMode[] modes = TargetMode.values();
|
||||
TargetMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)];
|
||||
tool.setTargetMode(newMode);
|
||||
BBC.BRUSH_TARGET_MODE_SET.send(player, newMode);
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = { "scroll" },
|
||||
usage = "[none|clipboard|mask|pattern|range|size|visual|target]",
|
||||
desc = "Toggle between different target modes",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
public void scroll(Player player, EditSession editSession, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(player);
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
switch (args.getString(0).toLowerCase()) {
|
||||
case "none":
|
||||
tool.setScrollAction(null);
|
||||
break;
|
||||
case "clipboard":
|
||||
if (args.argsLength() != 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "clipboard [file]");
|
||||
return;
|
||||
}
|
||||
String filename = args.getString(1);
|
||||
try {
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, true);
|
||||
if (clipboards == null) {
|
||||
return;
|
||||
}
|
||||
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards));
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
case "mask":
|
||||
if (args.argsLength() < 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "mask [mask 1] [mask 2] [mask 3]...");
|
||||
return;
|
||||
}
|
||||
Mask[] masks = new Mask[args.argsLength() - 1];
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
masks[i - 1] = worldEdit.getMaskFactory().parseFromInput(arg, parserContext);
|
||||
}
|
||||
tool.setScrollAction(new ScrollMask(tool, masks));
|
||||
break;
|
||||
case "pattern":
|
||||
if (args.argsLength() < 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "pattern [pattern 1] [pattern 2] [pattern 3]...");
|
||||
return;
|
||||
}
|
||||
Pattern[] patterns = new Pattern[args.argsLength() - 1];
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
patterns[i - 1] = worldEdit.getPatternFactory().parseFromInput(arg, parserContext);
|
||||
}
|
||||
tool.setScrollAction(new ScrollPattern(tool, patterns));
|
||||
break;
|
||||
case "range":
|
||||
tool.setScrollAction(new ScrollRange(tool));
|
||||
break;
|
||||
case "size":
|
||||
tool.setScrollAction(new ScrollSize(tool));
|
||||
break;
|
||||
case "target":
|
||||
tool.setScrollAction(new ScrollTarget(tool));
|
||||
break;
|
||||
default:
|
||||
BBC.COMMAND_SYNTAX.send(player, "[none|clipboard|mask|pattern|range|size|visual|target]");
|
||||
return;
|
||||
|
||||
}
|
||||
BBC.BRUSH_SCROLL_ACTION_SET.send(player, args.getJoinedStrings(0));
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -614,16 +436,16 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "layer" },
|
||||
usage = "<radius> <pattern1> <patern2>...",
|
||||
usage = "<radius> [color|<pattern1> <patern2>...]",
|
||||
desc = "Replaces terrain with a layer.",
|
||||
help = "Replaces terrain with a layer.\n" +
|
||||
"Example: /br layer 5 95:1 95:2 35:15 - Places several layers on a surface\n" +
|
||||
"Pic: https://i.imgur.com/XV0vYoX.png",
|
||||
min = 3,
|
||||
min = 0,
|
||||
max = 999
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.layer")
|
||||
public void surfaceLayer(Player player, EditSession editSession, LocalSession session, double radius, CommandContext args) throws WorldEditException {
|
||||
public void surfaceLayer(Player player, EditSession editSession, LocalSession session, double radius, CommandContext args) throws WorldEditException, InvalidUsageException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setSize(radius);
|
||||
@ -633,9 +455,21 @@ public class BrushCommands {
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
List<BaseBlock> blocks = new ArrayList<>();
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
blocks.add(worldEdit.getBlockFactory().parseFromInput(arg, parserContext));
|
||||
if (args.argsLength() < 2) {
|
||||
throw new InvalidUsageException(getCallable());
|
||||
}
|
||||
try {
|
||||
Color color = Color.web(args.getString(1));
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
char[] glassLayers = Fawe.get().getTextureUtil().getNearestLayer(awtColor.getRGB());
|
||||
for (char layer : glassLayers) {
|
||||
blocks.add(FaweCache.CACHE_BLOCK[layer]);
|
||||
}
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
blocks.add(worldEdit.getBlockFactory().parseFromInput(arg, parserContext));
|
||||
}
|
||||
}
|
||||
tool.setBrush(new LayerBrush(blocks.toArray(new BaseBlock[blocks.size()])), "worldedit.brush.layer", player);
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_LAYER.f(radius, args.getJoinedStrings(1)));
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.extent.DefaultTransformParser;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
@ -28,7 +28,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class GeneralCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
private final DefaultTransformParser transformParser;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -38,7 +37,6 @@ public class GeneralCommands {
|
||||
public GeneralCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
transformParser = new DefaultTransformParser(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -87,6 +85,7 @@ public class GeneralCommands {
|
||||
@Command(
|
||||
aliases = { "/gmask", "gmask", "globalmask", "/globalmask" },
|
||||
usage = "[mask]",
|
||||
help = "The global destination mask applies to all edits you do and masks based on the destination blocks (i.e. the blocks in the world).",
|
||||
desc = "Set the global mask",
|
||||
min = 0,
|
||||
max = -1
|
||||
@ -112,6 +111,7 @@ public class GeneralCommands {
|
||||
aliases = { "/gsmask", "gsmask", "globalsourcemask", "/globalsourcemask" },
|
||||
usage = "[mask]",
|
||||
desc = "Set the global source mask",
|
||||
help = "The global source mask applies to all edits you do and masks based on the source blocks (e.g. the blocks in your clipboard)",
|
||||
min = 0,
|
||||
max = -1
|
||||
)
|
||||
@ -150,7 +150,7 @@ public class GeneralCommands {
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
ResettableExtent transform = transformParser.parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
ResettableExtent transform = Fawe.get().getTransformParser().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
session.setTransform(transform);
|
||||
BBC.TRANSFORM.send(player);
|
||||
}
|
||||
|
388
core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java
Normal file
388
core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java
Normal file
@ -0,0 +1,388 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.AdjacentMask;
|
||||
import com.boydti.fawe.object.mask.AngleMask;
|
||||
import com.boydti.fawe.object.mask.BiomeMask;
|
||||
import com.boydti.fawe.object.mask.BlockLightMask;
|
||||
import com.boydti.fawe.object.mask.BrightnessMask;
|
||||
import com.boydti.fawe.object.mask.DataMask;
|
||||
import com.boydti.fawe.object.mask.IdDataMask;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.object.mask.LightMask;
|
||||
import com.boydti.fawe.object.mask.OpacityMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.boydti.fawe.object.mask.RandomMask;
|
||||
import com.boydti.fawe.object.mask.SimplexMask;
|
||||
import com.boydti.fawe.object.mask.SkyLightMask;
|
||||
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.minecraft.util.commands.Command;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExpressionMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
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.OffsetMask;
|
||||
import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.request.RequestSelection;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
@Command(aliases = { "masks" },
|
||||
desc = "Help for the various masks. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit---FAWE-mask-list)"
|
||||
)
|
||||
public class MaskCommands extends MethodCommands {
|
||||
public MaskCommands(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#simplex"},
|
||||
desc = "Use simplex noise as the mask",
|
||||
usage = "<scale=10> <min=0> <max=100>",
|
||||
min = 3,
|
||||
max = 3
|
||||
)
|
||||
public Mask simplex(double scale, double min, double max) {
|
||||
scale = (1d / Math.max(1, scale));
|
||||
min = (min - 50) / 50;
|
||||
max = (max - 50) / 50;
|
||||
return new SimplexMask(scale, min, max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#light"},
|
||||
desc = "Restrict to specific light levels",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask light(EditSession editSession, double min, double max) {
|
||||
return new LightMask(editSession, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#skylight"},
|
||||
desc = "Restrict to specific sky light levels",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask skylight(EditSession editSession, double min, double max) {
|
||||
return new SkyLightMask(editSession, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#blocklight", "#emittedlight"},
|
||||
desc = "Restrict to specific block light levels",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask blocklight(EditSession editSession, double min, double max) {
|
||||
return new BlockLightMask(editSession, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#opacity"},
|
||||
desc = "Restrict to specific opacity levels",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask opacity(EditSession editSession, double min, double max) {
|
||||
return new OpacityMask(editSession, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#brightness"},
|
||||
desc = "Restrict to specific block brightness",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask brightness(EditSession editSession, double min, double max) {
|
||||
return new BrightnessMask(editSession, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#offset"},
|
||||
desc = "Offset a mask",
|
||||
usage = "<dx> <dy> <dz> <mask>",
|
||||
min = 4,
|
||||
max = 4
|
||||
)
|
||||
public Mask offset(double x, double y, double z, Mask mask) {
|
||||
return new OffsetMask(mask, new Vector(x, y, z));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#haslight"},
|
||||
desc = "Restricts to blocks with light (sky or emitted)"
|
||||
)
|
||||
public Mask haslight(EditSession extent) {
|
||||
return new LightMask(extent, 1, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#nolight"},
|
||||
desc = "Restrict to blocks without light (sky or emitted)"
|
||||
)
|
||||
public Mask nolight(EditSession extent) {
|
||||
return new LightMask(extent, 0, 0);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#existing"},
|
||||
desc = "If there is a non air block"
|
||||
)
|
||||
public Mask existing(EditSession extent) {
|
||||
return new ExistingBlockMask(extent);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#existing"},
|
||||
desc = "If there is a solid block"
|
||||
)
|
||||
public Mask solid(EditSession extent) {
|
||||
return new SolidBlockMask(extent);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#dregion", "#dselection", "#dsel"},
|
||||
desc = "inside the player's selection"
|
||||
)
|
||||
public Mask dregion(EditSession extent) {
|
||||
return new RegionMask(new RequestSelection());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#region", "#selection", "#sel"},
|
||||
desc = "inside the provided selection"
|
||||
)
|
||||
public Mask selection(Player player, LocalSession session) throws IncompleteRegionException {
|
||||
return new RegionMask(session.getSelection(player.getWorld()).clone());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#xaxis"},
|
||||
desc = "Restrict to initial x axis"
|
||||
)
|
||||
public Mask xaxis() {
|
||||
return new XAxisMask();
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#yaxis"},
|
||||
desc = "Restrict to initial y axis"
|
||||
)
|
||||
public Mask yaxis() {
|
||||
return new YAxisMask();
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#zaxis"},
|
||||
desc = "Restrict to initial z axis"
|
||||
)
|
||||
public Mask zaxis() {
|
||||
return new ZAxisMask();
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#id"},
|
||||
desc = "Restrict to initial id"
|
||||
)
|
||||
public Mask id(EditSession editSession) {
|
||||
return new IdMask(editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#data"},
|
||||
desc = "Restrict to initial data"
|
||||
)
|
||||
public Mask data(EditSession editSession) {
|
||||
return new DataMask(editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#iddata"},
|
||||
desc = "Restrict to initial block id and data"
|
||||
)
|
||||
public Mask iddata(EditSession editSession) {
|
||||
return new IdDataMask(editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#wall"},
|
||||
desc = "Restrict to walls (any block n,e,s,w of air)"
|
||||
)
|
||||
public Mask wall(EditSession extent) {
|
||||
BlockMask blockMask = new BlockMask(extent, new BaseBlock(0));
|
||||
return new MaskUnion(new ExistingBlockMask(extent), new WallMask(blockMask, 1, 8));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#surface"},
|
||||
desc = "Restrict to surfaces (any solid block touching air)"
|
||||
)
|
||||
public Mask surface(EditSession extent) {
|
||||
return new MaskUnion(new ExistingBlockMask(extent), new AdjacentAnyMask(new BlockMask(extent, new BaseBlock(0))));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"\\", "/"},
|
||||
desc = "Restrict to specific terrain angle",
|
||||
help = "Restrict to specific terrain angle\n" +
|
||||
"The -o flag will only overlay" +
|
||||
"Example: /[0d][45d]\n" +
|
||||
"Explanation: Allows any block where the adjacent block is between 0 and 45 degrees.\n" +
|
||||
"Example: /[3][20]\n" +
|
||||
"Explanation: Allows any block where the adjacent block is between 3 and 20 blocks below",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask angle(EditSession extent, String min, String max, @Switch('o') boolean overlay) throws ExpressionException {
|
||||
double y1,y2;
|
||||
boolean override;
|
||||
if (max.endsWith("d")) {
|
||||
double y1d = Expression.compile(max.substring(0, max.length() - 1)).evaluate();
|
||||
double y2d = Expression.compile(min.substring(0, min.length() - 1)).evaluate();
|
||||
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||
} else {
|
||||
y1 = (Expression.compile(max).evaluate());
|
||||
y2 = (Expression.compile(min).evaluate());
|
||||
}
|
||||
return new AngleMask(extent, y1, y2, overlay);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"{"},
|
||||
desc = "Restricts blocks to within a specific radius range of the initial block",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Mask radius(double min, double max) throws ExpressionException {
|
||||
return new RadiusMask((int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"|"},
|
||||
desc = "sides with a specific number of other blocks",
|
||||
usage = "<mask> <min> <max>",
|
||||
min = 3,
|
||||
max = 3
|
||||
)
|
||||
public Mask wall(Mask mask, double min, double max) throws ExpressionException {
|
||||
return new WallMask(mask, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"~"},
|
||||
desc = "Adjacent to a specific number of other blocks",
|
||||
usage = "<mask> [min=1] [max=8]",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
public Mask adjacent(Mask mask, @Optional("-1") double min, @Optional("-1") double max) throws ExpressionException {
|
||||
if (min == -1 && max == -1) { min = 1; max = 8; }
|
||||
else if (max == -1) max = min;
|
||||
if (max >= 8 && min == 1) {
|
||||
return new AdjacentAnyMask(mask);
|
||||
}
|
||||
return new AdjacentMask(mask, (int) min, (int) max);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"<"},
|
||||
desc = "below a specific block",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask below(Mask mask) throws ExpressionException {
|
||||
OffsetMask offsetMask = new OffsetMask(mask, new Vector(0, 1, 0));
|
||||
return new MaskIntersection(offsetMask, Masks.negate(mask));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {">"},
|
||||
desc = "above a specific block",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask above(Mask mask) throws ExpressionException {
|
||||
OffsetMask offsetMask = new OffsetMask(mask, new Vector(0, -1, 0));
|
||||
return new MaskIntersection(offsetMask, Masks.negate(mask));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"$", "#biome"},
|
||||
desc = "in a specific biome",
|
||||
help = "in a specific biome. For a list of biomes use //biomelist",
|
||||
usage = "<biome>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask biome(EditSession editSession, BaseBiome biome) throws ExpressionException {
|
||||
return new BiomeMask(editSession, biome);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"%"},
|
||||
desc = "percentage chance",
|
||||
usage = "<chance>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask random(double chance) throws ExpressionException {
|
||||
chance = chance / 100;
|
||||
return new RandomMask(chance);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"="},
|
||||
desc = "expression mask",
|
||||
usage = "<expression>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask expression(EditSession editSession, String input) throws ExpressionException {
|
||||
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
|
||||
editSession, Vector.ONE, Vector.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
return new ExpressionMask(exp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"!", "#not", "#negate"},
|
||||
desc = "Negate another mask",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Mask expression(Mask mask) throws ExpressionException {
|
||||
return Masks.negate(mask);
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class MethodCommands {
|
||||
public final WorldEdit worldEdit;
|
||||
private ConcurrentHashMap<Method, CommandCallable> callables;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
public MethodCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
callables = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MethodCommands() {
|
||||
this.worldEdit = WorldEdit.getInstance();
|
||||
}
|
||||
|
||||
public void register(Method method, CommandCallable callable, Dispatcher dispatcher) {
|
||||
this.dispatcher = dispatcher;
|
||||
this.callables.put(method, callable);
|
||||
}
|
||||
|
||||
public CommandCallable getCallable() {
|
||||
try {
|
||||
StackTraceElement[] stack = new Exception().getStackTrace();
|
||||
for (StackTraceElement elem : stack) {
|
||||
Class<?> clazz = Class.forName(elem.getClassName());
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getName().equals(elem.getMethodName())) {
|
||||
Command command = method.getAnnotation(Command.class);
|
||||
if (command != null) return callables.get(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
public Command getCommand() {
|
||||
try {
|
||||
StackTraceElement[] stack = new Exception().getStackTrace();
|
||||
for (StackTraceElement elem : stack) {
|
||||
Class<?> clazz = Class.forName(elem.getClassName());
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getName().equals(elem.getMethodName())) {
|
||||
Command command = method.getAnnotation(Command.class);
|
||||
if (command != null) return Commands.translate(clazz, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,443 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.DataAngleMask;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.collection.RandomCollection;
|
||||
import com.boydti.fawe.object.pattern.AngleColorPattern;
|
||||
import com.boydti.fawe.object.pattern.AverageColorPattern;
|
||||
import com.boydti.fawe.object.pattern.BiomePattern;
|
||||
import com.boydti.fawe.object.pattern.BufferedPattern;
|
||||
import com.boydti.fawe.object.pattern.BufferedPattern2D;
|
||||
import com.boydti.fawe.object.pattern.DataPattern;
|
||||
import com.boydti.fawe.object.pattern.DesaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ExistingPattern;
|
||||
import com.boydti.fawe.object.pattern.ExpressionPattern;
|
||||
import com.boydti.fawe.object.pattern.FullClipboardPattern;
|
||||
import com.boydti.fawe.object.pattern.IdDataMaskPattern;
|
||||
import com.boydti.fawe.object.pattern.IdPattern;
|
||||
import com.boydti.fawe.object.pattern.Linear3DBlockPattern;
|
||||
import com.boydti.fawe.object.pattern.LinearBlockPattern;
|
||||
import com.boydti.fawe.object.pattern.MaskedPattern;
|
||||
import com.boydti.fawe.object.pattern.NoXPattern;
|
||||
import com.boydti.fawe.object.pattern.NoYPattern;
|
||||
import com.boydti.fawe.object.pattern.NoZPattern;
|
||||
import com.boydti.fawe.object.pattern.OffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.PatternExtent;
|
||||
import com.boydti.fawe.object.pattern.RandomFullClipboardPattern;
|
||||
import com.boydti.fawe.object.pattern.RandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.RelativePattern;
|
||||
import com.boydti.fawe.object.pattern.SaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ShadePattern;
|
||||
import com.boydti.fawe.object.pattern.SolidRandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.SurfaceRandomOffsetPattern;
|
||||
import com.boydti.fawe.object.random.SimplexRandom;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
@Command(aliases = { "patterns" },
|
||||
desc = "Help for the various patterns. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-and-FAWE-patterns)"
|
||||
)
|
||||
public class PatternCommands extends MethodCommands {
|
||||
public PatternCommands(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#existing", "#*"},
|
||||
desc = "Use the block that is already there")
|
||||
public Pattern existing(EditSession editSession) {
|
||||
return new ExistingPattern(editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#clipboard", "#copy"},
|
||||
desc = "Use the blocks in your clipboard as the pattern")
|
||||
public Pattern clipboard(LocalSession session) throws EmptyClipboardException {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
return new ClipboardPattern(clipboard);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#simplex"},
|
||||
desc = "Use simplex noise to randomize blocks",
|
||||
usage = "<scale=10> <pattern>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Pattern simplex(double scale, Pattern other) {
|
||||
if (other instanceof RandomPattern) {
|
||||
scale = (1d / Math.max(1, scale));
|
||||
RandomCollection<Pattern> collection = ((RandomPattern) other).getCollection();
|
||||
collection.setRandom(new SimplexRandom(scale));
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#color"},
|
||||
desc = "Use the block closest to a specific color",
|
||||
usage = "<color>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern color(String arg) {
|
||||
Color color = Color.web(arg);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
return Fawe.get().getTextureUtil().getNearestBlock(awtColor.getRGB());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#anglecolor"},
|
||||
desc = "A darker block based on the existing terrain angle",
|
||||
usage = "[randomize=true] [max-complexity=100]",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
public Pattern anglecolor(EditSession editSession, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
return new AngleColorPattern(util, editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#angledata"},
|
||||
desc = "Block data based on the existing terrain angle"
|
||||
)
|
||||
public Pattern angledata(EditSession editSession) {
|
||||
return new DataAngleMask(editSession);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#saturate"},
|
||||
desc = "Saturate the existing block with a color",
|
||||
usage = "<color> [randomize=true] [max-complexity=100]",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
public Pattern saturate(EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
Color color = Color.web(arg);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
return new SaturatePattern(editSession, util, awtColor.getRGB());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#averagecolor"},
|
||||
desc = "Average between the existing block and a color",
|
||||
usage = "<color> [randomize=true] [max-complexity=100]",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
public Pattern averagecolor(EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
Color color = Color.web(arg);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
return new AverageColorPattern(editSession, util, awtColor.getRGB());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#desaturate"},
|
||||
desc = "Desaturated color of the existing block",
|
||||
usage = "[percent=100] [randomize=true] [max-complexity=100]",
|
||||
min = 0,
|
||||
max = 3
|
||||
)
|
||||
public Pattern desaturate(EditSession editSession, @Optional("100") double percent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
return new DesaturatePattern(editSession, util, percent / 100d);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#lighten"},
|
||||
desc = "Lighten the existing block",
|
||||
usage = "[randomize=true] [max-complexity=100]",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
public Pattern lighten(EditSession editSession, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
return new ShadePattern(editSession, util, false);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#darken"},
|
||||
desc = "Darken the existing block",
|
||||
usage = "[randomize=true] [max-complexity=100]",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
public Pattern darken(EditSession editSession, @Optional("true") boolean randomize, @Optional("100") double maxComplexity) {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);
|
||||
return new ShadePattern(editSession, util, true);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#fullcopy"},
|
||||
desc = "Places your full clipboard at each block",
|
||||
usage = "[schem|folder|url=#copy] [rotate=false] [flip=false]",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
public Pattern fullcopy(Actor actor, EditSession editSession, LocalSession session, @Optional("#copy") String location, @Optional("false") boolean rotate, @Optional("false") boolean flip) throws EmptyClipboardException, InputParseException, IOException {
|
||||
ClipboardHolder[] clipboards;
|
||||
switch (location.toLowerCase()) {
|
||||
case "#copy":
|
||||
case "#clipboard":
|
||||
ClipboardHolder clipboard = session.getExistingClipboard();
|
||||
if (clipboard == null) {
|
||||
throw new InputParseException("To use #fullcopy, please first copy something to your clipboard");
|
||||
}
|
||||
if (!rotate && !flip) {
|
||||
return new FullClipboardPattern(editSession, clipboard.getClipboard());
|
||||
}
|
||||
clipboards = new ClipboardHolder[]{clipboard};
|
||||
break;
|
||||
default:
|
||||
clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(actor, editSession.getWorldData(), location, true);
|
||||
break;
|
||||
}
|
||||
if (clipboards == null) {
|
||||
throw new InputParseException("#fullcopy:<source>");
|
||||
}
|
||||
return new RandomFullClipboardPattern(editSession, editSession.getWorldData(), clipboards, rotate, flip);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#buffer"},
|
||||
desc = "Only place a block once while a pattern is in use",
|
||||
help = "Only place a block once while a pattern is in use\n" +
|
||||
"Use with a brush when you don't want to apply to the same spot twice",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern buffer(Actor actor, Pattern pattern) {
|
||||
return new BufferedPattern(FawePlayer.wrap(actor), pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#buffer2d"},
|
||||
desc = "Only place a block once in a column while a pattern is in use",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern buffer2d(Actor actor, Pattern pattern) {
|
||||
return new BufferedPattern2D(FawePlayer.wrap(actor), pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#iddatamask"},
|
||||
desc = "Use the pattern's id and the existing blocks data with the provided mask",
|
||||
help = "Use the pattern's id and the existing blocks data with the provided mask\n" +
|
||||
" - Use to replace slabs or where the data values needs to be shifted instead of set",
|
||||
usage = "<bitmask=15> <pattern>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Pattern iddatamask(Actor actor, LocalSession session, EditSession editSession, int bitmask, Pattern pattern) {
|
||||
return new IdDataMaskPattern(editSession, pattern, bitmask);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#id"},
|
||||
desc = "Only change the block id",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern id(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new IdPattern(editSession, pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#data"},
|
||||
desc = "Only change the block data",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern data(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new DataPattern(editSession, pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#biome", "$"},
|
||||
desc = "Set the biome",
|
||||
usage = "<biome>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern data(Actor actor, LocalSession session, EditSession editSession, BaseBiome biome) {
|
||||
return new BiomePattern(editSession, biome);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#relative", "#~", "#r", "#rel"},
|
||||
desc = "Offset the pattern to where you click",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern relative(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new RelativePattern(pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#!x", "#nx", "#nox"},
|
||||
desc = "The pattern will not be provided the x axis info",
|
||||
help = "The pattern will not be provided the z axis info.\n" +
|
||||
"Example: #!x[#!z[#~[#l3d[pattern]]]]",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern nox(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new NoXPattern(pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#!y", "#ny", "#noy"},
|
||||
desc = "The pattern will not be provided the y axis info",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern noy(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new NoYPattern(pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#!z", "#nz", "#noz"},
|
||||
desc = "The pattern will not be provided the z axis info",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern noz(Actor actor, LocalSession session, EditSession editSession, Pattern pattern) {
|
||||
return new NoZPattern(pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#mask"},
|
||||
desc = "Apply a pattern depending on a mask",
|
||||
usage = "<mask> <pattern-true> <pattern-false>",
|
||||
min = 3,
|
||||
max = 3
|
||||
)
|
||||
public Pattern mask(Actor actor, LocalSession session, Mask mask, Pattern pass, Pattern fail) {
|
||||
PatternExtent extent = new PatternExtent(pass);
|
||||
return new MaskedPattern(mask, extent, fail);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#offset"},
|
||||
desc = "Offset a pattern",
|
||||
usage = "<dx> <dy> <dz> <pattern>",
|
||||
min = 4,
|
||||
max = 4
|
||||
)
|
||||
public Pattern offset(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
return new OffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#surfacespread"},
|
||||
desc = "Randomly change the position to another block on the surface",
|
||||
usage = "<distance> <pattern>",
|
||||
min = 2,
|
||||
max = 2
|
||||
)
|
||||
public Pattern surfacespread(Actor actor, LocalSession session, EditSession editSession, double distance, Pattern pattern) {
|
||||
return new SurfaceRandomOffsetPattern(editSession, pattern, (int) distance);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#solidspread"},
|
||||
desc = "Randomly spread solid blocks",
|
||||
usage = "<dx> <dy> <dz> <pattern>",
|
||||
min = 4,
|
||||
max = 4
|
||||
)
|
||||
public Pattern solidspread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
return new SolidRandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#spread", "#randomoffset"},
|
||||
desc = "Randomly spread blocks",
|
||||
usage = "<dx> <dy> <dz> <pattern>",
|
||||
min = 4,
|
||||
max = 4
|
||||
)
|
||||
public Pattern spread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
|
||||
return new RandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#linear", "#l"},
|
||||
desc = "Sequentially set blocks from a list of patterns",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern linear(Actor actor, LocalSession session, Pattern other) {
|
||||
if (other instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
|
||||
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#linear3d", "#l3d"},
|
||||
desc = "Use the x,y,z coordinate to pick a block from the list",
|
||||
usage = "<pattern>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern linear3d(Actor actor, LocalSession session, Pattern other) {
|
||||
if (other instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
|
||||
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"="},
|
||||
desc = "Expression pattern: http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax",
|
||||
usage = "<expression>",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
public Pattern expression(Actor actor, LocalSession session, EditSession editSession, String input) throws ExpressionException {
|
||||
Expression exp = Expression.compile(input, "x", "y", "z");
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(editSession, Vector.ONE, Vector.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
return new ExpressionPattern(exp);
|
||||
}
|
||||
}
|
@ -1,35 +1,52 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.extent.DefaultTransformParser;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollClipboard;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollMask;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollPattern;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollRange;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollSize;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollTarget;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.Tool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Tool commands.
|
||||
*/
|
||||
@Command(aliases = {}, desc = "Tool commands")
|
||||
public class ToolUtilCommands {
|
||||
private final WorldEdit we;
|
||||
private final DefaultTransformParser transformParser;
|
||||
public class ToolUtilCommands extends MethodCommands {
|
||||
|
||||
public ToolUtilCommands(WorldEdit we) {
|
||||
this.we = we;
|
||||
this.transformParser = new DefaultTransformParser(we);
|
||||
super(we);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -52,19 +69,233 @@ public class ToolUtilCommands {
|
||||
BBC.SUPERPICKAXE_DISABLED.send(player);
|
||||
} else {
|
||||
if ("off".equals(newState)) {
|
||||
|
||||
BBC.SUPERPICKAXE_DISABLED.send(player);
|
||||
return;
|
||||
}
|
||||
session.enableSuperPickAxe();
|
||||
BBC.SUPERPICKAXE_ENABLED.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "patterns" },
|
||||
usage = "[page=1|search|pattern]",
|
||||
desc = "View help about patterns",
|
||||
help = "Patterns determine what blocks are placed\n" +
|
||||
" - Use [brackets] for arguments\n" +
|
||||
" - Use , to OR multiple\n" +
|
||||
"e.g. #surfacespread[10][#existing],andesite\n" +
|
||||
"More Info: https://git.io/vSPmA",
|
||||
min = 1
|
||||
)
|
||||
public void patterns(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
HashTagPatternParser parser = FaweAPI.getParser(HashTagPatternParser.class);
|
||||
if (parser != null) {
|
||||
UtilityCommands.help(args, worldEdit, player, "/" + getCommand().aliases()[0] + " ", parser.getDispatcher());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "masks" },
|
||||
usage = "[page=1|search|mask]",
|
||||
desc = "View help about masks",
|
||||
help = "Masks determine if a block can be placed\n" +
|
||||
" - Use [brackets] for arguments\n" +
|
||||
" - Use , to OR multiple\n" +
|
||||
" - Use & to AND multiple\n" +
|
||||
"e.g. >[stone,dirt],#light[0][5],$jungle\n" +
|
||||
"More Info: https://git.io/v9r4K",
|
||||
min = 1
|
||||
)
|
||||
public void masks(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
DefaultMaskParser parser = FaweAPI.getParser(DefaultMaskParser.class);
|
||||
if (parser != null) {
|
||||
UtilityCommands.help(args, worldEdit, player, "/" + getCommand().aliases()[0] + " ", parser.getDispatcher());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "transforms" },
|
||||
usage = "[page=1|search|transform]",
|
||||
desc = "View help about transforms",
|
||||
help = "Masks modify how a block is placed\n" +
|
||||
" - Use [brackets] for arguments\n" +
|
||||
" - Use , to OR multiple\n" +
|
||||
" - Use & to AND multiple\n" +
|
||||
"More Info: https://git.io/v9KHO",
|
||||
min = 1
|
||||
)
|
||||
public void transforms(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
DefaultTransformParser parser = Fawe.get().getTransformParser();
|
||||
if (parser != null) {
|
||||
UtilityCommands.help(args, worldEdit, player, "/" + getCommand().aliases()[0] + " ", parser.getDispatcher());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "primary" },
|
||||
usage = "[brush arguments]",
|
||||
desc = "Set the right click brush",
|
||||
help = "Set the right click brush",
|
||||
min = 1
|
||||
)
|
||||
public void primary(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BaseBlock item = player.getBlockInHand();
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
session.setTool(item.getId(), item.getData(), null, player);
|
||||
String cmd = "brush " + args.getJoinedStrings(0);
|
||||
CommandEvent event = new CommandEvent(player, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
BrushTool newTool = session.getBrushTool(item.getId(), item.getData(), player, false);
|
||||
if (newTool != null && tool != null) {
|
||||
newTool.setSecondary(tool.getSecondary());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "secondary" },
|
||||
usage = "[brush arguments]",
|
||||
desc = "Set the left click brush",
|
||||
help = "Set the left click brush",
|
||||
min = 1
|
||||
)
|
||||
public void secondary(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BaseBlock item = player.getBlockInHand();
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
session.setTool(item.getId(), item.getData(), null, player);
|
||||
String cmd = "brush " + args.getJoinedStrings(0);
|
||||
CommandEvent event = new CommandEvent(player, cmd);
|
||||
CommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||
BrushTool newTool = session.getBrushTool(item.getId(), item.getData(), player, false);
|
||||
if (newTool != null && tool != null) {
|
||||
newTool.setPrimary(tool.getPrimary());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "visualize", "visual", "vis" },
|
||||
usage = "[mode]",
|
||||
desc = "Toggle between different visualization modes",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
public void visual(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
VisualMode[] modes = VisualMode.values();
|
||||
VisualMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)];
|
||||
tool.setVisualMode(newMode);
|
||||
BBC.BRUSH_VISUAL_MODE_SET.send(player, newMode);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "target", "tar" },
|
||||
usage = "[mode]",
|
||||
desc = "Toggle between different target modes",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
public void target(Player player, LocalSession session, @Optional("0") int mode) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
TargetMode[] modes = TargetMode.values();
|
||||
TargetMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)];
|
||||
tool.setTargetMode(newMode);
|
||||
BBC.BRUSH_TARGET_MODE_SET.send(player, newMode);
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = { "scroll" },
|
||||
usage = "[none|clipboard|mask|pattern|range|size|visual|target]",
|
||||
desc = "Toggle between different target modes",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
public void scroll(Player player, EditSession editSession, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
BBC.BRUSH_NONE.send(player);
|
||||
return;
|
||||
}
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(player);
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
switch (args.getString(0).toLowerCase()) {
|
||||
case "none":
|
||||
tool.setScrollAction(null);
|
||||
break;
|
||||
case "clipboard":
|
||||
if (args.argsLength() != 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "clipboard [file]");
|
||||
return;
|
||||
}
|
||||
String filename = args.getString(1);
|
||||
try {
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, true);
|
||||
if (clipboards == null) {
|
||||
return;
|
||||
}
|
||||
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards));
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
case "mask":
|
||||
if (args.argsLength() < 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "mask [mask 1] [mask 2] [mask 3]...");
|
||||
return;
|
||||
}
|
||||
Mask[] masks = new Mask[args.argsLength() - 1];
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
masks[i - 1] = worldEdit.getMaskFactory().parseFromInput(arg, parserContext);
|
||||
}
|
||||
tool.setScrollAction(new ScrollMask(tool, masks));
|
||||
break;
|
||||
case "pattern":
|
||||
if (args.argsLength() < 2) {
|
||||
BBC.COMMAND_SYNTAX.send(player, "pattern [pattern 1] [pattern 2] [pattern 3]...");
|
||||
return;
|
||||
}
|
||||
Pattern[] patterns = new Pattern[args.argsLength() - 1];
|
||||
for (int i = 1; i < args.argsLength(); i++) {
|
||||
String arg = args.getString(i);
|
||||
patterns[i - 1] = worldEdit.getPatternFactory().parseFromInput(arg, parserContext);
|
||||
}
|
||||
tool.setScrollAction(new ScrollPattern(tool, patterns));
|
||||
break;
|
||||
case "range":
|
||||
tool.setScrollAction(new ScrollRange(tool));
|
||||
break;
|
||||
case "size":
|
||||
tool.setScrollAction(new ScrollSize(tool));
|
||||
break;
|
||||
case "target":
|
||||
tool.setScrollAction(new ScrollTarget(tool));
|
||||
break;
|
||||
default:
|
||||
BBC.COMMAND_SYNTAX.send(player, "[none|clipboard|mask|pattern|range|size|visual|target]");
|
||||
return;
|
||||
|
||||
}
|
||||
BBC.BRUSH_SCROLL_ACTION_SET.send(player, args.getJoinedStrings(0));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "mask", "/mask" },
|
||||
usage = "[mask]",
|
||||
desc = "Set the brush mask",
|
||||
desc = "Set the brush destination mask",
|
||||
min = 0,
|
||||
max = -1
|
||||
)
|
||||
@ -84,7 +315,7 @@ public class ToolUtilCommands {
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
mask = we.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
mask = worldEdit.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
}
|
||||
if (tool instanceof BrushTool) {
|
||||
BrushTool bt = (BrushTool) tool;
|
||||
@ -104,7 +335,8 @@ public class ToolUtilCommands {
|
||||
@Command(
|
||||
aliases = { "smask", "/smask", "/sourcemask", "sourcemask" },
|
||||
usage = "[mask]",
|
||||
desc = "Set the brush mask",
|
||||
desc = "Set the brush source mask",
|
||||
help = "Set the brush source mask",
|
||||
min = 0,
|
||||
max = -1
|
||||
)
|
||||
@ -124,7 +356,7 @@ public class ToolUtilCommands {
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
mask = we.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
mask = worldEdit.getMaskFactory().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
}
|
||||
if (tool instanceof BrushTool) {
|
||||
BrushTool bt = (BrushTool) tool;
|
||||
@ -163,7 +395,7 @@ public class ToolUtilCommands {
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(editSession);
|
||||
transform = transformParser.parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
transform = Fawe.get().getTransformParser().parseFromInput(context.getJoinedStrings(0), parserContext);
|
||||
}
|
||||
if (tool instanceof BrushTool) {
|
||||
BrushTool bt = (BrushTool) tool;
|
||||
@ -230,7 +462,7 @@ public class ToolUtilCommands {
|
||||
public void size(Player player, LocalSession session, CommandContext args, @Switch('h') boolean offHand) throws WorldEditException {
|
||||
|
||||
int radius = args.getInteger(0);
|
||||
we.checkMaxBrushRadius(radius);
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool instanceof BrushTool) {
|
||||
|
@ -0,0 +1,126 @@
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.object.extent.Linear3DTransform;
|
||||
import com.boydti.fawe.object.extent.LinearTransform;
|
||||
import com.boydti.fawe.object.extent.OffsetExtent;
|
||||
import com.boydti.fawe.object.extent.PatternTransform;
|
||||
import com.boydti.fawe.object.extent.RandomOffsetTransform;
|
||||
import com.boydti.fawe.object.extent.RandomTransform;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.object.extent.ScaleTransform;
|
||||
import com.boydti.fawe.object.extent.TransformExtent;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Command(aliases = { "transforms" },
|
||||
desc = "Help for the various transforms. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Transforms)"
|
||||
)
|
||||
public class TransformCommands extends MethodCommands {
|
||||
public TransformCommands(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#linear", "#l"},
|
||||
desc = "Sequentially pick from a list of transform",
|
||||
usage = "<transform>",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
public ResettableExtent linear(Actor actor, LocalSession session, @Optional("#null") ResettableExtent other) {
|
||||
if (other instanceof RandomTransform) {
|
||||
Set<ResettableExtent> extents = ((RandomTransform) other).getExtents();
|
||||
return new LinearTransform(extents.toArray(new ResettableExtent[extents.size()]));
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#linear3d", "#l3d"},
|
||||
desc = "Use the x,y,z coordinate to pick a transform from the list",
|
||||
usage = "<transform>",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
public ResettableExtent linear3d(Actor actor, LocalSession session, @Optional("#null") ResettableExtent other) {
|
||||
if (other instanceof RandomTransform) {
|
||||
Set<ResettableExtent> extents = ((RandomTransform) other).getExtents();
|
||||
return new Linear3DTransform(extents.toArray(new ResettableExtent[extents.size()]));
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#pattern"},
|
||||
desc = "Always use a specific pattern",
|
||||
usage = "<pattern> [transform]",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
public ResettableExtent pattern(Actor actor, LocalSession session, Pattern pattern, @Optional("#null") ResettableExtent other) {
|
||||
return new PatternTransform(other, pattern);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#offset"},
|
||||
desc = "Offset transform",
|
||||
usage = "<dx> <dy> <dz> [transform]",
|
||||
min = 3,
|
||||
max = 4
|
||||
)
|
||||
public ResettableExtent offset(Actor actor, LocalSession session, double x, double y, double z, @Optional("#null") ResettableExtent other) {
|
||||
return new OffsetExtent(other, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#spread", "#randomoffset"},
|
||||
desc = "Random offset transform",
|
||||
usage = "<dx> <dy> <dz> [transform]",
|
||||
min = 3,
|
||||
max = 4
|
||||
)
|
||||
public ResettableExtent randomoffset(Actor actor, LocalSession session, double x, double y, double z, @Optional("#null") ResettableExtent other) {
|
||||
return new RandomOffsetTransform(other, (int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#scale"},
|
||||
desc = "All changes will be scaled",
|
||||
usage = "<dx> <dy> <dz> [transform]",
|
||||
min = 3,
|
||||
max = 4
|
||||
)
|
||||
public ResettableExtent scale(Actor actor, LocalSession session, double x, double y, double z, @Optional("#null") ResettableExtent other) {
|
||||
return new ScaleTransform(other, x, y, z);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"#rotate"},
|
||||
desc = "All changes will be rotate around the initial position",
|
||||
usage = "<rotateX> <rotateY> <rotateZ> [transform]",
|
||||
min = 3,
|
||||
max = 4
|
||||
)
|
||||
public ResettableExtent rotate(Player player, LocalSession session, double x, double y, double z, @Optional("#null") ResettableExtent other) {
|
||||
ExtentTraverser traverser = new ExtentTraverser(other).find(TransformExtent.class);
|
||||
BlockTransformExtent affine = (TransformExtent) (traverser != null ? traverser.get() : null);
|
||||
if (affine == null) {
|
||||
other = affine = new TransformExtent(other, player.getWorld().getWorldData().getBlockRegistry());
|
||||
}
|
||||
AffineTransform transform = (AffineTransform) affine.getTransform();
|
||||
transform = transform.rotateX(x);
|
||||
transform = transform.rotateY(y);
|
||||
transform = transform.rotateZ(z);
|
||||
affine.setTransform(transform);
|
||||
return (ResettableExtent) other;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.util.concurrent.AtomicDouble;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
@ -70,8 +71,10 @@ import com.sk89q.worldedit.world.World;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -85,14 +88,13 @@ import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
|
||||
* Utility commands.
|
||||
*/
|
||||
@Command(aliases = {}, desc = "Various utility commands: [More Info](http://wiki.sk89q.com/wiki/WorldEdit/Utilities)")
|
||||
public class UtilityCommands {
|
||||
|
||||
private final WorldEdit we;
|
||||
public class UtilityCommands extends MethodCommands {
|
||||
|
||||
public UtilityCommands(WorldEdit we) {
|
||||
this.we = we;
|
||||
super(we);
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = { "/fill" },
|
||||
usage = "<block> <radius> [depth]",
|
||||
@ -103,7 +105,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.fill")
|
||||
@Logging(PLACEMENT)
|
||||
public void fill(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
|
||||
we.checkMaxRadius(radius);
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected = 0;
|
||||
if (pattern instanceof BlockPattern) {
|
||||
@ -124,7 +126,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.fill.recursive")
|
||||
@Logging(PLACEMENT)
|
||||
public void fillr(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
|
||||
we.checkMaxRadius(radius);
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected = 0;
|
||||
if (pattern instanceof BlockPattern) {
|
||||
@ -145,7 +147,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.drain")
|
||||
@Logging(PLACEMENT)
|
||||
public void drain(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
|
||||
we.checkMaxRadius(radius);
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
int affected = editSession.drainArea(
|
||||
session.getPlacementPosition(player), radius);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been changed.");
|
||||
@ -161,7 +163,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.fixlava")
|
||||
@Logging(PLACEMENT)
|
||||
public void fixLava(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
|
||||
we.checkMaxRadius(radius);
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
int affected = editSession.fixLiquid(
|
||||
session.getPlacementPosition(player), radius, 10, 11);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been changed.");
|
||||
@ -177,7 +179,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.fixwater")
|
||||
@Logging(PLACEMENT)
|
||||
public void fixWater(Player player, LocalSession session, EditSession editSession, double radius) throws WorldEditException {
|
||||
we.checkMaxRadius(radius);
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
int affected = editSession.fixLiquid(
|
||||
session.getPlacementPosition(player), radius, 8, 9);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been changed.");
|
||||
@ -193,7 +195,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.removeabove")
|
||||
@Logging(PLACEMENT)
|
||||
public void removeAbove(Player player, LocalSession session, EditSession editSession, @Optional("1") double size, @Optional("256") double height) throws WorldEditException {
|
||||
we.checkMaxRadius(size);
|
||||
worldEdit.checkMaxRadius(size);
|
||||
int affected = editSession.removeAbove(session.getPlacementPosition(player), (int) size, (int) height);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
|
||||
}
|
||||
@ -208,7 +210,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.removebelow")
|
||||
@Logging(PLACEMENT)
|
||||
public void removeBelow(Player player, LocalSession session, EditSession editSession, @Optional("1") double size, @Optional("256") double height) throws WorldEditException {
|
||||
we.checkMaxRadius(size);
|
||||
worldEdit.checkMaxRadius(size);
|
||||
int affected = editSession.removeBelow(session.getPlacementPosition(player), (int) size, (int) height);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
|
||||
}
|
||||
@ -223,7 +225,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.removenear")
|
||||
@Logging(PLACEMENT)
|
||||
public void removeNear(Player player, LocalSession session, EditSession editSession, BaseBlock block, @Optional("50") double size) throws WorldEditException {
|
||||
we.checkMaxRadius(size);
|
||||
worldEdit.checkMaxRadius(size);
|
||||
int affected = editSession.removeNear(session.getPlacementPosition(player), block.getId(), (int) size);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
|
||||
}
|
||||
@ -315,12 +317,12 @@ public class UtilityCommands {
|
||||
@Logging(PLACEMENT)
|
||||
public void extinguish(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
|
||||
int defaultRadius = config.maxRadius != -1 ? Math.min(40, config.maxRadius) : 40;
|
||||
int size = args.argsLength() > 0 ? Math.max(1, args.getInteger(0))
|
||||
: defaultRadius;
|
||||
we.checkMaxRadius(size);
|
||||
worldEdit.checkMaxRadius(size);
|
||||
|
||||
int affected = editSession.removeNear(session.getPlacementPosition(player), 51, size);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been removed.");
|
||||
@ -349,7 +351,7 @@ public class UtilityCommands {
|
||||
@CommandPermissions("worldedit.butcher")
|
||||
@Logging(PLACEMENT)
|
||||
public void butcher(Actor actor, CommandContext args) throws WorldEditException {
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
Player player = actor instanceof Player ? (Player) actor : null;
|
||||
|
||||
// technically the default can be larger than the max, but that's not my problem
|
||||
@ -379,7 +381,7 @@ public class UtilityCommands {
|
||||
EditSession editSession = null;
|
||||
|
||||
if (player != null) {
|
||||
session = we.getSessionManager().get(player);
|
||||
session = worldEdit.getSessionManager().get(player);
|
||||
Vector center = session.getPlacementPosition(player);
|
||||
editSession = session.createEditSession(player);
|
||||
List<? extends Entity> entities;
|
||||
@ -391,7 +393,7 @@ public class UtilityCommands {
|
||||
}
|
||||
visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(editSession.getWorld().getWorldData().getEntityRegistry())));
|
||||
} else {
|
||||
Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
||||
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
||||
for (World world : platform.getWorlds()) {
|
||||
List<? extends Entity> entities = world.getEntities();
|
||||
visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(world.getWorldData().getEntityRegistry())));
|
||||
@ -439,7 +441,7 @@ public class UtilityCommands {
|
||||
EditSession editSession = null;
|
||||
|
||||
if (player != null) {
|
||||
session = we.getSessionManager().get(player);
|
||||
session = worldEdit.getSessionManager().get(player);
|
||||
Vector center = session.getPlacementPosition(player);
|
||||
editSession = session.createEditSession(player);
|
||||
List<? extends Entity> entities;
|
||||
@ -451,7 +453,7 @@ public class UtilityCommands {
|
||||
}
|
||||
visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(editSession.getWorld().getWorldData().getEntityRegistry())));
|
||||
} else {
|
||||
Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
||||
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
||||
for (World world : platform.getWorlds()) {
|
||||
List<? extends Entity> entities = world.getEntities();
|
||||
visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(world.getWorldData().getEntityRegistry())));
|
||||
@ -515,7 +517,7 @@ public class UtilityCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.help")
|
||||
public void help(Actor actor, CommandContext args) throws WorldEditException {
|
||||
help(args, we, actor);
|
||||
help(args, worldEdit, actor);
|
||||
}
|
||||
|
||||
private static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) {
|
||||
@ -547,8 +549,13 @@ public class UtilityCommands {
|
||||
}
|
||||
|
||||
public static void help(CommandContext args, WorldEdit we, Actor actor) {
|
||||
CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher();
|
||||
help(args, we, actor, "/", null);
|
||||
}
|
||||
|
||||
public static void help(CommandContext args, WorldEdit we, Actor actor, String prefix, CommandCallable callable) {
|
||||
if (callable == null) {
|
||||
callable = we.getPlatformManager().getCommandManager().getDispatcher();
|
||||
}
|
||||
CommandLocals locals = args.getLocals();
|
||||
|
||||
int page = -1;
|
||||
@ -567,7 +574,8 @@ public class UtilityCommands {
|
||||
}
|
||||
effectiveLength--;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
boolean isRootLevel = true;
|
||||
List<String> visited = new ArrayList<String>();
|
||||
@ -616,7 +624,39 @@ public class UtilityCommands {
|
||||
callable = mapping.getCallable();
|
||||
} else {
|
||||
if (isRootLevel) {
|
||||
actor.printError(String.format("The command '%s' could not be found.", args.getString(i)));
|
||||
Set<String> found = new HashSet<>();
|
||||
String arg = args.getString(i).toLowerCase();
|
||||
String closest = null;
|
||||
int distance = Integer.MAX_VALUE;
|
||||
for (CommandMapping map : aliases) {
|
||||
String desc = map.getDescription().getDescription();
|
||||
if (desc == null) desc = map.getDescription().getHelp();
|
||||
if (desc == null) desc = "";
|
||||
String[] descSplit = desc.replaceAll("[^A-Za-z0-9]", "").toLowerCase().split(" ");
|
||||
for (String alias : map.getAllAliases()) {
|
||||
if (alias.equals(arg)) {
|
||||
closest = map.getPrimaryAlias();
|
||||
distance = 0;
|
||||
found.add(map.getPrimaryAlias());
|
||||
} else if (alias.contains(arg)) {
|
||||
closest = map.getPrimaryAlias();
|
||||
distance = 1;
|
||||
found.add(map.getPrimaryAlias());
|
||||
} else if (StringMan.isEqualIgnoreCaseToAny(arg, descSplit)) {
|
||||
closest = map.getPrimaryAlias();
|
||||
distance = 1;
|
||||
found.add(map.getPrimaryAlias());
|
||||
} else {
|
||||
int currentDist = StringMan.getLevenshteinDistance(alias, arg);
|
||||
if (currentDist < distance) {
|
||||
distance = currentDist;
|
||||
closest = map.getPrimaryAlias();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found.add(closest);
|
||||
BBC.HELP_SUGGEST.send(actor, arg, StringMan.join(found, ", "));
|
||||
return;
|
||||
} else {
|
||||
actor.printError(String.format("The sub-command '%s' under '%s' could not be found.",
|
||||
@ -642,9 +682,8 @@ public class UtilityCommands {
|
||||
aliases = mappings;
|
||||
}
|
||||
page = Math.max(0, page);
|
||||
} else {
|
||||
} else if (grouped.size() > 1) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
String cmd = args.getCommand();
|
||||
message.append(BBC.getPrefix() + BBC.HELP_HEADER_CATEGORIES.s() + "\n");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean first = true;
|
||||
@ -663,7 +702,7 @@ public class UtilityCommands {
|
||||
Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
|
||||
|
||||
// Calculate pagination
|
||||
int offset = perPage * page;
|
||||
int offset = perPage * Math.max(0, page);
|
||||
int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage);
|
||||
|
||||
// Box
|
||||
@ -673,14 +712,14 @@ public class UtilityCommands {
|
||||
message.append("&c").append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal));
|
||||
} else {
|
||||
message.append(BBC.getPrefix() + BBC.HELP_HEADER.format(page + 1, pageTotal) + "\n");
|
||||
List<CommandMapping> list = aliases.subList(offset, Math.min(offset + perPage, aliases.size()));
|
||||
List<CommandMapping> list = aliases.subList(offset, Math.min(offset + perPage, aliases.size() - 1));
|
||||
|
||||
boolean first = true;
|
||||
// Add each command
|
||||
for (CommandMapping mapping : list) {
|
||||
CommandCallable c = mapping.getCallable();
|
||||
StringBuilder s1 = new StringBuilder();
|
||||
s1.append("/");
|
||||
s1.append(prefix);
|
||||
if (!visited.isEmpty()) {
|
||||
s1.append(Joiner.on(" ").join(visited));
|
||||
s1.append(" ");
|
||||
|
@ -168,6 +168,9 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
blockType = BlockType.lookup(testId);
|
||||
if (blockType == null) {
|
||||
int t = worldEdit.getServer().resolveItem(testId);
|
||||
if (t == 0 && !testId.contains("air")) {
|
||||
throw new NoMatchException("Invalid block '" + input + "'.");
|
||||
}
|
||||
if (t >= 0) {
|
||||
blockType = BlockType.fromID(t); // Could be null
|
||||
blockId = t;
|
||||
|
@ -1,419 +1,170 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.AdjacentMask;
|
||||
import com.boydti.fawe.object.mask.AngleMask;
|
||||
import com.boydti.fawe.object.mask.BlockLightMask;
|
||||
import com.boydti.fawe.object.mask.BrightnessMask;
|
||||
import com.boydti.fawe.object.mask.CustomMask;
|
||||
import com.boydti.fawe.object.mask.DataMask;
|
||||
import com.boydti.fawe.object.mask.IdDataMask;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.object.mask.LightMask;
|
||||
import com.boydti.fawe.object.mask.OpacityMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.boydti.fawe.object.mask.SkyLightMask;
|
||||
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.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.MaskCommands;
|
||||
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.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.BiomeMask2D;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExpressionMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
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.NoiseFilter;
|
||||
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||
import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.math.noise.RandomNoise;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.session.request.RequestSelection;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.biome.Biomes;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import java.lang.reflect.Constructor;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Parses mask input strings.
|
||||
*/
|
||||
public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
|
||||
public static final String[] EXPRESSION_MASK = new String[] { "=<expression>" };
|
||||
|
||||
public static final String[] BLOCK_MASK = new String[] { "<blocks>" };
|
||||
|
||||
public static final String[] SIMPLE_MASK = new String[] {
|
||||
"#nolight", "#haslight", "#existing", "#solid", "#dregion", "#dselection", "#dsel", "#selection", "#region", "#sel", "#xaxis", "#yaxis", "#zaxis", "#id", "#data", "#wall", "#surface",
|
||||
};
|
||||
|
||||
public static final String[] DELEGATE_MASKS = new String[] {
|
||||
"#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);
|
||||
private final Dispatcher dispatcher;
|
||||
private final Pattern INTERSECTION_PATTERN = Pattern.compile("[&|;]+(?![^\\[]*\\])");
|
||||
|
||||
public DefaultMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
this.dispatcher = new SimpleDispatcher();
|
||||
this.register(new MaskCommands(worldEdit));
|
||||
}
|
||||
|
||||
private static Map<String, Class<? extends CustomMask>> customMasks = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Register a mask!
|
||||
* @param id
|
||||
* @param clazz
|
||||
*/
|
||||
public void addMask(String id, Class<? extends CustomMask> clazz) {
|
||||
checkNotNull(clazz);
|
||||
checkNotNull(id);
|
||||
customMasks.put(id.toLowerCase(), clazz);
|
||||
public Dispatcher getDispatcher() {
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
public static Map<String, Class<? extends CustomMask>> getCustomMasks() {
|
||||
return customMasks;
|
||||
public void register(Object clazz) {
|
||||
ParametricBuilder builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
builder.registerMethodsAsCommands(dispatcher, clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
List<Mask> masks = new ArrayList<Mask>();
|
||||
|
||||
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 : StringMan.split(component, ',')) {
|
||||
ArrayList<Mask> list = new ArrayList<Mask>();
|
||||
list.add(catchSuggestion(input, list, elem, context));
|
||||
if (list.size() == 1) {
|
||||
Mask mask = list.get(0);
|
||||
if (mask.getClass() == BlockMask.class) {
|
||||
blocks.addAll(((BlockMask) mask).getBlocks());
|
||||
} else {
|
||||
masksUnion.add(mask);
|
||||
}
|
||||
} else {
|
||||
masksUnion.add(new MaskIntersection(list));
|
||||
}
|
||||
}
|
||||
if (!blocks.isEmpty()) {
|
||||
masksUnion.add(new BlockMask(Request.request().getExtent(), blocks));
|
||||
}
|
||||
if (masksUnion.size() == 1) {
|
||||
masks.add(masksUnion.get(0));
|
||||
} else {
|
||||
masks.add(new MaskUnion(masksUnion));
|
||||
}
|
||||
}
|
||||
switch (masks.size()) {
|
||||
case 0:
|
||||
return null;
|
||||
|
||||
case 1:
|
||||
return masks.get(0);
|
||||
|
||||
default:
|
||||
return new MaskIntersection(masks);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
if (input.isEmpty()) return null;
|
||||
Extent extent = Request.request().getExtent();
|
||||
if (extent == null) extent = context.getExtent();
|
||||
final char firstChar = input.charAt(0);
|
||||
switch (firstChar) {
|
||||
case '#':
|
||||
int colon = input.indexOf(':');
|
||||
String component = input;
|
||||
if (colon != -1) {
|
||||
component = component.substring(0, colon).toLowerCase();
|
||||
String rest = input.substring(colon + 1);
|
||||
Class<? extends CustomMask> customMask = customMasks.get(component);
|
||||
if (customMask != null) {
|
||||
try {
|
||||
Constructor<? extends CustomMask> constructor = customMask.getDeclaredConstructor(List.class, String.class, ParserContext.class);
|
||||
return constructor.newInstance(masks, rest, context);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
HashSet<BaseBlock> blocks = new HashSet<BaseBlock>();
|
||||
List<Mask> intersection = new ArrayList<>();
|
||||
List<Mask> union = new ArrayList<>();
|
||||
final CommandLocals locals = new CommandLocals();
|
||||
Actor actor = context != null ? context.getActor() : null;
|
||||
if (actor != null) {
|
||||
locals.put(Actor.class, actor);
|
||||
}
|
||||
//
|
||||
try {
|
||||
List<Map.Entry<ParseEntry, List<String>>> parsed = parse(input);
|
||||
for (Map.Entry<ParseEntry, List<String>> entry : parsed) {
|
||||
ParseEntry pe = entry.getKey();
|
||||
String command = pe.input;
|
||||
Mask mask = null;
|
||||
if (command.isEmpty()) {
|
||||
mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
} if (dispatcher.get(command) == null) {
|
||||
// Legacy patterns
|
||||
char char0 = command.charAt(0);
|
||||
boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
||||
if (charMask && input.charAt(0) == '=') {
|
||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
}
|
||||
switch (component) {
|
||||
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) {
|
||||
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);
|
||||
if (mask == null) {
|
||||
// Legacy syntax
|
||||
if (charMask) {
|
||||
switch (char0) {
|
||||
case '\\': //
|
||||
case '/': //
|
||||
case '{': //
|
||||
case '$': //
|
||||
case '%': {
|
||||
command = command.substring(1);
|
||||
String value = command + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
if (value.contains(":")) {
|
||||
if (value.charAt(0) == ':') value.replaceFirst(":", "");
|
||||
value= value.replaceAll(":", "][");
|
||||
}
|
||||
mask = parseFromInput(char0 + "[" + value + "]", context);
|
||||
break;
|
||||
}
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
e.printStackTrace();
|
||||
throw new SuggestInputParseException(input, component + ":<min>:<max>");
|
||||
case '|':
|
||||
case '~':
|
||||
case '<':
|
||||
case '>':
|
||||
case '!':
|
||||
input = input.substring(input.indexOf(char0) + 1);
|
||||
mask = parseFromInput(char0 + "[" + input + "]", context);
|
||||
if (actor != null) {
|
||||
actor.print("&7Added clarifying bracket for: " + char0 + "&c[&7" + input + "&c]&7");
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
case "#~":
|
||||
case "#rel":
|
||||
case "#relative":
|
||||
case "#offset":
|
||||
}
|
||||
if (mask == null) {
|
||||
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>");
|
||||
BaseBlock block = worldEdit.getBlockFactory().parseFromInput(command, context);
|
||||
if (pe.and) {
|
||||
mask = new BlockMask(extent, block);
|
||||
} else {
|
||||
blocks.add(block);
|
||||
continue;
|
||||
}
|
||||
} catch (NoMatchException e) {
|
||||
throw new NoMatchException(e.getMessage() + " See: //masks");
|
||||
}
|
||||
}
|
||||
}
|
||||
Mask mask = catchSuggestion(input, masks, rest, context);
|
||||
masks.add(mask);
|
||||
} else {
|
||||
Class<? extends CustomMask> customMask = customMasks.get(component);
|
||||
if (customMask != null) {
|
||||
try {
|
||||
Constructor<? extends CustomMask> constructor = customMask.getDeclaredConstructor(List.class, String.class, ParserContext.class);
|
||||
return constructor.newInstance(masks, "", context);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
List<String> args = entry.getValue();
|
||||
if (!args.isEmpty()) {
|
||||
command += " " + StringMan.join(args, " ");
|
||||
}
|
||||
mask = (Mask) dispatcher.call(command, locals, new String[0]);
|
||||
}
|
||||
switch (component.toLowerCase()) {
|
||||
case "#haslight":
|
||||
return new LightMask(extent, 1, Integer.MAX_VALUE);
|
||||
case "#nolight":
|
||||
return new LightMask(extent, 0, 0);
|
||||
case "#existing":
|
||||
return new ExistingBlockMask(extent);
|
||||
case "#solid":
|
||||
return new SolidBlockMask(extent);
|
||||
case "#dregion":
|
||||
case "#dselection":
|
||||
case "#dsel":
|
||||
return new RegionMask(new RequestSelection());
|
||||
case "#selection":
|
||||
case "#region":
|
||||
case "#sel":
|
||||
try {
|
||||
return new RegionMask(context.requireSession().getSelection(context.requireWorld()).clone());
|
||||
} catch (IncompleteRegionException e) {
|
||||
throw new InputParseException("Please make a selection first.");
|
||||
}
|
||||
case "#xaxis":
|
||||
return new XAxisMask();
|
||||
case "#yaxis":
|
||||
return new YAxisMask();
|
||||
case "#zaxis":
|
||||
return new ZAxisMask();
|
||||
case "#id":
|
||||
return new IdMask(extent);
|
||||
case "#data":
|
||||
return new DataMask(extent);
|
||||
case "#iddata":
|
||||
return new IdDataMask(extent);
|
||||
case "#wall":
|
||||
masks.add(new ExistingBlockMask(extent));
|
||||
BlockMask matchAir = new BlockMask(extent, EditSession.nullBlock);
|
||||
return new WallMask(extent, Arrays.asList(new BaseBlock(0)), 1, 8);
|
||||
case "#surface":
|
||||
masks.add(new ExistingBlockMask(extent));
|
||||
return new AdjacentAnyMask(extent, Arrays.asList(new BaseBlock(0)));
|
||||
default:
|
||||
throw new SuggestInputParseException(input, HASHTAG_MASKS);
|
||||
}
|
||||
case '\\':
|
||||
case '/': {
|
||||
String[] split = input.substring(1).split(":");
|
||||
if (split.length != 2) {
|
||||
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||
}
|
||||
try {
|
||||
double y1,y2;
|
||||
boolean override;
|
||||
if (split[1].endsWith("o")) {
|
||||
override = true;
|
||||
split[1] = split[1].substring(0, split[1].length() - 1);
|
||||
} else {
|
||||
override = false;
|
||||
}
|
||||
if (split[0].endsWith("d")) {
|
||||
double y1d = Expression.compile(split[0].substring(0, split[0].length() - 1)).evaluate();
|
||||
double y2d = Expression.compile(split[1].substring(0, split[1].length() - 1)).evaluate();
|
||||
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||
} else {
|
||||
y1 = (Expression.compile(split[0]).evaluate());
|
||||
y2 = (Expression.compile(split[1]).evaluate());
|
||||
}
|
||||
return new AngleMask(extent, y1, y2, override);
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||
}
|
||||
}
|
||||
case '{': {
|
||||
String[] split = input.substring(1).split(":");
|
||||
if (split.length != 2) {
|
||||
throw new SuggestInputParseException(input, "{<min-radius>:<max-radius>");
|
||||
}
|
||||
try {
|
||||
int y1 = (int) Math.abs(Expression.compile(split[0]).evaluate());
|
||||
int y2 = (int) Math.abs(Expression.compile(split[1]).evaluate());
|
||||
return new RadiusMask(y1, y2);
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "{<min-radius>:<max-radius>");
|
||||
}
|
||||
}
|
||||
case '|':
|
||||
case '~': {
|
||||
String[] split = input.substring(1).split("=");
|
||||
ParserContext tempContext = new ParserContext(context);
|
||||
tempContext.setRestricted(false);
|
||||
tempContext.setPreferringWildcard(true);
|
||||
try {
|
||||
int requiredMin = 1;
|
||||
int requiredMax = 8;
|
||||
if (split.length == 2) {
|
||||
String[] split2 = split[1].split("[:|,]");
|
||||
requiredMin = (int) Math.abs(Expression.compile(split2[0]).evaluate());
|
||||
if (split2.length >= 2) {
|
||||
requiredMax = (int) Math.abs(Expression.compile(split2[1]).evaluate());
|
||||
}
|
||||
}
|
||||
if (firstChar == '~') {
|
||||
if (requiredMax >= 8 && requiredMin == 1) {
|
||||
return new AdjacentAnyMask(extent, worldEdit.getBlockFactory().parseFromListInput(split[0], tempContext));
|
||||
}
|
||||
return new AdjacentMask(extent, worldEdit.getBlockFactory().parseFromListInput(split[0], tempContext), requiredMin, requiredMax);
|
||||
} else {
|
||||
return new WallMask(extent, worldEdit.getBlockFactory().parseFromListInput(input.substring(1), tempContext), requiredMin, requiredMax);
|
||||
}
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "~<blocks>=<min>:<max>");
|
||||
}
|
||||
}
|
||||
case '>':
|
||||
case '<':
|
||||
Mask submask;
|
||||
if (input.length() > 1) {
|
||||
submask = getBlockMaskComponent(masks, input.substring(1), context);
|
||||
if (pe.and) { // &
|
||||
intersection.add(mask);
|
||||
} else {
|
||||
submask = new ExistingBlockMask(extent);
|
||||
}
|
||||
OffsetMask offsetMask = new OffsetMask(submask, new Vector(0, firstChar == '>' ? -1 : 1, 0));
|
||||
return new MaskIntersection(offsetMask, Masks.negate(submask));
|
||||
|
||||
case '$':
|
||||
Set<BaseBiome> biomes = new HashSet<BaseBiome>();
|
||||
String[] biomesList = input.substring(1).split(",");
|
||||
BiomeRegistry biomeRegistry = context.requireWorld().getWorldData().getBiomeRegistry();
|
||||
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
||||
for (String biomeName : biomesList) {
|
||||
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry);
|
||||
if (biome == null) {
|
||||
throw new SuggestInputParseException(input, "$<biome>");
|
||||
if (!intersection.isEmpty()) {
|
||||
if (intersection.size() == 1) {
|
||||
throw new InputParseException("Error, floating &");
|
||||
}
|
||||
union.add(new MaskIntersection(intersection));
|
||||
intersection.clear();
|
||||
}
|
||||
biomes.add(biome);
|
||||
union.add(mask);
|
||||
}
|
||||
return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes));
|
||||
|
||||
case '%':
|
||||
try {
|
||||
double i = Math.abs(Expression.compile(input.substring(1)).evaluate());
|
||||
return new NoiseFilter(new RandomNoise(), (i) / 100);
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "%<percent>");
|
||||
}
|
||||
case '=':
|
||||
try {
|
||||
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
|
||||
Request.request().getEditSession (), Vector.ONE, Vector.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
return new ExpressionMask(exp);
|
||||
} catch (ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "=<expression>");
|
||||
}
|
||||
|
||||
case '!':
|
||||
if (input.length() > 1) {
|
||||
return Masks.negate(getBlockMaskComponent(masks, input.substring(1), context));
|
||||
}
|
||||
throw new SuggestInputParseException(input, "!<mask>");
|
||||
default:
|
||||
ParserContext tempContext = new ParserContext(context);
|
||||
tempContext.setRestricted(false);
|
||||
tempContext.setPreferringWildcard(true);
|
||||
return new BlockMask(extent, worldEdit.getBlockFactory().parseFromListInput(input, tempContext));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new InputParseException(e.getMessage(), e);
|
||||
}
|
||||
if (!blocks.isEmpty()) {
|
||||
union.add(new BlockMask(extent, blocks));
|
||||
}
|
||||
if (!intersection.isEmpty()) {
|
||||
if (intersection.size() == 1) {
|
||||
throw new InputParseException("Error, floating &");
|
||||
}
|
||||
union.add(new MaskIntersection(intersection));
|
||||
intersection.clear();
|
||||
}
|
||||
if (union.isEmpty()) {
|
||||
return null;
|
||||
} else if (union.size() == 1) {
|
||||
return union.get(0);
|
||||
} else {
|
||||
return new MaskUnion(union);
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return DefaultMaskParser.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,151 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.object.extent.MultiTransform;
|
||||
import com.boydti.fawe.object.extent.RandomTransform;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.object.random.TrueRandom;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.TransformCommands;
|
||||
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.platform.Actor;
|
||||
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
||||
private final Pattern INTERSECTION_PATTERN = Pattern.compile("[&|;]+(?![^\\[]*\\])");
|
||||
private final Dispatcher dispatcher;
|
||||
|
||||
public DefaultTransformParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
this.dispatcher = new SimpleDispatcher();
|
||||
this.register(new TransformCommands(worldEdit));
|
||||
}
|
||||
|
||||
public Dispatcher getDispatcher() {
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
public void register(Object clazz) {
|
||||
ParametricBuilder builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
builder.registerMethodsAsCommands(dispatcher, clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.isEmpty()) return null;
|
||||
|
||||
List<Double> unionChances = new ArrayList<>();
|
||||
List<Double> intersectionChances = new ArrayList<>();
|
||||
|
||||
List<ResettableExtent> intersection = new ArrayList<>();
|
||||
List<ResettableExtent> union = new ArrayList<>();
|
||||
final CommandLocals locals = new CommandLocals();
|
||||
Actor actor = context != null ? context.getActor() : null;
|
||||
if (actor != null) {
|
||||
locals.put(Actor.class, actor);
|
||||
}
|
||||
try {
|
||||
List<Map.Entry<ParseEntry, List<String>>> parsed = parse(input);
|
||||
for (Map.Entry<ParseEntry, List<String>> entry : parsed) {
|
||||
ParseEntry pe = entry.getKey();
|
||||
String command = pe.input;
|
||||
ResettableExtent transform = null;
|
||||
double chance = 1;
|
||||
if (command.isEmpty()) {
|
||||
transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
} if (dispatcher.get(command) == null) {
|
||||
// Legacy syntax
|
||||
int percentIndex = command.indexOf('%');
|
||||
if (percentIndex != -1) { // Legacy percent pattern
|
||||
chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
|
||||
command = command.substring(percentIndex + 1);
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
if (!command.isEmpty()) command += " ";
|
||||
command += StringMan.join(entry.getValue(), " ");
|
||||
}
|
||||
transform = parseFromInput(command, context);
|
||||
} else {
|
||||
throw new NoMatchException("See: //transforms");
|
||||
}
|
||||
} else {
|
||||
List<String> args = entry.getValue();
|
||||
if (!args.isEmpty()) {
|
||||
command += " " + StringMan.join(args, " ");
|
||||
}
|
||||
transform = (ResettableExtent) dispatcher.call(command, locals, new String[0]);
|
||||
}
|
||||
if (pe.and) { // &
|
||||
intersectionChances.add(chance);
|
||||
intersection.add(transform);
|
||||
} else {
|
||||
if (!intersection.isEmpty()) {
|
||||
if (intersection.size() == 1) {
|
||||
throw new InputParseException("Error, floating &");
|
||||
}
|
||||
MultiTransform multi = new MultiTransform();
|
||||
double total = 0;
|
||||
for (int i = 0; i < intersection.size(); i++) {
|
||||
Double value = intersectionChances.get(i);
|
||||
total += value;
|
||||
multi.add(intersection.get(i), value);
|
||||
}
|
||||
union.add(multi);
|
||||
unionChances.add(total);
|
||||
intersection.clear();
|
||||
intersectionChances.clear();
|
||||
}
|
||||
unionChances.add(chance);
|
||||
union.add(transform);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new InputParseException(e.getMessage(), e);
|
||||
}
|
||||
if (!intersection.isEmpty()) {
|
||||
if (intersection.size() == 1) {
|
||||
throw new InputParseException("Error, floating &");
|
||||
}
|
||||
MultiTransform multi = new MultiTransform();
|
||||
double total = 0;
|
||||
for (int i = 0; i < intersection.size(); i++) {
|
||||
Double value = intersectionChances.get(i);
|
||||
total += value;
|
||||
multi.add(intersection.get(i), value);
|
||||
}
|
||||
union.add(multi);
|
||||
unionChances.add(total);
|
||||
intersection.clear();
|
||||
intersectionChances.clear();
|
||||
}
|
||||
if (union.isEmpty()) {
|
||||
throw new NoMatchException("See: //transforms");
|
||||
} else if (union.size() == 1) {
|
||||
return union.get(0);
|
||||
} else {
|
||||
RandomTransform random = new RandomTransform(new TrueRandom());
|
||||
for (int i = 0; i < union.size(); i++) {
|
||||
random.add(union.get(i), unionChances.get(i));
|
||||
}
|
||||
return random;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return HashTagPatternParser.class;
|
||||
}
|
||||
}
|
@ -1,453 +1,135 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.object.DataAngleMask;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.pattern.AngleColorPattern;
|
||||
import com.boydti.fawe.object.pattern.AverageColorPattern;
|
||||
import com.boydti.fawe.object.pattern.BiomePattern;
|
||||
import com.boydti.fawe.object.pattern.BufferedPattern;
|
||||
import com.boydti.fawe.object.pattern.DataPattern;
|
||||
import com.boydti.fawe.object.pattern.DesaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ExistingPattern;
|
||||
import com.boydti.fawe.object.pattern.ExpressionPattern;
|
||||
import com.boydti.fawe.object.pattern.FullClipboardPattern;
|
||||
import com.boydti.fawe.object.pattern.IdDataMaskPattern;
|
||||
import com.boydti.fawe.object.pattern.IdPattern;
|
||||
import com.boydti.fawe.object.pattern.Linear3DBlockPattern;
|
||||
import com.boydti.fawe.object.pattern.LinearBlockPattern;
|
||||
import com.boydti.fawe.object.pattern.MaskedPattern;
|
||||
import com.boydti.fawe.object.pattern.NoXPattern;
|
||||
import com.boydti.fawe.object.pattern.NoYPattern;
|
||||
import com.boydti.fawe.object.pattern.NoZPattern;
|
||||
import com.boydti.fawe.object.pattern.OffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.PatternExtent;
|
||||
import com.boydti.fawe.object.pattern.RandomFullClipboardPattern;
|
||||
import com.boydti.fawe.object.pattern.RandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.RelativePattern;
|
||||
import com.boydti.fawe.object.pattern.SaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ShadePattern;
|
||||
import com.boydti.fawe.object.pattern.SolidRandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.SurfaceRandomOffsetPattern;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.object.random.TrueRandom;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.command.PatternCommands;
|
||||
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.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.biome.Biomes;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.IOException;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.scene.paint.Color;
|
||||
import java.util.Map;
|
||||
|
||||
public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
|
||||
public static final String[] EXPRESSION_PATTERN = new String[] { "=<expression>" };
|
||||
|
||||
public static final String[] BLOCK_PATTERN = new String[] { "<block>" };
|
||||
|
||||
public static final String[] SIMPLE_PATTERNS = new String[] {
|
||||
"#existing", "#fullcopy", "#clipboard",
|
||||
};
|
||||
|
||||
public static final String[] DELEGATE_PATTERNS = new String[] {
|
||||
"#linear3d:", "#linear:", "#spread:", "#solidspread:", "#surfacespread:", "#offset:", "#mask:", "#!x:", "#!y:", "#!z:", "#relative:", "#id:", "#data:",
|
||||
};
|
||||
|
||||
public static final String[] MISC_PATTERNS = new String[] {
|
||||
"hand", "pos1",
|
||||
};
|
||||
|
||||
public static final String[] ALL_PATTERNS = MainUtil.joinArrayGeneric(BLOCK_PATTERN, SIMPLE_PATTERNS, DELEGATE_PATTERNS, MISC_PATTERNS);
|
||||
private final Dispatcher dispatcher;
|
||||
|
||||
public HashTagPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
this.dispatcher = new SimpleDispatcher();
|
||||
this.register(new PatternCommands(worldEdit));
|
||||
}
|
||||
|
||||
public Dispatcher getDispatcher() {
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
public void register(Object clazz) {
|
||||
ParametricBuilder builder = new ParametricBuilder();
|
||||
builder.setAuthorizer(new ActorAuthorizer());
|
||||
builder.addBinding(new WorldEditBinding(worldEdit));
|
||||
builder.registerMethodsAsCommands(dispatcher, clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.isEmpty()) {
|
||||
throw new SuggestInputParseException(input, ALL_PATTERNS);
|
||||
if (input.isEmpty()) return null;
|
||||
List<Double> chances = new ArrayList<>();
|
||||
List<Pattern> patterns = new ArrayList<>();
|
||||
final CommandLocals locals = new CommandLocals();
|
||||
Actor actor = context != null ? context.getActor() : null;
|
||||
if (actor != null) {
|
||||
locals.put(Actor.class, actor);
|
||||
}
|
||||
List<String> items = StringMan.split(input, ',');
|
||||
if (items.size() == 1) {
|
||||
return parseSinglePatternFromInput(items.get(0), context);
|
||||
}
|
||||
RandomPattern randomPattern = new RandomPattern();
|
||||
try {
|
||||
for (String token : items) {
|
||||
Pattern pattern;
|
||||
double chance;
|
||||
// Parse special percentage syntax
|
||||
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
|
||||
String[] p = token.split("%");
|
||||
if (p.length < 2) {
|
||||
throw new InputParseException("Missing the pattern after the % symbol for '" + input + "'");
|
||||
} else {
|
||||
chance = Expression.compile(p[0]).evaluate();
|
||||
pattern = catchSuggestion(input, p[1], context);
|
||||
}
|
||||
for (Map.Entry<ParseEntry, List<String>> entry : parse(input)) {
|
||||
ParseEntry pe = entry.getKey();
|
||||
String command = pe.input;
|
||||
Pattern pattern = null;
|
||||
double chance = 1;
|
||||
if (command.isEmpty()) {
|
||||
pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
} else {
|
||||
chance = 1;
|
||||
pattern = catchSuggestion(input, token, context);
|
||||
}
|
||||
randomPattern.add(pattern, chance);
|
||||
}
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new InputParseException("Invalid, see: https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-and-FAWE-patterns");
|
||||
}
|
||||
return randomPattern;
|
||||
}
|
||||
|
||||
public Pattern parseSinglePatternFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.isEmpty()) {
|
||||
throw new SuggestInputParseException(input, ALL_PATTERNS);
|
||||
}
|
||||
switch (input.toLowerCase().charAt(0)) {
|
||||
case '#': {
|
||||
String[] split2 = input.split(":");
|
||||
String rest = split2.length > 1 ? input.substring(split2[0].length() + 1) : "";
|
||||
String arg = split2[0].toLowerCase();
|
||||
switch (arg) {
|
||||
case "#*":
|
||||
case "#existing": {
|
||||
return new ExistingPattern(Request.request().getExtent());
|
||||
}
|
||||
case "#clipboard":
|
||||
case "#copy": {
|
||||
LocalSession session = context.requireSession();
|
||||
if (session != null) {
|
||||
try {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
return new ClipboardPattern(clipboard);
|
||||
} catch (EmptyClipboardException e) {
|
||||
throw new InputParseException("To use #clipboard, please first copy something to your clipboard");
|
||||
}
|
||||
} else {
|
||||
throw new InputParseException("No session is available, so no clipboard is available");
|
||||
if (dispatcher.get(command) == null) {
|
||||
// Legacy patterns
|
||||
char char0 = command.charAt(0);
|
||||
boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
||||
if (charMask && input.charAt(0) == '=') {
|
||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
}
|
||||
}
|
||||
case "#color": {
|
||||
if (split2.length > 1) {
|
||||
Color color = Color.web(split2[1]);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
BaseBlock block = Fawe.get().getTextureUtil().getNearestBlock(awtColor.getRGB());
|
||||
return new BlockPattern(block);
|
||||
} else {
|
||||
throw new InputParseException("#color:<hex>");
|
||||
}
|
||||
}
|
||||
case "#anglecolor": {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 2 ? true : Boolean.parseBoolean(split2[1]), 0, split2.length < 3 ? 100 : Integer.parseInt(split2[2]));
|
||||
return new AngleColorPattern(util, Request.request().getExtent());
|
||||
}
|
||||
case "#angledata": {
|
||||
return new DataAngleMask(Request.request().getExtent());
|
||||
}
|
||||
case "#saturate":
|
||||
case "#averagecolor": {
|
||||
try {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 3 ? true : Boolean.parseBoolean(split2[2]), 0, split2.length < 4 ? 100 : Integer.parseInt(split2[3]));
|
||||
Color color = Color.web(split2[1]);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
if (arg.equals("#saturate"))
|
||||
return new SaturatePattern(Request.request().getExtent(), util, awtColor.getRGB());
|
||||
else return new AverageColorPattern(Request.request().getExtent(), util, awtColor.getRGB());
|
||||
} catch (NumberFormatException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#" + arg + "[:<color>:<randomize=true>:<complexity=100>]");
|
||||
}
|
||||
}
|
||||
case "#desaturate": {
|
||||
try {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 3 ? true : Boolean.parseBoolean(split2[2]), 0, split2.length < 4 ? 100 : Integer.parseInt(split2[3]));
|
||||
double chance = split2.length < 2 ? 100 : Expression.compile(split2[1]).evaluate();
|
||||
return new DesaturatePattern(Request.request().getExtent(), util, chance / 100d);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#desaturate[:<percent=100>:<randomize=true>:<complexity=100>]");
|
||||
}
|
||||
}
|
||||
case "#lighten":
|
||||
case "#darken": {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 2 ? true : Boolean.parseBoolean(split2[1]), 0, split2.length < 3 ? 100 : Integer.parseInt(split2[2]));
|
||||
return new ShadePattern(Request.request().getExtent(), util, arg.equals("#darken"));
|
||||
}
|
||||
case "#fullcopy": {
|
||||
LocalSession session = context.requireSession();
|
||||
if (session != null) {
|
||||
try {
|
||||
if (split2.length > 1) {
|
||||
String location = split2[1];
|
||||
try {
|
||||
ClipboardHolder[] clipboards;
|
||||
switch (location.toLowerCase()) {
|
||||
case "#copy":
|
||||
case "#clipboard":
|
||||
ClipboardHolder clipboard = session.getExistingClipboard();
|
||||
if (clipboard == null) {
|
||||
throw new InputParseException("To use #fullcopy, please first copy something to your clipboard");
|
||||
}
|
||||
clipboards = new ClipboardHolder[] {clipboard};
|
||||
break;
|
||||
default:
|
||||
clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(context.getActor(), context.requireWorld().getWorldData(), location, true);
|
||||
break;
|
||||
}
|
||||
if (clipboards == null) {
|
||||
throw new InputParseException("#fullcopy:<source>");
|
||||
}
|
||||
boolean randomRotate = split2.length >= 3 && split2[2].equalsIgnoreCase("true");
|
||||
boolean randomFlip = split2.length >= 4 && split2[3].equalsIgnoreCase("true");
|
||||
return new RandomFullClipboardPattern(Request.request().getExtent(), context.requireWorld().getWorldData(), clipboards, randomRotate, randomFlip);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (charMask) {
|
||||
switch (char0) {
|
||||
case '$': {
|
||||
command = command.substring(1);
|
||||
String value = command + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
if (value.contains(":")) {
|
||||
if (value.charAt(0) == ':') value.replaceFirst(":", "");
|
||||
value= value.replaceAll(":", "][");
|
||||
}
|
||||
pattern = parseFromInput(char0 + "[" + value + "]", context);
|
||||
break;
|
||||
}
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
return new FullClipboardPattern(Request.request().getExtent(), clipboard);
|
||||
} catch (EmptyClipboardException e) {
|
||||
throw new InputParseException("To use #fullcopy, please first copy something to your clipboard");
|
||||
}
|
||||
} else {
|
||||
throw new InputParseException("No session is available, so no clipboard is available");
|
||||
}
|
||||
}
|
||||
case "#buffer": {
|
||||
return new BufferedPattern(FawePlayer.wrap(context.requireActor()), catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#iddatamask": {
|
||||
String[] split = rest.split(":", 1);
|
||||
if (split.length != 2) {
|
||||
throw new InputParseException("#iddatamask:<mask>:<pattern>");
|
||||
}
|
||||
int mask = Integer.parseInt(split[0]);
|
||||
return new IdDataMaskPattern(Request.request().getExtent(), catchSuggestion(input, split[1], context), mask);
|
||||
}
|
||||
case "#id": {
|
||||
return new IdPattern(Request.request().getExtent(), catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#data": {
|
||||
return new DataPattern(Request.request().getExtent(), catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#biome": {
|
||||
if (MathMan.isInteger(rest)) {
|
||||
return new BiomePattern(Request.request().getExtent(), new BaseBiome(Integer.parseInt(rest)));
|
||||
}
|
||||
World world = context.requireWorld();
|
||||
BiomeRegistry biomeRegistry = world.getWorldData().getBiomeRegistry();
|
||||
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
||||
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, rest, biomeRegistry);
|
||||
return new BiomePattern(Request.request().getExtent(), biome);
|
||||
}
|
||||
case "#~":
|
||||
case "#r":
|
||||
case "#relative":
|
||||
case "#rel": {
|
||||
return new RelativePattern(catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#!x":
|
||||
case "#nx":
|
||||
case "#nox": {
|
||||
return new NoXPattern(catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#!y":
|
||||
case "#ny":
|
||||
case "#noy": {
|
||||
return new NoYPattern(catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#!z":
|
||||
case "#nz":
|
||||
case "#noz": {
|
||||
return new NoZPattern(catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#mask": {
|
||||
List<String> split3 = suggestRemaining(rest, "#mask", "<mask>", "<pattern-if>", "<pattern-else>");
|
||||
Pattern primary = catchSuggestion(input, split3.get(1), context);
|
||||
Pattern secondary = catchSuggestion(input, split3.get(2), context);
|
||||
PatternExtent extent = new PatternExtent(primary);
|
||||
Request request = Request.request();
|
||||
request.setExtent(extent);
|
||||
request.setSession(context.getSession());
|
||||
request.setWorld(context.getWorld());
|
||||
context.setExtent(extent);
|
||||
MaskFactory factory = worldEdit.getMaskFactory();
|
||||
Mask mask = factory.parseFromInput(split3.get(0), context);
|
||||
if (mask == null | primary == null || secondary == null) {
|
||||
throw new SuggestInputParseException(null, "#mask:<mask>:<pattern-if>:<pattern-else>");
|
||||
}
|
||||
return new MaskedPattern(mask, extent, secondary);
|
||||
}
|
||||
case "#offset":
|
||||
try {
|
||||
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||
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()), ":");
|
||||
Pattern pattern = catchSuggestion(input, rest, context);
|
||||
return new OffsetPattern(pattern, x, y, z);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#offset:<dx>:<dy>:<dz>:<pattern>");
|
||||
}
|
||||
case "#surfacespread": {
|
||||
try {
|
||||
List<String> split3 = suggestRemaining(rest, "#surfacespread", "<distance>", "<pattern>");
|
||||
int dist = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||
rest = StringMan.join(split3.subList(1, split3.size()), ":");
|
||||
Pattern pattern = catchSuggestion(input, rest, context);
|
||||
return new SurfaceRandomOffsetPattern(Request.request().getExtent(), pattern, dist);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#surfacespread:<distance>:<pattern>");
|
||||
}
|
||||
}
|
||||
case "#solidspread": {
|
||||
try {
|
||||
List<String> split3 = suggestRemaining(rest, "#solidspread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||
Pattern pattern = catchSuggestion(input, rest, context);
|
||||
return new SolidRandomOffsetPattern(pattern, x, y, z);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#solidspread:<dx>:<dy>:<dz>:<pattern>");
|
||||
}
|
||||
}
|
||||
case "#randomoffset":
|
||||
case "#spread": {
|
||||
try {
|
||||
List<String> split3 = suggestRemaining(rest, "#spread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||
Pattern pattern = catchSuggestion(input, rest, context);
|
||||
return new RandomOffsetPattern(pattern, x, y, z);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#spread:<dx>:<dy>:<dz>:<pattern>");
|
||||
}
|
||||
}
|
||||
case "#l":
|
||||
case "#linear": {
|
||||
if (rest.startsWith("\"") && rest.endsWith("\"")) {
|
||||
rest = rest.substring(1, rest.length() - 1);
|
||||
}
|
||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
for (String token : StringMan.split(rest, ',')) {
|
||||
patterns.add(catchSuggestion(input, token, context));
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
||||
}
|
||||
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
}
|
||||
case "#l3d":
|
||||
case "#linear3d": {
|
||||
if (rest.startsWith("\"") && rest.endsWith("\"")) {
|
||||
rest = rest.substring(1, rest.length() - 1);
|
||||
}
|
||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||
for (String token : StringMan.split(rest, ',')) {
|
||||
patterns.add(catchSuggestion(input, token, context));
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
||||
}
|
||||
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||
}
|
||||
default:
|
||||
throw new SuggestInputParseException(input, MainUtil.joinArrayGeneric(SIMPLE_PATTERNS, DELEGATE_PATTERNS));
|
||||
}
|
||||
}
|
||||
case '=': {
|
||||
try {
|
||||
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
|
||||
EditSession editSession = Request.request().getEditSession();
|
||||
if (editSession == null) {
|
||||
editSession = context.requireSession().createEditSession((Player) context.getActor());
|
||||
}
|
||||
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
|
||||
editSession, Vector.ONE, Vector.ZERO);
|
||||
exp.setEnvironment(env);
|
||||
return new ExpressionPattern(exp);
|
||||
} catch (ExpressionException e) {
|
||||
throw new SuggestInputParseException("=http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax");
|
||||
}
|
||||
}
|
||||
default:
|
||||
switch (input) {
|
||||
case "<dx>":
|
||||
case "<dy>":
|
||||
case "<dz>":
|
||||
throw new SuggestInputParseException(input, "0", "-3", "7");
|
||||
case "<pattern>":
|
||||
case "<pattern-if>":
|
||||
case "<pattern-else>":
|
||||
throw new SuggestInputParseException(input, ALL_PATTERNS);
|
||||
case "<block>":
|
||||
throw new SuggestInputParseException(input, BundledBlockData.getInstance().getBlockNames());
|
||||
}
|
||||
List<String> items = StringMan.split(input, ',');
|
||||
if (items.size() == 1) {
|
||||
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items.get(0), context));
|
||||
}
|
||||
BlockFactory blockRegistry = worldEdit.getBlockFactory();
|
||||
RandomPattern randomPattern = new RandomPattern();
|
||||
try {
|
||||
for (String token : items) {
|
||||
Pattern pattern;
|
||||
double chance;
|
||||
// Parse special percentage syntax
|
||||
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
|
||||
String[] p = token.split("%");
|
||||
if (p.length < 2) {
|
||||
throw new InputParseException("Missing the pattern after the % symbol for '" + input + "'");
|
||||
} else {
|
||||
chance = Expression.compile(p[0]).evaluate();
|
||||
pattern = catchSuggestion(input, p[1], context);
|
||||
if (pattern == null) {
|
||||
int percentIndex = command.indexOf('%');
|
||||
if (percentIndex != -1) { // Legacy percent pattern
|
||||
chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
|
||||
command = command.substring(percentIndex + 1);
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
if (!command.isEmpty()) command += " ";
|
||||
command += StringMan.join(entry.getValue(), " ");
|
||||
}
|
||||
pattern = parseFromInput(command, context);
|
||||
} else { // legacy block pattern
|
||||
try {
|
||||
pattern = worldEdit.getBlockFactory().parseFromInput(command, context);
|
||||
} catch (NoMatchException e) {
|
||||
throw new NoMatchException(e.getMessage() + " See: //patterns");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chance = 1;
|
||||
pattern = catchSuggestion(input, token, context);
|
||||
}
|
||||
randomPattern.add(pattern, chance);
|
||||
} else {
|
||||
List<String> args = entry.getValue();
|
||||
if (!args.isEmpty()) {
|
||||
command += " " + StringMan.join(args, " ");
|
||||
}
|
||||
pattern = (Pattern) dispatcher.call(command, locals, new String[0]);
|
||||
}
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new InputParseException("Invalid, see: https://github.com/boy0001/FastAsyncWorldedit/wiki/WorldEdit-and-FAWE-patterns");
|
||||
}
|
||||
return randomPattern;
|
||||
patterns.add(pattern);
|
||||
chances.add(chance);
|
||||
}
|
||||
} catch (CommandException | ExpressionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
return null;
|
||||
} else if (patterns.size() == 1) {
|
||||
return patterns.get(0);
|
||||
} else {
|
||||
RandomPattern random = new RandomPattern(new TrueRandom());
|
||||
for (int i = 0; i < patterns.size(); i++) {
|
||||
random.add(patterns.get(i), chances.get(i));
|
||||
}
|
||||
return random;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return HashTagPatternParser.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,8 +375,11 @@ public final class CommandManager {
|
||||
// exceptions without writing a hook into every dispatcher, we need to unwrap these
|
||||
// exceptions and rethrow their converted form, if their is one.
|
||||
try {
|
||||
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
|
||||
Object result = dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
|
||||
} catch (Throwable t) {
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
// Use the exception converter to convert the exception if any of its causes
|
||||
// can be converted, otherwise throw the original exception
|
||||
Throwable next = t;
|
||||
@ -391,7 +394,7 @@ public final class CommandManager {
|
||||
BBC.NO_PERM.send(finalActor, StringMan.join(failedPermissions, " "));
|
||||
} catch (InvalidUsageException e) {
|
||||
if (e.isFullHelpSuggested()) {
|
||||
finalActor.print(BBC.getPrefix() + ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)));
|
||||
finalActor.printRaw(BBC.getPrefix() + ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("", ""), locals)));
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(message);
|
||||
@ -414,7 +417,7 @@ public final class CommandManager {
|
||||
finalActor.printRaw(t.getClass().getName() + ": " + t.getMessage());
|
||||
log.log(Level.SEVERE, "An unexpected error occurred while handling a FAWE command", t);
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
} catch (Throwable e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
finalActor.printError(e.getMessage());
|
||||
|
@ -43,7 +43,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||
*/
|
||||
public abstract class AbstractDelegateExtent implements LightingExtent {
|
||||
public class AbstractDelegateExtent implements LightingExtent {
|
||||
|
||||
private final Extent extent;
|
||||
|
||||
@ -52,7 +52,7 @@ public abstract class AbstractDelegateExtent implements LightingExtent {
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
protected AbstractDelegateExtent(Extent extent) {
|
||||
public AbstractDelegateExtent(Extent extent) {
|
||||
checkNotNull(extent);
|
||||
this.extent = extent;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.sk89q.worldedit.function.pattern;
|
||||
|
||||
import com.boydti.fawe.object.collection.RandomCollection;
|
||||
import com.boydti.fawe.object.random.SimpleRandom;
|
||||
import com.boydti.fawe.object.random.TrueRandom;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
@ -18,10 +20,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public class RandomPattern extends AbstractPattern {
|
||||
|
||||
private final SimpleRandom random;
|
||||
private Map<Pattern, Double> weights = new HashMap<>();
|
||||
private RandomCollection<Pattern> collection;
|
||||
private LinkedHashSet<Pattern> patterns = new LinkedHashSet<>();
|
||||
|
||||
public RandomPattern() {
|
||||
this(new TrueRandom());
|
||||
}
|
||||
|
||||
public RandomPattern(SimpleRandom random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pattern to the weight list of patterns.
|
||||
*
|
||||
@ -34,7 +45,7 @@ public class RandomPattern extends AbstractPattern {
|
||||
public void add(Pattern pattern, double chance) {
|
||||
checkNotNull(pattern);
|
||||
weights.put(pattern, chance);
|
||||
collection = RandomCollection.of(weights);
|
||||
collection = RandomCollection.of(weights, random);
|
||||
this.patterns.add(pattern);
|
||||
}
|
||||
|
||||
@ -42,32 +53,18 @@ public class RandomPattern extends AbstractPattern {
|
||||
return patterns;
|
||||
}
|
||||
|
||||
public RandomCollection<Pattern> getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
return collection.next().apply(position);
|
||||
public BaseBlock apply(Vector get) {
|
||||
return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector set, Vector get) throws WorldEditException {
|
||||
return collection.next().apply(extent, set, get);
|
||||
}
|
||||
|
||||
private static class Chance {
|
||||
private Pattern pattern;
|
||||
private double chance;
|
||||
|
||||
private Chance(Pattern pattern, double chance) {
|
||||
this.pattern = pattern;
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public Pattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, set, get);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -26,6 +26,7 @@ import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.command.MethodCommands;
|
||||
import com.sk89q.worldedit.util.auth.Authorizer;
|
||||
import com.sk89q.worldedit.util.auth.NullAuthorizer;
|
||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||
@ -156,8 +157,11 @@ public class ParametricBuilder {
|
||||
for (Method method : object.getClass().getDeclaredMethods()) {
|
||||
Command definition = method.getAnnotation(Command.class);
|
||||
if (definition != null) {
|
||||
definition = Commands.translate(definition);
|
||||
definition = Commands.translate(method.getDeclaringClass(), definition);
|
||||
CommandCallable callable = build(object, method, definition);
|
||||
if (object instanceof MethodCommands) {
|
||||
((MethodCommands) object).register(method, callable, dispatcher);
|
||||
}
|
||||
dispatcher.registerCommand(callable, definition.aliases());
|
||||
}
|
||||
}
|
||||
|
@ -241,21 +241,22 @@ public class ParametricCallable implements CommandCallable {
|
||||
}
|
||||
|
||||
// Execute!
|
||||
method.invoke(object, args);
|
||||
Object result = method.invoke(object, args);
|
||||
|
||||
// postInvoke handlers
|
||||
for (InvokeHandler handler : handlers) {
|
||||
handler.postInvoke(handler, method, parameters, args, context);
|
||||
}
|
||||
return result;
|
||||
} catch (MissingParameterException e) {
|
||||
throw new InvalidUsageException("Too few parameters!", this);
|
||||
throw new InvalidUsageException("Too few parameters!", this, true);
|
||||
} catch (UnconsumedParameterException e) {
|
||||
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this);
|
||||
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this, true);
|
||||
} catch (ParameterException e) {
|
||||
assert parameter != null;
|
||||
String name = parameter.getName();
|
||||
|
||||
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this);
|
||||
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this, true);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof CommandException) {
|
||||
throw (CommandException) e.getCause();
|
||||
@ -264,8 +265,6 @@ public class ParametricCallable implements CommandCallable {
|
||||
} catch (Throwable t) {
|
||||
throw new WrappedCommandException(t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
|
Loading…
Reference in New Issue
Block a user