Merge pull request #600 from IronApollo/mask-work

Reimplement Masks + Fixes
This commit is contained in:
Josh Knight 2020-09-08 16:21:20 -04:00 committed by GitHub
commit 4a18147125
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 336 additions and 212 deletions

View File

@ -1,8 +1,8 @@
package com.boydti.fawe.object.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.AbstractMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
@ -14,7 +14,7 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
private final CachedMask mask;
private final MutableBlockVector3 mutable;
public AdjacentAnyMask(AbstractExtentMask mask) {
public AdjacentAnyMask(Mask mask) {
this.mask = CachedMask.cache(mask);
mutable = new MutableBlockVector3();
}

View File

@ -94,32 +94,32 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
boolean aboveMin;
lastY = y;
slope =
Math.abs(getHeight(extent, x + distance, y, z) - getHeight(extent, x - distance, y, z))
* ADJACENT_MOD;
Math.abs(getHeight(extent, x + distance, y, z) - getHeight(extent, x - distance, y, z))
* ADJACENT_MOD;
if (checkFirst) {
if (slope >= min) {
return lastValue = true;
}
slope = Math.max(slope, Math.abs(
getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance))
* ADJACENT_MOD);
getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance))
* ADJACENT_MOD);
slope = Math.max(slope, Math.abs(
getHeight(extent, x + distance, y, z + distance) - getHeight(extent,
x - distance, y, z - distance)) * DIAGONAL_MOD);
getHeight(extent, x + distance, y, z + distance) - getHeight(extent,
x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(
getHeight(extent, x - distance, y, z + distance) - getHeight(extent,
x + distance, y, z - distance)) * DIAGONAL_MOD);
getHeight(extent, x - distance, y, z + distance) - getHeight(extent,
x + distance, y, z - distance)) * DIAGONAL_MOD);
return lastValue = (slope >= min);
} else {
slope = Math.max(slope, Math.abs(
getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance))
* ADJACENT_MOD);
getHeight(extent, x, y, z + distance) - getHeight(extent, x, y, z - distance))
* ADJACENT_MOD);
slope = Math.max(slope, Math.abs(
getHeight(extent, x + distance, y, z + distance) - getHeight(extent,
x - distance, y, z - distance)) * DIAGONAL_MOD);
getHeight(extent, x + distance, y, z + distance) - getHeight(extent,
x - distance, y, z - distance)) * DIAGONAL_MOD);
slope = Math.max(slope, Math.abs(
getHeight(extent, x - distance, y, z + distance) - getHeight(extent,
x + distance, y, z - distance)) * DIAGONAL_MOD);
getHeight(extent, x - distance, y, z + distance) - getHeight(extent,
x + distance, y, z - distance)) * DIAGONAL_MOD);
return lastValue = (slope >= min && slope <= max);
}
}
@ -166,11 +166,9 @@ public class AngleMask extends SolidBlockMask implements ResettableMask {
return false;
}
if (overlay) {
if (y < 255 && !mask.test(extent, x, y + 1, z)) {
if (y < 255 && !adjacentAir(extent, vector)) {
return lastValue = false;
}
} else if (!adjacentAir(extent, vector)) {
return false;
}
return testSlope(extent, x, y, z);
}

View File

@ -14,19 +14,19 @@ public class ROCAngleMask extends AngleMask {
int base = getHeight(extent, x, y, z);
double slope =
(getHeight(extent, x + distance, y, z) - base - (base - getHeight(extent, x - distance, y, z)))
* ADJACENT_MOD;
(getHeight(extent, x + distance, y, z) - base - (base - getHeight(extent, x - distance, y, z)))
* ADJACENT_MOD;
double tmp = (getHeight(extent, x, y, z + distance) - base - (base - getHeight(extent, x, y,
z - distance))) * ADJACENT_MOD;
z - distance))) * ADJACENT_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = (getHeight(extent, x + distance, y, z + distance) - base - (base - getHeight(extent, x - distance, y,
z - distance))) * DIAGONAL_MOD;
z - distance))) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
tmp = (getHeight(extent, x - distance, y, z + distance) - base - (base - getHeight(extent, x + distance, y,
z - distance))) * DIAGONAL_MOD;
z - distance))) * DIAGONAL_MOD;
if (Math.abs(tmp) > Math.abs(slope)) slope = tmp;
return lastValue = slope >= min && slope <= max;

