Re-implement richer mask and transform parsing (#1223)

Co-authored-by: dordsor21 <dordsor21@gmail.com>
Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
Dieser Commit ist enthalten in:
dordsor21 2021-08-16 10:03:06 +01:00 committet von GitHub
Ursprung 50137b31c4
Commit d4d98708f9
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
109 geänderte Dateien mit 4068 neuen und 2414 gelöschten Zeilen

Datei anzeigen

@ -1,114 +0,0 @@
// TODO: Ping @MattBDev to reimplement 2020-02-04
//package com.boydti.fawe.command;
//
//import com.boydti.fawe.util.StringMan;
//import com.sk89q.worldedit.WorldEdit;
//import com.sk89q.worldedit.extension.input.InputParseException;
//import com.sk89q.worldedit.extension.input.ParserContext;
//import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
//import com.sk89q.worldedit.internal.registry.InputParser;
//import org.enginehub.piston.inject.InjectedValueAccess;
//
//import java.util.*;
//
//public abstract class FaweParser<T> extends InputParser<T> {
//
// private final String prefix;
//
// protected FaweParser(WorldEdit worldEdit, String prefix) {
// super(worldEdit);
// this.prefix = prefix;
// }
//
// public PlatformCommandManager getPlatform() {
// return PlatformCommandManager.getInstance();
// }
//
// public T parse(String input, ParserContext context) {
// input = prefix + " " + input;
// InjectedValueAccess injected = context.getInjected();
// if (injected != null) {
// return getPlatform().parseCommand(input, injected);
// } else {
// return getPlatform().parseCommand(input, context.getActor());
// }
// }
//
// public T catchSuggestion(String currentInput, String nextInput, ParserContext context) throws InputParseException {
// try {
// return parseFromInput(nextInput, context);
// } catch (SuggestInputParseException e) {
// e.prepend(currentInput.substring(0, currentInput.length() - nextInput.length()));
// throw e;
// }
// }
//
// protected static class ParseEntry {
// public boolean and;
// public String input;
// public String full;
//
// public ParseEntry(String full, String input, boolean type) {
// this.full = full;
// this.input = input;
// this.and = type;
// }
//
// @Override
// public String toString() {
// return input + " | " + and;
// }
// }
//
// public static List<Map.Entry<ParseEntry, List<String>>> parse(String toParse) throws InputParseException {
// List<Map.Entry<ParseEntry, List<String>>> keys = new ArrayList<>();
// List<String> inputs = new ArrayList<>();
// List<Boolean> and = new ArrayList<>();
// int last = 0;
// outer:
// for (int i = 0; i < toParse.length(); i++) {
// char c = toParse.charAt(i);
// switch (c) {
// case ',':
// case '&':
// String result = toParse.substring(last, i);
// if (!result.isEmpty()) {
// inputs.add(result);
// and.add(c == '&');
// } else {
// throw new InputParseException("Invalid dangling character " + c);
// }
// last = i + 1;
// continue outer;
// default:
// if (c == '[' && StringMan.getMatchingBracket(c) != c) {
// int next = StringMan.findMatchingBracket(toParse, i);
// if (next != -1) {
// i = next;
// } else {
// toParse += "]";
// i = toParse.length();
// }
// continue outer;
// }
// }
// }
// inputs.add(toParse.substring(last));
// for (int i = 0; i < inputs.size(); i++) {
// String full = inputs.get(i);
// String command = full;
// List<String> args = new ArrayList<>();
// while (!command.isEmpty() && command.charAt(command.length() - 1) == ']') {
// int startPos = StringMan.findMatchingBracket(command, command.length() - 1);
// if (startPos == -1) break;
// String arg = command.substring(startPos + 1, command.length() - 1);
// args.add(arg);
// command = full.substring(0, startPos);
// }
// Collections.reverse(args);
// ParseEntry entry = new ParseEntry(full, command, i > 0 ? and.get(i - 1) : false);
// keys.add(new AbstractMap.SimpleEntry<>(entry, args));
// }
// return keys;
// }
//}

Datei anzeigen

@ -1,132 +0,0 @@
// TODO: Ping @MattBDev to reimplement (or remove because this class is stupid) 2020-02-04
//package com.fastasyncworldedit.core.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.ExtremaMask;
//import com.boydti.fawe.object.mask.LightMask;
//import com.boydti.fawe.object.mask.OpacityMask;
//import com.boydti.fawe.object.mask.ROCAngleMask;
//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.SurfaceMask;
//import com.boydti.fawe.object.mask.WallMask;
//import com.boydti.fawe.function.mask.XAxisMask;
//import com.boydti.fawe.function.mask.YAxisMask;
//import com.boydti.fawe.function.mask.ZAxisMask;
//import com.sk89q.worldedit.IncompleteRegionException;
//import com.sk89q.worldedit.LocalSession;
//import com.sk89q.worldedit.WorldEdit;
//import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
//import com.sk89q.worldedit.entity.Player;
//import com.sk89q.worldedit.extent.Extent;
//import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
//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.ExpressionEnvironment;
//import com.sk89q.worldedit.internal.expression.ExpressionException;
//import com.sk89q.worldedit.math.BlockVector3;
//import com.sk89q.worldedit.math.Vector3;
//import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
//import com.sk89q.worldedit.session.request.RequestSelection;
//import com.sk89q.worldedit.world.biome.BiomeType;
//import org.enginehub.piston.annotation.Command;
//import org.enginehub.piston.annotation.CommandContainer;
//import org.enginehub.piston.annotation.param.Arg;
//import org.enginehub.piston.annotation.param.Switch;
//
////@Command(aliases = {"masks"},
//// desc = "Help for the various masks. [More Info](https://git.io/v9r4K)",
//// descFooter = "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"
////)
//@CommandContainer//(superTypes = CommandPermissionsConditionGenerator.Registration.class)
//public class MaskCommands {
// private final WorldEdit worldEdit;
//
// public MaskCommands(WorldEdit worldEdit) {
// this.worldEdit = worldEdit;
// }
// @Command(
// name = "#light",
// desc = "Restrict to specific light levels"
// )
// public Mask light(Extent extent, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// return new LightMask(extent, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "#skylight",
// desc = "Restrict to specific sky light levels"
// )
// public Mask skylight(Extent extent, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// return new SkyLightMask(extent, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "#blocklight",
// aliases = {"#emittedlight"},
// desc = "Restrict to specific block light levels"
// )
// public Mask blocklight(Extent extent, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// return new BlockLightMask(extent, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "#opacity",
// desc = "Restrict to specific opacity levels"
// )
// public Mask opacity(Extent extent, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// return new OpacityMask(extent, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "#brightness",
// desc = "Restrict to specific block brightness"
// )
// public Mask brightness(Extent extent, @Arg(name="mine", desc = "min light") double minInt, @Arg(name="mine", desc = "max light") double maxInt) {
// return new BrightnessMask(extent, (int) minInt, (int) maxInt);
// }
//
// @Command(
// name = "#haslight",
// desc = "Restricts to blocks with light (sky or emitted)"
// )
// public Mask haslight(Extent extent) {
// return new LightMask(extent, 1, Integer.MAX_VALUE);
// }
//
// @Command(
// name = "#nolight",
// desc = "Restrict to blocks without light (sky or emitted)"
// )
// public Mask nolight(Extent extent) {
// return new LightMask(extent, 0, 0);
// }
// @Command(
// name = "#iddata",
// desc = "Restrict to initial block id and data"
// )
// public Mask iddata(Extent extent) {
// return new IdDataMask(extent);
// }
//}

Datei anzeigen

@ -1,356 +0,0 @@
// TODO: Ping @MattBDev to reimplement 2020-02-04
//package com.sk89q.worldedit.command;
//
//import com.boydti.fawe.object.DataAnglePattern;
//import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
//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.Linear2DBlockPattern;
//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.PropertyPattern;
//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.ColorUtil;
//import com.boydti.fawe.util.TextureUtil;
//import com.sk89q.worldedit.EmptyClipboardException;
//import com.sk89q.worldedit.LocalSession;
//import com.sk89q.worldedit.entity.Player;
//import com.sk89q.worldedit.extension.input.InputParseException;
//import com.sk89q.worldedit.extension.platform.Actor;
//import com.sk89q.worldedit.extent.Extent;
//import com.sk89q.worldedit.extent.clipboard.Clipboard;
//import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
//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.math.Vector3;
//import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
//import com.sk89q.worldedit.session.ClipboardHolder;
//import com.sk89q.worldedit.world.biome.BiomeType;
//import java.awt.Color;
//import java.io.IOException;
//import java.util.Collections;
//import java.util.List;
//import java.util.Set;
//import org.enginehub.piston.annotation.Command;
//import org.enginehub.piston.annotation.CommandContainer;
//import org.enginehub.piston.annotation.param.Arg;
//import org.jetbrains.annotations.Range;
//
////@Command(aliases = {"patterns"},
//// desc = "Help for the various patterns. [More Info](https://git.io/vSPmA)",
//// descFooter = "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"
////)
//@CommandContainer//(superTypes = CommandPermissionsConditionGenerator.Registration.class)
//public class PatternCommands {
//
//
// @Command(
// name = "#simplex",
// desc = "Use simplex noise to randomize blocks. Tutorial: https://imgur.com/a/rwVAE"
//)
// public Pattern simplex(@Arg(desc = "scale factor") double scale, @Arg(desc = "Pattern") 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(
// name = "#color",
// desc = "Use the block closest to a specific color"
//)
// public Pattern color(TextureUtil textureUtil, @Arg(desc = "String color") String color) {
// Color colorObj = ColorUtil.parseColor(color);
// return textureUtil.getNearestBlock(colorObj.getRGB()).getDefaultState();
// }
//
// @Command(
// name = "#anglecolor",
// desc = "A darker block based on the existing terrain angle"
//)
// public Pattern anglecolor(Extent extent, LocalSession session, @Arg(desc = "int", def = "1") int distance) {
// return new AngleColorPattern(extent, session, distance);
// }
//
// @Command(
// name = "#angledata",
// desc = "Block data based on the existing terrain angle"
// )
// public Pattern angledata(Extent extent, @Arg(desc = "int", def = "1") int distance) {
// return new DataAnglePattern(extent, distance);
// }
//
// @Command(
// name = "#saturate",
// desc = "Saturate the existing block with a color"
//)
// public Pattern saturate(Extent extent, LocalSession session, @Arg(desc = "Color code") String colorStr) {
// Color color = ColorUtil.parseColor(colorStr);
// return new SaturatePattern(extent, color.getRGB(), session);
// }
//
// @Command(
// name = "#averagecolor",
// desc = "Average between the existing block and a color"
//)
// public Pattern averagecolor(Extent extent, LocalSession session, @Arg(desc = "Color code") String colorStr) {
// Color color = ColorUtil.parseColor(colorStr);
// return new AverageColorPattern(extent, color.getRGB(), session);
// }
//
// @Command(
// name = "#desaturate",
// desc = "Desaturated color of the existing block"
//)
// public Pattern desaturate(Extent extent, LocalSession session, @Arg(desc = "double", def = "100") double percent) {
// return new DesaturatePattern(extent, percent / 100d, session);
// }
//
// @Command(
// name = "#lighten",
// desc = "Lighten the existing block"
//)
// public Pattern lighten(Extent extent, TextureUtil util) {
// return new ShadePattern(extent, false, util);
// }
//
// @Command(
// name = "#darken",
// desc = "Darken the existing block"
//)
// public Pattern darken(Extent extent, TextureUtil util) {
// return new ShadePattern(extent, true, util);
// }
//
// @Command(
// name = "#buffer",
// desc = "Only place a block once while a pattern is in use",
// descFooter = "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"
//)
// public Pattern buffer(Actor actor, @Arg(desc = "Pattern")Pattern pattern) {
// return new BufferedPattern(actor, pattern);
// }
//
// @Command(
// name = "#buffer2d",
// desc = "Only place a block once in a column while a pattern is in use"
//)
// public Pattern buffer2d(Actor actor, @Arg(desc = "Pattern")Pattern pattern) {
// return new BufferedPattern2D(actor, pattern);
// }
//
// @Command(
// name = "#iddatamask",
// desc = "Use the pattern's id and the existing blocks data with the provided mask",
// descFooter = "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"
//)
// public Pattern iddatamask(Extent extent, @Range(from = 0, to = 15) @Arg(desc = "bit mask") int bitmask, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new IdDataMaskPattern(extent, pattern, bitmask);
// }
//
// @Command(
// name = "#id",
// desc = "Only change the block id"
//)
// public Pattern id(Extent extent, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new IdPattern(extent, pattern);
// }
//
// @Command(
// name = "#data",
// desc = "Only change the block data"
//)
// public Pattern data(Extent extent, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new DataPattern(extent, pattern);
// }
//
// @Command(
// name = "#biome",
// aliases = {"$"},
// desc = "Set the biome"
//)
// public Pattern biome(Extent extent, @Arg(desc = "Biome type") BiomeType biome) {
//
// return new BiomePattern(extent, biome);
// }
//
// @Command(
// name = "#relative",
// aliases = {"#~", "#r", "#rel"},
// desc = "Offset the pattern to where you click"
//)
// public Pattern relative(@Arg(desc = "Pattern")Pattern pattern) {
//
// return new RelativePattern(pattern);
// }
//
// @Command(
// name = "#!x",
// aliases = {"#nx", "#nox"},
// desc = "The pattern will not be provided the x axis info",
// descFooter = "The pattern will not be provided the z axis info.\n" +
// "Example: #!x[#!z[#~[#l3d[pattern]]]]"
//)
// public Pattern nox(@Arg(desc = "Pattern")Pattern pattern) {
//
// return new NoXPattern(pattern);
// }
//
// @Command(
// name = "#!y",
// aliases = {"#ny", "#noy"},
// desc = "The pattern will not be provided the y axis info"
//)
// public Pattern noy(@Arg(desc = "Pattern")Pattern pattern) {
//
// return new NoYPattern(pattern);
// }
//
// @Command(
// name = "#!z",
// aliases = {"#nz", "#noz"},
// desc = "The pattern will not be provided the z axis info"
//)
// public Pattern noz(@Arg(desc = "Pattern")Pattern pattern) {
//
// return new NoZPattern(pattern);
// }
//
// @Command(
// name = "#mask",
// desc = "Apply a pattern depending on a mask"
//)
// public Pattern mask(@Arg(desc = "Mask") Mask mask, @Arg(desc = "Pattern")Pattern pass, @Arg(desc = "Pattern")Pattern fail) {
// return new MaskedPattern(mask, pass, fail);
// }
//
// @Command(
// name = "#offset",
// desc = "Offset a pattern"
//)
// public Pattern offset(@Arg(desc = "x offset") double x, @Arg(desc = "y offset") double y, @Arg(desc = "z offset") double z, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new OffsetPattern(pattern, (int) x, (int) y, (int) z);
// }
//
// @Command(
// name = "#surfacespread",
// desc = "Applies to only blocks on a surface. Selects a block from provided pattern with a given randomized offset `[0, <distance>)`. e.g., Use `#existing` to randomly offset blocks in the world, or `#copy` to offset blocks in your clipboard"
//)
// public Pattern surfacespread(@Arg(desc = "spread distance (blocks)") double distance, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new SurfaceRandomOffsetPattern(pattern, (int) distance);
// }
//
// @Command(
// name = "#solidspread",
// desc = "Randomly spread solid blocks"
//)
// public Pattern solidspread(@Arg(desc = "x offset") double x, @Arg(desc = "y offset") double y, @Arg(desc = "z offset") double z, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new SolidRandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
// }
//
// @Command(
// name = "#spread",
// aliases = {"#randomoffset"},
// desc = "Randomly spread blocks"
//)
// public Pattern spread(@Arg(desc = "x offset") double x, @Arg(desc = "y offset") double y, @Arg(desc = "z offset") double z, @Arg(desc = "Pattern")Pattern pattern) {
//
// return new RandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
// }
//
// @Command(
// name = "#linear",
// aliases = {"#l"},
// desc = "Sequentially set blocks from a list of patterns"
//)
// public Pattern linear(@Arg(desc = "Pattern") Pattern other) {
//
// if (other instanceof RandomPattern) {
// Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
// return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
// }
// return other;
// }
//
// @Command(
// name = "#linear3d",
// aliases = {"#l3d"},
// desc = "Use the x,y,z coordinate to pick a block from the list"
//)
// public Pattern linear3d(@Arg(desc = "Pattern") Pattern other) {
//
// if (other instanceof RandomPattern) {
// Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
// return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
// }
// return other;
// }
//
// @Command(
// name = "#linear2d",
// aliases = {"#l2d"},
// desc = "Use the x,z coordinate to pick a block from the list"
//)
// public Pattern linear2d(@Arg(desc = "Pattern") Pattern other) {
//
// if (other instanceof RandomPattern) {
// Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
// return new Linear2DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
// }
// return other;
// }
//
// @Command(
// name = "=",
// aliases = {"#=", "#expression"},
// desc = "Expression pattern: http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax"
//)
// public Pattern expression(Extent extent, @Arg(desc = "Expression") String input) throws ExpressionException {
//
// Expression exp = Expression.compile(input, "x", "y", "z");
// WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(extent, Vector3.ONE, Vector3.ZERO);
// exp.setEnvironment(env);
// return new ExpressionPattern(exp);
// }
//}

Datei anzeigen

@ -1,105 +0,0 @@
// TODO: Ping @MattBDev to reimplement 2020-02-04
//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.worldedit.LocalSession;
//import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
//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 java.util.Set;
//import org.enginehub.piston.annotation.Command;
//import org.enginehub.piston.annotation.CommandContainer;
//import org.enginehub.piston.annotation.param.Arg;
//
//@CommandContainer//(superTypes = CommandPermissionsConditionGenerator.Registration.class)
//public class TransformCommands {
//
// @Command(
// name = "#linear",
// aliases = {"#l"},
// desc = "Sequentially pick from a list of transform"
// )
// public ResettableExtent linear(Actor actor, LocalSession session, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// if (other instanceof RandomTransform) {
// Set<ResettableExtent> extents = ((RandomTransform) other).getExtents();
// return new LinearTransform(extents.toArray(new ResettableExtent[0]));
// }
// return other;
// }
//
// @Command(
// name = "#linear3d",
// aliases = {"#l3d"},
// desc = "Use the x,y,z coordinate to pick a transform from the list"
// )
// public ResettableExtent linear3d(Actor actor, LocalSession session, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// if (other instanceof RandomTransform) {
// Set<ResettableExtent> extents = ((RandomTransform) other).getExtents();
// return new Linear3DTransform(extents.toArray(new ResettableExtent[0]));
// }
// return other;
// }
//
// @Command(
// name = "#pattern",
// desc = "Always use a specific pattern"
// )
// public ResettableExtent pattern(Actor actor, LocalSession session, @Arg(desc = "Pattern") Pattern pattern, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// return new PatternTransform(other, pattern);
// }
//
// @Command(
// name = "#offset",
// desc = "Offset transform"
// )
// public ResettableExtent offset(Actor actor, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// return new OffsetExtent(other, (int) x, (int) y, (int) z);
// }
//
// @Command(
// name = "#spread",
// aliases = {"#randomoffset"},
// desc = "Random offset transform"
//)
// public ResettableExtent randomOffset(Actor actor, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// return new RandomOffsetTransform(other, (int) x, (int) y, (int) z);
// }
//
// @Command(
// name = "#scale",
// desc = "All changes will be scaled"
// )
// public ResettableExtent scale(Actor actor, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// return new ScaleTransform(other, x, y, z);
// }
//
// @Command(
// name = "#rotate",
// desc = "All changes will be rotate around the initial position"
// )
// public ResettableExtent rotate(Player player, LocalSession session, double x, double y, double z, @Arg(name = "other", desc = "ResettableExtent", def = "#null") ResettableExtent other) {
// ExtentTraverser<TransformExtent> traverser = new ExtentTraverser<>(other).find(TransformExtent.class);
// BlockTransformExtent affine = traverser != null ? traverser.get() : null;
// if (affine == null) {
// other = affine = new TransformExtent(other);
// }
// AffineTransform transform = (AffineTransform) affine.getTransform();
// transform = transform.rotateX(x);
// transform = transform.rotateY(y);
// transform = transform.rotateZ(z);
// affine.setTransform(transform);
// return other;
// }
//}

Datei anzeigen

@ -18,6 +18,8 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.awt.image.BufferedImage;
import java.io.IOException;
@ -54,8 +56,14 @@ public class ImageBrush implements Brush {
default:
BlockState block = extent.getBlock(pos);
TextureUtil tu = session.getTextureUtil();
int existingColor = tu.getColor(block.getBlockType());
return tu.combineTransparency(color, existingColor);
BlockType type = block.getBlockType();
int existingColor;
if (type == BlockTypes.GRASS_BLOCK) {
existingColor = tu.getColor(extent.getBiome(pos));
} else {
existingColor = tu.getColor(type);
}
return TextureUtil.combineTransparency(color, existingColor);
}
};

