Plex-FAWE/worldedit-core/src/main/java/com/boydti/fawe/object/brush/StencilBrush.java

106 lines
4.2 KiB
Java

package com.boydti.fawe.object.brush;
import com.boydti.fawe.object.brush.heightmap.HeightMap;
import com.boydti.fawe.object.mask.AdjacentAnyMask;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.util.Location;
import java.io.InputStream;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
public class StencilBrush extends HeightBrush {
private final boolean onlyWhite;
public StencilBrush(InputStream stream, int rotation, double yscale, boolean onlyWhite, Clipboard clipboard) {
super(stream, rotation, yscale, false, true, clipboard);
this.onlyWhite = onlyWhite;
}
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
final int cx = position.getBlockX();
final int cy = position.getBlockY();
final int cz = position.getBlockZ();
int size = (int) sizeDouble;
int size2 = (int) (sizeDouble * sizeDouble);
int maxY = editSession.getMaxY();
int add;
if (yscale < 0) {
add = maxY;
} else {
add = 0;
}
double scale = (yscale / sizeDouble) * (maxY + 1);
final HeightMap map = getHeightMap();
map.setSize(size);
int cutoff = onlyWhite ? maxY : 0;
final SolidBlockMask solid = new SolidBlockMask(editSession);
final AdjacentAnyMask adjacent = new AdjacentAnyMask(Masks.negate(solid));
Player player = editSession.getPlayer().getPlayer();
// BlockVector3 pos = player.getLocation();
Location loc = editSession.getPlayer().getPlayer().getLocation();
float yaw = loc.getYaw();
float pitch = loc.getPitch();
AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX(pitch - 90).inverse();
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
private final MutableVector3 mutable = new MutableVector3();
@Override
public boolean test(BlockVector3 vector) {
if (solid.test(vector)) {
int dx = vector.getBlockX() - cx;
int dy = vector.getBlockY() - cy;
int dz = vector.getBlockZ() - cz;
Vector3 srcPos = transform.apply(mutable.setComponents(dx, dy, dz));
dx = MathMan.roundInt(srcPos.getX());
dz = MathMan.roundInt(srcPos.getZ());
int distance = dx * dx + dz * dz;
if (distance > size2 || Math.abs(dx) > 256 || Math.abs(dz) > 256) return false;
double raise = map.getHeight(dx, dz);
int val = (int) Math.ceil(raise * scale) + add;
if (val < cutoff) {
return true;
}
if (val >= 255 || ThreadLocalRandom.current().nextInt(maxY) < val) {
editSession.setBlock(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), pattern);
}
return true;
}
return false;
}
}, vector -> true, Integer.MAX_VALUE, editSession);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
visitor.visit(position);
Operations.completeBlindly(visitor);
}
private void apply(double val) {
}
}