Reimplement l2d, l3d, existing and buffer pattern (#684)

* Reimplement l2d, l3d, existing and buffer pattern
Also smaller translation improvements and cleanup

* Allow aliases in RichParser
This commit is contained in:
Hannes Greule 2020-10-08 17:39:15 +02:00 committed by GitHub
parent 116c5d17c5
commit 4407749219
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 395 additions and 89 deletions

View File

@ -10,14 +10,18 @@ import com.sk89q.worldedit.world.block.BaseBlock;
public class Linear2DBlockPattern extends AbstractPattern {
private final Pattern[] patternsArray;
private final int xScale;
private final int zScale;
public Linear2DBlockPattern(Pattern[] patterns) {
public Linear2DBlockPattern(Pattern[] patterns, int xScale, int zScale) {
this.patternsArray = patterns;
this.xScale = xScale;
this.zScale = zScale;
}
@Override
public BaseBlock apply(BlockVector3 position) {
int index = (position.getBlockX() + position.getBlockZ()) % patternsArray.length;
int index = (position.getBlockX() / this.xScale + position.getBlockZ() / this.zScale) % patternsArray.length;
if (index < 0) {
index += patternsArray.length;
}
@ -26,7 +30,7 @@ public class Linear2DBlockPattern extends AbstractPattern {
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
int index = (get.getBlockX() + get.getBlockZ()) % patternsArray.length;
int index = (get.getBlockX() / this.xScale + get.getBlockZ() / this.zScale) % patternsArray.length;
if (index < 0) {
index += patternsArray.length;
}

View File

@ -10,14 +10,21 @@ import com.sk89q.worldedit.world.block.BaseBlock;
public class Linear3DBlockPattern extends AbstractPattern {
private final Pattern[] patternsArray;
private final int xScale;
private final int yScale;
private final int zScale;
public Linear3DBlockPattern(Pattern[] patterns) {
public Linear3DBlockPattern(Pattern[] patterns, int xScale, int yScale, int zScale) {
this.patternsArray = patterns;
this.xScale = xScale;
this.yScale = yScale;
this.zScale = zScale;
}
@Override
public BaseBlock apply(BlockVector3 position) {
int index = (position.getBlockX() + position.getBlockY() + position.getBlockZ()) % patternsArray.length;
int index = (position.getBlockX() / this.xScale
+ position.getBlockY() / this.yScale + position.getBlockZ() / this.zScale) % patternsArray.length;
if (index < 0) {
index += patternsArray.length;
}
@ -26,7 +33,8 @@ public class Linear3DBlockPattern extends AbstractPattern {
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
int index = (get.getBlockX() + get.getBlockY() + get.getBlockZ()) % patternsArray.length;
int index = (get.getBlockX() / this.xScale
+ get.getBlockY() / this.yScale + get.getBlockZ() / this.zScale) % patternsArray.length;
if (index < 0) {
index += patternsArray.length;
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.util;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.NamespacedRegistry;
import com.sk89q.worldedit.registry.Registry;
@ -35,6 +36,7 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static org.enginehub.piston.converter.SuggestionHelper.byPrefix;
@ -173,4 +175,57 @@ public final class SuggestionHelper {
Predicate<String> search = byPrefix(input.toLowerCase(Locale.ROOT));
return registry.keySet().stream().filter(search);
}
/**
* Returns a stream of suggestions for positive doubles.
*
* @param argumentInput the given input to filter with.
* @return a stream of suggestions.
*/
public static Stream<String> suggestPositiveDoubles(String argumentInput) {
if (argumentInput.isEmpty()) {
return Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9");
}
// if already a valid number, suggest more digits
if (isDouble(argumentInput)) {
Stream<String> numbers = Stream.of("", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
if (argumentInput.indexOf('.') == -1) {
numbers = Stream.concat(numbers, Stream.of("."));
}
return numbers.map(s -> argumentInput + s);
}
// no valid input anymore
return Stream.empty();
}
/**
* Returns a stream of suggestions for positive integers.
*
* @param argumentInput the given input to filter with.
* @return a stream of suggestions.
*/
public static Stream<String> suggestPositiveIntegers(String argumentInput) {
if (argumentInput.isEmpty()) {
return IntStream.rangeClosed(1, 9).mapToObj(Integer::toString);
}
if (MathMan.isInteger(argumentInput)) {
return IntStream.rangeClosed(0, 9).mapToObj(Integer::toString).map(s -> argumentInput + s);
}
// no valid input anymore
return Stream.empty();
}
private static boolean isDouble(String input) {
boolean point = false;
for (char c : input.toCharArray()) {
if (!Character.isDigit(c)) {
if (c == '.' && !point) {
point = true;
} else {
return false;
}
}
}
return true;
}
}

View File

@ -22,7 +22,11 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BiomePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.BufferedPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ExistingPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.Linear2DPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.Linear3DPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.PerlinPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
@ -66,6 +70,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
register(new PerlinPatternParser(worldEdit));
register(new RidgedMultiFractalPatternParser(worldEdit));
register(new BiomePatternParser(worldEdit));
register(new Linear2DPatternParser(worldEdit));
register(new Linear3DPatternParser(worldEdit));
register(new BufferedPatternParser(worldEdit));
register(new ExistingPatternParser(worldEdit));
}
}

View File

@ -1,5 +1,6 @@
package com.sk89q.worldedit.extension.factory.parser;
import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -7,8 +8,10 @@ import com.sk89q.worldedit.internal.registry.InputParser;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
@ -18,52 +21,76 @@ import java.util.stream.Stream;
* @param <E> the parse result.
*/
public abstract class RichParser<E> extends InputParser<E> {
private final String prefix;
private final String required;
private final String[] prefixes;
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
* @param prefix the prefix of this parser result.
* @param aliases the prefix of this parser result.
*/
protected RichParser(WorldEdit worldEdit, String prefix) {
protected RichParser(WorldEdit worldEdit, String... aliases) {
super(worldEdit);
this.prefix = prefix;
this.required = prefix + "[";
Preconditions.checkArgument(aliases.length >= 1, "Aliases may not be empty");
this.prefixes = aliases;
}
@Override
public Stream<String> getSuggestions(String input) {
// we don't even want to start suggesting if it's not meant to be this parser result
if (input.length() >= this.required.length() && !input.startsWith(this.required)) {
return Stream.empty();
@NotNull
private static Predicate<String> validPrefix(String other) {
return prefix -> {
if (prefix.length() > other.length()) {
return prefix.startsWith(other);
}
// suggest until the first [ as long as it isn't fully typed
if (input.length() < this.required.length()) {
return Stream.of(this.required).filter(s -> s.startsWith(input));
return other.startsWith(prefix);
};
}
// we know that it is at least "<required>"
String[] strings = extractArguments(input.substring(this.prefix.length()), false);
@NotNull
private Function<String, Stream<? extends String>> extractArguments(String input) {
return prefix -> {
if (input.length() > prefix.length()) {
// input already contains argument(s) -> extract them
String[] strings = extractArguments(input.substring(prefix.length()), false);
// rebuild the argument string without the last argument
StringBuilder builder = new StringBuilder();
for (int i = 0; i < strings.length - 1; i++) {
builder.append('[').append(strings[i]).append(']');
}
String previous = this.prefix + builder;
return getSuggestions(strings[strings.length - 1], strings.length - 1).map(s -> previous + "[" + s + "]");
String previous = prefix + builder;
// read the suggestions for the last argument
return getSuggestions(strings[strings.length - 1], strings.length - 1)
.map(suggestion -> previous + "[" + suggestion);
} else {
return Stream.of(prefix);
}
};
}
public String getPrefix() {
return this.prefixes[0];
}
@Override
public Stream<String> getSuggestions(String input) {
return Arrays.stream(this.prefixes)
.filter(validPrefix(input))
.flatMap(extractArguments(input));
}
@Override
public E parseFromInput(String input, ParserContext context) throws InputParseException {
if (!input.startsWith(this.prefix)) {
return null;
for (String prefix : this.prefixes) {
if (!input.startsWith(prefix)) {
continue;
}
if (input.length() < this.prefix.length()) {
return null;
if (input.length() < prefix.length()) {
continue;
}
String[] arguments = extractArguments(input.substring(prefix.length()), true);
return parseFromInput(arguments, context);
}
return null;
}
/**
* Returns a stream of suggestions for the argument at the given index.
@ -118,40 +145,4 @@ public abstract class RichParser<E> extends InputParser<E> {
}
return arguments.toArray(new String[0]);
}
/**
* Returns a stream of suggestions for positive doubles.
*
* @param argumentInput the given input to filter with.
* @return a stream of suggestions.
*/
protected Stream<String> suggestPositiveDoubles(String argumentInput) {
if (argumentInput.isEmpty()) {
return Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9");
}
// if already a valid number, suggest more digits
if (isDouble(argumentInput)) {
Stream<String> numbers = Stream.of("", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
if (argumentInput.indexOf('.') == -1) {
numbers = Stream.concat(numbers, Stream.of("."));
}
return numbers.map(s -> argumentInput + s);
}
// no valid input anymore
return Stream.empty();
}
private static boolean isDouble(String input) {
boolean point = false;
for (char c : input.toCharArray()) {
if (!Character.isDigit(c)) {
if (c == '.' && !point) {
point = true;
} else {
return false;
}
}
}
return true;
}
}

View File

@ -3,6 +3,7 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.AdjacentAnyMask;
import com.boydti.fawe.object.mask.AdjacentMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -22,7 +23,7 @@ public class AdjacentMaskParser extends RichParser<Mask> {
if (index == 0) {
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
} else if (index == 1 || index == 2) {
return this.suggestPositiveDoubles(argumentInput);
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}

View File

@ -2,10 +2,13 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.AngleMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
@ -21,7 +24,7 @@ public class AngleMaskParser extends RichParser<Mask> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
@ -37,7 +40,7 @@ public class AngleMaskParser extends RichParser<Mask> {
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
if (degree ^ maxArg.endsWith("d")) {
throw new InputParseException("Cannot combine degree with block-step");
throw new InputParseException(TranslatableComponent.of("fawe.error.mask.angle"));
}
boolean overlay = false;
if (arguments.length > 2) {
@ -46,7 +49,8 @@ public class AngleMaskParser extends RichParser<Mask> {
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
throw new InputParseException(TranslatableComponent.of("fawe.error.invalid-flag",
TextComponent.of(flag)));
}
}
}

View File

@ -2,10 +2,13 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.ExtremaMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
@ -21,7 +24,7 @@ public class ExtremaMaskParser extends RichParser<Mask> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
@ -37,7 +40,7 @@ public class ExtremaMaskParser extends RichParser<Mask> {
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
if (degree ^ maxArg.endsWith("d")) {
throw new InputParseException("Cannot combine degree with block-step");
throw new InputParseException(TranslatableComponent.of("fawe.error.mask.angle"));
}
double min;
double max;
@ -48,7 +51,8 @@ public class ExtremaMaskParser extends RichParser<Mask> {
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
throw new InputParseException(TranslatableComponent.of("fawe.error.invalid-flag",
TextComponent.of(flag)));
}
}
}

View File

@ -2,10 +2,13 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.ROCAngleMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
@ -21,7 +24,7 @@ public class ROCAngleMaskParser extends RichParser<Mask> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
@ -37,7 +40,7 @@ public class ROCAngleMaskParser extends RichParser<Mask> {
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
if (degree ^ maxArg.endsWith("d")) {
throw new InputParseException("Cannot combine degree with block-step");
throw new InputParseException(TranslatableComponent.of("fawe.error.mask.angle"));
}
double min;
double max;
@ -48,7 +51,8 @@ public class ROCAngleMaskParser extends RichParser<Mask> {
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
throw new InputParseException(TranslatableComponent.of("fawe.error.invalid-flag",
TextComponent.of(flag)));
}
}
}

View File

@ -2,6 +2,7 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.RadiusMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -19,7 +20,7 @@ public class RadiusMaskParser extends RichParser<Mask> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput);
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}

View File

@ -2,6 +2,7 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.SimplexMask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -20,7 +21,7 @@ public class SimplexMaskParser extends RichParser<Mask> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index < 3) {
suggestPositiveDoubles(argumentInput);
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}

View File

@ -0,0 +1,43 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.object.pattern.BufferedPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class BufferedPatternParser extends RichParser<Pattern> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public BufferedPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#buffer");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 1) {
throw new InputParseException(TranslatableComponent.of("fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
return new BufferedPattern(context.requireActor(), inner);
}
}

View File

@ -0,0 +1,29 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.object.pattern.ExistingPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import java.util.Collections;
import java.util.List;
public class ExistingPatternParser extends SimpleInputParser<Pattern> {
private final List<String> aliases = Collections.singletonList("#existing");
public ExistingPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return this.aliases;
}
@Override
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
return new ExistingPattern(context.requireExtent());
}
}

View File

@ -0,0 +1,71 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.object.pattern.Linear2DBlockPattern;
import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.stream.Stream;
public class Linear2DPatternParser extends RichParser<Pattern> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public Linear2DPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#linear2d", "#l2d");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
switch (index) {
case 0:
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
case 1:
case 2:
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
default:
return Stream.empty();
}
}
@Override
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length == 0 || arguments.length > 3) {
throw new InputParseException(TranslatableComponent.of("fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
if (inner instanceof BlockStateHolder) {
return inner;
}
int xScale = 1;
int zScale = 1;
if (arguments.length > 1) {
xScale = Integer.parseInt(arguments[1]);
Preconditions.checkArgument(xScale != 0);
}
if (arguments.length > 2) {
zScale = Integer.parseInt(arguments[2]);
Preconditions.checkArgument(zScale != 0);
}
if (inner instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns();
return new Linear2DBlockPattern(patterns.toArray(new Pattern[0]), xScale, zScale);
}
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with " + getPrefix()));
}
}

View File

@ -0,0 +1,77 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.object.pattern.Linear3DBlockPattern;
import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.stream.Stream;
public class Linear3DPatternParser extends RichParser<Pattern> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public Linear3DPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#linear3d", "#l3d");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
switch (index) {
case 0:
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
case 1:
case 2:
case 3:
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
default:
return Stream.empty();
}
}
@Override
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length == 0 || arguments.length > 4) {
throw new InputParseException(TranslatableComponent.of("fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
if (inner instanceof BlockStateHolder) {
return inner;
}
int xScale = 1;
int yScale = 1;
int zScale = 1;
if (arguments.length > 1) {
xScale = Integer.parseInt(arguments[1]);
Preconditions.checkArgument(xScale != 0);
}
if (arguments.length > 2) {
yScale = Integer.parseInt(arguments[2]);
Preconditions.checkArgument(yScale != 0);
}
if (arguments.length > 3) {
zScale = Integer.parseInt(arguments[3]);
Preconditions.checkArgument(zScale != 0);
}
if (inner instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns();
return new Linear3DBlockPattern(patterns.toArray(new Pattern[0]), xScale, yScale,zScale);
}
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with " + getPrefix()));
}
}

View File

@ -2,12 +2,15 @@ package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.object.random.NoiseRandom;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.factory.parser.RichParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.math.noise.NoiseGenerator;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.jetbrains.annotations.NotNull;
@ -35,7 +38,7 @@ public abstract class NoisePatternParser extends RichParser<Pattern> {
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return suggestPositiveDoubles(argumentInput);
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
if (index == 1) {
return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
@ -46,8 +49,8 @@ public abstract class NoisePatternParser extends RichParser<Pattern> {
@Override
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) {
if (arguments.length != 2) {
throw new InputParseException(this.name + " requires a scale and a pattern, e.g. #"
+ this.name + "[5][dirt,stone]");
throw new InputParseException(TranslatableComponent.of("fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[scale][pattern] (e.g. " + getPrefix() + "[5][dirt,stone])")));
}
double scale = parseScale(arguments[0]);
Pattern inner = worldEdit.getPatternFactory().parseFromInput(arguments[1], context);
@ -56,8 +59,8 @@ public abstract class NoisePatternParser extends RichParser<Pattern> {
} else if (inner instanceof BlockStateHolder) {
return inner; // single blocks won't have any impact on how a noise behaves
} else {
throw new InputParseException("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with #" + this.name);
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with #" + this.name));
}
}

View File

@ -102,6 +102,8 @@
"fawe.error.player.not.found": "Player not found: {0}",
"fawe.error.worldedit.some.fails": "{0} blocks weren't placed because they were outside your allowed region.",
"fawe.error.worldedit.some.fails.blockbag": "Missing blocks: {0}",
"fawe.error.mask.angle": "Cannot combine degree with block-step",
"fawe.error.invalid-flag": "The flag {0} is not applicable here",
"fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.",
"fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {2}",