Datei anzeigen

@ -1,136 +0,0 @@
// TODO: Ping @MattBDev to reimplement 2020-02-04
//package com.sk89q.worldedit.extension.factory;
//
//import com.boydti.fawe.command.FaweParser;
//import com.boydti.fawe.command.SuggestInputParseException;
//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.google.common.collect.Iterables;
//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.expression.Expression;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//
//public class DefaultTransformParser extends FaweParser<ResettableExtent> {
//
// public DefaultTransformParser(WorldEdit worldEdit) {
// super(worldEdit, "transforms");
// }
//
// @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;
// double chance = 1;
// if (command.isEmpty()) {
// transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
// } else {
// List<String> args = entry.getValue();
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
// try {
// transform = parse(command + cmdArgs, context);
// } catch (SuggestInputParseException rethrow) {
// throw rethrow;
// } catch (Throwable e) {
// throw new NoMatchException("See: //transforms");
// }
// if (transform == 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");
// }
// }
// 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;
// }
// }
//
//
//}

Datei anzeigen

@ -0,0 +1,144 @@
package com.fastasyncworldedit.core.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.transform.RichTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.Linear3DTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.LinearTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.OffsetTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.PatternTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.RandomTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.RotateTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.ScaleTransformParser;
import com.fastasyncworldedit.core.extension.factory.parser.transform.SpreadTransformParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.RandomTransform;
import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.sk89q.worldedit.WorldEdit;
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.internal.registry.AbstractFactory;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.ArrayList;
import java.util.List;
public class TransformFactory extends AbstractFactory<ResettableExtent> {
private final RichTransformParser richTransformParser;
/**
* Create a new factory.
*
* @param worldEdit the WorldEdit instance
*/
public TransformFactory(WorldEdit worldEdit) {
super(worldEdit, new NullTransformParser(worldEdit));
richTransformParser = new RichTransformParser(worldEdit);
// split and parse each sub-transform
register(new RandomTransformParser(worldEdit));
register(new OffsetTransformParser(worldEdit));
register(new ScaleTransformParser(worldEdit));
register(new RotateTransformParser(worldEdit));
register(new SpreadTransformParser(worldEdit));
register(new PatternTransformParser(worldEdit));
register(new LinearTransformParser(worldEdit));
register(new Linear3DTransformParser(worldEdit));
}
@Override
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
List<ResettableExtent> transforms = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
ResettableExtent match = richTransformParser.parseFromInput(component, context);
if (match != null) {
transforms.add(match);
continue;
}
parseFromParsers(context, transforms, component);
}
return getResettableExtent(input, transforms);
}
private void parseFromParsers(
final ParserContext context,
final List<ResettableExtent> transforms,
final String component
) {
ResettableExtent match = null;
for (InputParser<ResettableExtent> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) {
break;
}
}
if (match == null) {
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component)));
}
transforms.add(match);
}
/**
* Parses a transform without considering parsing through the {@link RichTransformParser}, therefore not accepting
* "richer" parsing where & and , are used. Exists to prevent stack overflows.
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
public ResettableExtent parseWithoutRich(String input, ParserContext context) throws InputParseException {
List<ResettableExtent> transforms = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
parseFromParsers(context, transforms, component);
}
return getResettableExtent(input, transforms);
}
private ResettableExtent getResettableExtent(final String input, final List<ResettableExtent> transforms) {
switch (transforms.size()) {
case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
case 1:
return transforms.get(0);
default:
RandomTransform randomTransform = new RandomTransform(new TrueRandom());
for (ResettableExtent transform : transforms) {
randomTransform.add(transform, 1d);
}
return randomTransform;
}
}
// TODO is there a better default?
private static final class NullTransformParser extends InputParser<ResettableExtent> {
private NullTransformParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
return null;
}
}
}

Datei anzeigen

@ -0,0 +1,14 @@
package com.fastasyncworldedit.core.extension.factory.parser;
import java.util.List;
public interface AliasedParser {
/**
* The strings this parser matches.
*
* @return the matching aliases
*/
List<String> getMatchedAliases();
}

Datei anzeigen

@ -0,0 +1,134 @@
package com.fastasyncworldedit.core.extension.factory.parser;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
import com.sk89q.worldedit.internal.registry.InputParser;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public abstract class FaweParser<T> extends InputParser<T> implements AliasedParser {
protected FaweParser(WorldEdit worldEdit) {
super(worldEdit);
}
/**
* Parse an input into a list of {@link java.util.Map.Entry} of {@link ParseEntry} and a list of the given arguments, where
* arguments are given in square brackets, e.g. {@code #offset[2][10][2]}. Different entries may be separated by , or &
* (OR and AND respectively)
*
* @param toParse the string to parse
* @return a list of parsed entries and their arguments
* @throws InputParseException if the input is not complete (has dangling characters)
*/
public static List<Map.Entry<ParseEntry, List<String>>> parse(String toParse) throws InputParseException {
List<Map.Entry<ParseEntry, List<String>>> keys = new ArrayList<>();
List<String> inputs = new ArrayList<>();
List<Boolean> and = new ArrayList<>();
int last = 0;
outer:
for (int i = 0; i < toParse.length(); i++) {
char c = toParse.charAt(i);
switch (c) {
case ',':
case '&':
String result = toParse.substring(last, i);
if (!result.isEmpty()) {
inputs.add(result);
and.add(c == '&');
} else {
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c));
}
last = i + 1;
continue outer;
default:
if (c == '[') {
int next = StringMan.findMatchingBracket(toParse, i);
if (next != -1) {
i = next;
} else {
toParse += "]";
i = toParse.length();
}
}
}
}
inputs.add(toParse.substring(last));
for (int i = 0; i < inputs.size(); i++) {
String full = inputs.get(i);
String command = full;
List<String> args = new ArrayList<>();
while (!command.isEmpty() && command.charAt(command.length() - 1) == ']') {
int startPos = StringMan.findMatchingBracket(command, command.length() - 1);
if (startPos == -1) {
break;
}
String arg = command.substring(startPos + 1, command.length() - 1);
args.add(arg);
command = full.substring(0, startPos);
}
Collections.reverse(args);
ParseEntry entry = new ParseEntry(full, command, i > 0 ? and.get(i - 1) : false);
keys.add(new AbstractMap.SimpleEntry<>(entry, args));
}
return keys;
}
protected PlatformCommandManager getPlatform() {
return PlatformCommandManager.getInstance();
}
public static class ParseEntry {
private final boolean and;
private final String input;
private final String full;
public ParseEntry(String full, String input, boolean type) {
this.full = full;
this.input = input;
this.and = type;
}
/**
* Gives if the parsed entry was appended to the original input as an AND.
*
* @return if appended to input with '&' rather than ','
*/
public boolean isAnd() {
return and;
}
/**
* The input "name" e.g. for {@code #offset[2][10][2]}, returns "offset"
*
* @return input name
*/
public String getInput() {
return input;
}
/**
* The original full input, including arguments e.g. for {@code #offset[2][10][2]}, returns "#offset[2][10][2]"
*
* @return original full input
*/
public String getFull() {
return full;
}
@Override
public String toString() {
return input + " | " + and;
}
}
}

Datei anzeigen

@ -22,7 +22,7 @@ import java.util.stream.Stream;
*
* @param <E> the parse result.
*/
public abstract class RichParser<E> extends InputParser<E> {
public abstract class RichParser<E> extends InputParser<E> implements AliasedParser {
private final String[] prefixes;
@ -51,7 +51,7 @@ public abstract class RichParser<E> extends InputParser<E> {
@Nonnull
private Function<String, Stream<? extends String>> extractArguments(String input) {
return prefix -> {
if (input.length() > prefix.length()) {
if (input.length() > prefix.length() && prefix.startsWith(input + "[")) {
// input already contains argument(s) -> extract them
String[] strings = extractArguments(input.substring(prefix.length()), false);
// rebuild the argument string without the last argument
@ -69,10 +69,24 @@ public abstract class RichParser<E> extends InputParser<E> {
};
}
/**
* Gives the default prefix/name of the pattern/mask/transform.
*
* @return default prefix
*/
public String getPrefix() {
return this.prefixes[0];
}
/**
* Return all prefix/name aliases of the pattern/mask/transform
*
* @return all prefix/name aliases
*/
public List<String> getMatchedAliases() {
return Arrays.asList(prefixes);
}
@Override
public Stream<String> getSuggestions(String input) {
return Arrays.stream(this.prefixes)
@ -140,8 +154,15 @@ public abstract class RichParser<E> extends InputParser<E> {
}
}
}
if (!requireClosing && open > 0) {
if (!requireClosing) {
if (open > 0) {
arguments.add(input.substring(openIndex + 1));
} else {
int last = input.lastIndexOf(']');
if (last != -1) {
arguments.add(input.substring(last));
}
}
}
if (requireClosing && open != 0) {
throw new InputParseException(Caption.of("fawe.error.invalid-bracketing", TextComponent.of("'[' or ']'?")));

Datei anzeigen

@ -1,189 +0,0 @@
// TODO: Ping @MattBDev to reimplement 2020-02-04
//*
//package com.fastasyncworldedit.core.extension.factory.parser.mask;
//
//import com.boydti.fawe.command.FaweParser;
//import com.boydti.fawe.command.SuggestInputParseException;
//import com.boydti.fawe.config.Caption;
//import com.boydti.fawe.util.StringMan;
//import com.sk89q.minecraft.util.commands.CommandLocals;
//import com.sk89q.worldedit.WorldEdit;
//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.function.mask.BlockMaskBuilder;
//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.session.request.Request;
//import com.sk89q.worldedit.world.block.BaseBlock;
//import com.sk89q.worldedit.world.block.BlockStateHolder;
//import com.sk89q.worldedit.world.block.BlockTypes;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
//public class DefaultMaskParser extends FaweParser<Mask> {
// public DefaultMaskParser(WorldEdit worldEdit) {
// super(worldEdit, "masks");
// }
//
// @Override
// public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
// if (input.isEmpty()) {
// throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
// }
// Extent extent = Request.request().getExtent();
// if (extent == null) extent = context.getExtent();
// List<List<Mask>> masks = new ArrayList<>();
// masks.add(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();
// final String command = pe.input;
// String full = pe.full;
// Mask mask = null;
// if (command.isEmpty()) {
// mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
// } else {
// List<String> args = entry.getValue();
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
// try {
// mask = parse(command + cmdArgs, context);
// } catch (SuggestInputParseException rethrow) {
// throw rethrow;
// } catch (Throwable e) {
// // TODO NOT IMPLEMENTED
//// throw SuggestInputParseException.of(e, full, () -> {
//// try {
//// List<String> suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals);
//// if (suggestions.size() <= 2) {
//// for (int i = 0; i < suggestions.size(); i++) {
//// String suggestion = suggestions.get(i);
//// if (suggestion.indexOf(' ') != 0) {
//// String[] split = suggestion.split(" ");
//// suggestion = "[" + StringMan.join(split, "][") + "]";
//// suggestions.set(i, suggestion);
//// }
//// }
//// }
//// return suggestions;
//// } catch (CommandException e1) {
//// throw new InputParseException(e1.getMessage());
//// } catch (Throwable e2) {
//// e2.printStackTrace();
//// throw new InputParseException(e2.getMessage());
//// }
//// });
// }
// if (mask == 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);
// }
// if (char0 == '#' || char0 == '?') {
// // TODO NOT IMPLEMENTED
//// throw new SuggestInputParseException(new NoMatchException("Unknown mask: " + full + ", See: //masks"), full,
//// () -> {
//// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
//// return dispatcher.getAliases().stream().filter(
//// s -> s.startsWith(command.toLowerCase(Locale.ROOT))
//// ).collect(Collectors.toList());
//// }
//// );
// }
// // Legacy syntax
// if (charMask) {
// switch (char0) {
// case '\\': //
// case '/': //
// case '{': //
// case '$': //
// case '%': {
// String value = command.substring(1) + ((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;
// }
// case '|':
// case '~':
// case '<':
// case '>':
// case '!':
// input = input.substring(input.indexOf(char0) + 1);
// mask = parseFromInput(char0 + "[" + input + "]", context);
// if (actor != null) {
// actor.print(Caption.of("fawe.worldedit.help.command.clarifying.bracket", char0 + "[" + input + "]"));
// }
// return mask;
// }
// }
// }
// if (mask == null) {
// if (command.startsWith("[")) {
// int end = command.lastIndexOf(']');
// mask = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
// } else {
// List<String> entries = entry.getValue();
// BlockMaskBuilder builder = new BlockMaskBuilder();
//// if (StringMan.containsAny(full, "\\^$.|?+(){}<>~$!%^&*+-/"))
// {
// try {
// builder.addRegex(full);
// } catch (InputParseException ignored) {}
// }
// if (mask == null) {
// context.setPreferringWildcard(false);
// context.setRestricted(false);
// BaseBlock block = worldEdit.getBlockFactory().parseFromInput(full, context);
// builder.add(block);
// mask = builder.build(extent);
// }
// }
// }
// }
// if (pe.and) {
// masks.add(new ArrayList<>());
// }
// masks.get(masks.size() - 1).add(mask);
// }
// } catch (InputParseException rethrow) {
// throw rethrow;
// } catch (Throwable e) {
// e.printStackTrace();
// throw new InputParseException(e.getMessage(), e);
// }
// List<Mask> maskUnions = new ArrayList<>();
// for (List<Mask> maskList : masks) {
// if (maskList.size() == 1) {
// maskUnions.add(maskList.get(0));
// } else if (maskList.size() != 0) {
// maskUnions.add(new MaskUnion(maskList));
// }
// }
// if (maskUnions.size() == 1) {
// return maskUnions.get(0);
// } else if (maskUnions.size() != 0) {
// return new MaskIntersection(maskUnions);
// } else {
// return null;
// }
//
// }
//}

Datei anzeigen

@ -0,0 +1,241 @@
package com.fastasyncworldedit.core.extension.factory.parser.mask;
import com.fastasyncworldedit.core.command.SuggestInputParseException;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.FaweParser;
import com.fastasyncworldedit.core.function.mask.BlockMaskBuilder;
import com.fastasyncworldedit.core.function.mask.MaskUnion;
import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.WorldEdit;
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.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.internal.command.CommandArgParser;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.enginehub.piston.inject.MemoizingValueAccess;
import org.enginehub.piston.suggestion.Suggestion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Attempts to parse masks given rich inputs, allowing for & and ,. Also allows for nested masks
*/
public class RichMaskParser extends FaweParser<Mask> {
/**
* New instance
*
* @param worldEdit {@link WorldEdit} instance.
*/
public RichMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.isEmpty()) {
throw new SuggestInputParseException("No input provided", "", () -> Stream
.of("#", ",", "&")
.map(n -> n + ":")
.collect(Collectors.toList())
// TODO namespaces
);
}
Extent extent = context.getExtent();
if (extent == null) {
extent = Request.request().getExtent();
}
List<List<Mask>> masks = new ArrayList<>();
masks.add(new ArrayList<>());
final CommandLocals locals = new CommandLocals();
Actor actor = context.getActor();
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();
final String command = pe.getInput();
String full = pe.getFull();
Mask mask = null;
if (command.isEmpty()) {
mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
} else if (!worldEdit.getMaskFactory().containsAlias(command)) {
// 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);
}
if (char0 == '#') {
throw new SuggestInputParseException(
new NoMatchException(Caption.of("fawe.error.parse.unknown-mask", full,
TextComponent
.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
)
.clickEvent(ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
))
)),
full,
() -> {
if (full.length() == 1) {
return new ArrayList<>(worldEdit.getMaskFactory().getSuggestions(""));
}
return new ArrayList<>(worldEdit
.getMaskFactory()
.getSuggestions(command.toLowerCase(Locale.ROOT)));
}
);
}
// Legacy syntax
if (charMask) {
switch (char0) {
case '\\': //
case '/': //
case '{': //
case '$': //
case '%': {
String value = command.substring(1) + ((entry.getValue().isEmpty())
? ""
: "[" + StringMan.join(
entry.getValue(),
"]["
) + "]");
if (value.contains(":")) {
if (value.charAt(0) == ':') {
value = value.replaceFirst(":", "");
}
value = value.replaceAll(":", "][");
}
mask = parseFromInput("#" + char0 + "[" + value + "]", context);
break;
}
case '|':
case '~':
case '<':
case '>':
case '!':
input = input.substring(input.indexOf(char0) + 1);
mask = parseFromInput(char0 + "[" + input + "]", context);
if (actor != null) {
actor.print(Caption.of(
"fawe.worldedit.help.command.clarifying.bracket",
char0 + "[" + input +
"]"
));
}
return mask;
}
}
if (mask == null) {
if (command.startsWith("[")) {
int end = command.lastIndexOf(']');
mask = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
} else {
BlockMaskBuilder builder = new BlockMaskBuilder();
try {
builder.addRegex(full);
} catch (InputParseException ignored) {
}
context.setPreferringWildcard(false);
context.setRestricted(false);
BaseBlock block = worldEdit.getBlockFactory().parseFromInput(full, context);
builder.add(block);
mask = builder.build(extent);
}
}
} else {
List<String> args = entry.getValue();
try {
mask = worldEdit.getMaskFactory().parseWithoutRich(full, context);
} catch (SuggestInputParseException rethrow) {
throw rethrow;
} catch (Throwable e) {
throw SuggestInputParseException.of(e, full, () -> {
try {
String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
List<Substring> split =
CommandArgParser.forArgString(cmdArgs).parseArgs().collect(Collectors.toList());
List<String> argStrings = split
.stream()
.map(Substring::getSubstring)
.collect(Collectors.toList());
MemoizingValueAccess access = getPlatform().initializeInjectedValues(() -> cmdArgs,
actor,
null, true
);
List<String> suggestions = getPlatform().getCommandManager().getSuggestions(
access,
argStrings
).stream().map(Suggestion::getSuggestion).collect(Collectors.toUnmodifiableList());
List<String> result = new ArrayList<>();
if (suggestions.size() <= 2) {
for (int i = 0; i < suggestions.size(); i++) {
String suggestion = suggestions.get(i);
if (suggestion.indexOf(' ') != 0) {
String[] splitSuggestion = suggestion.split(" ");
suggestion = "[" + StringMan.join(splitSuggestion, "][") + "]";
result.set(i, suggestion);
}
}
}
return result;
} catch (Throwable e2) {
e2.printStackTrace();
throw new InputParseException(Caption.of(e2.getMessage()));
}
});
}
}
if (pe.isAnd()) {
masks.add(new ArrayList<>());
}
masks.get(masks.size() - 1).add(mask);
}
} catch (InputParseException rethrow) {
throw rethrow;
} catch (Throwable e) {
e.printStackTrace();
throw new InputParseException(Caption.of(e.getMessage()), e);
}
List<Mask> maskUnions = new ArrayList<>();
for (List<Mask> maskList : masks) {
if (maskList.size() == 1) {
maskUnions.add(maskList.get(0));
} else if (maskList.size() != 0) {
maskUnions.add(new MaskUnion(maskList));
}
}
if (maskUnions.size() == 1) {
return maskUnions.get(0);
} else if (maskUnions.size() != 0) {
return new MaskIntersection(maskUnions);
} else {
return null;
}
}
@Override
public List<String> getMatchedAliases() {
return Collections.emptyList();
}
}

Datei anzeigen

@ -0,0 +1,47 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.AngleColorPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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 javax.annotation.Nonnull;
import java.util.stream.Stream;
public class AngleColorPatternParser 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 AngleColorPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#anglecolor", "#anglecolour");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index != 0) {
return Stream.empty();
}
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[distance] (e.g. " + getPrefix() + "[10])")
));
}
int distance = Integer.parseInt(input[0]);
return new AngleColorPattern(context.requireExtent(), context.requireSession(), distance);
}
}

Datei anzeigen

@ -0,0 +1,53 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.AverageColorPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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 javax.annotation.Nonnull;
import java.util.stream.Stream;
public class AverageColorPatternParser 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 AverageColorPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#averagecolor", "#averagecolour");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index > 4) {
return Stream.empty();
}
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[r][g][b][a] (e.g. " + getPrefix() + "[156][100][0][120])")
));
}
return new AverageColorPattern(
context.requireExtent(),
context.requireSession(),
Integer.parseInt(input[0]),
Integer.parseInt(input[1]),
Integer.parseInt(input[2]),
Integer.parseInt(input[3])
);
}
}

Datei anzeigen

@ -25,7 +25,7 @@ public class BiomePatternParser extends RichParser<Pattern> {
* @param worldEdit the worldedit instance.
*/
public BiomePatternParser(WorldEdit worldEdit) {
super(worldEdit, "#biome");
super(worldEdit, "#biome", "$");
}
// overridden to provide $<biome> too

Datei anzeigen

@ -0,0 +1,46 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.BufferedPattern2D;
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.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class BufferedPattern2DParser 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 BufferedPattern2DParser(WorldEdit worldEdit) {
super(worldEdit, "#buffer2d");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(input[0], context);
return new BufferedPattern2D(context.requireActor(), inner);
}
}

Datei anzeigen

@ -0,0 +1,53 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.util.MathMan;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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 javax.annotation.Nonnull;
import java.awt.Color;
import java.util.stream.Stream;
public class ColorPatternParser 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 ColorPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#color", "#colour");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index > 4) {
return Stream.empty();
}
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[r][g][b][a] (e.g. " + getPrefix() + "[156][100][0][120])")
));
}
Color color = new Color(
MathMan.clamp(Integer.parseInt(input[0]), 0, 255),
MathMan.clamp(Integer.parseInt(input[1]), 0, 255),
MathMan.clamp(Integer.parseInt(input[2]), 0, 255),
MathMan.clamp(Integer.parseInt(input[3]), 0, 255)
);
return context.requireSession().getTextureUtil().getNearestBlock(color.getRGB());
}
}

Datei anzeigen

@ -0,0 +1,36 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.function.pattern.ShadePattern;
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 DarkenPatternParser extends SimpleInputParser<Pattern> {
private final List<String> aliases = Collections.singletonList("#darken");
/**
* Create a new simple parser with a defined prefix for the result.
*
* @param worldEdit the worldedit instance.
*/
public DarkenPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return this.aliases;
}
@Override
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
return new ShadePattern(context.requireExtent(), context.requireSession(), true);
}
}

Datei anzeigen

@ -1,167 +0,0 @@
// TODO: Ping @MattBDev to reimplement (or remove because this class is stupid) 2020-02-04
///*
//package com.fastasyncworldedit.core.extension.factory.parser.pattern;
//
//import com.boydti.fawe.command.FaweParser;
//import com.boydti.fawe.command.SuggestInputParseException;
//import com.boydti.fawe.object.random.TrueRandom;
//import com.boydti.fawe.util.StringMan;
//import com.google.common.collect.Iterables;
//import com.sk89q.minecraft.util.commands.CommandLocals;
//import com.sk89q.worldedit.WorldEdit;
//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.extension.platform.PlatformCommandManager;
//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.world.block.BlockTypes;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
//public class DefaultPatternParser extends FaweParser<Pattern> {
//
// public DefaultPatternParser(WorldEdit worldEdit) {
// super(worldEdit, "patterns");
// }
//
// @Override
// public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
// if (input.isEmpty()) {
// throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
// }
// 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);
// }
// try {
// for (Map.Entry<ParseEntry, List<String>> entry : parse(input)) {
// ParseEntry pe = entry.getKey();
// final String command = pe.input;
// String full = pe.full;
// Pattern pattern = null;
// double chance = 1;
// if (command.isEmpty()) {
// pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
// } else {
// List<String> args = entry.getValue();
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
// try {
// pattern = parse(command + cmdArgs, context);
// } catch (SuggestInputParseException rethrow) {
// throw rethrow;
// } catch (Throwable e) {
// // TODO NOT IMPLEMENTED
//// throw SuggestInputParseException.of(e, full, () -> {
//// try {
//// List<String> suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals);
//// if (suggestions.size() <= 2) {
//// for (int i = 0; i < suggestions.size(); i++) {
//// String suggestion = suggestions.get(i);
//// if (suggestion.indexOf(' ') != 0) {
//// String[] split = suggestion.split(" ");
//// suggestion = "[" + StringMan.join(split, "][") + "]";
//// suggestions.set(i, suggestion);
//// }
//// }
//// }
//// return suggestions;
//// } catch (CommandException e1) {
//// throw new InputParseException(e1.getMessage());
//// } catch (Throwable e2) {
//// e2.printStackTrace();
//// throw new InputParseException(e2.getMessage());
//// }
//// });
// }
// if (pattern == 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);
// }
// if (char0 == '#') {
// // TODO NOT IMPLEMENTED
//// throw new SuggestInputParseException(new NoMatchException("Unknown pattern: " + full + ", See: //patterns"), full,
//// () -> {
//// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
//// return dispatcher.getAliases().stream().filter(
//// s -> s.startsWith(command.toLowerCase(Locale.ROOT))
//// ).collect(Collectors.toList());
//// }
//// );
// }
//
//
// if (charMask) {
// if (char0 == '$') {
// String value = command.substring(1) + ((entry.getValue().isEmpty()) ? ""
// : "[" + StringMan.join(entry.getValue(), "][") + "]");
// if (value.contains(":")) {
// if (value.charAt(0) == ':') {
// value.replaceFirst(":", "");
// }
// value = value.replaceAll(":", "][");
// }
// pattern = parseFromInput(char0 + "[" + value + "]", context);
// }
// }
// if (pattern == null) {
// if (command.startsWith("[")) {
// int end = command.lastIndexOf(']');
// pattern = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
// } else {
// int percentIndex = command.indexOf('%');
// if (percentIndex != -1) { // Legacy percent pattern
// chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
// String value = command.substring(percentIndex + 1);
// if (!entry.getValue().isEmpty()) {
// if (!value.isEmpty()) value += " ";
// value += StringMan.join(entry.getValue(), " ");
// }
// pattern = parseFromInput(value, context);
// } else { // legacy block pattern
// try {
// pattern = worldEdit.getBlockFactory().parseFromInput(pe.full, context);
// } catch (NoMatchException e) {
// throw new NoMatchException(e.getMessage() + " See: //patterns");
// }
// }
// }
// }
// }
// }
// if (pattern != null) {
// patterns.add(pattern);
// chances.add(chance);
// }
// }
// } catch (InputParseException rethrow) {
// throw rethrow;
// } catch (Throwable e) {
// e.printStackTrace();
// throw new InputParseException(e.getMessage(), e);
// }
// if (patterns.isEmpty()) {
// return null;
// }
// if (patterns.size() == 1) {
// return patterns.get(0);
// }
// RandomPattern random = new RandomPattern(new TrueRandom());
// for (int i = 0; i < patterns.size(); i++) {
// random.add(patterns.get(i), chances.get(i));
// }
// return random;
// }
//}

Datei anzeigen

@ -0,0 +1,46 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.DesaturatePattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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 javax.annotation.Nonnull;
import java.util.stream.Stream;
public class DesaturatePatternParser 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 DesaturatePatternParser(WorldEdit worldEdit) {
super(worldEdit, "#desaturate");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[percent] (e.g. " + getPrefix() + "[90])")
));
}
return new DesaturatePattern(context.requireExtent(), context.requireSession(), Double.parseDouble(arguments[0]) / 100);
}
}

Datei anzeigen

@ -14,6 +14,11 @@ public class ExistingPatternParser extends SimpleInputParser<Pattern> {
private final List<String> aliases = Collections.singletonList("#existing");
/**
* Create a new simple parser with a defined prefix for the result.
*
* @param worldEdit the worldedit instance.
*/
public ExistingPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}

Datei anzeigen

@ -0,0 +1,53 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.function.pattern.ExpressionPattern;
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.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.Collections;
import java.util.List;
public class ExpressionPatternParser extends SimpleInputParser<Pattern> {
private final List<String> aliases = Collections.singletonList("=");
/**
* Create a new simple parser with a defined prefix for the result.
*
* @param worldEdit the worldedit instance.
*/
public ExpressionPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return this.aliases;
}
@Override
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
try {
Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
context.requireExtent(), Vector3.ONE, Vector3.ZERO);
exp.setEnvironment(env);
return new ExpressionPattern(exp);
} catch (ExpressionException e) {
throw new InputParseException(Caption.of(
"worldedit.error.parser.invalid-expression",
TextComponent.of(e.getMessage())
));
}
}
}

Datei anzeigen

@ -0,0 +1,36 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.function.pattern.ShadePattern;
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 LightenPatternParser extends SimpleInputParser<Pattern> {
private final List<String> aliases = Collections.singletonList("#lighten");
/**
* Create a new simple parser with a defined prefix for the result.
*
* @param worldEdit the worldedit instance.
*/
public LightenPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public List<String> getMatchedAliases() {
return this.aliases;
}
@Override
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
return new ShadePattern(context.requireExtent(), context.requireSession(), false);
}
}

Datei anzeigen

@ -0,0 +1,64 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.LinearBlockPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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.world.block.BlockStateHolder;
import javax.annotation.Nonnull;
import java.util.Set;
import java.util.stream.Stream;
public class LinearPatternParser 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 LinearPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#linear", "#l");
}
@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(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 1) {
throw new InputParseException(Caption.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;
}
if (inner instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns();
return new LinearBlockPattern(patterns.toArray(new Pattern[0]));
}
throw new InputParseException(Caption.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with " + getPrefix()));
}
}

Datei anzeigen

@ -0,0 +1,54 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.MaskedPattern;
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.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class MaskedPatternParser 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 MaskedPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#mask");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
switch (index) {
case 0:
return this.worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
case 1:
case 2:
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
default:
return Stream.empty();
}
}
@Override
protected Pattern parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 3) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[mask][pattern][pattern] (e.g. " + getPrefix() + "[oak_planks][dirt][stone])")
));
}
Mask mask = this.worldEdit.getMaskFactory().parseFromInput(arguments[0], context);
Pattern inner1 = this.worldEdit.getPatternFactory().parseFromInput(arguments[1], context);
Pattern inner2 = this.worldEdit.getPatternFactory().parseFromInput(arguments[2], context);
return new MaskedPattern(mask, inner1, inner2);
}
}

Datei anzeigen

@ -0,0 +1,46 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.NoXPattern;
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.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class NoXPatternParser 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 NoXPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#!x", "#nx", "#nox");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(input[0], context);
return new NoXPattern(inner);
}
}

Datei anzeigen

@ -0,0 +1,46 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.NoYPattern;
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.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class NoYPatternParser 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 NoYPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#!y", "#ny", "#noy");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(input[0], context);
return new NoYPattern(inner);
}
}

Datei anzeigen

@ -0,0 +1,46 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.NoZPattern;
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.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class NoZPatternParser 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 NoZPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#!z", "#nz", "#noz");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(input[0], context);
return new NoZPattern(inner);
}
}

Datei anzeigen

@ -0,0 +1,67 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.OffsetPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class OffsetPatternParser 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 OffsetPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#offset");
}
@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(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 2 && arguments.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone][2][0][4])")
));
}
int x;
int y;
int z;
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
if (arguments.length == 4) {
x = Integer.parseInt(arguments[1]);
y = Integer.parseInt(arguments[2]);
z = Integer.parseInt(arguments[3]);
} else {
x = y = z = Integer.parseInt(arguments[1]);
}
Extent extent = context.requireExtent();
int minY = extent.getMinY();
int maxY = extent.getMaxY();
return new OffsetPattern(inner, x, y, z, minY, maxY);
}
}

Datei anzeigen

@ -0,0 +1,93 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
import com.fastasyncworldedit.core.function.pattern.RandomFullClipboardPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
public class RandomFullClipboardPatternParser 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 RandomFullClipboardPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#fullcopy");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
switch (index) {
case 1:
case 2:
return SuggestionHelper.suggestBoolean(argumentInput);
default:
return Stream.empty();
}
}
@Override
protected Pattern parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length == 0 || arguments.length > 3) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[#copy][true][false])")
));
}
try {
boolean rotate = arguments.length >= 2 && Boolean.getBoolean(arguments[1]);
boolean flip = arguments.length == 3 && Boolean.getBoolean(arguments[2]);
List<ClipboardHolder> clipboards;
switch (arguments[0].toLowerCase()) {
case "#copy":
case "#clipboard":
ClipboardHolder clipboard = context.requireSession().getExistingClipboard();
if (clipboard == null) {
throw new InputParseException(Caption.of("fawe.error.parse.no-clipboard", getPrefix()));
}
clipboards = Collections.singletonList(clipboard);
break;
default:
Actor player = context.requireActor();
MultiClipboardHolder multi = ClipboardFormats.loadAllFromInput(player,
arguments[0], ClipboardFormats.findByAlias("fast"), true
);
if (multi == null) {
multi = ClipboardFormats.loadAllFromInput(player,
arguments[0], ClipboardFormats.findByAlias("sponge"), true
);
}
if (multi == null) {
multi = ClipboardFormats.loadAllFromInput(player,
arguments[0], ClipboardFormats.findByAlias("mcedit"), true
);
}
if (multi == null) {
throw new InputParseException(Caption.of("fawe.error.parse.no-clipboard-source", arguments[0]));
}
clipboards = multi.getHolders();
break;
}
return new RandomFullClipboardPattern(clipboards, rotate, flip);
} catch (IOException e) {
throw new InputParseException(Caption.of(e.getMessage()), e);
}
}
}

Datei anzeigen

@ -0,0 +1,65 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.RandomOffsetPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class RandomOffsetPatternParser 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 RandomOffsetPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#spread", "#randomoffset");
}
@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(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 2 && arguments.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone][2][0][4])")
));
}
int x;
int y;
int z;
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
if (arguments.length == 4) {
x = Integer.parseInt(arguments[1]);
y = Integer.parseInt(arguments[2]);
z = Integer.parseInt(arguments[3]);
} else {
x = y = z = Integer.parseInt(arguments[1]);
}
Extent extent = context.requireExtent();
return new RandomOffsetPattern(inner, x, y, z, extent.getMinY(), extent.getMaxY());
}
}

Datei anzeigen

@ -15,6 +15,11 @@ import java.util.stream.Stream;
public class RandomPatternParser extends InputParser<Pattern> {
/**
* Create a new input parser.
*
* @param worldEdit the worldedit instance.
*/
public RandomPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}

Datei anzeigen

@ -0,0 +1,48 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.RelativePattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class RelativePatternParser 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 RelativePatternParser(WorldEdit worldEdit) {
super(worldEdit, "#relative", "#~", "#r", "#rel");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 1) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(input[0], context);
Extent extent = context.requireExtent();
return new RelativePattern(inner, extent.getMinY(), extent.getMaxY());
}
}

Datei anzeigen

@ -0,0 +1,211 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.command.SuggestInputParseException;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.FaweParser;
import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.WorldEdit;
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.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.command.CommandArgParser;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.enginehub.piston.inject.MemoizingValueAccess;
import org.enginehub.piston.suggestion.Suggestion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RichPatternParser extends FaweParser<Pattern> {
/**
* Create a new rich pattern-parser.
*
* @param worldEdit the worldedit instance.
*/
public RichPatternParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.isEmpty()) {
throw new SuggestInputParseException(
"No input provided",
"",
() -> Stream
.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":"))
.collect(Collectors.toList())
);
}
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);
}
try {
for (Map.Entry<ParseEntry, List<String>> entry : parse(input)) {
ParseEntry pe = entry.getKey();
final String command = pe.getInput();
String full = pe.getFull();
Pattern pattern = null;
double chance = 1;
if (command.isEmpty()) {
pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
} else if (!worldEdit.getPatternFactory().containsAlias(command)) {
// Legacy patterns
char char0 = command.charAt(0);
boolean charPattern = input.length() > 1 && input.charAt(1) != '[';
if (charPattern && input.charAt(0) == '=') {
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
}
if (char0 == '#' && command.length() > 1 && command.charAt(1) != '#') {
throw new SuggestInputParseException(
new NoMatchException(Caption.of("fawe.error.parse.unknown-pattern", full,
TextComponent
.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
)
.clickEvent(
ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
))
)),
full,
() -> {
if (full.length() == 1) {
return new ArrayList<>(worldEdit.getPatternFactory().getSuggestions(""));
}
return new ArrayList<>(worldEdit
.getPatternFactory()
.getSuggestions(command.toLowerCase(Locale.ROOT)));
}
);
}
if (charPattern) {
if (char0 == '$' || char0 == '^' || char0 == '*' || (char0 == '#' && input.charAt(1) == '#')) {
pattern = worldEdit.getPatternFactory().parseWithoutRich(full, context);
}
}
if (pattern == null) {
if (command.startsWith("[")) {
int end = command.lastIndexOf(']');
pattern = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
} else {
int percentIndex = command.indexOf('%');
if (percentIndex != -1) { // Legacy percent pattern
chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
String value = command.substring(percentIndex + 1);
if (!entry.getValue().isEmpty()) {
if (!value.isEmpty()) {
value += " ";
}
value += StringMan.join(entry.getValue(), " ");
}
pattern = parseFromInput(value, context);
} else { // legacy block pattern
try {
pattern = worldEdit.getBlockFactory().parseFromInput(pe.getFull(), context);
} catch (NoMatchException e) {
throw new NoMatchException(Caption.of("fawe.error.parse.unknown-pattern", full,
TextComponent
.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
)
.clickEvent(
com.sk89q.worldedit.util.formatting.text.event.ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
))
));
}
}
}
}
} else {
List<String> args = entry.getValue();
try {
pattern = worldEdit.getPatternFactory().parseWithoutRich(full, context);
} catch (SuggestInputParseException rethrow) {
throw rethrow;
} catch (Throwable e) {
throw SuggestInputParseException.of(e, full, () -> {
try {
String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
List<Substring> split =
CommandArgParser.forArgString(cmdArgs).parseArgs().collect(Collectors.toList());
List<String> argStrings = split
.stream()
.map(Substring::getSubstring)
.collect(Collectors.toList());
MemoizingValueAccess access = getPlatform().initializeInjectedValues(() -> cmdArgs,
actor,
null, true
);
List<String> suggestions = getPlatform().getCommandManager().getSuggestions(
access,
argStrings
).stream().map(Suggestion::getSuggestion).collect(Collectors.toUnmodifiableList());
List<String> result = new ArrayList<>();
if (suggestions.size() <= 2) {
for (int i = 0; i < suggestions.size(); i++) {
String suggestion = suggestions.get(i);
if (suggestion.indexOf(' ') != 0) {
String[] splitSuggestion = suggestion.split(" ");
suggestion = "[" + StringMan.join(splitSuggestion, "][") + "]";
result.set(i, suggestion);
}
}
}
return result;
} catch (Throwable e2) {
e2.printStackTrace();
throw new InputParseException(Caption.of(e2.getMessage()));
}
});
}
}
if (pattern != null) {
patterns.add(pattern);
chances.add(chance);
}
}
} catch (InputParseException rethrow) {
throw rethrow;
} catch (Throwable e) {
e.printStackTrace();
throw new InputParseException(Caption.of(e.getMessage()), e);
}
if (patterns.isEmpty()) {
return null;
}
if (patterns.size() == 1) {
return patterns.get(0);
}
RandomPattern random = new RandomPattern(new TrueRandom());
for (int i = 0; i < patterns.size(); i++) {
random.add(patterns.get(i), chances.get(i));
}
return random;
}
@Override
public List<String> getMatchedAliases() {
return Collections.emptyList();
}
}

Datei anzeigen

@ -0,0 +1,51 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.SaturatePattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
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 javax.annotation.Nonnull;
import java.util.stream.Stream;
public class SaturatePatternParser 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 SaturatePatternParser(WorldEdit worldEdit) {
super(worldEdit, "#saturate");
}
@Override
public Stream<String> getSuggestions(String argumentInput, int index) {
if (index > 3) {
return Stream.empty();
}
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
}
@Override
public Pattern parseFromInput(@Nonnull String[] input, ParserContext context) throws InputParseException {
if (input.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[r][g][b][a] (e.g. " + getPrefix() + "[156][100][0][120])")
));
}
return new SaturatePattern(context.requireExtent(), context.requireSession(),
Integer.parseInt(input[0]),
Integer.parseInt(input[1]),
Integer.parseInt(input[2]),
Integer.parseInt(input[3])
);
}
}

Datei anzeigen

