From 7519f735bc90d5e5f33a3ff4b320373e2b6c1ee1 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sun, 29 Apr 2018 23:38:05 +1000 Subject: [PATCH] Add #extrema mask --- .../java/com/boydti/fawe/config/Settings.java | 4 +- .../jnbt/anvil/HeightMapMCAGenerator.java | 8 +-- .../boydti/fawe/object/mask/ExtremaMask.java | 65 +++++++++++++++++++ .../sk89q/worldedit/command/MaskCommands.java | 35 ++++++++-- .../worldedit/command/PatternCommands.java | 2 +- 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/object/mask/ExtremaMask.java diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index c2b1a567..fc6d3aae 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -30,14 +30,14 @@ public class Settings extends Config { public boolean UPDATE = false; @Comment("Send anonymous usage statistics") public boolean METRICS = true; - @Comment("FAWE will skip chunks when there's not enough memory available") - public boolean PREVENT_CRASHES = false; @Comment({ "Set true to enable WorldEdit restrictions per region (e.g. PlotSquared or WorldGuard).", "To be allowed to WorldEdit in a region, users need the appropriate", "fawe. permission. See the Permissions page for supported region plugins." }) public boolean REGION_RESTRICTIONS = true; + @Comment("FAWE will skip chunks when there's not enough memory available") + public boolean PREVENT_CRASHES = false; @Comment({ "FAWE will cancel non admin edits when memory consumption exceeds this %", " - Bypass with `/wea` or `//fast` or `fawe.bypass`", diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/HeightMapMCAGenerator.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/HeightMapMCAGenerator.java index 7fd7049f..99963c75 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/HeightMapMCAGenerator.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/HeightMapMCAGenerator.java @@ -282,10 +282,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr int pcx = (position.x >> 4) - OX; int pcz = (position.z >> 4) - OZ; - int scx = Math.max(0, pcx - 10); - int scz = Math.max(0, pcz - 10); - int ecx = Math.min(lenCX - 1, pcx + 10); - int ecz = Math.min(lenCZ - 1, pcz + 10); + int scx = Math.max(0, pcx - 15); + int scz = Math.max(0, pcz - 15); + int ecx = Math.min(lenCX - 1, pcx + 15); + int ecz = Math.min(lenCZ - 1, pcz + 15); MCAChunk chunk = new MCAChunk(this, 0, 0); for (int cz = scz; cz <= ecz; cz++) { diff --git a/core/src/main/java/com/boydti/fawe/object/mask/ExtremaMask.java b/core/src/main/java/com/boydti/fawe/object/mask/ExtremaMask.java new file mode 100644 index 00000000..a60af239 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/mask/ExtremaMask.java @@ -0,0 +1,65 @@ +package com.boydti.fawe.object.mask; + +import com.sk89q.worldedit.extent.Extent; + +public class ExtremaMask extends AngleMask { + public ExtremaMask(Extent extent, double min, double max, boolean overlay, int distance) { + super(extent, min, max, overlay, distance); + } + + @Override + protected boolean testSlope(int x, int y, int z) { + double slope, tmp; + boolean aboveMin; + lastY = y; + + int base = getHeight(x, y, z); + + slope = get(base, x, y, z, 1, 0, distance) * ADJACENT_MOD; + + tmp = get(base, x, y, z, 0, 1, distance) * ADJACENT_MOD; + if (Math.abs(tmp) > Math.abs(slope)) slope = tmp; + + tmp = get(base, x, y, z, 1, 1, distance) * DIAGONAL_MOD; + if (Math.abs(tmp) > Math.abs(slope)) slope = tmp; + + tmp = get(base, x, y, z, 1, -1, distance) * DIAGONAL_MOD; + if (Math.abs(tmp) > Math.abs(slope)) slope = tmp; + + return lastValue = (slope > min && slope < max); + } + + private int get(int base, int x, int y, int z, int OX, int OZ, int iterations) { + int sign = 0; + int lastHeight1 = base; + int lastHeight2 = base; + + int cox = OX, coz = OZ; + for (int i = 0; i < iterations; i++, cox += OX, coz += OZ) { + int x1 = x + cox; + int z1 = z + coz; + int x2 = x - cox; + int z2 = z - coz; + int height1 = getHeight(x1, y, z1); + int height2 = getHeight(x2, y, z2); + int diff1 = height1 - lastHeight1; + int diff2 = height2 - lastHeight2; + int sign1 = Integer.signum(diff1); + int sign2 = Integer.signum(diff2); + + if (sign == 0) { + if (sign1 != 0) sign = sign1; + else if (sign2 != 0) sign = sign2; + } + if (sign1 == 0) sign1 = sign; + if (sign2 == 0) sign2 = sign; + if (sign1 != sign2) { + return (lastHeight1 - base) + (lastHeight2 - base); + } + + lastHeight1 = height1; + lastHeight2 = height2; + } + return (lastHeight1 - base) + (lastHeight2 - base); + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java index dd456c56..f130e72b 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/MaskCommands.java @@ -265,8 +265,7 @@ public class MaskCommands extends MethodCommands { "Example: /[3][20]\n" + "Explanation: Allows any block where the adjacent block is between 3 and 20 blocks below", usage = " [distance=1]", - min = 2, - max = 2 + min = 2 ) public Mask angle(Extent extent, String min, String max, @Switch('o') boolean overlay, @Optional("1") int distance) throws ExpressionException { double y1, y2; @@ -291,9 +290,8 @@ public class MaskCommands extends MethodCommands { "Example: ([0d][45d][5]\n" + "Explanation: Restrict near where the angle changes between 0-45 degrees within 5 blocks\n" + "Note: Use negatives for decreasing slope", - usage = " [distance=1]", - min = 2, - max = 2 + usage = " [distance=4]", + min = 2 ) public Mask roc(Extent extent, String min, String max, @Switch('o') boolean overlay, @Optional("4") int distance) throws ExpressionException { double y1, y2; @@ -310,6 +308,33 @@ public class MaskCommands extends MethodCommands { return new ROCAngleMask(extent, y1, y2, overlay, distance); } + @Command( + aliases = {"^", "#extrema"}, + desc = "Restrict to near specific terrain extrema", + help = "Restrict to near specific terrain extrema\n" + + "The -o flag will only overlay\n" + + "Example: ([0d][45d][5]\n" + + "Explanation: Restrict to near 45 degrees of local maxima\n" + + "Note: Use negatives for local minima", + usage = " [distance=1]", + min = 2, + max = 4 + ) + public Mask extrema(Extent extent, String min, String max, @Switch('o') boolean overlay, @Optional("4") int distance) throws ExpressionException { + double y1, y2; + boolean override; + if (max.endsWith("d")) { + double y1d = Expression.compile(min.substring(0, min.length() - 1)).evaluate(); + double y2d = Expression.compile(max.substring(0, max.length() - 1)).evaluate(); + y1 = (Math.tan(y1d * (Math.PI / 180))); + y2 = (Math.tan(y2d * (Math.PI / 180))); + } else { + y1 = (Expression.compile(min).evaluate()); + y2 = (Expression.compile(max).evaluate()); + } + return new ExtremaMask(extent, y1, y2, overlay, distance); + } + @Command( aliases = {"{"}, desc = "Restricts blocks to within a specific radius range of the initial block", diff --git a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java index d4794e46..4b0610c4 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/PatternCommands.java @@ -126,7 +126,7 @@ public class PatternCommands extends MethodCommands { desc = "A darker block based on the existing terrain angle", usage = "[randomize=true] [max-complexity=100] [distance=1]", min = 0, - max = 2 + max = 3 ) public Pattern anglecolor(Extent extent, @Optional("true") boolean randomize, @Optional("100") double maxComplexity, @Optional("1") int distance) { TextureUtil util = Fawe.get().getCachedTextureUtil(randomize, 0, (int) maxComplexity);