diff --git a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java index 8e7d76f7..43c576d4 100644 --- a/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java +++ b/core/src/main/java/com/boydti/fawe/object/mask/AngleMask.java @@ -1,112 +1,55 @@ package com.boydti.fawe.object.mask; -import com.boydti.fawe.Fawe; -import com.boydti.fawe.util.MathMan; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MutableBlockVector; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.function.mask.Mask2D; import com.sk89q.worldedit.function.mask.SolidBlockMask; -import java.util.HashMap; import javax.annotation.Nullable; -public class AngleMask extends SolidBlockMask implements ResettableMask { - private final int max; - private final int min; +public class AngleMask extends SolidBlockMask { + + private static double ADJACENT_MOD = 0.5; + private static double DIAGONAL_MOD = 1 / Math.sqrt(8); + + private final double max; + private final double min; + private final EditSession extent; + private MutableBlockVector mutable = new MutableBlockVector(); private int maxY; - public AngleMask(Extent extent, int min, int max) { - super(extent); - this.maxY = extent.getMaximumPoint().getBlockY(); + public AngleMask(EditSession editSession, double min, double max) { + super(editSession); + this.extent = editSession; this.min = min; this.max = max; + this.maxY = extent.getMaxY(); } - private HashMap heights = new HashMap<>(); - private long tick = 0; - @Override public boolean test(Vector vector) { - return testAngle(vector) && getExtent().getLazyBlock(vector).getId() != 0; - } - - private boolean testAngle(Vector vector) { - long currentTick = Fawe.get().getTimer().getTick(); - if (tick != (tick = currentTick)) { - heights.clear(); - tick = currentTick; - } - return getAngle(vector); - } - - - - @Override - public void reset() { - this.heights.clear(); - } - - public boolean getAngle(Vector vector) { int x = vector.getBlockX(); - int z = vector.getBlockZ(); -// int o = getHighestTerrainBlock(x, z, 0, maxY); int y = vector.getBlockY(); - if (getHighestTerrainBlock(x - 1, z, y + min, y + max) != -1) { + int z = vector.getBlockZ(); + BaseBlock block = extent.getBlock(x, y, z); + if (!test(block.getId(), block.getData())) { + return false; + } + block = extent.getBlock(x, y + 1, z); + if (test(block.getId(), block.getData())) { + return false; + } + double slope; + boolean aboveMin; + slope = Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z, y, 0, maxY)) * ADJACENT_MOD; + if (slope >= min && max >= Math.max(maxY - y, y)) { return true; } - if (getHighestTerrainBlock(x + 1, z, y + min, y + max) != -1) { - return true; - } - if (getHighestTerrainBlock(x, z - 1, y + min, y + max) != -1) { - return true; - } - if (getHighestTerrainBlock(x, z + 1, y + min, y + max) != -1) { - return true; - } - return false; - } - - private MutableBlockVector mutable = new MutableBlockVector(); - - private int getHighestTerrainBlock(final int x, final int z, int minY, int maxY) { - long pair = MathMan.pairInt(x, z); - Integer height = heights.get(pair); - if (height != null) { - if (height >= minY && height <= maxY && height >= 0 && height <= this.maxY) { - return height; - } else { - return -1; - } - } - int maxSearchY = Math.min(this.maxY, Math.max(0, maxY)); - int minSearchY = Math.min(this.maxY, Math.max(0, minY)); - mutable.mutX(x); - mutable.mutZ(z); - boolean air = false; - if (maxSearchY != this.maxY) { - mutable.mutY(maxSearchY + 1); - air = !super.test(mutable); - } - for (int y = maxSearchY; y >= minSearchY; --y) { - mutable.mutY(y); - if (super.test(mutable)) { - if (!air) { - break; - } - heights.put(pair, y); - return y; - - } else { - air = true; - } - } - if (minSearchY == 0 && maxSearchY == this.maxY) { - heights.put(pair, -1); - } else { - int value = getHighestTerrainBlock(x, z, 0, this.maxY); - heights.put(pair, value); - } - return -1; + slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x, z - 1, y, 0, maxY)) * ADJACENT_MOD); + slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD); + slope = Math.max(slope, Math.abs(extent.getNearestSurfaceTerrainBlock(x - 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x + 1, z - 1, y, 0, maxY)) * DIAGONAL_MOD); + return (slope >= min && slope <= max); } @Nullable diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index abbc253b..a9594775 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -132,7 +132,7 @@ public class ClipboardCommands { @Command( - aliases = { "/copy" }, + aliases = { "/copy", "/c" }, flags = "em", desc = "Copy the selection to the clipboard", help = "Copy the selection to the clipboard\n" + @@ -350,7 +350,7 @@ public class ClipboardCommands { } @Command( - aliases = { "/paste" }, + aliases = { "/paste", "/p" }, usage = "", flags = "sao", desc = "Paste the clipboard's contents", diff --git a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index ad43d925..01b46165 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -290,7 +290,7 @@ public class RegionCommands { } @Command( - aliases = { "/replace", "/re", "/rep" }, + aliases = { "/replace", "/re", "/rep", "/r" }, usage = "[from-block] ", desc = "Replace all blocks in the selection with another", flags = "f", diff --git a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index a230f533..effd2804 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -81,7 +81,7 @@ public class SelectionCommands { } @Command( - aliases = { "/pos1", "posa" }, + aliases = { "/pos1", "posa", "/1" }, usage = "[coordinates]", desc = "Set position 1", min = 0, @@ -113,7 +113,7 @@ public class SelectionCommands { } @Command( - aliases = { "/pos2", "posb" }, + aliases = { "/pos2", "posb", "/2" }, usage = "[coordinates]", desc = "Set position 2", min = 0, diff --git a/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java b/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java index 170f0603..5c7c3726 100644 --- a/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java +++ b/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java @@ -252,17 +252,17 @@ public class DefaultMaskParser extends FaweParser { throw new SuggestInputParseException(input, "/:"); } try { - int y1,y2; + double y1,y2; if (split[0].endsWith("d")) { double y1d = Expression.compile(split[0].substring(0, split[0].length() - 1)).evaluate(); double y2d = Expression.compile(split[1].substring(0, split[1].length() - 1)).evaluate(); - y1 = (int) Math.round(Math.tan(y1d * (Math.PI / 180))); - y2 = (int) Math.round(Math.tan(y2d * (Math.PI / 180))); + y1 = (Math.tan(y1d * (Math.PI / 180))); + y2 = (Math.tan(y2d * (Math.PI / 180))); } else { - y1 = (int) (Expression.compile(split[0]).evaluate()); - y2 = (int) (Expression.compile(split[1]).evaluate()); + y1 = (Expression.compile(split[0]).evaluate()); + y2 = (Expression.compile(split[1]).evaluate()); } - return new AngleMask(extent, y1, y2); + return new AngleMask(Request.request().getEditSession(), y1, y2); } catch (NumberFormatException | ExpressionException e) { throw new SuggestInputParseException(input, "/:"); }