Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-03 01:50:07 +01:00
Create SurfaceAngleMask (#1215)
Dieser Commit ist enthalten in:
Ursprung
2376ce8d9d
Commit
d10b038e84
@ -0,0 +1,45 @@
|
|||||||
|
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||||
|
import com.fastasyncworldedit.core.function.mask.SurfaceAngleMask;
|
||||||
|
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.mask.Mask;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class SurfaceAngleMaskParser extends RichParser<Mask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new surface angle mask parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||||
|
*
|
||||||
|
* @param worldEdit the worldedit instance.
|
||||||
|
*/
|
||||||
|
public SurfaceAngleMaskParser(WorldEdit worldEdit) {
|
||||||
|
super(worldEdit, "#surfaceangle");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||||
|
if (index <= 2) {
|
||||||
|
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mask parseFromInput(@Nonnull String[] arguments, ParserContext context) throws InputParseException {
|
||||||
|
if (arguments.length > 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
double min = Double.parseDouble(arguments[0]);
|
||||||
|
double max = Double.parseDouble(arguments[1]);
|
||||||
|
|
||||||
|
int size = (arguments.length > 2 ? Integer.parseInt(arguments[2]) : 1);
|
||||||
|
return new SurfaceAngleMask(context.getExtent(), min, max, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package com.fastasyncworldedit.core.function.mask;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class SurfaceAngleMask extends AbstractExtentMask {
|
||||||
|
|
||||||
|
private final double min;
|
||||||
|
private final double max;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public SurfaceAngleMask(Extent extent, double min, double max, int size) {
|
||||||
|
super(extent);
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockVector3 vector) {
|
||||||
|
if (!vector.getBlock(getExtent()).isAir() && nextToAir(vector)) {
|
||||||
|
double angle = 1 - getAverageAirDirection(vector.toVector3(), size).getY();
|
||||||
|
return (angle >= (min / 90.0) && angle <= (max / 90.0));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Extent extent, BlockVector3 vector) {
|
||||||
|
if (!vector.getBlock(getExtent()).isAir() && nextToAir(vector)) {
|
||||||
|
double angle = 1 - getAverageAirDirection(vector.toVector3(), size).getY();
|
||||||
|
return (angle >= (min / 90.0) && angle <= (max / 90.0));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 getAverageAirDirection(Vector3 currentLocation, int size) {
|
||||||
|
ArrayList<Vector3> airDirections = new ArrayList<>();
|
||||||
|
for (int i = -size; i <= size; i++) {
|
||||||
|
for (int j = -size; j <= size; j++) {
|
||||||
|
for (int k = -size; k <= size; k++) {
|
||||||
|
Vector3 block = Vector3.at(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ()).add(
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
).add(i, j, k);
|
||||||
|
if (block
|
||||||
|
.toBlockPoint()
|
||||||
|
.clampY(getExtent().getMinY(), getExtent().getMaxY())
|
||||||
|
.getBlock(getExtent())
|
||||||
|
.getMaterial()
|
||||||
|
.isAir()) {
|
||||||
|
airDirections.add(block.subtract(currentLocation.add(0.5, 0.5, 0.5)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double x = 0.0;
|
||||||
|
double y = 0.0;
|
||||||
|
double z = 0.0;
|
||||||
|
for (Vector3 vector3 : airDirections) {
|
||||||
|
x += vector3.getX();
|
||||||
|
y += vector3.getY();
|
||||||
|
z += vector3.getZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 averageAirDirection = Vector3.at(x / airDirections.size(), y / airDirections.size(), z / airDirections.size());
|
||||||
|
return (Double.isNaN(averageAirDirection.getY()) ? Vector3.ZERO : averageAirDirection.normalize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mask copy() {
|
||||||
|
return new SurfaceAngleMask(super.getExtent(), min, max, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean nextToAir(BlockVector3 blockVector3) {
|
||||||
|
if (getExtent().getBlock(blockVector3.add(1, 0, 0)).toBaseBlock().getMaterial().isAir()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getExtent().getBlock(blockVector3.add(-1, 0, 0)).toBaseBlock().getMaterial().isAir()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getExtent().getBlock(blockVector3.add(0, 1, 0)).toBaseBlock().getMaterial().isAir()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getExtent().getBlock(blockVector3.add(0, -1, 0)).toBaseBlock().getMaterial().isAir()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getExtent().getBlock(blockVector3.add(0, 0, 1)).toBaseBlock().getMaterial().isAir()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return getExtent().getBlock(blockVector3.add(0, 0, -1)).toBaseBlock().getMaterial().isAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -28,6 +28,7 @@ import com.fastasyncworldedit.core.extension.factory.parser.mask.LiquidMaskParse
|
|||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.ROCAngleMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.ROCAngleMaskParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.RichOffsetMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.RichOffsetMaskParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.SimplexMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.SimplexMaskParser;
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.SurfaceAngleMaskParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.SurfaceMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.SurfaceMaskParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.TrueMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.TrueMaskParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.WallMaskParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.mask.WallMaskParser;
|
||||||
@ -108,6 +109,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
|||||||
register(new XAxisMaskParser(worldEdit));
|
register(new XAxisMaskParser(worldEdit));
|
||||||
register(new YAxisMaskParser(worldEdit));
|
register(new YAxisMaskParser(worldEdit));
|
||||||
register(new ZAxisMaskParser(worldEdit));
|
register(new ZAxisMaskParser(worldEdit));
|
||||||
|
register(new SurfaceAngleMaskParser(worldEdit));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren