Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-25 10:30:04 +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.RichOffsetMaskParser;
|
||||
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.TrueMaskParser;
|
||||
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 YAxisMaskParser(worldEdit));
|
||||
register(new ZAxisMaskParser(worldEdit));
|
||||
register(new SurfaceAngleMaskParser(worldEdit));
|
||||
//FAWE end
|
||||
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren