Various
angle patterns (using different blocks based on the angle) pattern buffering - only apply once to a block - resets when the pattern is no longer being used (brushes?) Anvil - schematic population with heightmap new texture patterns (will document later) fixes texture complexity and block filtering Some fixes to height based region commands Surface brush Fix line brush -s flag Add optimized local Vector2D set Tweak and optimize overlay behavior Print time on command completion (if duration > 1s)
This commit is contained in:
parent
95faf00467
commit
7586e87644
@ -7,9 +7,12 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualQueue;
|
||||
import com.boydti.fawe.regions.general.plot.PlotSquaredFeature;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
@ -321,6 +324,13 @@ public class Fawe {
|
||||
return updater;
|
||||
}
|
||||
|
||||
public TextureUtil getCachedTextureUtil(boolean randomize, int min, int max) {
|
||||
TextureUtil tu = getTextureUtil();
|
||||
tu = min == 0 && max == 100 ? tu : new CleanTextureUtil(tu, min, max);
|
||||
tu = randomize ? new RandomTextureUtil(tu) : new CachedTextureUtil(tu);
|
||||
return tu;
|
||||
}
|
||||
|
||||
public TextureUtil getTextureUtil() {
|
||||
TextureUtil tmp = textures;
|
||||
if (tmp == null) {
|
||||
@ -685,10 +695,4 @@ public class Fawe {
|
||||
public Collection<FawePlayer> getCachedPlayers() {
|
||||
return players.values();
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO FIXME
|
||||
* - Async packet sending
|
||||
* - Optimize lighting updates / chunk sending
|
||||
*/
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ public enum BBC {
|
||||
BRUSH_POPULATE("Populate brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
||||
BRUSH_LAYER("Layer brush shape equipped (%s0, %s1).", "WorldEdit.Brush"),
|
||||
BRUSH_STENCIL("Stencil brush equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_SURFACE("Surface brush equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_LINE("Line brush shape equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_SPLINE("Spline brush shape equipped (%s0). Right click an end to add a shape", "WorldEdit.Brush"),
|
||||
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
||||
|
@ -3,6 +3,8 @@ package com.boydti.fawe.jnbt.anvil;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
|
||||
import com.boydti.fawe.object.schematic.Schematic;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
@ -15,9 +17,12 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
@ -110,11 +115,59 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
addCaves(region);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addSchems(Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, boolean rotate) throws WorldEditException{
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
||||
}
|
||||
|
||||
public void addSchems(BufferedImage img, Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException{
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength()) throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
double doubleRarity = rarity / 100d;
|
||||
int index = 0;
|
||||
AffineTransform identity = new AffineTransform();
|
||||
LocalBlockVector2DSet placed = new LocalBlockVector2DSet();
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < getWidth(); x++, index++){
|
||||
int y = heights[index];
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 0 || PseudoRandom.random.nextInt(256) > height * doubleRarity) {
|
||||
continue;
|
||||
}
|
||||
mutable.mutX(x);
|
||||
mutable.mutY(y);
|
||||
if (!mask.test(mutable)) {
|
||||
continue;
|
||||
}
|
||||
if (placed.containsRadius(x, z, distance)) {
|
||||
continue;
|
||||
}
|
||||
placed.add(x, z);
|
||||
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||
if (randomRotate) {
|
||||
int rotate = PseudoRandom.random.random(4) * 90;
|
||||
if (rotate != 0) {
|
||||
holder.setTransform(new AffineTransform().rotateY(PseudoRandom.random.random(4) * 90));
|
||||
} else {
|
||||
holder.setTransform(identity);
|
||||
}
|
||||
}
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
Schematic schematic = new Schematic(clipboard);
|
||||
Transform transform = holder.getTransform();
|
||||
if (transform.isIdentity()) {
|
||||
schematic.paste(this, mutable, false);
|
||||
} else {
|
||||
schematic.paste(this, worldData, mutable, false, transform);
|
||||
}
|
||||
x += distance;
|
||||
index += distance;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
|
@ -35,6 +35,7 @@ public class SchemGen extends Resource {
|
||||
mutable.mutX(x);
|
||||
mutable.mutZ(z);
|
||||
int y = extent.getNearestSurfaceTerrainBlock(x, z, mutable.getBlockY(), 0, 255);
|
||||
if (y == -1) return false;
|
||||
mutable.mutY(y);
|
||||
if (!mask.test(mutable)) {
|
||||
return false;
|
||||
|
53
core/src/main/java/com/boydti/fawe/object/DataAngleMask.java
Normal file
53
core/src/main/java/com/boydti/fawe/object/DataAngleMask.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
|
||||
public class DataAngleMask extends AbstractPattern {
|
||||
public final Extent extent;
|
||||
public final int maxY;
|
||||
public final double factor = 1d/255;
|
||||
|
||||
public DataAngleMask(Extent extent) {
|
||||
this.extent = extent;
|
||||
this.maxY = extent.getMaximumPoint().getBlockY();
|
||||
}
|
||||
|
||||
public int getSlope(BaseBlock block, Vector vector) {
|
||||
int x = vector.getBlockX();
|
||||
int y = vector.getBlockY();
|
||||
int z = vector.getBlockZ();
|
||||
if (FaweCache.canPassThrough(block.getId(), block.getData())) {
|
||||
return -1;
|
||||
}
|
||||
int slope;
|
||||
boolean aboveMin;
|
||||
slope = Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z, y, 0, maxY)) * 7;
|
||||
slope += Math.abs(extent.getNearestSurfaceTerrainBlock(x, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x, z - 1, y, 0, maxY)) * 7;
|
||||
slope += Math.abs(extent.getNearestSurfaceTerrainBlock(x + 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x - 1, z - 1, y, 0, maxY)) * 5;
|
||||
slope += Math.abs(extent.getNearestSurfaceTerrainBlock(x - 1, z + 1, y, 0, maxY) - extent.getNearestSurfaceTerrainBlock(x + 1, z - 1, y, 0, maxY)) * 5;
|
||||
return slope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
BaseBlock block = extent.getBlock(position);
|
||||
int slope = getSlope(block, position);
|
||||
if (slope == -1) return block;
|
||||
int data = (Math.min(slope, 255)) >> 4;
|
||||
return FaweCache.getBlock(block.getId(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
BaseBlock block = extent.getBlock(getPosition);
|
||||
int slope = getSlope(block, getPosition);
|
||||
if (slope == -1) return false;
|
||||
int data = (Math.min(slope, 255)) >> 4;
|
||||
return extent.setBlock(setPosition, FaweCache.getBlock(block.getId(), data));
|
||||
}
|
||||
}
|
@ -197,6 +197,12 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
}
|
||||
|
||||
public boolean runAction(final Runnable ifFree, boolean checkFree, boolean async) {
|
||||
long[] actionTime = getMeta("lastActionTime");
|
||||
if (actionTime == null) {
|
||||
setMeta("lastActionTime", actionTime = new long[2]);
|
||||
}
|
||||
actionTime[1] = actionTime[0];
|
||||
actionTime[0] = Fawe.get().getTimer().getTick();
|
||||
if (checkFree) {
|
||||
if (async) {
|
||||
TaskManager.IMP.taskNow(new Runnable() {
|
||||
|
@ -26,9 +26,13 @@ public class LineBrush implements Brush, ResettableTool {
|
||||
return;
|
||||
}
|
||||
editSession.drawLine(pattern, pos1, position, size, !shell, flat);
|
||||
if (!select && !visual) {
|
||||
pos1 = null;
|
||||
return;
|
||||
if (!visual) {
|
||||
if (!select) {
|
||||
pos1 = null;
|
||||
return;
|
||||
} else {
|
||||
pos1 = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,36 +85,6 @@ public class StencilBrush extends HeightBrush {
|
||||
visitor.setDirections(Arrays.asList(visitor.DIAGONAL_DIRECTIONS));
|
||||
visitor.visit(position);
|
||||
Operations.completeBlindly(visitor);
|
||||
|
||||
// Mask mask = new ExistingBlockMask(editSession);
|
||||
// int maxY = editSession.getMaxY();
|
||||
// double scale = (yscale / sizeDouble) * (maxY + 1);
|
||||
// heightMap.setSize(size);
|
||||
// int cutoff = onlyWhite ? maxY : 0;
|
||||
//
|
||||
// for (int x = -size; x <= size; x++) {
|
||||
// int xx = position.getBlockX() + x;
|
||||
// for (int z = -size; z <= size; z++) {
|
||||
// double raise;
|
||||
// switch (rotation) {
|
||||
// default:raise = heightMap.getHeight(x, z); break;
|
||||
// case 1: raise = heightMap.getHeight(z, x); break;
|
||||
// case 2: raise = heightMap.getHeight(-x, -z); break;
|
||||
// case 3: raise = heightMap.getHeight(-z, -x);break;
|
||||
// }
|
||||
// int val = (int) Math.ceil(raise * scale);
|
||||
// if (val <= cutoff) {
|
||||
// continue;
|
||||
// }
|
||||
// if (val >= 255 || PseudoRandom.random.random(maxY) < val) {
|
||||
// int zz = position.getBlockZ() + z;
|
||||
// int y = editSession.getNearestSurfaceTerrainBlock(xx, zz, position.getBlockY(), 0, maxY);
|
||||
// for (int i = 0; i < depth; i++) {
|
||||
// editSession.setBlock(xx, y - i, zz, pattern);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private void apply(double val) {
|
||||
|
@ -0,0 +1,40 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.mask.AdjacentAnyMask;
|
||||
import com.boydti.fawe.object.mask.RadiusMask;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
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 java.util.Arrays;
|
||||
|
||||
public class SurfaceSphereBrush implements Brush {
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||
Mask mask = editSession.getMask();
|
||||
if (mask == null) {
|
||||
mask = Masks.alwaysTrue();
|
||||
}
|
||||
AdjacentAnyMask adjacent = new AdjacentAnyMask(editSession, Arrays.asList(new BaseBlock(0)));
|
||||
for (int id = 0; id < 256; id++) {
|
||||
if (FaweCache.canPassThrough(id, 0)) {
|
||||
adjacent.add(new BaseBlock(id, -1));
|
||||
}
|
||||
}
|
||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||
final RadiusMask radius = new RadiusMask(0, (int) size);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(vector -> solid.test(vector) && radius.test(vector) && adjacent.test(vector), vector -> editSession.setBlock(vector, pattern));
|
||||
visitor.visit(position);
|
||||
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
|
||||
Operations.completeBlindly(visitor);
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ public class SurfaceSpline implements Brush {
|
||||
boolean vis = editSession.getExtent() instanceof VisualExtent;
|
||||
if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
|
||||
int max = editSession.getNearestSurfaceTerrainBlock(pos.getBlockX(), pos.getBlockZ(), pos.getBlockY(), 0, editSession.getMaxY());
|
||||
if (max == -1) return;
|
||||
pos.mutY(max);
|
||||
path.add(pos);
|
||||
editSession.getPlayer().sendMessage(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY_2.s());
|
||||
@ -56,6 +57,7 @@ public class SurfaceSpline implements Brush {
|
||||
final int tipz = (int) tipv.getZ();
|
||||
int tipy = (int) Math.round(tipv.getY());
|
||||
tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, 0, maxY);
|
||||
if (tipy == -1) continue;
|
||||
if (radius == 0) {
|
||||
editSession.setBlock(tipx, tipy, tipz, pattern.next(tipx, tipy, tipz));
|
||||
} else {
|
||||
@ -72,6 +74,7 @@ public class SurfaceSpline implements Brush {
|
||||
for (int loopz = tipz - ceilrad; loopz <= (tipz + ceilrad); loopz++) {
|
||||
if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) {
|
||||
int y = editSession.getNearestSurfaceTerrainBlock(loopx, loopz, v.getBlockY(), 0, maxY);
|
||||
if (y == -1) continue;
|
||||
newSet.add(loopx, y, loopz);
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ public interface HeightMap {
|
||||
height = session.getNearestSurfaceLayer(xx, zz, pos.getBlockY(), 0, maxY);
|
||||
} else {
|
||||
height = session.getNearestSurfaceTerrainBlock(xx, zz, pos.getBlockY(), 0, maxY);
|
||||
if (height == -1) continue;
|
||||
}
|
||||
oldData[index] = height;
|
||||
if (height == 0) {
|
||||
@ -141,7 +142,8 @@ public interface HeightMap {
|
||||
if (layers) {
|
||||
height = session.getNearestSurfaceLayer(xx, zz, height, 0, maxY);
|
||||
} else {
|
||||
height = session.getNearestSurfaceTerrainBlock(xx, zz, height, 0, 255);
|
||||
height = session.getNearestSurfaceTerrainBlock(xx, zz, height, 0, maxY);
|
||||
if (height == -1) continue;
|
||||
}
|
||||
oldData[index] = height;
|
||||
if (height == 0) {
|
||||
|
@ -0,0 +1,278 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.MutableBlockVector2D;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The LocalPartitionedBlockVector2DSet is a Memory and CPU optimized Set for storing Vector2Ds which are all in a local region
|
||||
* - All Vector2Ds must be within x[0,32768), y[0,32768)
|
||||
* - This will use 8 bytes for every 64 Vector2Ds (about 800x less than a HashSet)
|
||||
*/
|
||||
public class LocalBlockVector2DSet implements Set<Vector2D> {
|
||||
private boolean chunksValid = true;
|
||||
private final SparseBitSet set;
|
||||
private final MutableBlockVector2D mutable = new MutableBlockVector2D();
|
||||
|
||||
public LocalBlockVector2DSet() {
|
||||
this.set = new SparseBitSet();
|
||||
}
|
||||
|
||||
public SparseBitSet getBitSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return set.cardinality();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return set.isEmpty();
|
||||
}
|
||||
|
||||
public boolean contains(int x, int y) {
|
||||
return set.get(MathMan.pairSearchCoords(x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
if (o instanceof Vector2D) {
|
||||
Vector2D v = (Vector2D) o;
|
||||
return contains(v.getBlockX(), v.getBlockZ());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsRadius(int x, int y, int radius) {
|
||||
int size = size();
|
||||
if (size == 0) return false;
|
||||
if (radius <= 0 || size == 1) {
|
||||
return contains(x, y);
|
||||
}
|
||||
// int centerIndex = MathMan.pairSearchCoords(x, y);
|
||||
int length = (radius << 1) + 1;
|
||||
if (size() < length * length) {
|
||||
int index = -1;
|
||||
int count = 0;
|
||||
while ((index = set.nextSetBit(index + 1)) != -1) {
|
||||
// if (index == centerIndex) continue;
|
||||
int curx = MathMan.unpairSearchCoordsX(index);
|
||||
int cury = MathMan.unpairSearchCoordsY(index);
|
||||
if (Math.abs(curx - x) <= radius && Math.abs(cury - y) <= radius) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int bcx = Math.max(0, (x - radius) >> 4);
|
||||
int bcy = Math.max(0, (y - radius) >> 4);
|
||||
int tcx = Math.min(2047, (x + radius) >> 4);
|
||||
int tcy = Math.min(2047, (y + radius) >> 4);
|
||||
for (int cy = bcy; cy <= tcy; cy++) {
|
||||
for (int cx = bcx; cx <= tcx; cx++) {
|
||||
int index = MathMan.pairSearchCoords(cx << 4, cy << 4) - 1;
|
||||
int endIndex = index + 256;
|
||||
while ((index = set.nextSetBit(index + 1)) <= endIndex && index != -1) {
|
||||
// if (index == centerIndex) continue;
|
||||
int curx = MathMan.unpairSearchCoordsX(index);
|
||||
int cury = MathMan.unpairSearchCoordsY(index);
|
||||
if (Math.abs(curx - x) <= radius && Math.abs(cury - y) <= radius) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Vector2D getIndex(int getIndex) {
|
||||
int size = size();
|
||||
if (getIndex > size) {
|
||||
return null;
|
||||
}
|
||||
int index = -1;
|
||||
for (int i = 0; i <= getIndex; i++) {
|
||||
index = set.nextSetBit(index + 1);
|
||||
}
|
||||
if (index != -1) {
|
||||
int x = MathMan.unpairSearchCoordsX(index);
|
||||
int y = MathMan.unpairSearchCoordsY(index);
|
||||
return mutable.setComponents(x, y);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Vector2D> iterator() {
|
||||
return new Iterator<Vector2D>() {
|
||||
int index = set.nextSetBit(0);
|
||||
int previous = -1;
|
||||
@Override
|
||||
public void remove() {
|
||||
chunksValid = false;
|
||||
set.clear(previous);
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index != -1;
|
||||
}
|
||||
@Override
|
||||
public Vector2D next() {
|
||||
if (index != -1) {
|
||||
int x = MathMan.unpairSearchCoordsX(index);
|
||||
int y = MathMan.unpairSearchCoordsY(index);
|
||||
mutable.setComponents(x, y);
|
||||
previous = index;
|
||||
index = set.nextSetBit(index + 1);
|
||||
return mutable;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return toArray(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] array) {
|
||||
int size = size();
|
||||
if (array == null || array.length < size) {
|
||||
array = (T[]) new BlockVector2D[size];
|
||||
}
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
index = set.nextSetBit(index);
|
||||
int x = MathMan.unpairSearchCoordsX(index);
|
||||
int y = MathMan.unpairSearchCoordsY(index);
|
||||
array[i] = (T) new BlockVector2D(x, y);
|
||||
index++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public boolean add(int x, int y) {
|
||||
if (x < 0 || x > 32766 || y < 0 || y > 32766) {
|
||||
throw new UnsupportedOperationException("LocalVector2DSet can only contain Vector2Ds within 1024 blocks (cuboid) of the first entry. ");
|
||||
}
|
||||
int index = getIndex(x, y);
|
||||
if (set.get(index)) {
|
||||
return false;
|
||||
} else {
|
||||
set.set(index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Vector2D vector) {
|
||||
return add(vector.getBlockX(), vector.getBlockZ());
|
||||
}
|
||||
|
||||
private int getIndex(Vector2D vector) {
|
||||
return MathMan.pairSearchCoords(vector.getBlockX(), vector.getBlockZ());
|
||||
}
|
||||
|
||||
private int getIndex(int x, int y) {
|
||||
return MathMan.pairSearchCoords(x, y);
|
||||
}
|
||||
|
||||
public boolean remove(int x, int y) {
|
||||
if (x < 0 || x > 32766 || y < 0 || y > 32766) {
|
||||
return false;
|
||||
}
|
||||
int index = MathMan.pairSearchCoords(x, y);
|
||||
boolean value = set.get(index);
|
||||
if (value) {
|
||||
set.clear(index);
|
||||
chunksValid = false;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
if (o instanceof Vector2D) {
|
||||
Vector2D v = (Vector2D) o;
|
||||
return remove(v.getBlockX(), v.getBlockZ());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
for (Object o : c) {
|
||||
if (!contains(o)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends Vector2D> c) {
|
||||
boolean result = false;
|
||||
for (Vector2D v : c) {
|
||||
result |= add(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
boolean result = false;
|
||||
int size = size();
|
||||
int index = -1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
index = set.nextSetBit(index + 1);
|
||||
int x = MathMan.unpairSearchCoordsX(index);
|
||||
int y = MathMan.unpairSearchCoordsY(index);
|
||||
mutable.setComponents(x, y);
|
||||
if (!c.contains(mutable)) {
|
||||
result = true;
|
||||
set.clear(index);
|
||||
chunksValid = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
boolean result = false;
|
||||
for (Object o : c) {
|
||||
result |= remove(o);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void forEach(BlockVector2DSetVisitor visitor) {
|
||||
int size = size();
|
||||
int index = -1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
index = set.nextSetBit(index + 1);
|
||||
int x = MathMan.unpairSearchCoordsX(index);
|
||||
int y = MathMan.unpairSearchCoordsY(index);
|
||||
mutable.setComponents(x, y);
|
||||
visitor.run(x, y, index);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class BlockVector2DSetVisitor {
|
||||
public abstract void run(int x, int y, int index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
set.clear();
|
||||
chunksValid = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.boydti.fawe.object.function;
|
||||
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.FlatRegionFunction;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
|
||||
public class SurfaceRegionFunction implements FlatRegionFunction {
|
||||
private final Extent extent;
|
||||
private final RegionFunction function;
|
||||
private final int minY;
|
||||
private final int maxY;
|
||||
private int lastY;
|
||||
private MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
public SurfaceRegionFunction(Extent extent, RegionFunction function, int minY, int maxY) {
|
||||
this.extent = extent;
|
||||
this.minY = minY;
|
||||
this.maxY = maxY;
|
||||
this.lastY = maxY;
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Vector2D position) throws WorldEditException {
|
||||
int x = position.getBlockX();
|
||||
int z = position.getBlockZ();
|
||||
int layer = extent.getNearestSurfaceTerrainBlock(x, z, lastY, minY, maxY);
|
||||
if (layer != -1) {
|
||||
lastY = layer;
|
||||
return function.apply(mutable.setComponents(x, layer, z));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -9,9 +9,8 @@ import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class AngleMask extends SolidBlockMask {
|
||||
|
||||
private static double ADJACENT_MOD = 0.5;
|
||||
private static double DIAGONAL_MOD = 1 / Math.sqrt(8);
|
||||
public static double ADJACENT_MOD = 0.5;
|
||||
public static double DIAGONAL_MOD = 1 / Math.sqrt(8);
|
||||
|
||||
private final double max;
|
||||
private final double min;
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.object.DataAngleMask;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
public class AngleColorPattern extends DataAngleMask {
|
||||
private final TextureUtil util;
|
||||
private final int maxY;
|
||||
private final double factor = 1d/196;
|
||||
|
||||
public AngleColorPattern(TextureUtil util, Extent extent) {
|
||||
super(extent);
|
||||
this.util = util;
|
||||
this.maxY = extent.getMaximumPoint().getBlockY();
|
||||
}
|
||||
|
||||
public int getColor(int color, int slope) {
|
||||
if (slope == 0) return color;
|
||||
double newFactor = (196 - Math.min(196, slope)) * factor;
|
||||
int newRed = (int) (((color >> 16) & 0xFF) * newFactor);
|
||||
int newGreen = (int) (((color >> 8) & 0xFF) * newFactor);
|
||||
int newBlue = (int) (((color >> 0) & 0xFF) * newFactor);
|
||||
return (((color >> 24) & 0xFF) << 24) + (newRed << 16) + (newGreen << 8) + (newBlue << 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
BaseBlock block = extent.getBlock(position);
|
||||
int slope = getSlope(block, position);
|
||||
if (slope == -1) return block;
|
||||
int color = util.getColor(block);
|
||||
if (color == 0) return block;
|
||||
int newColor = getColor(color, slope);
|
||||
return util.getNearestBlock(newColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
BaseBlock block = extent.getBlock(getPosition);
|
||||
int slope = getSlope(block, getPosition);
|
||||
if (slope == -1) return false;
|
||||
int color = util.getColor(block);
|
||||
if (color == 0) return false;
|
||||
int newColor = getColor(color, slope);
|
||||
BaseBlock newBlock = util.getNearestBlock(newColor);
|
||||
if (newBlock == null) return false;
|
||||
return extent.setBlock(setPosition, newBlock);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import java.awt.Color;
|
||||
|
||||
public class AverageColorPattern extends AbstractPattern {
|
||||
private final int color;
|
||||
private final Extent extent;
|
||||
private final TextureUtil util;
|
||||
|
||||
public AverageColorPattern(Extent extent, TextureUtil util, int color) {
|
||||
this.extent = extent;
|
||||
this.util = util;
|
||||
this.color = new Color(color).getRGB();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
BaseBlock block = extent.getBlock(position);
|
||||
int currentColor = util.getColor(block);
|
||||
int newColor = util.averageColor(currentColor, color);
|
||||
return util.getNearestBlock(newColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
BaseBlock block = extent.getBlock(getPosition);
|
||||
int currentColor = util.getColor(block);
|
||||
if (currentColor == 0) return false;
|
||||
int newColor = util.averageColor(currentColor, color);
|
||||
BaseBlock newBlock = util.getNearestBlock(newColor);
|
||||
if (newBlock.equals(block)) return false;
|
||||
return extent.setBlock(setPosition, newBlock);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class BufferedPattern extends AbstractPattern implements ResettablePattern {
|
||||
private final Pattern pattern;
|
||||
private final LocalBlockVectorSet set = new LocalBlockVectorSet();
|
||||
private final FaweTimer timer;
|
||||
private final long[] actionTime;
|
||||
|
||||
public BufferedPattern(FawePlayer fp, Pattern parent) {
|
||||
long[] actionTime = fp.getMeta("lastActionTime");
|
||||
if (actionTime == null) fp.setMeta("lastActionTime", actionTime = new long[2]);
|
||||
this.actionTime = actionTime;
|
||||
this.pattern = parent;
|
||||
this.timer = Fawe.get().getTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
return pattern.apply(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
long now = timer.getTick();
|
||||
try {
|
||||
if (!set.add(setPosition)) {
|
||||
return false;
|
||||
}
|
||||
return pattern.apply(extent, setPosition, getPosition);
|
||||
} catch (UnsupportedOperationException ignore) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
long now = timer.getTick();
|
||||
if (now - actionTime[1] > 5) {
|
||||
set.clear();
|
||||
}
|
||||
actionTime[1] = actionTime[0];
|
||||
actionTime[0] = now;
|
||||
}
|
||||
}
|
@ -7,11 +7,16 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class DataPattern extends AbstractPattern {
|
||||
private final Extent extent;
|
||||
private final Pattern pattern;
|
||||
|
||||
public DataPattern(Extent extent, Pattern parent) {
|
||||
checkNotNull(extent);
|
||||
checkNotNull(parent);
|
||||
this.extent = extent;
|
||||
this.pattern = parent;
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
|
||||
public class DesaturatePattern extends AbstractPattern{
|
||||
private final TextureUtil util;
|
||||
private final Extent extent;
|
||||
private final double value;
|
||||
|
||||
public DesaturatePattern(Extent extent, TextureUtil util, double value) {
|
||||
this.extent = extent;
|
||||
this.util = util;
|
||||
this.value = Math.max(0, Math.min(1, value));
|
||||
}
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
BaseBlock block = extent.getBlock(position);
|
||||
int color = util.getColor(block);
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8) & 0xFF;
|
||||
int b = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
double l = 0.3f * r + 0.6f * g + 0.1f * b;
|
||||
int red = (int) (r + value * (l - r));
|
||||
int green = (int) (g + value * (l - g));
|
||||
int blue = (int) (b + value * (l - b));
|
||||
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
return util.getNearestBlock(newColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
BaseBlock block = extent.getBlock(getPosition);
|
||||
int color = util.getColor(block);
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8) & 0xFF;
|
||||
int b = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
double l = 0.3f * r + 0.6f * g + 0.1f * b;
|
||||
int red = (int) (r + value * (l - r));
|
||||
int green = (int) (g + value * (l - g));
|
||||
int blue = (int) (b + value * (l - b));
|
||||
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
if (newColor == color) {
|
||||
return false;
|
||||
}
|
||||
BaseBlock newBlock = util.getNextNearestBlock(newColor);
|
||||
if (block.equals(newBlock)) {
|
||||
return false;
|
||||
}
|
||||
return extent.setBlock(setPosition, newBlock);
|
||||
}
|
||||
}
|
@ -7,11 +7,16 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class IdPattern extends AbstractPattern {
|
||||
private final Extent extent;
|
||||
private final Pattern pattern;
|
||||
|
||||
public IdPattern(Extent extent, Pattern parent) {
|
||||
checkNotNull(extent);
|
||||
checkNotNull(parent);
|
||||
this.extent = extent;
|
||||
this.pattern = parent;
|
||||
}
|
||||
|
@ -6,16 +6,17 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import java.awt.Color;
|
||||
|
||||
public class ColorPattern extends AbstractPattern {
|
||||
public class SaturatePattern extends AbstractPattern {
|
||||
private final int color;
|
||||
private final Extent extent;
|
||||
private final TextureUtil util;
|
||||
|
||||
public ColorPattern(Extent extent, TextureUtil util, int color) {
|
||||
public SaturatePattern(Extent extent, TextureUtil util, int color) {
|
||||
this.extent = extent;
|
||||
this.util = util;
|
||||
this.color = color;
|
||||
this.color = new Color(color).getRGB();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -28,7 +29,7 @@ public class ColorPattern extends AbstractPattern {
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
BaseBlock block = extent.getBlock(setPosition);
|
||||
BaseBlock block = extent.getBlock(getPosition);
|
||||
int currentColor = util.getColor(block);
|
||||
if (currentColor == 0) return false;
|
||||
int newColor = util.multiplyColor(currentColor, color);
|
||||
@ -36,4 +37,4 @@ public class ColorPattern extends AbstractPattern {
|
||||
if (newBlock.equals(block)) return false;
|
||||
return extent.setBlock(setPosition, newBlock);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,26 +2,28 @@ package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class ShadePattern extends AbstractPattern{
|
||||
private final TextureUtil util;
|
||||
private final Extent extent;
|
||||
private final boolean darken;
|
||||
|
||||
public ShadePattern(Extent extent, TextureUtil util) {
|
||||
public ShadePattern(Extent extent, TextureUtil util, boolean darken) {
|
||||
checkNotNull(extent);
|
||||
checkNotNull(util);
|
||||
this.extent = extent;
|
||||
this.util = util;
|
||||
this.darken = darken;
|
||||
}
|
||||
@Override
|
||||
public BaseBlock apply(Vector position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
return false;
|
||||
BaseBlock block = extent.getBlock(position);
|
||||
return darken ? util.getDarkerBlock(block) : util.getLighterBlock(block);
|
||||
}
|
||||
}
|
@ -143,7 +143,7 @@ public class CreateFromImage extends Command {
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi column [url|mask] <pattern> [white=false]");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi caves");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi ore[s]");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi schem <mask> <schem> <rarity> <rotate>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi schem [url] <mask> <schem> <rarity> <distance> <rotate>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi height <image-url|height>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi waterHeight <height>");
|
||||
fp.sendMessage(BBC.getPrefix() + "/2 cfi waterId <number-id>");
|
||||
@ -185,23 +185,35 @@ public class CreateFromImage extends Command {
|
||||
Request.request().setExtent(generator);
|
||||
try {
|
||||
switch (argList.get(0).toLowerCase()) {
|
||||
// BufferedImage, Mask, WorldData, ClipboardHolder[], rarity, distance, randomRotate
|
||||
case "schem":
|
||||
case "schems":
|
||||
case "addschems": {
|
||||
if (argList.size() != 5) {
|
||||
C.COMMAND_SYNTAX.send(player, "/2 cfi " + argList.get(0) + " <mask> <file|folder|url> <rarity> <rotate>");
|
||||
if (argList.size() != 6 && argList.size() != 7) {
|
||||
C.COMMAND_SYNTAX.send(player, "/2 cfi " + argList.get(0) + " [url] <mask> <file|folder|url> <rarity> <distance> <rotate>");
|
||||
return;
|
||||
}
|
||||
int argOffset = 0;
|
||||
BufferedImage img = null;
|
||||
if (argList.get(1).startsWith("http")) {
|
||||
img = getImgurImage(argList.get(1), fp);
|
||||
argOffset++;
|
||||
}
|
||||
World world = fp.getWorld();
|
||||
WorldData wd = world.getWorldData();
|
||||
Mask mask = we.getMaskFactory().parseFromInput(argList.get(1), context);
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), wd, argList.get(2), true);
|
||||
Mask mask = we.getMaskFactory().parseFromInput(argList.get(1 + argOffset), context);
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), wd, argList.get(2 + argOffset), true);
|
||||
if (clipboards == null) {
|
||||
return;
|
||||
}
|
||||
int rarity = Integer.parseInt(argList.get(3));
|
||||
boolean rotate = Boolean.parseBoolean(argList.get(4));
|
||||
generator.addSchems(mask, wd, clipboards, rarity, rotate);
|
||||
int rarity = Integer.parseInt(argList.get(3 + argOffset));
|
||||
int distance = Integer.parseInt(argList.get(4 + argOffset));
|
||||
boolean rotate = Boolean.parseBoolean(argList.get(5 + argOffset));
|
||||
if (img == null) {
|
||||
generator.addSchems(mask, wd, clipboards, rarity, rotate);
|
||||
} else {
|
||||
generator.addSchems(img, mask, wd, clipboards, rarity, distance, rotate);
|
||||
}
|
||||
player.sendMessage(BBC.getPrefix() + "Added schems, what's next?");
|
||||
return;
|
||||
}
|
||||
@ -530,6 +542,7 @@ public class CreateFromImage extends Command {
|
||||
} catch (InputParseException e) {
|
||||
player.sendMessage("Invalid mask " + e.getMessage());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
player.sendMessage("Error " + e.getMessage());
|
||||
} finally {
|
||||
Request.reset();
|
||||
|
@ -5,12 +5,13 @@ import java.util.Arrays;
|
||||
public class CleanTextureUtil extends TextureUtil {
|
||||
public CleanTextureUtil(TextureUtil parent, int minPercent, int maxPercent) {
|
||||
super(parent.getFolder());
|
||||
int minIndex = (parent.distances.length * minPercent) / 100;
|
||||
int maxIndex = (parent.distances.length * maxPercent) / 100;
|
||||
int minIndex = ((parent.distances.length - 1) * minPercent) / 100;
|
||||
int maxIndex = ((parent.distances.length - 1) * maxPercent) / 100;
|
||||
long min = parent.distances[minIndex];
|
||||
long max = parent.distances[maxIndex];
|
||||
for (; minIndex > 0 && parent.distances[minIndex - 1] == min; minIndex--);
|
||||
for (; maxIndex < parent.distances.length - 2 && parent.distances[maxIndex + 1] == max; maxIndex++);
|
||||
int num = maxIndex - minIndex + 1;
|
||||
|
||||
this.validBiomes = parent.validBiomes;
|
||||
this.blockColors = parent.blockColors;
|
||||
this.blockDistance = parent.blockDistance;
|
||||
|
@ -18,6 +18,16 @@ public class DelegateTextureUtil extends TextureUtil {
|
||||
return parent.getNearestBlock(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getNearestBlock(BaseBlock block) {
|
||||
return parent.getNearestBlock(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getNextNearestBlock(int color) {
|
||||
return parent.getNextNearestBlock(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getNearestLayer(int color) {
|
||||
return parent.getNearestLayer(color);
|
||||
|
@ -90,6 +90,8 @@ public final class DocumentationPrinter {
|
||||
stream.println();
|
||||
stream.print("## Content");
|
||||
stream.println();
|
||||
stream.print("Click on a category to go to the list of commands, or `More Info` for detailed descriptions ");
|
||||
stream.println();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
writePermissionsWikiTable(stream, builder, "/we ", WorldEditCommands.class);
|
||||
writePermissionsWikiTable(stream, builder, "/", GeneralCommands.class);
|
||||
@ -117,7 +119,7 @@ public final class DocumentationPrinter {
|
||||
stream.append("| --- | --- | --- | --- |\n");
|
||||
stream.append("| //cancel | fawe.cancel | | Cancels your current operations |\n");
|
||||
stream.append("| /plot replaceall | plots.replaceall | | Replace all blocks in the plot world |\n");
|
||||
stream.append("| /plot createfromimage | plots.createfromimage | | Starts world creation from a heightmap image: [More Info](https://www.youtube.com/watch?v=cJZk1GTig7A) |\n");
|
||||
stream.append("| /plot createfromimage | plots.createfromimage | | Starts world creation from a heightmap image: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/CreateFromImage) |\n");
|
||||
stream.print("\n---\n");
|
||||
|
||||
stream.print(builder);
|
||||
@ -139,7 +141,12 @@ public final class DocumentationPrinter {
|
||||
// //setbiome || worldedit.biome.set || //setbiome || p || Sets the biome of the player's current block or region.
|
||||
if (title) {
|
||||
String path = "https://github.com/boy0001/FastAsyncWorldedit/edit/master/core/src/main/java/" + cls.getName().replaceAll("\\.", "/") + ".java";
|
||||
stream.append("### **" + cls.getSimpleName().replaceAll("(\\p{Ll})(\\p{Lu})","$1 $2") + "** [`✎`](" + path + ")");
|
||||
stream.append("### **" + cls.getSimpleName().replaceAll("(\\p{Ll})(\\p{Lu})","$1 $2") + "** [`✎`](" + path + ")[`▲`](#overview)");
|
||||
stream.append("\n");
|
||||
Command cmd = cls.getAnnotation(Command.class);
|
||||
if (cmd != null) {
|
||||
stream.append(" (" + (cmd.help().isEmpty() ? cmd.desc() : cmd.help()) + ")");
|
||||
}
|
||||
stream.append("\n");
|
||||
stream.append("\n");
|
||||
stream.append("---");
|
||||
|
@ -30,4 +30,4 @@ public class FilteredTextureUtil extends TextureUtil {
|
||||
}
|
||||
this.calculateLayerArrays();
|
||||
}
|
||||
}
|
||||
}
|
@ -155,6 +155,18 @@ public class MathMan {
|
||||
return (long) (round + Math.signum(val - round));
|
||||
}
|
||||
|
||||
public static final int pair(short x, short y) {
|
||||
return (x << 16) | (y & 0xFFFF);
|
||||
}
|
||||
|
||||
public static final short unpairX(int hash) {
|
||||
return (short) (hash >> 16);
|
||||
}
|
||||
|
||||
public static final short unpairY(int hash) {
|
||||
return (short) (hash & 0xFFFF);
|
||||
}
|
||||
|
||||
public static final short pairByte(int x, int y) {
|
||||
return (short) ((x << 8) | (y & 0xFF));
|
||||
}
|
||||
@ -221,6 +233,33 @@ public class MathMan {
|
||||
;
|
||||
}
|
||||
|
||||
public static int pairSearchCoords(int x, int y) {
|
||||
byte b1 = (byte) ((x & 0xF) + ((y & 0xF) << 4));
|
||||
byte b2 = (byte) ((x >> 4) & 0xFF);
|
||||
byte b3 = (byte) ((y >> 4) & 0xFF);
|
||||
int x16 = (x >> 12) & 0xF;
|
||||
int y16 = (y >> 12) & 0xF;
|
||||
byte b4 = (byte) ((x16 & 0xF) + ((y16 & 0xF) << 4));
|
||||
return ((b1 & 0xFF)
|
||||
+ ((b2 & 0xFF) << 8)
|
||||
+ ((b3 & 0xFF) << 16)
|
||||
+ ((b4 & 0xFF) << 24));
|
||||
}
|
||||
|
||||
public static int unpairSearchCoordsX(int pair) {
|
||||
int x1 = (pair >> 24) & 0x7;
|
||||
int x2 = (pair >> 8) & 0xFF;
|
||||
int x3 = (pair & 0xF);
|
||||
return x3 + (x2 << 4) + (x1 << 12);
|
||||
}
|
||||
|
||||
public static int unpairSearchCoordsY(int pair) {
|
||||
int y1 = ((pair >> 24) & 0x7F) >> 3;
|
||||
int y2 = (pair >> 16) & 0xFF;
|
||||
int y3 = (pair & 0xFF) >> 4;
|
||||
return y3 + (y2 << 4) + (y1 << 12);
|
||||
}
|
||||
|
||||
public static final long chunkXZ2Int(int x, int z) {
|
||||
return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
|
||||
}
|
||||
@ -360,18 +399,6 @@ public class MathMan {
|
||||
return count / array.length;
|
||||
}
|
||||
|
||||
public static final int pair(short x, short y) {
|
||||
return (x << 16) | (y & 0xFFFF);
|
||||
}
|
||||
|
||||
public static final short unpairX(int hash) {
|
||||
return (short) (hash >> 16);
|
||||
}
|
||||
|
||||
public static final short unpairY(int hash) {
|
||||
return (short) (hash & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [x, y, z]
|
||||
* @param yaw
|
||||
|
@ -344,6 +344,33 @@ public class TextureUtil {
|
||||
return FaweCache.CACHE_BLOCK[closest];
|
||||
}
|
||||
|
||||
public BaseBlock getNearestBlock(BaseBlock block) {
|
||||
int color = getColor(block);
|
||||
if (color == 0) return null;
|
||||
return getNextNearestBlock(color);
|
||||
}
|
||||
|
||||
public BaseBlock getNextNearestBlock(int color) {
|
||||
long min = Long.MAX_VALUE;
|
||||
int closest = 0;
|
||||
int red1 = (color >> 16) & 0xFF;
|
||||
int green1 = (color >> 8) & 0xFF;
|
||||
int blue1 = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
for (int i = 0; i < validColors.length; i++) {
|
||||
int other = validColors[i];
|
||||
if (other != color && ((other >> 24) & 0xFF) == alpha) {
|
||||
long distance = colorDistance(red1, green1, blue1, other);
|
||||
if (distance < min) {
|
||||
min = distance;
|
||||
closest = validBlockIds[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (min == Long.MAX_VALUE) return null;
|
||||
return FaweCache.CACHE_BLOCK[closest];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block combined ids as an array
|
||||
* @param color
|
||||
@ -374,7 +401,7 @@ public class TextureUtil {
|
||||
}
|
||||
|
||||
public BaseBlock getDarkerBlock(BaseBlock block) {
|
||||
return getNearestBlock(block, false);
|
||||
return getNearestBlock(block, true);
|
||||
}
|
||||
|
||||
public int getColor(BaseBlock block) {
|
||||
@ -644,9 +671,25 @@ public class TextureUtil {
|
||||
int green2 = (c2 >> 8) & 0xFF;
|
||||
int blue2 = (c2 >> 0) & 0xFF;
|
||||
int red = ((red1 * red2)) / 255;
|
||||
int green = ((green1 * green2)) / 256;
|
||||
int blue = ((blue1 * blue2)) / 256;
|
||||
int alpha = ((alpha1 * alpha2)) / 256;
|
||||
int green = ((green1 * green2)) / 255;
|
||||
int blue = ((blue1 * blue2)) / 255;
|
||||
int alpha = ((alpha1 * alpha2)) / 255;
|
||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
|
||||
public int averageColor(int c1, int c2) {
|
||||
int alpha1 = (c1 >> 24) & 0xFF;
|
||||
int alpha2 = (c2 >> 24) & 0xFF;
|
||||
int red1 = (c1 >> 16) & 0xFF;
|
||||
int green1 = (c1 >> 8) & 0xFF;
|
||||
int blue1 = (c1 >> 0) & 0xFF;
|
||||
int red2 = (c2 >> 16) & 0xFF;
|
||||
int green2 = (c2 >> 8) & 0xFF;
|
||||
int blue2 = (c2 >> 0) & 0xFF;
|
||||
int red = ((red1 + red2)) / 2;
|
||||
int green = ((green1 + green2)) / 2;
|
||||
int blue = ((blue1 + blue2)) / 2;
|
||||
int alpha = ((alpha1 + alpha2)) / 2;
|
||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
|
||||
@ -709,14 +752,14 @@ public class TextureUtil {
|
||||
int green1 = (color >> 8) & 0xFF;
|
||||
int blue1 = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
int intensity1 = red1 + green1 + blue1;
|
||||
int intensity1 = 2 * red1 + 4 * green1 + 3 * blue1;
|
||||
for (int i = 0; i < validColors.length; i++) {
|
||||
int other = validColors[i];
|
||||
if (other != color && ((other >> 24) & 0xFF) == alpha) {
|
||||
int red2 = (other >> 16) & 0xFF;
|
||||
int green2 = (other >> 8) & 0xFF;
|
||||
int blue2 = (other >> 0) & 0xFF;
|
||||
int intensity2 = red2 + green2 + blue2;
|
||||
int intensity2 = 2 * red2 + 4 * green2 + 3 * blue2;
|
||||
if (darker ? intensity2 >= intensity1 : intensity1 >= intensity2) {
|
||||
continue;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.object.extent.SingleRegionExtent;
|
||||
import com.boydti.fawe.object.extent.SlowExtent;
|
||||
import com.boydti.fawe.object.extent.SourceMaskExtent;
|
||||
import com.boydti.fawe.object.function.SurfaceRegionFunction;
|
||||
import com.boydti.fawe.object.mask.ResettableMask;
|
||||
import com.boydti.fawe.object.progress.ChatProgressTracker;
|
||||
import com.boydti.fawe.object.progress.DefaultProgressTracker;
|
||||
@ -105,6 +106,7 @@ import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.util.RegionOffset;
|
||||
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.LayerVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.NonRisingVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
||||
@ -1901,7 +1903,6 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
@SuppressWarnings("deprecation")
|
||||
public int overlayCuboidBlocks(final Region region, final BaseBlock block) throws MaxChangedBlocksException {
|
||||
checkNotNull(block);
|
||||
|
||||
return this.overlayCuboidBlocks(region, new BlockPattern(block));
|
||||
}
|
||||
|
||||
@ -1920,10 +1921,12 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
checkNotNull(pattern);
|
||||
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
|
||||
final RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
|
||||
final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), offset);
|
||||
final LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
|
||||
int minY = region.getMinimumPoint().getBlockY();
|
||||
int maxY = Math.min(getMaximumPoint().getBlockY(), region.getMaximumPoint().getBlockY() + 1);
|
||||
SurfaceRegionFunction surface = new SurfaceRegionFunction(this, offset, minY, maxY);
|
||||
FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this);
|
||||
Operations.completeBlindly(visitor);
|
||||
return this.changes = ground.getAffected();
|
||||
return this.changes = visitor.getAffected();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,7 @@ import com.boydti.fawe.object.brush.ShatterBrush;
|
||||
import com.boydti.fawe.object.brush.SplatterBrush;
|
||||
import com.boydti.fawe.object.brush.SplineBrush;
|
||||
import com.boydti.fawe.object.brush.StencilBrush;
|
||||
import com.boydti.fawe.object.brush.SurfaceSphereBrush;
|
||||
import com.boydti.fawe.object.brush.SurfaceSpline;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
|
||||
@ -109,7 +110,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Commands to set brush shape.
|
||||
*/
|
||||
@Command(aliases = { "brush", "br" }, desc = "Commands to build and draw from far away: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Brushes)")
|
||||
@Command(aliases = { "brush", "br" },
|
||||
desc = "Commands to build and draw from far away. [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Brushes)"
|
||||
)
|
||||
public class BrushCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
@ -285,9 +288,10 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "blendball", "bb", "blend" },
|
||||
usage = "[radius]",
|
||||
desc = "Choose the blend ball brush",
|
||||
help = "Chooses the blend ball brush",
|
||||
usage = "[radius=5]",
|
||||
desc = "Smooths and blends terrain",
|
||||
help = "Smooths and blends terrain\n" +
|
||||
"Pic: https://i.imgur.com/cNUQUkj.png -> https://i.imgur.com/hFOFsNf.png",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@ -302,9 +306,9 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "erode", "e" },
|
||||
usage = "[radius]",
|
||||
desc = "Choose the erode brush",
|
||||
help = "Chooses the erode brush",
|
||||
usage = "[radius=5]",
|
||||
desc = "Erodes terrain",
|
||||
help = "Erodes terrain",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@ -319,9 +323,9 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "pull" },
|
||||
usage = "[radius]",
|
||||
desc = "Choose the raise brush",
|
||||
help = "Chooses the raise brush",
|
||||
usage = "[radius=5]",
|
||||
desc = "Pull terrain towards you",
|
||||
help = "Pull terrain towards you",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@ -336,14 +340,15 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "circle" },
|
||||
usage = "<pattern> [radius]",
|
||||
desc = "Choose the circle brush",
|
||||
help = "Chooses the circle brush.",
|
||||
usage = "<pattern> [radius=5]",
|
||||
desc = "Creates a circle which revolves around your facing direction",
|
||||
help = "Creates a circle which revolves around your facing direction.\n" +
|
||||
"Note: Decrease brush radius, and enabled visualization to assist with placement mid-air",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.sphere")
|
||||
public void circleBrush(Player player, LocalSession session, Pattern fill, @Optional("5") double radius) throws WorldEditException {
|
||||
public void circleBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setSize(radius);
|
||||
@ -354,15 +359,16 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "recursive", "recurse", "r" },
|
||||
usage = "<pattern-to> [radius]",
|
||||
desc = "Choose the recursive brush",
|
||||
help = "Chooses the recursive brush\n" +
|
||||
"The -d flag Will apply in depth first order",
|
||||
usage = "<pattern-to> [radius=5]",
|
||||
desc = "Set all connected blocks",
|
||||
help = "Set all connected blocks\n" +
|
||||
"The -d flag Will apply in depth first order\n" +
|
||||
"Note: Set a mask to recurse along specific blocks",
|
||||
min = 0,
|
||||
max = 3
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.recursive")
|
||||
public void recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("2") double radius, @Switch('d') boolean depthFirst) throws WorldEditException {
|
||||
public void recursiveBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("5") double radius, @Switch('d') boolean depthFirst) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setSize(radius);
|
||||
@ -374,11 +380,11 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "line", "l" },
|
||||
usage = "<pattern> [radius]",
|
||||
usage = "<pattern> [radius=0]",
|
||||
flags = "hsf",
|
||||
desc = "Choose the line brush",
|
||||
desc = "Create lines",
|
||||
help =
|
||||
"Chooses the line brush.\n" +
|
||||
"Create lines.\n" +
|
||||
"The -h flag creates only a shell\n" +
|
||||
"The -s flag selects the clicked point after drawing\n" +
|
||||
"The -f flag creates a flat line",
|
||||
@ -386,7 +392,7 @@ public class BrushCommands {
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.line")
|
||||
public void lineBrush(Player player, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException {
|
||||
public void lineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
@ -398,13 +404,16 @@ public class BrushCommands {
|
||||
@Command(
|
||||
aliases = { "spline", "spl", "curve" },
|
||||
usage = "<pattern>",
|
||||
desc = "Choose the spline brush",
|
||||
help = "Chooses the spline brush",
|
||||
desc = "Join multiple objects together in a curve",
|
||||
help = "Click to select some objects,click the same block twice to connect the objects.\n" +
|
||||
"Insufficient brush radius, or clicking the the wrong spot will result in undesired shapes. The shapes must be simple lines or loops.\n" +
|
||||
"Pic1: http://i.imgur.com/CeRYAoV.jpg -> http://i.imgur.com/jtM0jA4.png\n" +
|
||||
"Pic2: http://i.imgur.com/bUeyc72.png -> http://i.imgur.com/tg6MkcF.png",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.spline")
|
||||
public void splineBrush(Player player, LocalSession session, Pattern fill, @Optional("25") double radius) throws WorldEditException {
|
||||
public void splineBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("25") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
@ -417,14 +426,15 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "sspl", "sspline", "surfacespline" },
|
||||
usage = "<pattern> [size] [tension] [bias] [continuity] [quality]",
|
||||
desc = "Draws a spline on the surface",
|
||||
help = "Chooses the surface spline brush",
|
||||
usage = "<pattern> [size=0] [tension=0] [bias=0] [continuity=0] [quality=10]",
|
||||
desc = "Draws a spline (curved line) on the surface",
|
||||
help = "Create a spline on the surface\n" +
|
||||
"Video: https://www.youtube.com/watch?v=zSN-2jJxXlM",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
|
||||
public void surfaceSpline(Player player, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality) throws WorldEditException {
|
||||
public void surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
@ -435,17 +445,17 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "sphere", "s" },
|
||||
usage = "<pattern> [radius]",
|
||||
usage = "<pattern> [radius=2]",
|
||||
flags = "h",
|
||||
desc = "Choose the sphere brush",
|
||||
desc = "Creates a sphere",
|
||||
help =
|
||||
"Chooses the sphere brush.\n" +
|
||||
"Creates a sphere.\n" +
|
||||
"The -h flag creates hollow spheres instead.",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.sphere")
|
||||
public void sphereBrush(Player player, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException {
|
||||
public void sphereBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
@ -473,10 +483,11 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "shatter", "partition", "split" },
|
||||
usage = "<pattern> [radius] [count]",
|
||||
usage = "<pattern> [radius=10] [count=10]",
|
||||
desc = "Creates random lines to break the terrain into pieces",
|
||||
help =
|
||||
"Chooses the shatter brush",
|
||||
"Creates uneven lines separating terrain into multiple pieces\n" +
|
||||
"Pic: https://i.imgur.com/2xKsZf2.png",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@ -494,10 +505,10 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "stencil", "color"},
|
||||
usage = "<pattern> [radius] [file|#clipboard|null] [rotation] [yscale]",
|
||||
usage = "<pattern> [radius=5] [file|#clipboard|imgur=null] [rotation=360] [yscale=1.0]",
|
||||
desc = "Use a height map to paint a surface",
|
||||
help =
|
||||
"Chooses the stencil brush.\n" +
|
||||
"Use a height map to paint any surface.\n" +
|
||||
"The -w flag will only apply at maximum saturation\n" +
|
||||
"The -r flag will apply random rotation",
|
||||
min = 1,
|
||||
@ -523,13 +534,35 @@ public class BrushCommands {
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_STENCIL.f(radius));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "surface", "surf"},
|
||||
usage = "<pattern> [radius=5]",
|
||||
desc = "Use a height map to paint a surface",
|
||||
help =
|
||||
"Use a height map to paint any surface.\n" +
|
||||
"The -w flag will only apply at maximum saturation\n" +
|
||||
"The -r flag will apply random rotation",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.surface")
|
||||
public void surfaceBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") double radius) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
BrushTool tool = session.getBrushTool(player);
|
||||
tool.setFill(fill);
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new SurfaceSphereBrush(), "worldedit.brush.surface");
|
||||
player.print(BBC.getPrefix() + BBC.BRUSH_SURFACE.f(radius));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "scatter", "scat" },
|
||||
usage = "<pattern> [radius=5] [points=5] [distance=1]",
|
||||
desc = "Scatter blocks on a surface",
|
||||
desc = "Scatter a pattern on a surface",
|
||||
help =
|
||||
"Chooses the scatter brush.\n" +
|
||||
" The -o flag will overlay the block",
|
||||
"Set a number of blocks randomly on a surface each a certain distance apart.\n" +
|
||||
" The -o flag will overlay the block\n" +
|
||||
"Video: https://youtu.be/RPZIaTbqoZw?t=34s",
|
||||
flags = "o",
|
||||
min = 1,
|
||||
max = 4
|
||||
@ -581,9 +614,11 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "layer" },
|
||||
usage = "<radius> <pattern1> <patern2> <pattern3>...",
|
||||
desc = "Scatter a schematic on a surface",
|
||||
help = "Chooses the layer brush.",
|
||||
usage = "<radius> <pattern1> <patern2>...",
|
||||
desc = "Replaces terrain with a layer.",
|
||||
help = "Replaces terrain with a layer.\n" +
|
||||
"Example: /br layer 5 95:1 95:2 35:15 - Places several layers on a surface\n" +
|
||||
"Pic: https://i.imgur.com/XV0vYoX.png",
|
||||
min = 3,
|
||||
max = 999
|
||||
)
|
||||
@ -609,9 +644,11 @@ public class BrushCommands {
|
||||
@Command(
|
||||
aliases = { "splatter", "splat" },
|
||||
usage = "<pattern> [radius=5] [seeds=1] [recursion=5] [solid=true]",
|
||||
desc = "Splatter blocks on a surface",
|
||||
help =
|
||||
"Chooses the Splatter brush.",
|
||||
desc = "Splatter a pattern on a surface",
|
||||
help = "Sets a bunch of blocks randomly on a surface.\n" +
|
||||
"Pic: https://i.imgur.com/hMD29oO.png\n" +
|
||||
"Example: /br splatter stone,dirt 30 15\n" +
|
||||
"Note: The seeds define how many splotches there are, recursion defines how large, solid defines whether the pattern is applied per seed, else per block.",
|
||||
min = 1,
|
||||
max = 5
|
||||
)
|
||||
@ -628,9 +665,12 @@ public class BrushCommands {
|
||||
@Command(
|
||||
aliases = { "scmd", "scattercmd", "scattercommand", "scommand" },
|
||||
usage = "<scatter-radius> <points> <cmd-radius=1> <cmd1;cmd2...>",
|
||||
desc = "Scatter commands on a surface",
|
||||
desc = "Run commands at random points on a surface",
|
||||
help =
|
||||
"Chooses the scatter command brush.",
|
||||
"Run commands at random points on a surface\n" +
|
||||
" - The scatter radius is the min distance between each point\n" +
|
||||
" - Your selection will be expanded to the specified size around each point\n" +
|
||||
" - Placeholders: {x}, {y}, {z}, {world}, {size}",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@ -645,17 +685,17 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "cylinder", "cyl", "c" },
|
||||
usage = "<block> [radius] [height]",
|
||||
usage = "<block> [radius=2] [height=1]",
|
||||
flags = "h",
|
||||
desc = "Choose the cylinder brush",
|
||||
desc = "Creates a cylinder",
|
||||
help =
|
||||
"Chooses the cylinder brush.\n" +
|
||||
"Creates a cylinder.\n" +
|
||||
"The -h flag creates hollow cylinders instead.",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.cylinder")
|
||||
public void cylinderBrush(Player player, LocalSession session, Pattern fill,
|
||||
public void cylinderBrush(Player player, EditSession editSession, LocalSession session, Pattern fill,
|
||||
@Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
worldEdit.checkMaxBrushRadius(height);
|
||||
@ -675,7 +715,7 @@ public class BrushCommands {
|
||||
@Command(
|
||||
aliases = { "clipboard"},
|
||||
usage = "",
|
||||
desc = "Choose the clipboard brush",
|
||||
desc = "Choose the clipboard brush (Recommended: `/br copypaste`)",
|
||||
help =
|
||||
"Chooses the clipboard brush.\n" +
|
||||
"The -a flag makes it not paste air.\n" +
|
||||
@ -701,9 +741,9 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "smooth" },
|
||||
usage = "[size] [iterations]",
|
||||
usage = "[size=2] [iterations=4]",
|
||||
flags = "n",
|
||||
desc = "Choose the terrain softener brush",
|
||||
desc = "Smooths terrain (Recommended: `/br blendball`)",
|
||||
help =
|
||||
"Chooses the terrain softener brush.\n" +
|
||||
"The -n flag makes it only consider naturally occurring blocks.",
|
||||
@ -729,7 +769,7 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "ex", "extinguish" },
|
||||
usage = "[radius]",
|
||||
usage = "[radius=5]",
|
||||
desc = "Shortcut fire extinguisher brush",
|
||||
min = 0,
|
||||
max = 1
|
||||
@ -750,7 +790,7 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "gravity", "grav" },
|
||||
usage = "[radius]",
|
||||
usage = "[radius=5]",
|
||||
flags = "h",
|
||||
desc = "Gravity brush",
|
||||
help =
|
||||
@ -772,14 +812,16 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "height", "heightmap" },
|
||||
usage = "[radius] [file|#clipboard|null] [rotation] [yscale]",
|
||||
usage = "[radius=5] [file|#clipboard|imgur=null] [rotation=0] [yscale=1.00]",
|
||||
flags = "h",
|
||||
desc = "Height brush",
|
||||
desc = "Raise or lower terrain using a heightmap",
|
||||
help =
|
||||
"This brush raises and lowers land.\n" +
|
||||
"The -r flag enables random off-axis rotation\n" +
|
||||
"The -l flag will work on snow layers\n" +
|
||||
"The -s flag disables smoothing",
|
||||
" - The `-r` flag enables random off-axis rotation\n" +
|
||||
" - The `-l` flag will work on snow layers\n" +
|
||||
" - The `-s` flag disables smoothing\n" +
|
||||
"Note: Note: Use a negative yscale to reduce height\n" +
|
||||
"Snow Pic: https://i.imgur.com/Hrzn0I4.png",
|
||||
min = 1,
|
||||
max = 4
|
||||
)
|
||||
@ -790,14 +832,14 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "cliff", "flatcylinder" },
|
||||
usage = "[radius] [file|#clipboard|null] [rotation] [yscale]",
|
||||
usage = "[radius=5] [file|#clipboard|imgur=null] [rotation=0] [yscale=1.00]",
|
||||
flags = "h",
|
||||
desc = "Cliff brush",
|
||||
help =
|
||||
"This brush flattens terrain and creates cliffs.\n" +
|
||||
"The -r flag enables random off-axis rotation\n" +
|
||||
"The -l flag will work on snow layers\n" +
|
||||
"The -s flag disables smoothing",
|
||||
" - The `-r` flag enables random off-axis rotation\n" +
|
||||
" - The `-l` flag will work on snow layers\n" +
|
||||
" - The `-s` flag disables smoothing",
|
||||
min = 1,
|
||||
max = 4
|
||||
)
|
||||
@ -808,12 +850,12 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "flatten", "flatmap", "flat" },
|
||||
usage = "[radius] [file|#clipboard|null] [rotation] [yscale]",
|
||||
usage = "[radius=5] [file|#clipboard|imgur=null] [rotation=0] [yscale=1.00]",
|
||||
flags = "h",
|
||||
help = "Flatten brush makes terrain flatter\n" +
|
||||
"The -r flag enables random off-axis rotation\n" +
|
||||
"The -l flag will work on snow layers\n" +
|
||||
"The -s flag disables smoothing",
|
||||
help = "Flatten brush flattens terrain\n" +
|
||||
" - The `-r` flag enables random off-axis rotation\n" +
|
||||
" - The `-l` flag will work on snow layers\n" +
|
||||
" - The `-s` flag disables smoothing",
|
||||
desc = "This brush raises and lowers land towards the clicked point\n",
|
||||
min = 1,
|
||||
max = 4
|
||||
@ -884,12 +926,13 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "copypaste", "copy", "paste", "cp", "copypasta" },
|
||||
usage = "[depth]",
|
||||
usage = "[depth=5]",
|
||||
desc = "Copy Paste brush",
|
||||
help =
|
||||
"Left click the base of an object to copy.\n" +
|
||||
help = "Left click the base of an object to copy.\n" +
|
||||
"Right click to paste\n" +
|
||||
"The -r flag Will apply random rotation on paste",
|
||||
"The -r flag Will apply random rotation on paste\n" +
|
||||
"Note: Works well with the clipboard scroll action\n" +
|
||||
"Video: https://www.youtube.com/watch?v=RPZIaTbqoZw",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@ -907,7 +950,10 @@ public class BrushCommands {
|
||||
usage = "<radius> [cmd1;cmd2...]",
|
||||
desc = "Command brush",
|
||||
help =
|
||||
"Right click executes the command at the position.\n",
|
||||
"Run the commands at the clicked position.\n" +
|
||||
" - Your selection will be expanded to the specified size around each point\n" +
|
||||
" - Placeholders: {x}, {y}, {z}, {world}, {size}",
|
||||
|
||||
min = 2,
|
||||
max = 99
|
||||
)
|
||||
@ -922,7 +968,7 @@ public class BrushCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "butcher", "kill" },
|
||||
usage = "[radius]",
|
||||
usage = "[radius=5]",
|
||||
flags = "plangbtfr",
|
||||
desc = "Butcher brush",
|
||||
help = "Kills nearby mobs within the specified radius.\n" +
|
||||
|
@ -24,6 +24,7 @@ import com.boydti.fawe.object.brush.InspectBrush;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
@ -151,7 +152,7 @@ public class ToolCommands {
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.tool.flood-fill")
|
||||
public void floodFill(Player player, LocalSession session, Pattern pattern, double range) throws WorldEditException {
|
||||
public void floodFill(Player player, EditSession editSession, LocalSession session, Pattern pattern, double range) throws WorldEditException {
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
if (range > config.maxSuperPickaxeSize) {
|
||||
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
|
||||
|
@ -188,7 +188,7 @@ public class ToolUtilCommands {
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.options.material")
|
||||
public void material(Player player, LocalSession session, Pattern pattern, @Switch('h') boolean offHand) throws WorldEditException {
|
||||
public void material(Player player, EditSession editSession, LocalSession session, Pattern pattern, @Switch('h') boolean offHand) throws WorldEditException {
|
||||
Tool tool = session.getTool(player);
|
||||
if (tool instanceof BrushTool) {
|
||||
BrushTool bt = (BrushTool) tool;
|
||||
|
@ -3,8 +3,14 @@ package com.sk89q.worldedit.extension.factory;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.object.DataAngleMask;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.pattern.AngleColorPattern;
|
||||
import com.boydti.fawe.object.pattern.AverageColorPattern;
|
||||
import com.boydti.fawe.object.pattern.BiomePattern;
|
||||
import com.boydti.fawe.object.pattern.BufferedPattern;
|
||||
import com.boydti.fawe.object.pattern.DataPattern;
|
||||
import com.boydti.fawe.object.pattern.DesaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ExistingPattern;
|
||||
import com.boydti.fawe.object.pattern.ExpressionPattern;
|
||||
import com.boydti.fawe.object.pattern.FullClipboardPattern;
|
||||
@ -21,11 +27,14 @@ import com.boydti.fawe.object.pattern.PatternExtent;
|
||||
import com.boydti.fawe.object.pattern.RandomFullClipboardPattern;
|
||||
import com.boydti.fawe.object.pattern.RandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.RelativePattern;
|
||||
import com.boydti.fawe.object.pattern.SaturatePattern;
|
||||
import com.boydti.fawe.object.pattern.ShadePattern;
|
||||
import com.boydti.fawe.object.pattern.SolidRandomOffsetPattern;
|
||||
import com.boydti.fawe.object.pattern.SurfaceRandomOffsetPattern;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -124,7 +133,8 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
case '#': {
|
||||
String[] split2 = input.split(":");
|
||||
String rest = split2.length > 1 ? input.substring(split2[0].length() + 1) : "";
|
||||
switch (split2[0].toLowerCase()) {
|
||||
String arg = split2[0].toLowerCase();
|
||||
switch (arg) {
|
||||
case "#*":
|
||||
case "#existing": {
|
||||
return new ExistingPattern(Request.request().getExtent());
|
||||
@ -154,6 +164,40 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
throw new InputParseException("#color:<hex>");
|
||||
}
|
||||
}
|
||||
case "#anglecolor": {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 2 ? true : Boolean.parseBoolean(split2[1]), 0, split2.length < 3 ? 100 : Integer.parseInt(split2[2]));
|
||||
return new AngleColorPattern(util, Request.request().getExtent());
|
||||
}
|
||||
case "#angledata": {
|
||||
return new DataAngleMask(Request.request().getExtent());
|
||||
}
|
||||
case "#saturate":
|
||||
case "#averagecolor": {
|
||||
try {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 3 ? true : Boolean.parseBoolean(split2[2]), 0, split2.length < 4 ? 100 : Integer.parseInt(split2[3]));
|
||||
Color color = Color.web(split2[1]);
|
||||
java.awt.Color awtColor = new java.awt.Color((float) color.getRed(), (float) color.getGreen(), (float) color.getBlue(), (float) color.getOpacity());
|
||||
if (arg.equals("#saturate"))
|
||||
return new SaturatePattern(Request.request().getExtent(), util, awtColor.getRGB());
|
||||
else return new AverageColorPattern(Request.request().getExtent(), util, awtColor.getRGB());
|
||||
} catch (NumberFormatException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#" + arg + "[:<color>:<randomize=true>:<complexity=100>]");
|
||||
}
|
||||
}
|
||||
case "#desaturate": {
|
||||
try {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 3 ? true : Boolean.parseBoolean(split2[2]), 0, split2.length < 4 ? 100 : Integer.parseInt(split2[3]));
|
||||
double chance = split2.length < 2 ? 100 : Expression.compile(split2[1]).evaluate();
|
||||
return new DesaturatePattern(Request.request().getExtent(), util, chance / 100d);
|
||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||
throw new SuggestInputParseException(null, "#desaturate[:<percent=100>:<randomize=true>:<complexity=100>]");
|
||||
}
|
||||
}
|
||||
case "#lighten":
|
||||
case "#darken": {
|
||||
TextureUtil util = Fawe.get().getCachedTextureUtil(split2.length < 2 ? true : Boolean.parseBoolean(split2[1]), 0, split2.length < 3 ? 100 : Integer.parseInt(split2[2]));
|
||||
return new ShadePattern(Request.request().getExtent(), util, arg.equals("#darken"));
|
||||
}
|
||||
case "#fullcopy": {
|
||||
LocalSession session = context.requireSession();
|
||||
if (session != null) {
|
||||
@ -196,6 +240,9 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
throw new InputParseException("No session is available, so no clipboard is available");
|
||||
}
|
||||
}
|
||||
case "#buffer": {
|
||||
return new BufferedPattern(FawePlayer.wrap(context.requireActor()), catchSuggestion(input, rest, context));
|
||||
}
|
||||
case "#iddatamask": {
|
||||
String[] split = rest.split(":", 1);
|
||||
if (split.length != 2) {
|
||||
|
@ -424,13 +424,12 @@ public final class CommandManager {
|
||||
}
|
||||
} finally {
|
||||
final EditSession editSession = locals.get(EditSession.class);
|
||||
boolean hasSession = false;
|
||||
if (editSession != null) {
|
||||
editSession.flushQueue();
|
||||
worldEdit.flushBlockBag(finalActor, editSession);
|
||||
session.remember(editSession);
|
||||
final long time = System.currentTimeMillis() - start;
|
||||
if (time > 250 && hasSession) {
|
||||
if (time > 1000) {
|
||||
BBC.ACTION_COMPLETE.send(finalActor, (time / 1000d));
|
||||
}
|
||||
Request.reset();
|
||||
|
@ -138,10 +138,9 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxY;
|
||||
return maxY >= 255 ? maxY : -1;
|
||||
}
|
||||
|
||||
|
||||
default public void addCaves(Region region) throws WorldEditException {
|
||||
generate(region, new CavesGen(8));
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.function;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Applies a {@link RegionFunction} to the first ground block.
|
||||
*/
|
||||
public class GroundFunction implements LayerFunction {
|
||||
|
||||
private Mask mask;
|
||||
private final RegionFunction function;
|
||||
private int affected;
|
||||
|
||||
/**
|
||||
* Create a new ground function.
|
||||
*
|
||||
* @param mask a mask
|
||||
* @param function the function to apply
|
||||
*/
|
||||
public GroundFunction(Mask mask, RegionFunction function) {
|
||||
checkNotNull(mask);
|
||||
checkNotNull(function);
|
||||
this.mask = mask;
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mask that determines what the ground consists of.
|
||||
*
|
||||
* @return a mask
|
||||
*/
|
||||
public Mask getMask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mask that determines what the ground consists of.
|
||||
*
|
||||
* @param mask a mask
|
||||
*/
|
||||
public void setMask(Mask mask) {
|
||||
checkNotNull(mask);
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of affected objects.
|
||||
*
|
||||
* @return the number of affected
|
||||
*/
|
||||
public int getAffected() {
|
||||
return affected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGround(Vector position) {
|
||||
return mask.test(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Vector position, int depth) throws WorldEditException {
|
||||
if (depth == 0) {
|
||||
if (function.apply(position)) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -20,6 +20,10 @@
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.example.MappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.object.visitor.Fast2DIterator;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.FlatRegionFunction;
|
||||
@ -38,6 +42,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class FlatRegionVisitor implements Operation {
|
||||
|
||||
private final FlatRegionFunction function;
|
||||
private MappedFaweQueue queue;
|
||||
private int affected = 0;
|
||||
private final Iterable<Vector2D> iterator;
|
||||
|
||||
@ -54,6 +59,15 @@ public class FlatRegionVisitor implements Operation {
|
||||
this.iterator = flatRegion.asFlatRegion();
|
||||
}
|
||||
|
||||
public FlatRegionVisitor(final FlatRegion flatRegion, final FlatRegionFunction function, HasFaweQueue hasFaweQueue) {
|
||||
checkNotNull(flatRegion);
|
||||
checkNotNull(function);
|
||||
this.function = function;
|
||||
this.iterator = flatRegion.asFlatRegion();
|
||||
FaweQueue queue = hasFaweQueue.getQueue();
|
||||
this.queue = (MappedFaweQueue) (queue instanceof MappedFaweQueue ? queue : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of affected objects.
|
||||
*
|
||||
@ -65,9 +79,13 @@ public class FlatRegionVisitor implements Operation {
|
||||
|
||||
@Override
|
||||
public Operation resume(final RunContext run) throws WorldEditException {
|
||||
for (final Vector2D pt : this.iterator) {
|
||||
if (this.function.apply(pt)) {
|
||||
affected++;
|
||||
if (this.queue != null) {
|
||||
for (final Vector2D pt : new Fast2DIterator(this.iterator, queue)) {
|
||||
if (this.function.apply(pt)) affected++;
|
||||
}
|
||||
} else {
|
||||
for (final Vector2D pt : this.iterator) {
|
||||
if (this.function.apply(pt)) affected++;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -43,6 +43,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
* maximum Y down to a minimum Y), and then applies a {@link LayerFunction} to
|
||||
* each layer.</p>
|
||||
*/
|
||||
@Deprecated
|
||||
public class LayerVisitor implements Operation {
|
||||
|
||||
private final LayerFunction function;
|
||||
|
Loading…
Reference in New Issue
Block a user