@ -7,6 +7,11 @@ public class SimplexPatternParser extends NoisePatternParser {
private static final String SIMPLEX_NAME = "simplex";
/**
* Create a new rich pattern parser with a defined prefix for the result.
*
* @param worldEdit the worldedit instance.
*/
public SimplexPatternParser(WorldEdit worldEdit) {
super(worldEdit, SIMPLEX_NAME, SimplexNoiseGenerator::new);
}

Datei anzeigen

@ -0,0 +1,65 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.SolidRandomOffsetPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class SolidRandomOffsetPatternParser 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 SolidRandomOffsetPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#solidspread");
}
@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(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 2 && arguments.length != 4) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone][2][0][4])")
));
}
int x;
int y;
int z;
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
if (arguments.length == 4) {
x = Integer.parseInt(arguments[1]);
y = Integer.parseInt(arguments[2]);
z = Integer.parseInt(arguments[3]);
} else {
x = y = z = Integer.parseInt(arguments[1]);
}
Extent extent = context.requireExtent();
return new SolidRandomOffsetPattern(inner, x, y, z, extent.getMinY(), extent.getMaxY());
}
}

Datei anzeigen

@ -0,0 +1,54 @@
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.SurfaceRandomOffsetPattern;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import javax.annotation.Nonnull;
import java.util.stream.Stream;
public class SurfaceRandomOffsetPatternParser 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 SurfaceRandomOffsetPatternParser(WorldEdit worldEdit) {
super(worldEdit, "#surfacespread");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
switch (index) {
case 0:
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
case 1:
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
default:
return Stream.empty();
}
}
@Override
protected Pattern parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 2) {
throw new InputParseException(Caption.of(
"fawe.error.command.syntax",
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone][2])")
));
}
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
int distance = Integer.parseInt(arguments[1]);
Extent extent = context.requireExtent();
return new SurfaceRandomOffsetPattern(inner, distance, extent.getMinY(), extent.getMaxY());
}
}

Datei anzeigen

@ -0,0 +1,45 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.Linear3DTransform;
import com.fastasyncworldedit.core.extent.transform.RandomTransform;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class Linear3DTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public Linear3DTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#linear3d", "#l3d");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 1) {
return null;
}
ResettableExtent inner = worldEdit.getTransformFactory().parseFromInput(arguments[0], context);
if (inner instanceof RandomTransform) {
return new Linear3DTransform(((RandomTransform) inner).getExtents().toArray(new ResettableExtent[0]));
}
return inner; // TODO what about non-random transforms?
}
}

Datei anzeigen

@ -0,0 +1,45 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.LinearTransform;
import com.fastasyncworldedit.core.extent.transform.RandomTransform;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class LinearTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public LinearTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#linear", "#l");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 1) {
return null;
}
ResettableExtent inner = worldEdit.getTransformFactory().parseFromInput(arguments[0], context);
if (inner instanceof RandomTransform) {
return new LinearTransform(((RandomTransform) inner).getExtents().toArray(new ResettableExtent[0]));
}
return inner; // TODO what about non-random transforms?
}
}

Datei anzeigen

@ -0,0 +1,55 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.transform.OffsetTransform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
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 OffsetTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public OffsetTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#offset");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index < 3) {
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
} else if (index == 3) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 3 && arguments.length != 4) {
throw new InputParseException(TranslatableComponent.of(
"fawe.error.command.syntax",
TextComponent.of("#offset[x][y][z]")
));
}
int xOffset = Integer.parseInt(arguments[0]);
int yOffset = Integer.parseInt(arguments[1]);
int zOffset = Integer.parseInt(arguments[2]);
Extent extent;
extent = arguments.length == 4 ? worldEdit.getTransformFactory().parseFromInput(arguments[3], context) :
context.requireExtent();
return new OffsetTransform(extent, xOffset, yOffset, zOffset);
}
}

Datei anzeigen

@ -0,0 +1,47 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.PatternTransform;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class PatternTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public PatternTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#pattern");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index == 0) {
return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
} else if (index == 1) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length > 2) {
return null;
}
Pattern pattern = worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
Extent extent = arguments.length == 2 ? worldEdit.getTransformFactory().parseFromInput(arguments[1], context) :
context.requireExtent();
return new PatternTransform(extent, pattern);
}
}

Datei anzeigen

@ -0,0 +1,60 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.RandomTransform;
import com.sk89q.util.StringUtil;
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.List;
import java.util.stream.Stream;
public class RandomTransformParser extends InputParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public RandomTransformParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public Stream<String> getSuggestions(String input) {
if (input.isEmpty()) {
return Stream.empty();
}
List<String> split = StringUtil.split(input, ',', '[', ']');
if (split.size() == 1) {
return Stream.empty();
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < split.size() - 1; i++) {
builder.append(split.get(i)).append(',');
}
String previous = builder.toString();
return worldEdit.getTransformFactory().getSuggestions(split.get(split.size() - 1)).stream()
.map(s -> previous + s);
}
@Override
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.isEmpty()) {
return null;
}
List<String> split = StringUtil.split(input, ',', '[', ']');
if (split.size() == 1) {
return null;
}
RandomTransform randomTransform = new RandomTransform();
for (int i = 0; i < split.size(); i++) {
ResettableExtent transform = worldEdit.getTransformFactory().parseFromInput(split.get(i), context);
randomTransform.add(transform, 1d);
}
return randomTransform;
}
}

Datei anzeigen

@ -0,0 +1,170 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.command.SuggestInputParseException;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.FaweParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.MultiTransform;
import com.fastasyncworldedit.core.extent.transform.RandomTransform;
import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.WorldEdit;
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.expression.Expression;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Attempts to parse transforms given rich inputs, allowing for & and ,. Also allows for nested transforms
*/
public class RichTransformParser extends FaweParser<ResettableExtent> {
/**
* New instance
*
* @param worldEdit {@link WorldEdit} instance.
*/
public RichTransformParser(WorldEdit worldEdit) {
super(worldEdit);
}
@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.getInput();
ResettableExtent transform;
double chance = 1;
if (command.isEmpty()) {
transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
} else if (!worldEdit.getTransformFactory().containsAlias(command)) {
// 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(Caption.of("fawe.error.parse.unknown-transform", pe.getFull(),
TextComponent
.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
)
.clickEvent(ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
))
));
}
} else {
try {
transform = worldEdit.getTransformFactory().parseWithoutRich(pe.getFull(), context);
} catch (SuggestInputParseException rethrow) {
throw rethrow;
} catch (Throwable e) {
throw new NoMatchException(Caption.of("fawe.error.parse.unknown-transform", pe.getFull(),
TextComponent
.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
)
.clickEvent(ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
))
));
}
}
if (pe.isAnd()) { // &
intersectionChances.add(chance);
intersection.add(transform);
} else {
if (!intersection.isEmpty()) {
if (intersection.size() == 1) {
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", "&"));
}
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(Caption.of(e.getMessage()), e);
}
if (!intersection.isEmpty()) {
if (intersection.size() == 1) {
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", "&"));
}
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(Caption.of("fawe.error.parse.unknown-transform", input,
TextComponent.of("https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/Transforms"
).clickEvent(ClickEvent.openUrl(
"https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki/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;
}
}
@Override
public List<String> getMatchedAliases() {
return Collections.emptyList();
}
}

Datei anzeigen

@ -0,0 +1,57 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.math.transform.AffineTransform;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class RotateTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public RotateTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#rotate");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index < 3) {
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
}
if (index == 3) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
AffineTransform transform = new AffineTransform();
Extent extent;
if (arguments.length == 1) {
transform = transform.rotateY(Double.parseDouble(arguments[0]));
extent = context.requireExtent();
} else if (arguments.length == 3 || arguments.length == 4) {
transform = transform.rotateX(Double.parseDouble(arguments[0]));
transform = transform.rotateY(Double.parseDouble(arguments[1]));
transform = transform.rotateZ(Double.parseDouble(arguments[2]));
extent = arguments.length == 4 ? worldEdit.getTransformFactory().parseFromInput(arguments[3], context) :
context.requireExtent();
} else {
return null;
}
return new BlockTransformExtent(extent, transform);
}
}

Datei anzeigen

@ -0,0 +1,57 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.ScaleTransform;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class ScaleTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #scale}.
*
* @param worldEdit the worldedit instance.
*/
public ScaleTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#scale");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index < 3) {
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
} else if (index == 3) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
double xScale;
double yScale;
double zScale;
Extent extent;
if (arguments.length == 1) {
xScale = yScale = zScale = Double.parseDouble(arguments[0]);
extent = context.requireExtent();
} else if (arguments.length == 3 || arguments.length == 4) {
xScale = Double.parseDouble(arguments[0]);
yScale = Double.parseDouble(arguments[1]);
zScale = Double.parseDouble(arguments[2]);
extent = arguments.length == 4 ? worldEdit.getTransformFactory().parseFromInput(arguments[3], context) :
context.requireExtent();
} else {
return null;
}
return new ScaleTransform(extent, xScale, yScale, zScale);
}
}

Datei anzeigen

@ -0,0 +1,49 @@
package com.fastasyncworldedit.core.extension.factory.parser.transform;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.transform.RandomOffsetTransform;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Stream;
public class SpreadTransformParser extends RichParser<ResettableExtent> {
/**
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
*
* @param worldEdit the worldedit instance.
*/
public SpreadTransformParser(WorldEdit worldEdit) {
super(worldEdit, "#spread", "#randomoffset");
}
@Override
protected Stream<String> getSuggestions(String argumentInput, int index) {
if (index < 3) {
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
} else if (index == 3) {
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
}
return Stream.empty();
}
@Override
protected ResettableExtent parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
if (arguments.length != 3 && arguments.length != 4) {
return null;
}
int xOffset = Integer.parseInt(arguments[0]);
int yOffset = Integer.parseInt(arguments[1]);
int zOffset = Integer.parseInt(arguments[2]);
Extent extent = arguments.length == 4 ? worldEdit.getTransformFactory().parseFromInput(arguments[3], context) :
context.requireExtent();
return new RandomOffsetTransform(extent, xOffset, yOffset, zOffset);
}
}

Datei anzeigen

