Better angle mask + some command tweaks
This commit is contained in:
parent
177e2252cc
commit
0434755333
@ -1,112 +1,55 @@
|
|||||||
package com.boydti.fawe.object.mask;
|
package com.boydti.fawe.object.mask;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.boydti.fawe.util.MathMan;
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
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.Mask2D;
|
||||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||||
import java.util.HashMap;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class AngleMask extends SolidBlockMask implements ResettableMask {
|
public class AngleMask extends SolidBlockMask {
|
||||||
private final int max;
|
|
||||||
private final int min;
|
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;
|
private int maxY;
|
||||||
|
|
||||||
public AngleMask(Extent extent, int min, int max) {
|
public AngleMask(EditSession editSession, double min, double max) {
|
||||||
super(extent);
|
super(editSession);
|
||||||
this.maxY = extent.getMaximumPoint().getBlockY();
|
this.extent = editSession;
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
|
this.maxY = extent.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<Long, Integer> heights = new HashMap<>();
|
|
||||||
private long tick = 0;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Vector vector) {
|
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 x = vector.getBlockX();
|
||||||
int z = vector.getBlockZ();
|
|
||||||
// int o = getHighestTerrainBlock(x, z, 0, maxY);
|
|
||||||
int y = vector.getBlockY();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
if (getHighestTerrainBlock(x + 1, z, y + min, y + max) != -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);
|
||||||
return true;
|
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);
|
||||||
if (getHighestTerrainBlock(x, z - 1, y + min, y + max) != -1) {
|
return (slope >= min && slope <= max);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -132,7 +132,7 @@ public class ClipboardCommands {
|
|||||||
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/copy" },
|
aliases = { "/copy", "/c" },
|
||||||
flags = "em",
|
flags = "em",
|
||||||
desc = "Copy the selection to the clipboard",
|
desc = "Copy the selection to the clipboard",
|
||||||
help = "Copy the selection to the clipboard\n" +
|
help = "Copy the selection to the clipboard\n" +
|
||||||
@ -350,7 +350,7 @@ public class ClipboardCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/paste" },
|
aliases = { "/paste", "/p" },
|
||||||
usage = "",
|
usage = "",
|
||||||
flags = "sao",
|
flags = "sao",
|
||||||
desc = "Paste the clipboard's contents",
|
desc = "Paste the clipboard's contents",
|
||||||
|
@ -290,7 +290,7 @@ public class RegionCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/replace", "/re", "/rep" },
|
aliases = { "/replace", "/re", "/rep", "/r" },
|
||||||
usage = "[from-block] <to-block>",
|
usage = "[from-block] <to-block>",
|
||||||
desc = "Replace all blocks in the selection with another",
|
desc = "Replace all blocks in the selection with another",
|
||||||
flags = "f",
|
flags = "f",
|
||||||
|
@ -81,7 +81,7 @@ public class SelectionCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/pos1", "posa" },
|
aliases = { "/pos1", "posa", "/1" },
|
||||||
usage = "[coordinates]",
|
usage = "[coordinates]",
|
||||||
desc = "Set position 1",
|
desc = "Set position 1",
|
||||||
min = 0,
|
min = 0,
|
||||||
@ -113,7 +113,7 @@ public class SelectionCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/pos2", "posb" },
|
aliases = { "/pos2", "posb", "/2" },
|
||||||
usage = "[coordinates]",
|
usage = "[coordinates]",
|
||||||
desc = "Set position 2",
|
desc = "Set position 2",
|
||||||
min = 0,
|
min = 0,
|
||||||
|
@ -252,17 +252,17 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int y1,y2;
|
double y1,y2;
|
||||||
if (split[0].endsWith("d")) {
|
if (split[0].endsWith("d")) {
|
||||||
double y1d = Expression.compile(split[0].substring(0, split[0].length() - 1)).evaluate();
|
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();
|
double y2d = Expression.compile(split[1].substring(0, split[1].length() - 1)).evaluate();
|
||||||
y1 = (int) Math.round(Math.tan(y1d * (Math.PI / 180)));
|
y1 = (Math.tan(y1d * (Math.PI / 180)));
|
||||||
y2 = (int) Math.round(Math.tan(y2d * (Math.PI / 180)));
|
y2 = (Math.tan(y2d * (Math.PI / 180)));
|
||||||
} else {
|
} else {
|
||||||
y1 = (int) (Expression.compile(split[0]).evaluate());
|
y1 = (Expression.compile(split[0]).evaluate());
|
||||||
y2 = (int) (Expression.compile(split[1]).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) {
|
} catch (NumberFormatException | ExpressionException e) {
|
||||||
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
throw new SuggestInputParseException(input, "/<min-angle>:<max-angle>");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user