View File

@ -13,9 +13,9 @@ public class SurfaceMask extends AdjacentAnyMask {
public static AbstractExtentMask getMask(Extent extent) {
return new BlockMaskBuilder()
.addTypes(BlockTypes.AIR, BlockTypes.CAVE_AIR, BlockTypes.VOID_AIR)
.addAll(b -> !b.getMaterial().isMovementBlocker())
.build(extent);
.addTypes(BlockTypes.AIR, BlockTypes.CAVE_AIR, BlockTypes.VOID_AIR)
.addAll(b -> !b.getMaterial().isMovementBlocker())
.build(extent);
}
@Override

View File

@ -65,18 +65,6 @@
// public MaskCommands(WorldEdit worldEdit) {
// this.worldEdit = worldEdit;
// }
//
// @Command(
// name = "#simplex",
// desc = "Use simplex noise as the mask"
// )
// public Mask simplex(@Arg(desc = "double scale") double scale, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// scale = 1d / Math.max(1, scale);
// minInt = (minInt - 50) / 50;
// maxInt = (maxInt - 50) / 50;
// return new SimplexMask(scale, minInt, maxInt);
// }
//
// @Command(
// name = "#light",
// desc = "Restrict to specific light levels"
@ -133,40 +121,7 @@
// public Mask nolight(Extent extent) {
// return new LightMask(extent, 0, 0);
// }
//
// @Command(
// name = "#region",
// aliases = {"#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(
// name = "#xaxis",
// desc = "Restrict to initial x axis"
// )
// public Mask xaxis() {
// return new XAxisMask();
// }
//
// @Command(
// name = "#yaxis",
// desc = "Restrict to initial y axis"
// )
// public Mask yaxis() {
// return new YAxisMask();
// }
//
// @Command(
// name = "#zaxis",
// desc = "Restrict to initial z axis"
// )
// public Mask zaxis() {
// return new ZAxisMask();
// }
//
// @Command(
// name = "#iddata",
// desc = "Restrict to initial block id and data"
@ -174,132 +129,4 @@
// public Mask iddata(Extent extent) {
// return new IdDataMask(extent);
// }
//
// @Command(
// name = "#wall",
// desc = "Restrict to walls (any block n,e,s,w of air)"
// )
// public Mask wall(Extent extent) {
// Mask blockMask = air(extent);
// return new MaskUnion(new ExistingBlockMask(extent), new WallMask(blockMask, 1, 8));
// }
//
// @Command(
// name = "#surface",
// desc = "Restrict to surfaces (any solid block touching air)"
// )
// public Mask surface(Extent extent) {
// return new SurfaceMask(extent);
// }
//
// @Command(
// name = "\\",
// aliases = {"/", "#angle", "#\\", "#/"},
// desc = "Restrict to specific terrain angle",
// descFooter = "Restrict to specific terrain angle\n" +
// "The -o flag will only overlay\n" +
// "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"
//)
// public Mask angle(Extent extent, @Arg(name="min", desc = "min angle") String minStr, @Arg(name="max", desc = "max angle") String maxStr, @Switch(name = 'o', desc = "TODO") boolean overlay, @Arg(name = "distance", desc = "int", def = "1") int distanceOpt) throws ExpressionException {
// double y1, y2;
// boolean override;
// if (maxStr.endsWith("d")) {
// double y1d = Expression.compile(minStr.substring(0, minStr.length() - 1)).evaluate();
// double y2d = Expression.compile(maxStr.substring(0, maxStr.length() - 1)).evaluate();
// y1 = Math.tan(y1d * (Math.PI / 180));
// y2 = Math.tan(y2d * (Math.PI / 180));
// } else {
// y1 = Expression.compile(minStr).evaluate();
// y2 = Expression.compile(maxStr).evaluate();
// }
// return new AngleMask(extent, y1, y2, overlay, distanceOpt);
// }
//
// @Command(
// name = "(",
// aliases = {")", "#roc", "#(", "#)"},
// desc = "Restrict to near specific terrain slope rate of change",
// descFooter = "Restrict to near specific terrain slope rate of change\n" +
// "The -o flag will only overlay\n" +
// "Example: ([0d][45d][5]\n" +
// "Explanation: Restrict near where the angle changes between 0-45 degrees within 5 blocks\n" +
// "Note: Use negatives for decreasing slope"
//)
// public Mask roc(Extent extent, @Arg(name="min", desc = "min angle") String minStr, @Arg(name="max", desc = "max angle") String maxStr, @Switch(name = 'o', desc = "TODO") boolean overlay, @Arg(name = "distance", desc = "int", def = "4") int distanceOpt) throws ExpressionException {
// double y1, y2;
// boolean override;
// if (maxStr.endsWith("d")) {
// double y1d = Expression.compile(minStr.substring(0, minStr.length() - 1)).evaluate();
// double y2d = Expression.compile(maxStr.substring(0, maxStr.length() - 1)).evaluate();
// y1 = Math.tan(y1d * (Math.PI / 180));
// y2 = Math.tan(y2d * (Math.PI / 180));
// } else {
// y1 = Expression.compile(minStr).evaluate();
// y2 = Expression.compile(maxStr).evaluate();
// }
// return new ROCAngleMask(extent, y1, y2, overlay, distanceOpt);
// }
//
// @Command(
// name = "^",
// aliases = {"#extrema", "#^"},
// desc = "Restrict to near specific terrain extrema",
// descFooter = "Restrict to near specific terrain extrema\n" +
// "The -o flag will only overlay\n" +
// "Example: ([0d][45d][5]\n" +
// "Explanation: Restrict to near 45 degrees of local maxima\n" +
// "Note: Use negatives for local minima"
//)
// public Mask extrema(Extent extent, @Arg(name="min", desc = "min angle") String minStr, @Arg(name="max", desc = "max angle") String maxStr, @Switch(name = 'o', desc = "TODO") boolean overlay, @Arg(name = "distance", desc = "int", def = "4") int distanceOpt) throws ExpressionException {
// double y1, y2;
// boolean override;
// if (maxStr.endsWith("d")) {
// double y1d = Expression.compile(minStr.substring(0, minStr.length() - 1)).evaluate();
// double y2d = Expression.compile(maxStr.substring(0, maxStr.length() - 1)).evaluate();
// y1 = Math.tan(y1d * (Math.PI / 180));
// y2 = Math.tan(y2d * (Math.PI / 180));
// } else {
// y1 = Expression.compile(minStr).evaluate();
// y2 = Expression.compile(maxStr).evaluate();
// }
// return new ExtremaMask(extent, y1, y2, overlay, distanceOpt);
// }
//
// @Command(
// name = "{",
// aliases = {"#{"},
// desc = "Restricts blocks to within a specific radius range of the initial block"
//)
// public Mask radius(@Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) throws ExpressionException {
// return new RadiusMask((int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "|",
// aliases = {"#|", "#side"},
// desc = "sides with a specific number of other blocks"
//)
// public Mask wall(@Arg(desc = "Mask") Mask mask, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) throws ExpressionException {
// return new WallMask(mask, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "~",
// aliases = {"#~", "#adjacent"},
// desc = "Adjacent to a specific number of other blocks"
//)
// public Mask adjacent(@Arg(desc = "Mask") Mask mask, @Arg(name = "min", desc = "double", def = "-1") double min, @Arg(name = "max", desc = "double", def = "-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);
// }
//
//}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.mask.AdjacentMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.AirMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.AngleMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BiomeMaskParser;
@ -28,16 +29,20 @@ import com.sk89q.worldedit.extension.factory.parser.mask.BlockStateMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.BlocksMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ExistingMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ExpressionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ExtremaMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.FalseMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.LazyRegionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.LiquidMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.NegateMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ROCAngleMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.SimplexMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.SurfaceMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.TrueMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.WallMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.XAxisMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.YAxisMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.ZAxisMaskParser;
@ -82,15 +87,21 @@ public final class MaskFactory extends AbstractFactory<Mask> {
register(new BlockCategoryMaskParser(worldEdit));
register(new BiomeMaskParser(worldEdit));
// Mask Parsers from FAWE
register(new FalseMaskParser(worldEdit));
register(new TrueMaskParser(worldEdit));
register(new AdjacentMaskParser(worldEdit));
register(new AirMaskParser(worldEdit));
register(new AngleMaskParser(worldEdit));
register(new ExtremaMaskParser(worldEdit));
register(new FalseMaskParser(worldEdit));
register(new LiquidMaskParser(worldEdit));
//register(new RadiusMaskParser(worldEdit)); TODO: Adapt to work with FAWE's Chunk I/O
register(new ROCAngleMaskParser(worldEdit));
register(new SimplexMaskParser(worldEdit));
register(new SurfaceMaskParser(worldEdit));
register(new TrueMaskParser(worldEdit));
register(new WallMaskParser(worldEdit));
register(new XAxisMaskParser(worldEdit));
register(new YAxisMaskParser(worldEdit));
register(new ZAxisMaskParser(worldEdit));
register(new SimplexMaskParser(worldEdit));
register(new AngleMaskParser(worldEdit));
}

View File

@ -36,7 +36,7 @@ public abstract class RichParser<E> extends InputParser<E> {
@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)) {
if (input.length() >= this.required.length() && !input.startsWith(this.required)) {
return Stream.empty();
}
// suggest until the first [ as long as it isn't fully typed
@ -45,11 +45,11 @@ public abstract class RichParser<E> extends InputParser<E> {
}
// we know that it is at least "<required>"
String[] strings = extractArguments(input.substring(this.prefix.length()), false);
StringJoiner joiner = new StringJoiner(",");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < strings.length - 1; i++) {
joiner.add("[" + strings[i] + "]");
builder.append('[').append(strings[i]).append(']');
}
String previous = this.prefix + joiner;
String previous = this.prefix + builder;
return getSuggestions(strings[strings.length - 1], strings.length - 1).map(s -> previous + "[" + s + "]");
}

View File

@ -0,0 +1,45 @@
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.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 org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class AdjacentMaskParser extends RichParser<Mask> {
public AdjacentMaskParser(WorldEdit worldEdit) {
super(worldEdit, "~");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
} else if (index == 1 || index == 2) {
return this.suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}
@Override
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length == 0) return null;
Mask subMask = worldEdit.getMaskFactory().parseFromInput(arguments[0], context);
int min = arguments.length > 1 ? Integer.parseInt(arguments[1]) : -1;
int max = arguments.length > 2 ? Integer.parseInt(arguments[2]) : -1;
if (min == -1 && max == -1) {
min = 1;
max = 8;
} else if (max == -1) max = min;
if (max >= 8 && min == 1) {
return new AdjacentAnyMask(subMask);
}
return new AdjacentMask(subMask, min, max);
}
}

View File

@ -12,6 +12,8 @@ import java.util.stream.Stream;
public class AngleMaskParser extends RichParser<Mask> {
private final String[] flags = new String[]{"-o"};
public AngleMaskParser(WorldEdit worldEdit) {
super(worldEdit, "/");
}
@ -20,13 +22,15 @@ public class AngleMaskParser extends RichParser<Mask> {
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
return null;
return Stream.empty();
}
@Override
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 2) return null;
if (arguments.length < 2 || arguments.length > 2 + flags.length) return null;
String minArg = arguments[0];
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
@ -34,6 +38,17 @@ public class AngleMaskParser extends RichParser<Mask> {
throw new InputParseException("Cannot combine degree with block-step");
}
double min, max;
boolean overlay = false;
if (arguments.length > 2) {
for (int index = 2; index < 2 + flags.length; index++) {
String flag = arguments[index];
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
}
}
}
if (degree) {
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
@ -44,6 +59,6 @@ public class AngleMaskParser extends RichParser<Mask> {
max = Double.parseDouble(maxArg);
}
return new AngleMask(context.getExtent(), min, max, false, 1);
return new AngleMask(context.getExtent(), min, max, overlay, 1);
}
}

View File

@ -0,0 +1,64 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.ExtremaMask;
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.mask.Mask;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class ExtremaMaskParser extends RichParser<Mask> {
private final String[] flags = new String[]{"-o"};
public ExtremaMaskParser(WorldEdit worldEdit) {
super(worldEdit, "#extrema");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
return Stream.empty();
}
@Override
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length < 2 || arguments.length > 2 + flags.length) return null;
String minArg = arguments[0];
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
if (degree ^ maxArg.endsWith("d")) {
throw new InputParseException("Cannot combine degree with block-step");
}
double min, max;
boolean overlay = false;
if (arguments.length > 2) {
for (int index = 2; index < 2 + flags.length; index++) {
String flag = arguments[index];
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
}
}
}
if (degree) {
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
min = (Math.tan(minDeg * (Math.PI / 180)));
max = (Math.tan(maxDeg * (Math.PI / 180)));
} else {
min = Double.parseDouble(minArg);
max = Double.parseDouble(maxArg);
}
return new ExtremaMask(context.getExtent(), min, max, overlay, 4);
}
}

View File

@ -0,0 +1,64 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.ROCAngleMask;
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.mask.Mask;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class ROCAngleMaskParser extends RichParser<Mask> {
private final String[] flags = new String[]{"-o"};
public ROCAngleMaskParser(WorldEdit worldEdit) {
super(worldEdit, "#roc");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
} else if (index > 1 && index <= 1 + flags.length) {
return Stream.of(flags);
}
return Stream.empty();
}
@Override
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length < 2 || arguments.length > 2 + flags.length) return null;
String minArg = arguments[0];
String maxArg = arguments[1];
boolean degree = minArg.endsWith("d");
if (degree ^ maxArg.endsWith("d")) {
throw new InputParseException("Cannot combine degree with block-step");
}
double min, max;
boolean overlay = false;
if (arguments.length > 2) {
for (int index = 2; index < 2 + flags.length; index++) {
String flag = arguments[index];
if (flag.equals("-o")) {
overlay = true;
} else {
throw new InputParseException("The flag " + flag + " is not applicable for this mask!");
}
}
}
if (degree) {
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
min = (Math.tan(minDeg * (Math.PI / 180)));
max = (Math.tan(maxDeg * (Math.PI / 180)));
} else {
min = Double.parseDouble(minArg);
max = Double.parseDouble(maxArg);
}
return new ROCAngleMask(context.getExtent(), min, max, overlay, 4);
}
}

View File

@ -0,0 +1,34 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.RadiusMask;
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.mask.Mask;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class RadiusMaskParser extends RichParser<Mask> {
public RadiusMaskParser(WorldEdit worldEdit) {
super(worldEdit, "{");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0 || index == 1) {
return suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}
@Override
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length < 2) return null;
int min = Integer.parseInt(arguments[0]);
int max = Integer.parseInt(arguments[1]);
return new RadiusMask(min, max);
}
}

View File

@ -0,0 +1,30 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.SurfaceMask;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
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.internal.registry.SimpleInputParser;
import java.util.List;
public class SurfaceMaskParser extends SimpleInputParser<Mask> {
private final List<String> aliases = ImmutableList.of("#surface");
public SurfaceMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return aliases;
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
return new SurfaceMask(context.getExtent());
}
}

View File

@ -0,0 +1,31 @@
package com.sk89q.worldedit.extension.factory.parser.mask;
import com.boydti.fawe.object.mask.WallMask;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.List;
public class WallMaskParser extends SimpleInputParser<Mask> {
private final List<String> aliases = ImmutableList.of("#wall");
public WallMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return aliases;
}
@Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
return new MaskIntersection(new ExistingBlockMask(context.getExtent()), new WallMask(new BlockMask(context.getExtent(), BlockTypes.AIR.getDefaultState().toBaseBlock()), 1, 8));
}
}

View File

@ -321,6 +321,11 @@ public class BlockMask extends ABlockMask {
for (int i = 0; i < cloned.length; i++) {
cloned[i] = !cloned[i];
}
if(replacesAir()){
cloned[BlockTypes.AIR.getDefaultState().getOrdinal()] = false;
cloned[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] = false;
cloned[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()] = false;
}
return new BlockMask(getExtent(), cloned);
}
}