@ -39,32 +39,6 @@ public class PrimitiveBindings extends Bindings {
}
}
// TODO: Ping @MattBDev to reimplement 2020-02-04
//
// /**
// * Gets an {@link Extent} from a {@link Binding}.
// *
// * @param argument the context
// * @return an extent
// * @throws InputParseException on other error
// */
// @Binding
// public ResettableExtent getResettableExtent(Actor actor, String argument) throws InputParseException {
// if (argument.equalsIgnoreCase("#null")) {
// return new NullExtent();
// }
// DefaultTransformParser parser = Fawe.get().getTransformParser();
// ParserContext parserContext = new ParserContext();
// 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(argument, parserContext);
// }
/**
* Gets a type from a {@link Binding}.
*

Datei anzeigen

@ -37,6 +37,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
this.limit = limit;
}
@Override
public abstract boolean contains(int x, int y, int z);
public abstract boolean contains(int x, int z);

Datei anzeigen

@ -81,74 +81,74 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
@Override
public List<Entity> getEntities() {
return Collections.emptyList();
throw reason;
}
@Nullable
@Override
public Entity createEntity(Location arg0, BaseEntity arg1) {
return null;
throw reason;
}
@Override
public BlockState getBlock(BlockVector3 position) {
return BlockTypes.AIR.getDefaultState();
throw reason;
}
@Override
public BlockState getBlock(int x, int y, int z) {
return BlockTypes.AIR.getDefaultState();
throw reason;
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return getBlock(position).toBaseBlock();
throw reason;
}
@Override
public BaseBlock getFullBlock(int x, int y, int z) {
return getBlock(x, y, z).toBaseBlock();
throw reason;
}
@Override
public BiomeType getBiome(BlockVector3 position) {
return BiomeTypes.THE_VOID;
throw reason;
}
@Override
public BiomeType getBiomeType(int x, int y, int z) {
return BiomeTypes.THE_VOID;
throw reason;
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block) throws WorldEditException {
return false;
throw reason;
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
throws WorldEditException {
return false;
throw reason;
}
@Override
public ResettableExtent setExtent(Extent extent) {
return this;
throw reason;
}
@Override
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
return false;
throw reason;
}
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
return false;
throw reason;
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return false;
throw reason;
}
@Override
@ -371,7 +371,7 @@ public class NullExtent extends FaweRegionExtent implements IBatchProcessor {
@Override
public ProcessorScope getScope() {
return ProcessorScope.ADDING_BLOCKS;
throw reason;
}
}

Datei anzeigen

@ -1,49 +0,0 @@
package com.fastasyncworldedit.core.extent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
public class OffsetExtent extends ResettableExtent {
private final int dx;
private final int dy;
private final int dz;
public OffsetExtent(Extent parent, int dx, int dy, int dz) {
super(parent);
this.dx = dx;
this.dy = dy;
this.dz = dz;
}
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
return getExtent()
.setBiome(position.getBlockX() + dx, position.getBlockY() + dy, position.getBlockZ() + dz,
biome
);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return getExtent().setBiome(x + dx, y + dy, z + dz, biome);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block)
throws WorldEditException {
return getExtent().setBlock(location.getBlockX() + dx, location.getBlockY() + dy,
location.getBlockZ() + dz, block
);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
throws WorldEditException {
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
}
}

Datei anzeigen

@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.extent;
import com.fastasyncworldedit.core.util.ExtentTraverser;
import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
@ -38,7 +39,7 @@ public class ResettableExtent extends AbstractDelegateExtent implements Serializ
&& next instanceof ResettableExtent) {
((ResettableExtent) next).setExtent(extent);
} else {
new ExtentTraverser(this).setNext(new AbstractDelegateExtent(extent));
new ExtentTraverser<Extent>(this).setNext(extent);
}
return this;
}

Datei anzeigen

@ -8,6 +8,8 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
@ -136,7 +138,14 @@ public class PNGWriter implements ClipboardWriter {
poly3X[3] = (int) cpx;
poly3Y[3] = (int) (cpy + dpxi[1]);
Color colorTop = new Color(tu.getColor(block.getBlockType()));
BlockType type = block.getBlockType();
int color;
if (type == BlockTypes.GRASS_BLOCK) {
color = tu.getColor(clipboard.getBiome(mutable));
} else {
color = tu.getColor(type);
}
Color colorTop = new Color(color);
g2.setColor(colorTop);
if (fill) {

Datei anzeigen

@ -8,12 +8,18 @@ public class Linear3DTransform extends SelectTransform {
private final ResettableExtent[] extentsArray;
/**
* New instance
*
* @param extents list of extents to choose from
*/
public Linear3DTransform(ResettableExtent[] extents) {
this.extentsArray = extents;
}
@Override
public ResettableExtent setExtent(Extent extent) {
super.setExtent(extent);
for (ResettableExtent cur : extentsArray) {
cur.setExtent(extent);
}

Datei anzeigen

@ -9,12 +9,18 @@ public class LinearTransform extends SelectTransform {
private final ResettableExtent[] extentsArray;
private int index;
/**
* New instance
*
* @param extents list of extents to choose from
*/
public LinearTransform(ResettableExtent[] extents) {
this.extentsArray = extents;
}
@Override
public ResettableExtent setExtent(Extent extent) {
super.setExtent(extent);
for (ResettableExtent cur : extentsArray) {
cur.setExtent(extent);
}
@ -26,7 +32,7 @@ public class LinearTransform extends SelectTransform {
if (index == extentsArray.length) {
index = 0;
}
return extentsArray[index];
return extentsArray[index++];
}
@Override

Datei anzeigen

@ -17,6 +17,11 @@ public class MultiTransform extends RandomTransform {
private ResettableExtent[] extents;
/**
* New instance
*
* @param extents list of extents to set blocks to
*/
public MultiTransform(Collection<ResettableExtent> extents) {
for (ResettableExtent extent : extents) {
add(extent, 1);
@ -65,6 +70,16 @@ public class MultiTransform extends RandomTransform {
return result;
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
// don't use streams for each block place, it'd be incredibly slow
boolean result = false;
for (AbstractDelegateExtent extent : extents) {
result |= extent.setBiome(x, y, z, biome);
}
return result;
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {

Datei anzeigen

@ -0,0 +1,77 @@
package com.fastasyncworldedit.core.extent.transform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
public class OffsetTransform extends ResettableExtent {
private final int dx;
private final int dy;
private final int dz;
/**
* New instance
*
* @param parent extent to set to
* @param dx offset x
* @param dy offset y
* @param dz offset z
*/
public OffsetTransform(Extent parent, int dx, int dy, int dz) {
super(parent);
this.dx = dx;
this.dy = dy;
this.dz = dz;
}
@Override
public boolean setBiome(BlockVector3 location, BiomeType biome) {
int x = location.getX() + dx;
int y = location.getX() + dy;
int z = location.getX() + dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBiome(x, y, z, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
x += dx;
y += dy;
z += dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBiome(x, y, z, biome);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block)
throws WorldEditException {
int x = location.getX() + dx;
int y = location.getX() + dy;
int z = location.getX() + dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBlock(x, y, z, block);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
throws WorldEditException {
x += dx;
y += dy;
z += dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBlock(x, y, z, block);
}
}

Datei anzeigen

@ -1,7 +1,6 @@
package com.fastasyncworldedit.core.extent.transform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
@ -12,6 +11,12 @@ public class PatternTransform extends ResettableExtent {
private final Pattern pattern;
/**
* New instance
*
* @param parent extent to set to
* @param pattern pattern to apply
*/
public PatternTransform(Extent parent, Pattern pattern) {
super(parent);
this.pattern = pattern;

Datei anzeigen

@ -1,5 +1,6 @@
package com.fastasyncworldedit.core.extent;
package com.fastasyncworldedit.core.extent.transform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
@ -15,6 +16,14 @@ public class RandomOffsetTransform extends ResettableExtent {
private final int dz;
private transient SplittableRandom random;
/**
* New instance
*
* @param parent extent to set to
* @param dx range of x values to choose from (0 -> x)
* @param dy range of y values to choose from (0 -> y)
* @param dz range of z values to choose from (0 -> z)
*/
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
super(parent);
this.dx = dx + 1;
@ -24,10 +33,24 @@ public class RandomOffsetTransform extends ResettableExtent {
}
@Override
public boolean setBiome(BlockVector3 pos, BiomeType biome) {
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;
public boolean setBiome(BlockVector3 position, BiomeType biome) {
int x = position.getBlockX() + random.nextInt(1 + (dx << 1)) - dx;
int y = position.getBlockY() + random.nextInt(1 + (dy << 1)) - dy;
int z = position.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBiome(x, y, z, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
x = x + random.nextInt(1 + (dx << 1)) - dx;
y = y + random.nextInt(1 + (dy << 1)) - dy;
z = z + random.nextInt(1 + (dz << 1)) - dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBiome(x, y, z, biome);
}
@ -37,6 +60,9 @@ public class RandomOffsetTransform extends ResettableExtent {
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;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBlock(x, y, z, block);
}
@ -46,6 +72,9 @@ public class RandomOffsetTransform extends ResettableExtent {
x = x + random.nextInt(1 + (dx << 1)) - dx;
y = y + random.nextInt(1 + (dy << 1)) - dy;
z = z + random.nextInt(1 + (dz << 1)) - dz;
if (!getExtent().contains(x, y, z)) {
return false;
}
return getExtent().setBlock(x, y, z, block);
}

Datei anzeigen

@ -29,6 +29,11 @@ public class RandomTransform extends SelectTransform {
this(new TrueRandom());
}
/**
* New instance
*
* @param random {@link SimpleRandom} used to choose between transforms, given weights
*/
public RandomTransform(SimpleRandom random) {
this.random = random;
}
@ -49,6 +54,7 @@ public class RandomTransform extends SelectTransform {
collection = RandomCollection.of(weights, random);
extents = new LinkedHashSet<>(weights.keySet());
}
super.setExtent(extent);
for (ResettableExtent current : extents) {
current.setExtent(extent);
}

Datei anzeigen

@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.extent.transform;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.fastasyncworldedit.core.math.MutableVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
@ -18,61 +19,76 @@ public class ScaleTransform extends ResettableExtent {
private final double dx;
private final double dy;
private final double dz;
private transient MutableBlockVector3 mutable = new MutableBlockVector3();
private transient MutableVector3 mutable = new MutableVector3();
private transient int minY;
private transient int maxy;
private transient BlockVector3 min;
/**
* New instance
*
* @param parent extent to set to
* @param dx x axis scaling
* @param dy y axis scaling
* @param dz z axis scaling
*/
public ScaleTransform(Extent parent, double dx, double dy, double dz) {
super(parent);
this.dx = dx;
this.dy = dy;
this.dz = dz;
this.maxy = parent.getMaximumPoint().getBlockY();
this.minY = parent.getMinY();
this.maxy = parent.getMaxY();
}
@Override
public ResettableExtent setExtent(Extent extent) {
min = null;
maxy = extent.getMaximumPoint().getBlockY();
mutable = new MutableBlockVector3();
mutable = new MutableVector3();
this.minY = extent.getMinY();
this.maxy = extent.getMaxY();
return super.setExtent(extent);
}
private void getPos(BlockVector3 pos) {
private MutableVector3 getPos(BlockVector3 pos) {
if (min == null) {
min = pos;
}
mutable.mutX(min.getX() + (pos.getX() - min.getX()) * dx);
mutable.mutY(min.getY() + (pos.getY() - min.getY()) * dy);
mutable.mutZ(min.getZ() + (pos.getZ() - min.getZ()) * dz);
return new MutableVector3(mutable);
}
private void getPos(int x, int y, int z) {
private MutableVector3 getPos(int x, int y, int z) {
if (min == null) {
min = BlockVector3.at(x, y, z);
}
mutable.mutX(min.getX() + (x - min.getX()) * dx);
mutable.mutY(min.getY() + (y - min.getY()) * dy);
mutable.mutZ(min.getZ() + (z - min.getZ()) * dz);
return new MutableVector3(mutable);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block)
throws WorldEditException {
boolean result = false;
getPos(location);
double sx = mutable.getX();
double sy = mutable.getY();
double sz = mutable.getZ();
MutableVector3 vector3 = getPos(location);
MutableBlockVector3 pos = new MutableBlockVector3();
double sx = vector3.getX();
double sy = vector3.getY();
double sz = vector3.getZ();
double ex = sx + dx;
double ey = Math.min(maxy, sy + dy);
double ey = Math.max(minY, Math.min(maxy, sy + dy));
double ez = sz + dz;
for (mutable.mutY(sy); mutable.getY() < ey; mutable.mutY(mutable.getY() + 1)) {
for (mutable.mutZ(sz); mutable.getZ() < ez; mutable.mutZ(mutable.getZ() + 1)) {
for (mutable.mutX(sx); mutable.getX() < ex; mutable.mutX(mutable.getX() + 1)) {
result |= super.setBlock(mutable, block);
for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) {
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
if (!getExtent().contains(pos)) {
continue;
}
result |= super.setBlock(pos, block);
}
}
}
@ -82,17 +98,21 @@ public class ScaleTransform extends ResettableExtent {
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
boolean result = false;
getPos(position);
double sx = mutable.getX();
double sy = mutable.getY();
double sz = mutable.getZ();
MutableVector3 vector3 = getPos(position);
MutableBlockVector3 pos = new MutableBlockVector3();
double sx = vector3.getX();
double sy = vector3.getY();
double sz = vector3.getZ();
double ex = sx + dx;
double ey = Math.min(maxy, sy + dy);
double ey = Math.max(minY, Math.min(maxy, sy + dy));
double ez = sz + dz;
for (mutable.mutY(sy); mutable.getY() < ey; mutable.mutY(mutable.getY() + 1)) {
for (mutable.mutZ(sz); mutable.getZ() < ez; mutable.mutZ(mutable.getZ() + 1)) {
for (mutable.mutX(sx); mutable.getX() < ex; mutable.mutX(mutable.getX() + 1)) {
result |= super.setBiome(mutable, biome);
for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) {
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
if (!getExtent().contains(pos)) {
continue;
}
result |= super.setBiome(pos, biome);
}
}
}
@ -103,17 +123,45 @@ public class ScaleTransform extends ResettableExtent {
public <B extends BlockStateHolder<B>> boolean setBlock(int x1, int y1, int z1, B block)
throws WorldEditException {
boolean result = false;
getPos(x1, y1, z1);
double sx = mutable.getX();
double sy = mutable.getY();
double sz = mutable.getZ();
double ex = mutable.getX() + dx;
MutableVector3 vector3 = getPos(x1, y1, z1);
MutableBlockVector3 pos = new MutableBlockVector3();
double sx = vector3.getX();
double sy = vector3.getY();
double sz = vector3.getZ();
double ex = vector3.getX() + dx;
double ey = Math.min(maxy, sy + dy);
double ez = mutable.getZ() + dz;
for (mutable.mutY(sy); mutable.getY() < ey; mutable.mutY(mutable.getY() + 1)) {
for (mutable.mutZ(sz); mutable.getZ() < ez; mutable.mutZ(mutable.getZ() + 1)) {
for (mutable.mutX(sx); mutable.getX() < ex; mutable.mutX(mutable.getX() + 1)) {
result |= super.setBlock(mutable, block);
double ez = vector3.getZ() + dz;
for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) {
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
if (!getExtent().contains(pos)) {
continue;
}
result |= super.setBlock(pos, block);
}
}
}
return result;
}
@Override
public boolean setBiome(int x1, int y1, int z1, BiomeType biome) {
boolean result = false;
MutableVector3 vector3 = getPos(x1, y1, z1);
MutableBlockVector3 pos = new MutableBlockVector3();
double sx = vector3.getX();
double sy = vector3.getY();
double sz = vector3.getZ();
double ex = sx + dx;
double ey = Math.max(minY, Math.min(maxy, sy + dy));
double ez = sz + dz;
for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) {
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
if (!getExtent().contains(pos)) {
continue;
}
result |= super.setBiome(pos, biome);
}
}
}
@ -123,11 +171,13 @@ public class ScaleTransform extends ResettableExtent {
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
getPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
Location newLoc = new Location(location.getExtent(),
mutable.toVector3(),
getPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()),
location.getYaw(), location.getPitch()
);
if (!getExtent().contains(newLoc.toBlockPoint())) {
return null;
}
return super.createEntity(newLoc, entity);
}

Datei anzeigen

@ -57,4 +57,9 @@ public abstract class SelectTransform extends ResettableExtent {
return getExtent(position).setBiome(position, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return getExtent(x, y, z).setBiome(x, y, z, biome);
}
}

Datei anzeigen

@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.registry.state.PropertyKey;
import com.fastasyncworldedit.core.registry.state.PropertyKeySet;
import com.fastasyncworldedit.core.util.MutableCharSequence;
import com.fastasyncworldedit.core.util.StringMan;
import com.fastasyncworldedit.core.world.block.BlanketBaseBlock;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockMask;
@ -423,6 +424,9 @@ public class BlockMaskBuilder {
public <T extends BlockStateHolder<T>> BlockMaskBuilder add(BlockStateHolder<T> state) {
BlockType type = state.getBlockType();
if (state instanceof BlanketBaseBlock) {
return add(type);
}
int i = type.getInternalId();
long[] states = bitSets[i];
if (states != ALL) {

Datei anzeigen

@ -3,22 +3,31 @@ package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.util.TextureHolder;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
public class AngleColorPattern extends DataAnglePattern {
public class AngleColorPattern extends AnglePattern {
protected transient TextureHolder holder;
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param holder {@link TextureHolder} to use to get textures
* @param distance distance to use to calculate angle
*/
public AngleColorPattern(Extent extent, TextureHolder holder, int distance) {
super(extent, distance);
this.holder = holder.getTextureUtil();
}
public int getColor(int color, int slope) {
private int getColor(int color, int slope) {
if (slope == 0) {
return color;
}
@ -54,7 +63,13 @@ public class AngleColorPattern extends DataAnglePattern {
if (slope == -1) {
return block;
}
int color = holder.getTextureUtil().getColor(block.getBlockType());
BlockType type = block.getBlockType();
int color;
if (type == BlockTypes.GRASS_BLOCK) {
color = holder.getTextureUtil().getColor(extent.getBiome(position));
} else {
color = holder.getTextureUtil().getColor(type);
}
if (color == 0) {
return block;
}
@ -69,7 +84,13 @@ public class AngleColorPattern extends DataAnglePattern {
if (slope == -1) {
return false;
}
int color = holder.getTextureUtil().getColor(block.getBlockType());
BlockType type = block.getBlockType();
int color;
if (type == BlockTypes.GRASS_BLOCK) {
color = holder.getTextureUtil().getColor(extent.getBiome(get));
} else {
color = holder.getTextureUtil().getColor(type);
}
if (color == 0) {
return false;
}

Datei anzeigen

@ -1,22 +1,27 @@
package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.extent.ExtentHeightCacher;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
public class DataAnglePattern extends AbstractPattern {
public abstract class AnglePattern extends AbstractPattern {
public final double factor;
public final Extent extent;
public final int maxY;
public final int distance;
public DataAnglePattern(Extent extent, int distance) {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param distance distance to calculate angle with
*/
public AnglePattern(Extent extent, int distance) {
this.extent = new ExtentHeightCacher(extent);
this.maxY = extent.getMaximumPoint().getBlockY();
this.distance = distance;
@ -58,25 +63,9 @@ public class DataAnglePattern extends AbstractPattern {
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BlockState block = extent.getBlock(position);
int slope = getSlope(block, position, extent);
if (slope == -1) {
return block.toBaseBlock();
}
int data = Math.min(slope, 255) >> 4;
return block.withPropertyId(data).toBaseBlock();
}
public abstract BaseBlock applyBlock(BlockVector3 position);
@Override
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
BlockState block = extent.getBlock(getPosition);
int slope = getSlope(block, getPosition, extent);
if (slope == -1) {
return false;
}
int data = Math.min(slope, 255) >> 4;
return extent.setBlock(setPosition, block.withPropertyId(data));
}
public abstract boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition);
}

Datei anzeigen

@ -1,12 +1,15 @@
package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.TextureHolder;
import com.fastasyncworldedit.core.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.awt.Color;
@ -15,18 +18,35 @@ public class AverageColorPattern extends AbstractExtentPattern {
private final transient TextureHolder holder;
private final int color;
public AverageColorPattern(Extent extent, int color, TextureHolder util) {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param holder {@link TextureHolder} to use to get textures
* @param r red channel, clamped 0 -> 255
* @param g green channel, clamped 0 -> 255
* @param b blue channel, clamped 0 -> 255
* @param a alpha channel, clamped 0 -> 255
*/
public AverageColorPattern(Extent extent, TextureHolder holder, int r, int g, int b, int a) {
super(extent);
this.holder = util;
this.color = new Color(color).getRGB();
this.holder = holder;
this.color = new Color(MathMan.clamp(r, 0, 255), MathMan.clamp(g, 0, 255), MathMan.clamp(b, 0, 255), MathMan.clamp(a, 0
, 255)).getRGB();
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BaseBlock block = getExtent().getFullBlock(position);
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(block.getBlockType());
int newColor = util.averageColor(currentColor, color);
BlockType type = block.getBlockType();
int currentColor;
if (type == BlockTypes.GRASS_BLOCK) {
currentColor = holder.getTextureUtil().getColor(getExtent().getBiome(position));
} else {
currentColor = holder.getTextureUtil().getColor(type);
}
int newColor = TextureUtil.averageColor(currentColor, color);
return util.getNearestBlock(newColor).getDefaultState().toBaseBlock();
}
@ -34,11 +54,16 @@ public class AverageColorPattern extends AbstractExtentPattern {
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType blockType = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(blockType);
int currentColor;
if (blockType == BlockTypes.GRASS_BLOCK) {
currentColor = holder.getTextureUtil().getColor(extent.getBiome(get));
} else {
currentColor = holder.getTextureUtil().getColor(blockType);
}
if (currentColor == 0) {
return false;
}
int newColor = util.averageColor(currentColor, color);
int newColor = TextureUtil.averageColor(currentColor, color);
BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock == blockType) {
return false;

Datei anzeigen

@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
@ -10,6 +11,12 @@ public class BiomeApplyingPattern extends AbstractExtentPattern {
private final BiomeType biomeType;
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param biomeType biome type to set
*/
public BiomeApplyingPattern(Extent extent, BiomeType biomeType) {
super(extent);
this.biomeType = biomeType;

Datei anzeigen

@ -11,8 +11,6 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.UUID;
public class BufferedPattern extends AbstractPattern implements ResettablePattern {
protected final LocalBlockVectorSet set = new LocalBlockVectorSet();
@ -20,10 +18,14 @@ public class BufferedPattern extends AbstractPattern implements ResettablePatter
protected final long[] actionTime;
protected final Pattern pattern;
protected final UUID uuid;
/**
* Create a new {@link Pattern} instance
*
* @param actor actor associated with the pattern
* @param parent pattern to set
*/
public BufferedPattern(Actor actor, Pattern parent) {
this.uuid = actor.getUniqueId();
long[] tmp = actor.getMeta("lastActionTime");
if (tmp == null) {
actor.setMeta("lastActionTime", tmp = new long[2]);

Datei anzeigen

@ -6,6 +6,12 @@ import com.sk89q.worldedit.math.BlockVector3;
public class BufferedPattern2D extends BufferedPattern {
/**
* Create a new {@link Pattern} instance
*
* @param actor actor associated with the pattern
* @param parent pattern to set
*/
public BufferedPattern2D(Actor actor, Pattern parent) {
super(actor, parent);
}

Datei anzeigen

@ -1,47 +0,0 @@
package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import static com.google.common.base.Preconditions.checkNotNull;
public class DataPattern extends AbstractExtentPattern {
private final Pattern pattern;
public DataPattern(Extent extent, Pattern parent) {
super(extent);
checkNotNull(parent);
this.pattern = parent;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BaseBlock oldBlock = getExtent().getFullBlock(position);
BaseBlock newBlock = pattern.applyBlock(position);
return oldBlock.toBlockState().withProperties(newBlock.toBlockState()).toBaseBlock(newBlock.getNbtData());
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BaseBlock oldBlock = get.getFullBlock(extent);
BaseBlock newBlock = pattern.applyBlock(get);
BlockState oldState = oldBlock.toBlockState();
BlockState newState = oldState.withProperties(newBlock.toBlockState());
if (newState != oldState) {
if (oldBlock.hasNbtData()) {
set.setFullBlock(extent, newState.toBaseBlock(oldBlock.getNbtData()));
} else {
set.setBlock(extent, newState);
}
return true;
}
return false;
}
}

Datei anzeigen

@ -5,9 +5,11 @@ import com.fastasyncworldedit.core.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
public class DesaturatePattern extends AbstractPattern {
@ -15,21 +17,33 @@ public class DesaturatePattern extends AbstractPattern {
private final Extent extent;
private final double value;
public DesaturatePattern(Extent extent, double value, TextureHolder util) {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param holder {@link TextureHolder} to use for textures
* @param value decimal percent to desaturate by (0 -> 1)
*/
public DesaturatePattern(Extent extent, TextureHolder holder, double value) {
this.extent = extent;
this.holder = util;
this.holder = holder;
this.value = Math.max(0, Math.min(1, value));
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BlockType block = extent.getBlock(position).getBlockType();
BlockType type = extent.getBlock(position).getBlockType();
TextureUtil util = holder.getTextureUtil();
int color = getColor(util.getColor(block));
int color;
if (type == BlockTypes.GRASS_BLOCK) {
color = holder.getTextureUtil().getColor(extent.getBiome(position));
} else {
color = holder.getTextureUtil().getColor(type);
}
return util.getNearestBlock(color).getDefaultState().toBaseBlock();
}
public int getColor(int color) {
private int getColor(int color) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
@ -45,7 +59,12 @@ public class DesaturatePattern extends AbstractPattern {
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType type = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int color = util.getColor(type);
int color;
if (type == BlockTypes.GRASS_BLOCK) {
color = holder.getTextureUtil().getColor(extent.getBiome(get));
} else {
color = holder.getTextureUtil().getColor(type);
}
int newColor = getColor(color);
if (newColor == color) {
return false;

Datei anzeigen

@ -2,11 +2,17 @@ package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
public class ExistingPattern extends AbstractExtentPattern {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
*/
public ExistingPattern(Extent extent) {
super(extent);
}

Datei anzeigen

@ -1,28 +0,0 @@
package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
public class IdDataMaskPattern extends AbstractExtentPattern {
private final Pattern pattern;
private final int bitMask;
public IdDataMaskPattern(Extent extent, Pattern parent, int bitMask) {
super(extent);
this.pattern = parent;
this.bitMask = bitMask;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BaseBlock oldBlock = getExtent().getFullBlock(position);
BaseBlock newBlock = pattern.applyBlock(position);
int oldData = oldBlock.getInternalPropertiesId();
int newData = newBlock.getInternalPropertiesId() + oldData - (oldData & bitMask);
return newBlock.withPropertyId(newData).toBaseBlock();
}
}

Datei anzeigen

@ -1,27 +0,0 @@
package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import static com.google.common.base.Preconditions.checkNotNull;
public class IdPattern extends AbstractExtentPattern {
private final Pattern pattern;
public IdPattern(Extent extent, Pattern parent) {
super(extent);
checkNotNull(parent);
this.pattern = parent;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BaseBlock oldBlock = getExtent().getFullBlock(position);
BaseBlock newBlock = pattern.applyBlock(position);
return newBlock.withPropertyId(oldBlock.getInternalPropertiesId()).toBaseBlock();
}
}

Datei anzeigen

@ -13,6 +13,13 @@ public class Linear2DBlockPattern extends AbstractPattern {
private final int xScale;
private final int zScale;
/**
* Create a new {@link Pattern} instance
*
* @param patterns array of patterns to linearly choose from based on x/z coordinates
* @param xScale x-axis scale
* @param zScale z-axis scale
*/
public Linear2DBlockPattern(Pattern[] patterns, int xScale, int zScale) {
this.patternsArray = patterns;
this.xScale = xScale;

Datei anzeigen

@ -14,6 +14,14 @@ public class Linear3DBlockPattern extends AbstractPattern {
private final int yScale;
private final int zScale;
/**
* Create a new {@link Pattern} instance
*
* @param patterns array of patterns to linearly choose from based on x/y/z coordinates
* @param xScale x-axis scale
* @param yScale y-axis scale
* @param zScale z-axis scale
*/
public Linear3DBlockPattern(Pattern[] patterns, int xScale, int yScale, int zScale) {
this.patternsArray = patterns;
this.xScale = xScale;

Datei anzeigen

@ -12,6 +12,11 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat
private final Pattern[] patternsArray;
private transient int index;
/**
* Create a new {@link Pattern} instance
*
* @param patterns array of patterns to linearly choose from based on x/z coordinates
*/
public LinearBlockPattern(Pattern[] patterns) {
this.patternsArray = patterns;
}

Datei anzeigen

@ -14,6 +14,13 @@ public class MaskedPattern extends AbstractPattern {
private final Pattern secondary;
private final Mask mask;
/**
* Create a new {@link Pattern} instance
*
* @param mask mask to use
* @param primary pattern if mask true
* @param secondary pattern if mask false
*/
public MaskedPattern(Mask mask, Pattern primary, Pattern secondary) {
this.mask = mask;
this.primary = primary;

Datei anzeigen

@ -13,6 +13,11 @@ public class NoXPattern extends AbstractPattern {
private final Pattern pattern;
private final MutableBlockVector3 mutable = new MutableBlockVector3();
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
*/
public NoXPattern(Pattern pattern) {
this.pattern = pattern;
}

Datei anzeigen

@ -13,6 +13,11 @@ public class NoYPattern extends AbstractPattern {
private final Pattern pattern;
private final MutableBlockVector3 mutable = new MutableBlockVector3();
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
*/
public NoYPattern(Pattern pattern) {
this.pattern = pattern;
}

Datei anzeigen

@ -11,13 +11,17 @@ import com.sk89q.worldedit.world.block.BaseBlock;
public class NoZPattern extends AbstractPattern {
private final Pattern pattern;
private final MutableBlockVector3 mutable = new MutableBlockVector3();
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
*/
public NoZPattern(Pattern pattern) {
this.pattern = pattern;
}
private final transient MutableBlockVector3 mutable = new MutableBlockVector3();
@Override
public BaseBlock applyBlock(BlockVector3 pos) {
mutable.mutX(pos.getX());

Datei anzeigen

@ -13,13 +13,27 @@ public class OffsetPattern extends AbstractPattern {
private final int dx;
private final int dy;
private final int dz;
private final int minY;
private final int maxY;
private final transient MutableBlockVector3 mutable = new MutableBlockVector3();
private final Pattern pattern;
public OffsetPattern(Pattern pattern, int dx, int dy, int dz) {
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
* @param dx offset x
* @param dy offset y
* @param dz offset z
* @param minY min applicable y (inclusive
* @param maxY max applicable y (inclusive
*/
public OffsetPattern(Pattern pattern, int dx, int dy, int dz, int minY, int maxY) {
this.dx = dx;
this.dy = dy;
this.dz = dz;
this.minY = minY;
this.maxY = maxY;
this.pattern = pattern;
}
@ -35,6 +49,9 @@ public class OffsetPattern extends AbstractPattern {
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
mutable.mutX(get.getX() + dx);
mutable.mutY(get.getY() + dy);
if (mutable.getY() < minY || mutable.getY() > maxY) {
return false;
}
mutable.mutZ(get.getZ() + dz);
return pattern.apply(extent, get, mutable);
}

Datei anzeigen

@ -1,259 +0,0 @@
package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.registry.state.PropertyKey;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.MutableCharSequence;
import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import java.util.ArrayList;
import java.util.List;
public class PropertyPattern extends AbstractExtentPattern {
private final int[] transformed;
public PropertyPattern(Extent extent, String[] properties) {
this(extent);
addRegex(".*[" + StringMan.join(properties, ",") + "]");
}
public PropertyPattern(Extent extent) {
super(extent);
this.transformed = new int[BlockTypesCache.states.length];
for (int i = 0; i < transformed.length; i++) {
transformed[i] = i;
}
}
private static final Operator EQUAL = (length, value, index) -> value;
private static final Operator PLUS = (length, value, index) -> index + value;
private static final Operator MINUS = (length, value, index) -> index - value;
private static final Operator MODULO = (length, value, index) -> index % value;
private static final Operator AND = (length, value, index) -> index & value;
private static final Operator OR = (length, value, index) -> index | value;
private static final Operator XOR = (length, value, index) -> index ^ value;
private interface Operator {
int apply(int length, int value, int index);
}
private Operator getOp(char c) {
switch (c) {
case '=':
return EQUAL;
case '+':
return PLUS;
case '-':
return MINUS;
case '%':
return MODULO;
case '&':
return AND;
case '|':
return OR;
case '^':
return XOR;
default:
return null;
}
}
private void add(BlockType type, PropertyKey key, Operator operator, MutableCharSequence value, boolean wrap) {
if (!type.hasProperty(key)) {
return;
}
AbstractProperty property = (AbstractProperty) type.getProperty(key);
BlockState defaultState = type.getDefaultState();
int valueInt;
if (value.length() == 0) {
valueInt = property.getIndex(defaultState.getInternalId());
} else if (!(property instanceof IntegerProperty) && MathMan.isInteger(value)) {
valueInt = StringMan.parseInt(value);
} else {
valueInt = property.getIndexFor(value);
}
List values = property.getValues();
int length = values.size();
for (int i = 0; i < values.size(); i++) {
int result = operator.apply(length, valueInt, i);
if (wrap) {
result = MathMan.wrap(result, 0, length - 1);
} else {
result = Math.max(Math.min(result, length - 1), 0);
}
if (result == i) {
continue;
}
int internalId = valueInt + i;
int state = property.modifyIndex(0, i);
if (type.getProperties().size() > 1) {
ArrayList<Property> properties = new ArrayList<>(type.getProperties().size() - 1);
for (Property current : type.getProperties()) {
if (current == property) {
continue;
}
properties.add(current);
}
applyRecursive(type, property, properties, 0, state, result);
} else {
int ordinal = type.withStateId(internalId).getOrdinal();
transformed[ordinal] = type.withStateId(result).getOrdinal();
}
}
}
private void applyRecursive(
BlockType type,
AbstractProperty property,
List<Property> properties,
int propertiesIndex,
int stateId,
int index
) {
AbstractProperty current = (AbstractProperty) properties.get(propertiesIndex);
List values = current.getValues();
if (propertiesIndex + 1 < properties.size()) {
for (int i = 0; i < values.size(); i++) {
int newState = current.modifyIndex(stateId, i);
applyRecursive(type, property, properties, propertiesIndex + 1, newState, index);
}
} else {
for (int i = 0; i < values.size(); i++) {
int statesIndex = current.modifyIndex(stateId, i) >> BlockTypesCache.BIT_OFFSET;
BlockState state = type.withPropertyId(statesIndex);
int existingOrdinal = transformed[state.getOrdinal()];
int existing = BlockTypesCache.states[existingOrdinal].getInternalId();
//states[statesIndex] << BlockTypesCache.BIT_OFFSET;
BlockState newState = state.withPropertyId(property.modifyIndex(existing, index) >> BlockTypesCache.BIT_OFFSET);
transformed[state.getOrdinal()] = newState.getOrdinal();
}
}
}
public PropertyPattern addRegex(String input) {
if (input.charAt(input.length() - 1) == ']') {
int propStart = StringMan.findMatchingBracket(input, input.length() - 1);
if (propStart == -1) {
return this;
}
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
charSequence.setString(input);
charSequence.setSubstring(0, propStart);
BlockType type = null;
List<BlockType> blockTypeList = null;
if (StringMan.isAlphanumericUnd(charSequence)) {
type = BlockTypes.get(charSequence);
} else {
String regex = charSequence.toString();
blockTypeList = new ArrayList<>();
for (BlockType myType : BlockTypesCache.values) {
if (myType.getId().matches(regex)) {
blockTypeList.add(myType);
}
}
if (blockTypeList.size() == 1) {
type = blockTypeList.get(0);
}
}
PropertyKey key = null;
int length = input.length();
int last = propStart + 1;
Operator operator = null;
boolean wrap = false;
for (int i = last; i < length; i++) {
char c = input.charAt(i);
switch (c) {
case '[':
case '{':
case '(':
int next = StringMan.findMatchingBracket(input, i);
if (next != -1) {
i = next;
}
break;
case ']':
case ',': {
charSequence.setSubstring(last, i);
char firstChar = input.charAt(last + 1);
if (type != null) {
add(type, key, operator, charSequence, wrap);
} else {
for (BlockType myType : blockTypeList) {
add(myType, key, operator, charSequence, wrap);
}
}
last = i + 1;
break;
}
default:
Operator tmp = getOp(c);
if (tmp != null) {
operator = tmp;
charSequence.setSubstring(last, i);
char cp = input.charAt(i + 1);
boolean extra = cp == '=';
wrap = cp == '~';
if (extra || wrap) {
i++;
}
if (charSequence.length() > 0) {
key = PropertyKey.getByName(charSequence);
}
last = i + 1;
}
break;
}
}
}
return this;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BaseBlock block = getExtent().getFullBlock(position);
return apply(block, block);
}
public BaseBlock apply(BaseBlock block, BaseBlock orDefault) {
int ordinal = block.getOrdinal();
int newOrdinal = transformed[ordinal];
if (newOrdinal != ordinal) {
CompoundTag nbt = block.getNbtData();
BlockState newState = BlockState.getFromOrdinal(newOrdinal);
return newState.toBaseBlock(nbt);
}
return orDefault;
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
int ordinal = get.getOrdinal(extent);
int newOrdinal = transformed[ordinal];
if (newOrdinal != ordinal) {
set.setOrdinal(extent, newOrdinal);
}
return false;
}
}

Datei anzeigen

@ -4,6 +4,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
@ -18,16 +19,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class RandomFullClipboardPattern extends AbstractPattern {
private final Extent extent;
private final List<ClipboardHolder> clipboards;
private final boolean randomRotate;
private final boolean randomFlip;
private final Vector3 flipVector = Vector3.at(1, 0, 0).multiply(-2).add(1, 1, 1);
public RandomFullClipboardPattern(Extent extent, List<ClipboardHolder> clipboards, boolean randomRotate, boolean randomFlip) {
/**
* Create a new {@link Pattern} instance
*
* @param clipboards list of clipboards to choose from. Does not paste air
* @param randomRotate if the clipboard should be randomly rotated (through multiples of 90)
* @param randomFlip if the clipboard should be randomly flipped
*/
public RandomFullClipboardPattern(List<ClipboardHolder> clipboards, boolean randomRotate, boolean randomFlip) {
checkNotNull(clipboards);
this.clipboards = clipboards;
this.extent = extent;
this.randomRotate = randomRotate;
this.randomFlip = randomFlip;
}
@ -40,7 +46,7 @@ public class RandomFullClipboardPattern extends AbstractPattern {
transform = transform.rotateY(ThreadLocalRandom.current().nextInt(4) * 90);
holder.setTransform(new AffineTransform().rotateY(ThreadLocalRandom.current().nextInt(4) * 90));
}
if (randomFlip) {
if (randomFlip && ThreadLocalRandom.current().nextBoolean()) {
transform = transform.scale(flipVector);
}
if (!transform.isIdentity()) {

Datei anzeigen

@ -15,6 +15,8 @@ public class RandomOffsetPattern extends AbstractPattern {
private final int dx;
private final int dy;
private final int dz;
private final int minY;
private final int maxY;
private final Pattern pattern;
private final transient int dx2;
@ -23,7 +25,17 @@ public class RandomOffsetPattern extends AbstractPattern {
private final transient MutableBlockVector3 mutable = new MutableBlockVector3();
private final transient SplittableRandom r;
public RandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
* @param dx offset x
* @param dy offset y
* @param dz offset z
* @param minY min applicable y (inclusive
* @param maxY max applicable y (inclusive
*/
public RandomOffsetPattern(Pattern pattern, int dx, int dy, int dz, int minY, int maxY) {
this.pattern = pattern;
this.dx = dx;
this.dy = dy;
@ -32,6 +44,8 @@ public class RandomOffsetPattern extends AbstractPattern {
this.dy2 = dy * 2 + 1;
this.dz2 = dz * 2 + 1;
this.r = new SplittableRandom();
this.minY = minY;
this.maxY = maxY;
}
@ -48,6 +62,9 @@ public class RandomOffsetPattern extends AbstractPattern {
mutable.mutX((set.getX() + r.nextInt(dx2) - dx));
mutable.mutY((set.getY() + r.nextInt(dy2) - dy));
mutable.mutZ((set.getZ() + r.nextInt(dz2) - dz));
if (mutable.getY() < minY || mutable.getY() > maxY) {
return false;
}
return pattern.apply(extent, get, mutable);
}

Datei anzeigen

@ -11,11 +11,22 @@ import com.sk89q.worldedit.world.block.BaseBlock;
public class RelativePattern extends AbstractPattern implements ResettablePattern {
private final Pattern pattern;
private BlockVector3 origin;
private final int minY;
private final int maxY;
private final MutableBlockVector3 mutable = new MutableBlockVector3();
private BlockVector3 origin;
public RelativePattern(Pattern pattern) {
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
* @param minY min applicable y (inclusive
* @param maxY max applicable y (inclusive
*/
public RelativePattern(Pattern pattern, int minY, int maxY) {
this.pattern = pattern;
this.minY = minY;
this.maxY = maxY;
}
@Override
@ -36,6 +47,9 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter
}
mutable.mutX(set.getX() - origin.getX());
mutable.mutY(set.getY() - origin.getY());
if (mutable.getY() < minY || mutable.getY() > maxY) {
return false;
}
mutable.mutZ(set.getZ() - origin.getZ());
return pattern.apply(extent, get, mutable);
}

Datei anzeigen

@ -1,13 +1,16 @@
package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.TextureHolder;
import com.fastasyncworldedit.core.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.awt.Color;
@ -17,33 +20,53 @@ public class SaturatePattern extends AbstractPattern {
private final int color;
private final Extent extent;
public SaturatePattern(Extent extent, int color, TextureHolder texture) {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param holder {@link TextureHolder} to use to get textures
* @param r red channel, clamped 0 -> 255
* @param g green channel, clamped 0 -> 255
* @param b blue channel, clamped 0 -> 255
* @param a alpha channel, clamped 0 -> 255
*/
public SaturatePattern(Extent extent, TextureHolder holder, int r, int g, int b, int a) {
this.extent = extent;
this.holder = texture;
this.color = new Color(color).getRGB();
this.holder = holder;
this.color = new Color(MathMan.clamp(r, 0, 255), MathMan.clamp(g, 0, 255), MathMan.clamp(b, 0, 255), MathMan.clamp(a, 0
, 255)).getRGB();
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BlockType block = extent.getBlock(position).getBlockType();
BlockType type = extent.getBlock(position).getBlockType();
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(block);
int newColor = util.multiplyColor(currentColor, color);
int currentColor;
if (type == BlockTypes.GRASS_BLOCK) {
currentColor = holder.getTextureUtil().getColor(extent.getBiome(position));
} else {
currentColor = holder.getTextureUtil().getColor(type);
}
int newColor = TextureUtil.multiplyColor(currentColor, color);
return util.getNearestBlock(newColor).getDefaultState().toBaseBlock();
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType block = get.getBlock(extent).getBlockType();
BlockType type = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(block);
int currentColor;
if (type == BlockTypes.GRASS_BLOCK) {
currentColor = holder.getTextureUtil().getColor(extent.getBiome(get));
} else {
currentColor = holder.getTextureUtil().getColor(type);
}
if (currentColor == 0) {
return false;
}
int newColor = util.multiplyColor(currentColor, color);
int newColor = TextureUtil.multiplyColor(currentColor, color);
BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock.equals(block)) {
if (newBlock.equals(type)) {
return false;
}
return set.setBlock(extent, newBlock.getDefaultState());

Datei anzeigen

@ -1,12 +1,15 @@
package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.util.TextureHolder;
import com.fastasyncworldedit.core.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import static com.google.common.base.Preconditions.checkNotNull;
@ -16,23 +19,43 @@ public class ShadePattern extends AbstractPattern {
private final Extent extent;
private final boolean darken;
public ShadePattern(Extent extent, boolean darken, TextureUtil util) {
/**
* Create a new {@link Pattern} instance
*
* @param extent extent to set to
* @param holder {@link TextureHolder} to use for textures
* @param darken if the shade should darken or lighten colours
*/
public ShadePattern(Extent extent, TextureHolder holder, boolean darken) {
checkNotNull(extent);
this.extent = extent;
this.util = util;
this.util = holder.getTextureUtil();
this.darken = darken;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
BlockType block = extent.getBlock(position).getBlockType();
return (darken ? util.getDarkerBlock(block) : util.getLighterBlock(block)).getDefaultState().toBaseBlock();
BlockType type;
if (block == BlockTypes.GRASS_BLOCK) {
int color = util.getColor(extent.getBiome(position));
type = (darken ? util.getDarkerBlock(color) : util.getLighterBlock(color));
} else {
type = (darken ? util.getDarkerBlock(block) : util.getLighterBlock(block));
}
return type.getDefaultState().toBaseBlock();
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType type = get.getBlock(extent).getBlockType();
BlockType newType = (darken ? util.getDarkerBlock(type) : util.getLighterBlock(type));
BlockType newType;
if (type == BlockTypes.GRASS_BLOCK) {
int color = util.getColor(extent.getBiome(get));
newType = (darken ? util.getDarkerBlock(color) : util.getLighterBlock(color));
} else {
newType = (darken ? util.getDarkerBlock(type) : util.getLighterBlock(type));
}
if (type != newType) {
return set.setBlock(extent, newType.getDefaultState());
}

Datei anzeigen

@ -18,6 +18,8 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
private final int dx;
private final int dy;
private final int dz;
private final int minY;
private final int maxY;
private final Pattern pattern;
private final int dx2;
@ -26,19 +28,23 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
private final MutableBlockVector3 mutable;
private final SplittableRandom r;
public static boolean[] getTypes() {
boolean[] types = new boolean[BlockTypes.size()];
for (BlockType type : BlockTypesCache.values) {
types[type.getInternalId()] = type.getMaterial().isSolid();
}
return types;
}
public SolidRandomOffsetPattern(Pattern pattern, int dx, int dy, int dz) {
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
* @param dx offset x
* @param dy offset y
* @param dz offset z
* @param minY min applicable y (inclusive
* @param maxY max applicable y (inclusive
*/
public SolidRandomOffsetPattern(Pattern pattern, int dx, int dy, int dz, int minY, int maxY) {
this.pattern = pattern;
this.dx = dx;
this.dy = dy;
this.dz = dz;
this.minY = minY;
this.maxY = maxY;
this.dx2 = dx * 2 + 1;
this.dy2 = dy * 2 + 1;
@ -47,6 +53,14 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
this.mutable = new MutableBlockVector3();
}
public static boolean[] getTypes() {
boolean[] types = new boolean[BlockTypes.size()];
for (BlockType type : BlockTypesCache.values) {
types[type.getInternalId()] = type.getMaterial().isSolid();
}
return types;
}
@Override
public BaseBlock applyBlock(BlockVector3 position) {
mutable.mutX(position.getX() + r.nextInt(dx2) - dx);
@ -63,6 +77,9 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
mutable.mutX(set.getX() + r.nextInt(dx2) - dx);
mutable.mutY(set.getY() + r.nextInt(dy2) - dy);
if (mutable.getY() < minY || mutable.getY() > maxY) {
return false;
}
mutable.mutZ(set.getZ() + r.nextInt(dz2) - dz);
BaseBlock block = pattern.applyBlock(mutable);
if (block.getMaterial().isSolid()) {

Datei anzeigen

@ -13,13 +13,25 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern {
private final Pattern pattern;
private final int moves;
private final int minY;
private final int maxY;
private final MutableBlockVector3 cur;
private final MutableBlockVector3[] buffer;
private final MutableBlockVector3[] allowed;
public SurfaceRandomOffsetPattern(Pattern pattern, int distance) {
/**
* Create a new {@link Pattern} instance
*
* @param pattern pattern to apply
* @param distance number of "spreads" to make
* @param minY min applicable y (inclusive
* @param maxY max applicable y (inclusive
*/
public SurfaceRandomOffsetPattern(Pattern pattern, int distance, int minY, int maxY) {
this.pattern = pattern;
this.minY = minY;
this.maxY = maxY;
this.moves = Math.min(255, distance);
cur = new MutableBlockVector3();
this.buffer = new MutableBlockVector3[BreadthFirstSearch.DIAGONAL_DIRECTIONS.length];
@ -70,12 +82,12 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern {
int y = v.getBlockY();
int z = v.getBlockZ();
v.mutY(y + 1);
if (canPassthrough(v)) {
if (y < maxY && canPassthrough(v)) {
v.mutY(y);
return true;
}
v.mutY(y - 1);
if (canPassthrough(v)) {
if (y > minY && canPassthrough(v)) {
v.mutY(y);
return true;
}

Datei anzeigen

@ -1,6 +1,7 @@
package com.fastasyncworldedit.core.util;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockType;
import java.awt.image.BufferedImage;
@ -22,11 +23,6 @@ public class DelegateTextureUtil extends TextureUtil {
return parent.getNearestBlock(color);
}
@Override
public BlockType getNearestBlock(BlockType block) {
return parent.getNearestBlock(block);
}
@Override
public BlockType getNextNearestBlock(int color) {
return parent.getNextNearestBlock(color);
@ -47,11 +43,26 @@ public class DelegateTextureUtil extends TextureUtil {
return parent.getDarkerBlock(block);
}
@Override
public BlockType getLighterBlock(final int color) {
return parent.getLighterBlock(color);
}
@Override
public BlockType getDarkerBlock(final int color) {
return parent.getDarkerBlock(color);
}
@Override
public int getColor(BlockType block) {
return parent.getColor(block);
}
@Override
public int getColor(final BiomeType biome) {
return parent.getColor(biome);
}
@Override
public boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color, int biomePriority) {
return parent.getIsBlockCloserThanBiome(blockAndBiomeIdOutput, color, biomePriority);
@ -77,11 +88,6 @@ public class DelegateTextureUtil extends TextureUtil {
return parent.getFolder();
}
@Override
public int combineTransparency(int top, int bottom) {
return parent.combineTransparency(top, bottom);
}
@Override
public void calculateLayerArrays() {
parent.calculateLayerArrays();
@ -92,11 +98,6 @@ public class DelegateTextureUtil extends TextureUtil {
parent.loadModTextures();
}
@Override
public int multiplyColor(int c1, int c2) {
return parent.multiplyColor(c1, c2);
}
@Override
public BlockType getNearestBlock(BlockType block, boolean darker) {
return parent.getNearestBlock(block, darker);
@ -112,19 +113,4 @@ public class DelegateTextureUtil extends TextureUtil {
return parent.hasAlpha(color);
}
@Override
public long colorDistance(int c1, int c2) {
return parent.colorDistance(c1, c2);
}
@Override
public long colorDistance(int red1, int green1, int blue1, int c2) {
return parent.colorDistance(red1, green1, blue1, c2);
}
@Override
public long getDistance(BufferedImage image, int c1) {
return parent.getDistance(image, c1);
}
}

Datei anzeigen

@ -11,15 +11,16 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import org.apache.logging.log4j.Logger;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
@ -32,24 +33,18 @@ import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.apache.logging.log4j.LogManager.getLogger;
// TODO FIXME
public class TextureUtil implements TextureHolder {
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -63,19 +58,6 @@ public class TextureUtil implements TextureHolder {
}
private final File folder;
protected int[] blockColors = new int[BlockTypes.size()];
protected long[] blockDistance = new long[BlockTypes.size()];
protected long[] distances;
protected int[] validColors;
protected int[] validBlockIds;
protected int[] validLayerColors;
protected int[][] validLayerBlocks;
protected int[] validMixBiomeColors;
protected long[] validMixBiomeIds;
/**
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
*/
protected BiomeColor[] validBiomes;
private final BiomeColor[] biomes = new BiomeColor[]{
// ID Name Temperature, rainfall, grass, foliage colors
// - note: the colors here are just placeholders, they are computed in the program
@ -122,17 +104,17 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(37, "badlands", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(38, "wooded_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(39, "badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(40, "small_end_islands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(41, "end_midlands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(42, "end_highlands", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(43, "end_barrens", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(44, "warm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(45, "lukewarm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(46, "cold_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(47, "deep_warm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(48, "deep_lukewarm_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(49, "deep_cold_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(50, "deep_frozen_ocean", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(40, "small_end_islands", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(41, "end_midlands", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(42, "end_highlands", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(43, "end_barrens", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(44, "warm_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(45, "lukewarm_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(46, "cold_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(47, "deep_warm_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(48, "deep_lukewarm_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(49, "deep_cold_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(50, "deep_frozen_ocean", 0.8f, 0.5f, 0x92BD59, 0x77AB2F),
new BiomeColor(51, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(52, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(53, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
@ -242,22 +224,22 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(156, "tall_birch_hills", 0.6f, 0.6f, 0x92BD59, 0x77AB2F),
new BiomeColor(157, "dark_forest_hills", 0.7f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(158, "snowy_taiga_mountains", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(159, "Unknown", -0.5f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(159, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(160, "giant_spruce_taiga", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
// special exception, temperature not 0.3
new BiomeColor(161, "giant_spruce_taiga_hills", 0.25f, 0.8f, 0x92BD59, 0x77AB2F),
new BiomeColor(162, "modified_gravelly_mountains", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(162, "gravelly_mountains+", 0.2f, 0.3f, 0x92BD59, 0x77AB2F),
new BiomeColor(163, "shattered_savanna", 1.1f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(164, "shattered_savanna_plateau", 1.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(165, "eroded_badlands", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(166, "modified_wooded_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(167, "modified_badlands_plateau", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(168, "bamboo_jungle", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(169, "bamboo_jungle_hills", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(170, "Unknown Biome", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(171, "Unknown Biome", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(172, "Unknown Biome", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(173, "Unknown Biome", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(168, "bamboo_jungle_hills", 0.95f, 0.9f, 0x92BD59, 0x77AB2F),
new BiomeColor(170, "soul_sand_valley", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(171, "crimson_forest", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(172, "warped_forest", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(173, "basalt_deltas", 2.0f, 0.0f, 0x92BD59, 0x77AB2F),
new BiomeColor(174, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(175, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(176, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
@ -341,24 +323,41 @@ public class TextureUtil implements TextureHolder {
new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F)};
private final BlockType[] layerBuffer = new BlockType[2];
protected int[] blockColors = new int[BlockTypes.size()];
protected long[] blockDistance = new long[BlockTypes.size()];
protected long[] distances;
protected int[] validColors;
protected int[] validBlockIds;
protected int[] validLayerColors;
protected int[][] validLayerBlocks;
protected int[] validMixBiomeColors;
protected long[] validMixBiomeIds;
/**
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
*/
protected BiomeColor[] validBiomes;
/**
* Do not use. Use {@link Fawe#getTextureUtil()}
*/
public TextureUtil() throws FileNotFoundException {
this(MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.TEXTURES));
}
/**
* Do not use. Use {@link Fawe#getTextureUtil()}
*/
public TextureUtil(File folder) throws FileNotFoundException {
this.folder = folder;
if (!folder.exists()) {
try {
LOGGER.info("Downloading asset jar from Mojang, please wait...");
new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/" + "/.minecraft/versions/")
.mkdirs();
new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/").mkdirs();
try (BufferedInputStream in = new BufferedInputStream(
new URL("https://launcher.mojang.com/v1/objects/8d9b65467c7913fcf6f5b2e729d44a1e00fde150/client.jar")
.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(
Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/"
+ "/.minecraft/versions/1.17.1.jar")) {
Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.17.1.jar")) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
@ -367,14 +366,16 @@ public class TextureUtil implements TextureHolder {
LOGGER.info("Asset jar down has been downloaded successfully.");
} catch (IOException e) {
LOGGER.error(
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` folder with `.minecraft/versions` jar in it.");
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " +
"folder with a `.minecraft/versions` jar in it.");
LOGGER.error("If the file exists, please make sure the server has read access to the directory.");
}
} catch (AccessControlException e) {
LOGGER.error(
"Could not download asset jar. It's likely your file permission are setup improperly and do not allow fetching data from the Mojang servers.");
LOGGER.error(
"Please create the following folder manually: `FastAsyncWorldEdit/textures` with `.minecraft/versions` jar in it.");
"Please create the following folder manually: `FastAsyncWorldEdit/textures` with a `" +
".minecraft/versions` jar in it.");
}
}
@ -423,22 +424,155 @@ public class TextureUtil implements TextureHolder {
}
int factor1 = FACTORS[total1];
int factor2 = FACTORS[total2];
long r = (512 * (red1 * factor1 - red2 * factor2)) >> 10;
long g = (green1 * factor1 - green2 * factor2);
long b = (767 * (blue1 * factor1 - blue2 * factor2)) >> 10;
long r = (512 * ((long) red1 * factor1 - (long) red2 * factor2)) >> 10;
long g = ((long) green1 * factor1 - (long) green2 * factor2);
long b = (767 * ((long) blue1 * factor1 - (long) blue2 * factor2)) >> 10;
return (int) ((r * r + g * g + b * b) >> 25);
}
@Override public TextureUtil getTextureUtil() {
protected static long colorDistance(int c1, int c2) {
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1) & 0xFF;
return colorDistance(red1, green1, blue1, c2);
}
private static long colorDistance(int red1, int green1, int blue1, int c2) {
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2) & 0xFF;
int rmean = (red1 + red2) >> 1;
int r = red1 - red2;
int g = green1 - green2;
int b = blue1 - blue2;
int hd = hueDistance(red1, green1, blue1, red2, green2, blue2);
return (((long) (512 + rmean) * r * r) >> 8) + 4L * g * g + (((long) (767 - rmean) * b * b) >> 8) + ((long) hd * hd);
}
/**
* Combine two colors by multipling
*
* @param c1 color 1
* @param c2 color 2
* @return new color
*/
public static int multiplyColor(int c1, int c2) {
int alpha1 = (c1 >> 24) & 0xFF;
int alpha2 = (c2 >> 24) & 0xFF;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1) & 0xFF;
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2) & 0xFF;
int red = ((red1 * red2)) / 255;
int green = ((green1 * green2)) / 255;
int blue = ((blue1 * blue2)) / 255;
int alpha = ((alpha1 * alpha2)) / 255;
return (alpha << 24) + (red << 16) + (green << 8) + (blue);
}
/**
* Combine two colors by averaging
*
* @param c1 color 1
* @param c2 color 2
* @return new color
*/
public static int averageColor(int c1, int c2) {
int alpha1 = (c1 >> 24) & 0xFF;
int alpha2 = (c2 >> 24) & 0xFF;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1) & 0xFF;
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2) & 0xFF;
int red = ((red1 + red2)) >> 1;
int green = ((green1 + green2)) >> 1;
int blue = ((blue1 + blue2)) >> 1;
int alpha = ((alpha1 + alpha2)) >> 1;
return (alpha << 24) + (red << 16) + (green << 8) + (blue);
}
/**
* Combine multiple colors by multipling
*
* @param colors colors
* @return new color
*/
public static int averageColor(int... colors) {
int alpha = 0;
int red = 0;
int green = 0;
int blue = 0;
for (int c : colors) {
alpha += (c >> 24) & 0xFF;
red += (c >> 16) & 0xFF;
green += (c >> 8) & 0xFF;
blue += (c) & 0xFF;
}
int num = colors.length;
alpha /= num;
red /= num;
green /= num;
blue /= num;
return (alpha << 24) + (red << 16) + (green << 8) + (blue);
}
/**
* Assumes the top layer is a transparent color and the bottom is opaque
*/
public static int combineTransparency(int top, int bottom) {
int alpha1 = (top >> 24) & 0xFF;
int alpha2 = 255 - alpha1;
int red1 = (top >> 16) & 0xFF;
int green1 = (top >> 8) & 0xFF;
int blue1 = (top) & 0xFF;
int red2 = (bottom >> 16) & 0xFF;
int green2 = (bottom >> 8) & 0xFF;
int blue2 = (bottom) & 0xFF;
int red = ((red1 * alpha1) + (red2 * alpha2)) / 255;
int green = ((green1 * alpha1) + (green2 * alpha2)) / 255;
int blue = ((blue1 * alpha1) + (blue2 * alpha2)) / 255;
return (red << 16) + (green << 8) + (blue) + (255 << 24);
}
private static long getDistance(BufferedImage image, int c1) {
long totalDistSqr = 0;
int width = image.getWidth();
int height = image.getHeight();
int area = width * height;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1) & 0xFF;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int c2 = image.getRGB(x, y);
long distance = colorDistance(red1, green1, blue1, c2);
totalDistSqr += distance * distance;
}
}
return totalDistSqr / area;
}
@Override
public TextureUtil getTextureUtil() {
return this;
}
/**
* Get the block most closely matching a color based on the block's average color
*
* @param color color to match
* @return matching block
*/
public BlockType getNearestBlock(int color) {
long min = Long.MAX_VALUE;
int closest = 0;
int red1 = (color >> 16) & 0xFF;
int green1 = (color >> 8) & 0xFF;
int blue1 = (color >> 0) & 0xFF;
int blue1 = (color) & 0xFF;
int alpha = (color >> 24) & 0xFF;
for (int i = 0; i < validColors.length; i++) {
int other = validColors[i];
@ -456,20 +590,18 @@ public class TextureUtil implements TextureHolder {
return BlockTypes.get(closest);
}
public BlockType getNearestBlock(BlockType block) {
int color = getColor(block);
if (color == 0) {
return null;
}
return getNextNearestBlock(color);
}
/**
* Get the block most closely matching a color, without matching the color, based on the block's average color
*
* @param color color to match
* @return matching block
*/
public BlockType getNextNearestBlock(int color) {
long min = Long.MAX_VALUE;
int closest = 0;
int red1 = (color >> 16) & 0xFF;
int green1 = (color >> 8) & 0xFF;
int blue1 = (color >> 0) & 0xFF;
int blue1 = (color) & 0xFF;
int alpha = (color >> 24) & 0xFF;
for (int i = 0; i < validColors.length; i++) {
int other = validColors[i];
@ -495,7 +627,7 @@ public class TextureUtil implements TextureHolder {
long min = Long.MAX_VALUE;
int red1 = (color >> 16) & 0xFF;
int green1 = (color >> 8) & 0xFF;
int blue1 = (color >> 0) & 0xFF;
int blue1 = (color) & 0xFF;
int alpha = (color >> 24) & 0xFF;
for (int i = 0; i < validLayerColors.length; i++) {
int other = validLayerColors[i];
@ -512,23 +644,80 @@ public class TextureUtil implements TextureHolder {
return layerBuffer;
}
/**
* Get the next lightest block
*
* @param block input block
* @return next lightest block
*/
public BlockType getLighterBlock(BlockType block) {
return getNearestBlock(block, false);
}
/**
* Get the next darkest block
*
* @param block input block
* @return next darkest block
*/
public BlockType getDarkerBlock(BlockType block) {
return getNearestBlock(block, true);
}
/**
* Get the next lightest block
*
* @param color input color
* @return next lightest block
*/
public BlockType getLighterBlock(int color) {
return getNearestBlock(color, false);
}
/**
* Get the next darkest block
*
* @param color input color
* @return next darkest block
*/
public BlockType getDarkerBlock(int color) {
return getNearestBlock(color, true);
}
/**
* Get the integer representation of a block's RGBA color.
*
* @param block input block
* @return integer RGBA color
*/
public int getColor(BlockType block) {
if (block == BlockTypes.GRASS_BLOCK) {
return validBiomes[0].grassCombined;
}
return blockColors[block.getInternalId()];
}
/**
* Get the integer representation of a biomes's RGBA color when applied to grass.
*
* @param biome input biome
* @return integer RGBA color
*/
public int getColor(BiomeType biome) {
return validBiomes[biome.getInternalId()].grassCombined;
}
/**
* Get the {@link BiomeColor} entry from a biome's ID
*
* @param biome biome id
* @return the {@link BiomeColor} entry
*/
public BiomeColor getBiome(int biome) {
return biomes[biome];
}
public boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color, int biomePriority) {
protected boolean getIsBlockCloserThanBiome(char[] blockAndBiomeIdOutput, int color, int biomePriority) {
BlockType block = getNearestBlock(color);
TextureUtil.BiomeColor biome = getNearestBiome(color);
int blockColor = getColor(block);
@ -537,13 +726,13 @@ public class TextureUtil implements TextureHolder {
return colorDistance(biome.grassCombined, color) - biomePriority > colorDistance(blockColor, color);
}
public int getBiomeMix(int[] biomeIdsOutput, int color) {
protected int getBiomeMix(int[] biomeIdsOutput, int color) {
long closest = Long.MAX_VALUE;
int closestAverage = Integer.MAX_VALUE;
long min = Long.MAX_VALUE;
int red1 = (color >> 16) & 0xFF;
int green1 = (color >> 8) & 0xFF;
int blue1 = (color >> 0) & 0xFF;
int blue1 = (color) & 0xFF;
int alpha = (color >> 24) & 0xFF;
for (int i = 0; i < validMixBiomeColors.length; i++) {
int other = validMixBiomeColors[i];
@ -556,12 +745,18 @@ public class TextureUtil implements TextureHolder {
}
}
}
biomeIdsOutput[0] = (int) ((closest >> 0) & 0xFF);
biomeIdsOutput[0] = (int) ((closest) & 0xFF);
biomeIdsOutput[1] = (int) ((closest >> 8) & 0xFF);
biomeIdsOutput[2] = (int) ((closest >> 16) & 0xFF);
return closestAverage;
}
/**
* Get the biome most closely matching a color based on the block's average color
*
* @param color color to match
* @return matching block
*/
public BiomeColor getNearestBiome(int color) {
int grass = blockColors[BlockTypes.GRASS_BLOCK.getInternalId()];
if (grass == 0) {
@ -571,7 +766,7 @@ public class TextureUtil implements TextureHolder {
long min = Long.MAX_VALUE;
int red = (color >> 16) & 0xFF;
int green = (color >> 8) & 0xFF;
int blue = (color >> 0) & 0xFF;
int blue = (color) & 0xFF;
for (BiomeColor biome : validBiomes) {
long distance = colorDistance(red, green, blue, biome.grassCombined);
if (distance < min) {
@ -582,17 +777,10 @@ public class TextureUtil implements TextureHolder {
return closest;
}
public File getFolder() {
protected File getFolder() {
return folder;
}
public long colorDistance(int c1, int c2) {
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1 >> 0) & 0xFF;
return colorDistance(red1, green1, blue1, c2);
}
private BufferedImage readImage(ZipFile zipFile, String name) throws IOException {
ZipEntry entry = getEntry(zipFile, name);
if (entry != null) {
@ -619,56 +807,35 @@ public class TextureUtil implements TextureHolder {
if (folder.exists()) {
// Get all the jar files
File[] files = folder.listFiles((dir, name) -> name.endsWith(".jar"));
for (BlockType blockType : BlockTypesCache.values) {
BlockMaterial material = blockType.getMaterial();
if (!material.isSolid() || !material.isFullCube()) {
continue;
}
int color = material.getMapColor();
if (color != 0) {
colorMap.put(blockType.getInternalId(), (Integer) color);
}
}
if (files.length == 0) {
new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/" + "/.minecraft/versions/")
new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/")
.mkdirs();
try (BufferedInputStream in = new BufferedInputStream(
new URL("https://launcher.mojang.com/v1/objects/8d9b65467c7913fcf6f5b2e729d44a1e00fde150/client.jar")
.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(
Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/"
+ "/.minecraft/versions/1.17.1.jar")) {
Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.17.1.jar")) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
fileOutputStream.close();
files = folder.listFiles((dir, name) -> name.endsWith(".jar"));
} catch (IOException e) {
LOGGER.error(
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` folder with `.minecraft/versions` jar or mods in it.");
"Could not download version jar. Please do so manually by creating a `FastAsyncWorldEdit/textures` " +
"folder with a `.minecraft/versions` jar or mods in it.");
LOGGER.error("If the file exists, please make sure the server has read access to the directory.");
}
} else {
}
if ((files.length > 0)) {
for (File file : files) {
ZipFile zipFile = new ZipFile(file);
// Get all the groups in the current jar
// The vanilla textures are in `assets/minecraft`
// A jar may contain textures for multiple mods
Enumeration<? extends ZipEntry> entries = zipFile.entries();
Set<String> mods = new HashSet<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
Path path = Paths.get(name);
if (path.startsWith("assets" + File.separator)) {
String[] split = path.toString().split(Pattern.quote(File.separator));
if (split.length > 1) {
String modId = split[1];
mods.add(modId);
}
}
}
String modelsDir = "assets/%1$s/models/block/%2$s.json";
String texturesDir = "assets/%1$s/textures/%2$s.png";
@ -679,18 +846,24 @@ public class TextureUtil implements TextureHolder {
if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) {
continue;
}
switch (blockType.getId().toLowerCase(Locale.ROOT)) {
case "slime_block":
case "honey_block":
case "mob_spawner":
case "spawner":
continue;
}
int combined = blockType.getInternalId();
String id = blockType.getId();
String[] split = id.split(":", 2);
String name = split.length == 1 ? id : split[1];
String nameSpace = split.length == 1 ? "" : split[0];
Map<String, String> texturesMap = new ConcurrentHashMap<>();
// Read models
String modelFileName = String.format(modelsDir, nameSpace, name);
ZipEntry entry = getEntry(zipFile, modelFileName);
if (entry == null) {
getLogger(TextureUtil.class).error("Cannot find {} in {}", modelFileName, file);
LOGGER.error("Cannot find {} in {}", modelFileName, file);
continue;
}
@ -728,7 +901,7 @@ public class TextureUtil implements TextureHolder {
BufferedImage image = readImage(zipFile, textureFileName);
if (image == null) {
getLogger(TextureUtil.class).error("Cannot find {}", textureFileName);
LOGGER.error("Cannot find {}", textureFileName);
continue;
}
int color = ImageUtil.getColor(image);
@ -738,15 +911,16 @@ public class TextureUtil implements TextureHolder {
}
Integer grass = null;
{
String grassFileName = String.format(texturesDir, "minecraft", "grass_block_top");
String grassFileName = String.format(texturesDir, "minecraft", "block/grass_block_top");
BufferedImage image = readImage(zipFile, grassFileName);
if (image != null) {
grass = ImageUtil.getColor(image);
}
}
if (grass != null) {
colorMap.put(BlockTypes.GRASS_BLOCK.getInternalId(), grass);
// assets\minecraft\textures\colormap
ZipEntry grassEntry = getEntry(zipFile, "assets/minecraft/textures/colormap/grass_block.png");
ZipEntry grassEntry = getEntry(zipFile, "assets/minecraft/textures/colormap/grass.png");
if (grassEntry != null) {
try (InputStream is = zipFile.getInputStream(grassEntry)) {
BufferedImage image = ImageIO.read(is);
@ -789,8 +963,6 @@ public class TextureUtil implements TextureHolder {
uniqueColors.add(color);
}
}
int count = 0;
int count2 = 0;
uniqueBiomesColors.clear();
LongArrayList layerIds = new LongArrayList();
@ -803,9 +975,8 @@ public class TextureUtil implements TextureHolder {
BiomeColor c3 = uniqueColors.get(k);
int average = averageColor(c1.grass, c2.grass, c3.grass);
if (uniqueBiomesColors.add(average)) {
count++;
layerColors.add(average);
layerIds.add((c1.id) + (c2.id << 8) + (c3.id << 16));
layerIds.add((c1.id) + ((long) c2.id << 8) + ((long) c3.id << 16));
}
}
}
@ -848,75 +1019,6 @@ public class TextureUtil implements TextureHolder {
calculateLayerArrays();
}
public int multiplyColor(int c1, int c2) {
int alpha1 = (c1 >> 24) & 0xFF;
int alpha2 = (c2 >> 24) & 0xFF;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1 >> 0) & 0xFF;
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2 >> 0) & 0xFF;
int red = ((red1 * red2)) / 255;
int green = ((green1 * green2)) / 255;
int blue = ((blue1 * blue2)) / 255;
int alpha = ((alpha1 * alpha2)) / 255;
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
}
public int averageColor(int c1, int c2) {
int alpha1 = (c1 >> 24) & 0xFF;
int alpha2 = (c2 >> 24) & 0xFF;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1 >> 0) & 0xFF;
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2 >> 0) & 0xFF;
int red = ((red1 + red2)) >> 1;
int green = ((green1 + green2)) >> 1;
int blue = ((blue1 + blue2)) >> 1;
int alpha = ((alpha1 + alpha2)) >> 1;
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
}
public int averageColor(int... colors) {
int alpha = 0;
int red = 0;
int green = 0;
int blue = 0;
for (int c : colors) {
alpha += (c >> 24) & 0xFF;
red += (c >> 16) & 0xFF;
green += (c >> 8) & 0xFF;
blue += (c >> 0) & 0xFF;
}
int num = colors.length;
alpha /= num;
red /= num;
green /= num;
blue /= num;
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
}
/**
* Assumes the top layer is a transparent color and the bottom is opaque
*/
public int combineTransparency(int top, int bottom) {
int alpha1 = (top >> 24) & 0xFF;
int alpha2 = 255 - alpha1;
int red1 = (top >> 16) & 0xFF;
int green1 = (top >> 8) & 0xFF;
int blue1 = (top >> 0) & 0xFF;
int red2 = (bottom >> 16) & 0xFF;
int green2 = (bottom >> 8) & 0xFF;
int blue2 = (bottom >> 0) & 0xFF;
int red = ((red1 * alpha1) + (red2 * alpha2)) / 255;
int green = ((green1 * alpha1) + (green2 * alpha2)) / 255;
int blue = ((blue1 * alpha1) + (blue2 * alpha2)) / 255;
return (red << 16) + (green << 8) + (blue << 0) + (255 << 24);
}
protected void calculateLayerArrays() {
Int2ObjectOpenHashMap<int[]> colorLayerMap = new Int2ObjectOpenHashMap<>();
for (int i = 0; i < validBlockIds.length; i++) {
@ -956,7 +1058,7 @@ public class TextureUtil implements TextureHolder {
int closest = 0;
int red1 = (color >> 16) & 0xFF;
int green1 = (color >> 8) & 0xFF;
int blue1 = (color >> 0) & 0xFF;
int blue1 = (color) & 0xFF;
int alpha = (color >> 24) & 0xFF;
int intensity1 = 2 * red1 + 4 * green1 + 3 * blue1;
for (int i = 0; i < validColors.length; i++) {
@ -964,7 +1066,7 @@ public class TextureUtil implements TextureHolder {
if (other != color && ((other >> 24) & 0xFF) == alpha) {
int red2 = (other >> 16) & 0xFF;
int green2 = (other >> 8) & 0xFF;
int blue2 = (other >> 0) & 0xFF;
int blue2 = (other) & 0xFF;
int intensity2 = 2 * red2 + 4 * green2 + 3 * blue2;
if (darker ? intensity2 >= intensity1 : intensity1 >= intensity2) {
continue;
@ -1003,36 +1105,6 @@ public class TextureUtil implements TextureHolder {
return alpha != 255;
}
protected long colorDistance(int red1, int green1, int blue1, int c2) {
int red2 = (c2 >> 16) & 0xFF;
int green2 = (c2 >> 8) & 0xFF;
int blue2 = (c2 >> 0) & 0xFF;
int rmean = (red1 + red2) >> 1;
int r = red1 - red2;
int g = green1 - green2;
int b = blue1 - blue2;
int hd = hueDistance(red1, green1, blue1, red2, green2, blue2);
return (((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8) + (hd * hd);
}
public long getDistance(BufferedImage image, int c1) {
long totalDistSqr = 0;
int width = image.getWidth();
int height = image.getHeight();
int area = width * height;
int red1 = (c1 >> 16) & 0xFF;
int green1 = (c1 >> 8) & 0xFF;
int blue1 = (c1 >> 0) & 0xFF;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int c2 = image.getRGB(x, y);
long distance = colorDistance(red1, green1, blue1, c2);
totalDistSqr += distance * distance;
}
}
return totalDistSqr / area;
}
public int[] getValidBlockIds() {
return validBlockIds.clone();
}

Datei anzeigen

@ -350,7 +350,7 @@ public final class StringUtil {
*/
public static List<String> split(String input, char delimiter, char open, char close) {
if (input.indexOf(open) == -1 && input.indexOf(close) == -1) {
return Arrays.asList(input.split(String.valueOf(delimiter)));
return Arrays.asList(input.split(String.valueOf(delimiter), -1));
}
int level = 0;
int begin = 0;
@ -366,7 +366,7 @@ public final class StringUtil {
level--;
}
}
if (begin < input.length()) {
if (begin <= input.length()) {
split.add(input.substring(begin));
}
return split;

Datei anzeigen

@ -20,6 +20,7 @@
package com.sk89q.worldedit;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.google.common.base.Throwables;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
@ -37,6 +38,7 @@ import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.factory.ItemFactory;
import com.sk89q.worldedit.extension.factory.MaskFactory;
import com.sk89q.worldedit.extension.factory.PatternFactory;
import com.fastasyncworldedit.core.extension.factory.TransformFactory;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
@ -138,6 +140,7 @@ public final class WorldEdit {
private final ItemFactory itemFactory = new ItemFactory(this);
private final MaskFactory maskFactory = new MaskFactory(this);
private final PatternFactory patternFactory = new PatternFactory(this);
private final TransformFactory transformFactory = new TransformFactory(this);
static {
getVersion();
@ -240,6 +243,16 @@ public final class WorldEdit {
return patternFactory;
}
/**
* Get the transform factory from which new {@link ResettableExtent}s
* can be constructed.
*
* @return the transform factory
*/
public TransformFactory getTransformFactory() {
return transformFactory;
}
/**
* Return the session manager.
*

Datei anzeigen

@ -86,6 +86,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class GeneralCommands {
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public GeneralCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
public static void register(
CommandRegistrationHandler registration,
CommandManager commandManager,
@ -149,18 +161,6 @@ public class GeneralCommands {
return CommandUtil.createNewCommandReplacementText("//perf " + flipped);
}
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public GeneralCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
@Command(
name = "/limit",
desc = "Modify block change limit"
@ -451,50 +451,6 @@ public class GeneralCommands {
);
}
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;
private final int page;
ItemSearcher(String search, boolean blocksOnly, boolean itemsOnly, int page) {
this.blocksOnly = blocksOnly;
this.itemsOnly = itemsOnly;
this.search = search;
this.page = page;
}
@Override
public Component call() throws Exception {
String command = "/searchitem " + (blocksOnly ? "-b " : "") + (itemsOnly ? "-i " : "") + "-p %page% " + search;
Map<String, Component> results = new TreeMap<>();
String idMatch = search.replace(' ', '_');
String nameMatch = search.toLowerCase(Locale.ROOT);
for (ItemType searchType : ItemType.REGISTRY) {
if (blocksOnly && !searchType.hasBlockType()) {
continue;
}
if (itemsOnly && searchType.hasBlockType()) {
continue;
}
final String id = searchType.getId();
if (id.contains(idMatch)) {
Component name = searchType.getRichName();
results.put(id, TextComponent.builder()
.append(name)
.append(" (" + id + ")")
.build());
}
}
List<Component> list = new ArrayList<>(results.values());
return PaginationBox.fromComponents("Search results for '" + search + "'", command, list)
.create(page);
}
}
//FAWE start
@Command(
name = "/gtexture",
@ -592,15 +548,18 @@ public class GeneralCommands {
}
}
@Command(
name = "/gtransform",
aliases = {"gtransform"},
desc = "Set the global transform"
)
@CommandPermissions({"worldedit.global-transform", "worldedit.transform.global"})
public void gtransform(Player player, EditSession editSession, LocalSession session, ResettableExtent transform) throws
WorldEditException {
public void gtransform(
Player player,
EditSession editSession,
LocalSession session,
@Arg(desc = "The transform to set", def = "") ResettableExtent transform
) throws WorldEditException {
session.setTransform(transform);
if (transform == null) {
player.print(Caption.of("fawe.worldedit.general.transform.disabled"));
@ -648,5 +607,49 @@ public class GeneralCommands {
actor.print(Caption.of("worldedit.fast.enabled"));
}
}
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;
private final int page;
ItemSearcher(String search, boolean blocksOnly, boolean itemsOnly, int page) {
this.blocksOnly = blocksOnly;
this.itemsOnly = itemsOnly;
this.search = search;
this.page = page;
}
@Override
public Component call() throws Exception {
String command = "/searchitem " + (blocksOnly ? "-b " : "") + (itemsOnly ? "-i " : "") + "-p %page% " + search;
Map<String, Component> results = new TreeMap<>();
String idMatch = search.replace(' ', '_');
String nameMatch = search.toLowerCase(Locale.ROOT);
for (ItemType searchType : ItemType.REGISTRY) {
if (blocksOnly && !searchType.hasBlockType()) {
continue;
}
if (itemsOnly && searchType.hasBlockType()) {
continue;
}
final String id = searchType.getId();
if (id.contains(idMatch)) {
Component name = searchType.getRichName();
results.put(id, TextComponent.builder()
.append(name)
.append(" (" + id + ")")
.build());
}
}
List<Component> list = new ArrayList<>(results.values());
return PaginationBox.fromComponents("Search results for '" + search + "'", command, list)
.create(page);
}
}
//FAWE end
}

Datei anzeigen

@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.command.tool.TargetMode;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.scroll.Scroll;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.StringMan;
import com.google.common.collect.Iterables;
@ -360,33 +361,33 @@ public class ToolUtilCommands {
player.print(Caption.of("fawe.worldedit.brush.brush.source.mask"));
}
// TODO: Ping @MattBDev to reimplement 2020-02-04
// @Command(
// name = "transform",
// desc = "Set the brush transform"
// )
// @CommandPermissions({"worldedit.brush.options.transform", "worldedit.transform.brush"})
// public void transform(Player player, LocalSession session, EditSession editSession,
// @Arg(desc = "The transform", def = "") ResettableExtent transform,
// @Switch(name = 'h', desc = "Whether the offhand should be considered or not")
// boolean offHand,
// Arguments arguments) throws WorldEditException {
// BrushTool tool = session.getBrushTool(player, false);
// if (tool == null) {
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.none"));
// return;
// }
// if (transform == null) {
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.transform.disabled"));
// tool.setTransform(null);
// return;
// }
// BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
// String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get())).getSubstring();
// settings.addSetting(BrushSettings.SettingType.TRANSFORM, lastArg);
// settings.setTransform(transform);
// tool.update();
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.transform"));
// }
@Command(
name = "transform",
aliases = {"/transform"},
desc = "Set the brush transform"
)
@CommandPermissions({"worldedit.brush.options.transform", "worldedit.transform.brush"})
public void transform(Player player, LocalSession session, EditSession editSession,
@Arg(desc = "The transform", def = "") ResettableExtent transform,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
Arguments arguments) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
return;
}
if (transform == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.transform.disabled"));
tool.setTransform(null);
return;
}
BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get())).getSubstring();
settings.addSetting(BrushSettings.SettingType.TRANSFORM, lastArg);
settings.setTransform(transform);
tool.update();
player.print(Caption.of("fawe.worldedit.brush.brush.transform"));
}
//FAWE end
}

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.argument;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.SupplyingExtent;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
@ -54,6 +55,23 @@ import java.util.function.Function;
public class FactoryConverter<T> implements ArgumentConverter<T> {
private final WorldEdit worldEdit;
private final Function<WorldEdit, AbstractFactory<T>> factoryExtractor;
private final String description;
@Nullable
private final Consumer<ParserContext> contextTweaker;
private FactoryConverter(
WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker
) {
this.worldEdit = worldEdit;
this.factoryExtractor = factoryExtractor;
this.description = description;
this.contextTweaker = contextTweaker;
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
commandManager.registerConverter(
Key.of(Pattern.class),
@ -67,6 +85,10 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
Key.of(BaseItem.class),
new FactoryConverter<>(worldEdit, WorldEdit::getItemFactory, "item", null)
);
commandManager.registerConverter(
Key.of(ResettableExtent.class),
new FactoryConverter<>(worldEdit, WorldEdit::getTransformFactory, "transform", null)
);
commandManager.registerConverter(
Key.of(Mask.class, ClipboardMask.class),
@ -90,24 +112,6 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
);
}
private final WorldEdit worldEdit;
private final Function<WorldEdit, AbstractFactory<T>> factoryExtractor;
private final String description;
@Nullable
private final Consumer<ParserContext> contextTweaker;
private FactoryConverter(
WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker
) {
this.worldEdit = worldEdit;
this.factoryExtractor = factoryExtractor;
this.description = description;
this.contextTweaker = contextTweaker;
}
@Override
public ConversionResult<T> convert(String argument, InjectedValueAccess context) {
Actor actor = context.injectedValue(Key.of(Actor.class))

Datei anzeigen

@ -234,6 +234,27 @@ public final class SuggestionHelper {
return Stream.empty();
}
//FAWE start
/**
* Returns a stream of suggestions for booleans.
*
* @param argumentInput the given input to filter with.
* @return a stream of suggestions.
*/
public static Stream<String> suggestBoolean(String argumentInput) {
if (argumentInput.isEmpty()) {
return Stream.of("true", "false");
}
if ("true".startsWith(argumentInput)) {
return Stream.of("true");
} else if ("false".startsWith(argumentInput)) {
return Stream.of("false");
}
// no valid input anymore
return Stream.empty();
}
//FAWE end
private static boolean isDouble(String input) {
boolean point = false;
for (char c : input.toCharArray()) {

Datei anzeigen

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.mask.AdjacentMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.AngleMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.RichMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.ExtremaMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.FalseMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.LiquidMaskParser;
@ -71,6 +72,10 @@ import java.util.stream.Collectors;
*/
public final class MaskFactory extends AbstractFactory<Mask> {
//FAWE start - rich mask parsing
private final RichMaskParser richMaskParser;
//FAWE end
/**
* Create a new mask registry.
*
@ -79,6 +84,10 @@ public final class MaskFactory extends AbstractFactory<Mask> {
public MaskFactory(WorldEdit worldEdit) {
super(worldEdit, new BlocksMaskParser(worldEdit));
//FAWE start - rich mask parsing
richMaskParser = new RichMaskParser(worldEdit);
//FAWE end
register(new ExistingMaskParser(worldEdit));
register(new AirMaskParser(worldEdit));
register(new SolidMaskParser(worldEdit));
@ -133,6 +142,25 @@ public final class MaskFactory extends AbstractFactory<Mask> {
continue;
}
//FAWE start - rich mask parsing
Mask match = richMaskParser.parseFromInput(component, context);
if (match != null) {
masks.add(match);
continue;
}
parseFromParsers(context, masks, component);
//FAWE end
}
return getMask(input, masks);
}
//FAWE start - rich mask parsing
private void parseFromParsers(
final ParserContext context,
final List<Mask> masks,
final String component
) {
Mask match = null;
for (InputParser<Mask> parser : getParsers()) {
match = parser.parseFromInput(component, context);
@ -147,6 +175,30 @@ public final class MaskFactory extends AbstractFactory<Mask> {
masks.add(match);
}
/**
* Parses a mask without considering parsing through the {@link RichMaskParser}, therefore not accepting
* "richer" parsing where & and , are used. Exists to prevent stack overflows.
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
public Mask parseWithoutRich(String input, ParserContext context) throws InputParseException {
List<Mask> masks = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
parseFromParsers(context, masks, component);
}
return getMask(input, masks);
}
private Mask getMask(final String input, final List<Mask> masks) {
switch (masks.size()) {
case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
@ -156,5 +208,6 @@ public final class MaskFactory extends AbstractFactory<Mask> {
return new MaskIntersection(masks).optimize();
}
}
//FAWE end
}

Datei anzeigen

@ -19,24 +19,56 @@
package com.sk89q.worldedit.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BufferedPattern2DParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BufferedPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.DarkenPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.DesaturatePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExistingPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExpressionPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.LightenPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear2DPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear3DPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.LinearPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.MaskedPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoXPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoYPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoZPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.OffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.PerlinPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomFullClipboardPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RelativePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SaturatePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SimplexPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SolidRandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser;
import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
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.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.ArrayList;
import java.util.List;
/**
* A registry of known {@link Pattern}s. Provides methods to instantiate
@ -47,6 +79,10 @@ import com.sk89q.worldedit.internal.registry.AbstractFactory;
*/
public final class PatternFactory extends AbstractFactory<Pattern> {
//FAWE start - rich pattern parsing
private final RichPatternParser richPatternParser;
//FAWE end
/**
* Create a new instance.
*
@ -55,6 +91,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
public PatternFactory(WorldEdit worldEdit) {
super(worldEdit, new SingleBlockPatternParser(worldEdit));
//FAWE start - rich pattern parsing
richPatternParser = new RichPatternParser(worldEdit);
//FAWE end
// split and parse each sub-pattern
register(new RandomPatternParser(worldEdit));
@ -65,16 +105,117 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
register(new BlockCategoryPatternParser(worldEdit));
//FAWE start
register(new SimplexPatternParser(worldEdit));
register(new VoronoiPatternParser(worldEdit));
register(new PerlinPatternParser(worldEdit));
register(new RidgedMultiFractalPatternParser(worldEdit));
register(new AngleColorPatternParser(worldEdit));
register(new AverageColorPatternParser(worldEdit));
register(new BiomePatternParser(worldEdit));
register(new BufferedPatternParser(worldEdit));
register(new BufferedPattern2DParser(worldEdit));
register(new ColorPatternParser(worldEdit));
register(new DarkenPatternParser(worldEdit));
register(new DesaturatePatternParser(worldEdit));
register(new ExistingPatternParser(worldEdit));
register(new ExpressionPatternParser(worldEdit));
register(new LightenPatternParser(worldEdit));
register(new Linear2DPatternParser(worldEdit));
register(new Linear3DPatternParser(worldEdit));
register(new BufferedPatternParser(worldEdit));
register(new ExistingPatternParser(worldEdit));
register(new LinearPatternParser(worldEdit));
register(new MaskedPatternParser(worldEdit));
register(new NoXPatternParser(worldEdit));
register(new NoYPatternParser(worldEdit));
register(new NoZPatternParser(worldEdit));
register(new OffsetPatternParser(worldEdit));
register(new PerlinPatternParser(worldEdit));
register(new RandomFullClipboardPatternParser(worldEdit));
register(new RandomOffsetPatternParser(worldEdit));
register(new RelativePatternParser(worldEdit));
register(new RidgedMultiFractalPatternParser(worldEdit));
register(new SaturatePatternParser(worldEdit));
register(new SimplexPatternParser(worldEdit));
register(new SolidRandomOffsetPatternParser(worldEdit));
register(new SurfaceRandomOffsetPatternParser(worldEdit));
register(new VoronoiPatternParser(worldEdit));
//FAWE end
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
List<Pattern> patterns = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
//FAWE start - rich pattern parsing
Pattern match = richPatternParser.parseFromInput(component, context);
if (match != null) {
patterns.add(match);
continue;
}
parseFromParsers(context, patterns, component);
//FAWE end
}
return getPattern(input, patterns);
}
//FAWE start - rich pattern parsing
private void parseFromParsers(
final ParserContext context,
final List<Pattern> patterns,
final String component
) {
Pattern match = null;
for (InputParser<Pattern> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) {
break;
}
}
if (match == null) {
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component)));
}
patterns.add(match);
}
/**
* Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting
* "richer" parsing where & and , are used. Exists to prevent stack overflows.
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
public Pattern parseWithoutRich(String input, ParserContext context) throws InputParseException {
List<Pattern> patterns = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
parseFromParsers(context, patterns, component);
}
return getPattern(input, patterns);
}
private Pattern getPattern(final String input, final List<Pattern> patterns) {
switch (patterns.size()) {
case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
case 1:
return patterns.get(0);
default:
RandomPattern randomPattern = new RandomPattern(new TrueRandom());
for (Pattern pattern : patterns) {
randomPattern.add(pattern, 1d);
}
return randomPattern;
}
}
//FAWE end
}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen