nukkit fixes
add new brushes
some other minor stuff
This commit is contained in:
Jesse Boyd 2016-09-09 03:41:03 +10:00
parent 733f5eabc4
commit 71071998c6
51 changed files with 1077 additions and 186 deletions

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.object.FaweQueue;
import com.sk89q.worldedit.world.World;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@ -53,5 +54,5 @@ public abstract class ABukkitMain extends JavaPlugin {
FaweBukkit imp = new FaweBukkit(this);
}
public abstract FaweQueue getQueue(String world);
public abstract FaweQueue getQueue(World world);
}

View File

@ -158,7 +158,7 @@ public class FaweBukkit implements IFawe, Listener {
* - When a block change is requested, the SetQueue will first check if the chunk exists in the queue, or it will create and add it<br>
*/
@Override
public FaweQueue getNewQueue(String world, boolean dontCareIfFast) {
public FaweQueue getNewQueue(World world, boolean dontCareIfFast) {
if (playerChunk != (playerChunk = true)) {
try {
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();

View File

@ -33,7 +33,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
public static Method methodToNative;
public static Method methodFromNative;
public BukkitQueue_0(final String world) {
public BukkitQueue_0(final com.sk89q.worldedit.world.World world) {
super(world);
setupAdapter(null);
if (!registered) {

View File

@ -21,7 +21,7 @@ public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
public static double TPS_TARGET = 18.5;
private static int LIGHT_MASK = 0x739C0;
public BukkitQueue_All(String world) {
public BukkitQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
if (Settings.QUEUE.EXTRA_TIME_MS != Integer.MIN_VALUE) {
ALLOCATE = Settings.QUEUE.EXTRA_TIME_MS;

View File

@ -129,7 +129,7 @@ public class AsyncWorld implements World {
* @return
*/
public synchronized static AsyncWorld create(final WorldCreator creator) {
BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(creator.name(), true, false);
BukkitQueue_0 queue = (BukkitQueue_0) SetQueue.IMP.getNewQueue(FaweAPI.getWorld(creator.name()), true, false);
World world = queue.createWorld(creator);
return wrap(world);
}
@ -182,7 +182,7 @@ public class AsyncWorld implements World {
@Override
public int getHighestBlockYAt(int x, int z) {
for (int y = 255; y >= 0; y--) {
for (int y = getMaxHeight() - 1; y >= 0; y--) {
if (queue.getCombinedId4Data(x, y, z, 0) != 0) {
return y;
}

View File

@ -7,6 +7,7 @@ import com.boydti.fawe.object.io.BufferedRandomAccessFile;
import com.boydti.fawe.object.io.FastByteArrayInputStream;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.worldedit.world.World;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
@ -26,7 +27,7 @@ import net.minecraft.server.v1_10_R1.RegionFileCache;
public class BukkitMain_110 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue_1_10(world);
}

View File

@ -80,7 +80,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
public BukkitQueue_1_10(final String world) {
public BukkitQueue_1_10(final com.sk89q.worldedit.world.World world) {
super(world);
checkVersion("v1_10_R1");
if (air == null) {

View File

@ -2,11 +2,12 @@ package com.boydti.fawe.bukkit.v1_7;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.sk89q.worldedit.world.World;
public class BukkitMain_17 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue17(world);
}
}

View File

@ -69,7 +69,7 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
private static Field fieldData;
private static Field fieldIds;
public BukkitQueue17(final String world) {
public BukkitQueue17(final com.sk89q.worldedit.world.World world) {
super(world);
checkVersion("v1_7_R4");
if (fieldData == null) {

View File

@ -2,11 +2,12 @@ package com.boydti.fawe.bukkit.v1_8;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.sk89q.worldedit.world.World;
public class BukkitMain_18 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue18R3(world);
}
}

View File

@ -69,7 +69,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
public static Field isDirty;
public BukkitQueue18R3(final String world) {
public BukkitQueue18R3(final com.sk89q.worldedit.world.World world) {
super(world);
checkVersion("v1_8_R3");
}

View File

@ -2,10 +2,11 @@ package com.boydti.fawe.bukkit.v1_9;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.sk89q.worldedit.world.World;
public class BukkitMain_19 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
public BukkitQueue_0 getQueue(World world) {
return new BukkitQueue_1_9_R1(world);
}
}

View File

@ -79,7 +79,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
private static IBlockData air;
private static Field fieldBits;
public BukkitQueue_1_9_R1(final String world) {
public BukkitQueue_1_9_R1(final com.sk89q.worldedit.world.World world) {
super(world);
checkVersion("v1_9_R2");
if (air == null) {

View File

@ -47,6 +47,7 @@ import com.sk89q.worldedit.extent.clipboard.io.SchematicWriter;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
@ -365,6 +366,8 @@ public class Fawe {
AbstractDelegateExtent.inject(); // Optimizations
// Vector
Vector.inject(); // Optimizations
// Pattern
Patterns.inject(); // Optimizations (reduce object creation)
// Operations
Operations.inject(); // Optimizations
// BlockData

View File

@ -98,6 +98,11 @@ public class FaweAPI {
return FawePlayer.wrap(obj);
}
@Deprecated
public static FaweQueue createQueue(String worldName, boolean autoqueue) {
return SetQueue.IMP.getNewQueue(getWorld(worldName), true, autoqueue);
}
/**
* You can either use a FaweQueue or an EditSession to change blocks<br>
* - The FaweQueue skips a bit of overhead so it's faster<br>
@ -108,8 +113,8 @@ public class FaweAPI {
* @param autoqueue If it should start dispatching before you enqueue it.
* @return
*/
public static FaweQueue createQueue(String worldName, boolean autoqueue) {
return SetQueue.IMP.getNewQueue(worldName, true, autoqueue);
public static FaweQueue createQueue(World world, boolean autoqueue) {
return SetQueue.IMP.getNewQueue(world, true, autoqueue);
}
public static World getWorld(String worldName) {
@ -355,32 +360,21 @@ public class FaweAPI {
return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2));
}
// /**
// * Fix the lighting in a chunk
// * @param world
// * @param x
// * @param z
// * @param mode
// */
// public static void fixLighting(String world, int x, int z, FaweQueue.RelightMode mode) {
// FaweQueue queue = SetQueue.IMP.getNewQueue(world, true, false);
// queue.fixLighting(queue.getFaweChunk(x, z), mode);
// }
//
// /**
// * Fix the lighting in a chunk
// * @param chunk
// * @param mode
// */
// public static void fixLighting(final Chunk chunk, FaweQueue.RelightMode mode) {
// FaweQueue queue = SetQueue.IMP.getNewQueue(chunk.getWorld().getName(), true, false);
// queue.fixLighting(queue.getFaweChunk(chunk.getX(), chunk.getZ()), mode);
// }
@Deprecated
public static int fixLighting(String world, Region selection) {
return fixLighting(world, selection, FaweQueue.RelightMode.ALL);
}
@Deprecated
public static int fixLighting(String world, Region selection, final FaweQueue.RelightMode mode) {
return fixLighting(world, selection, null, mode);
}
@Deprecated
public static int fixLighting(String world, Region selection, @Nullable FaweQueue queue, final FaweQueue.RelightMode mode) {
return fixLighting(getWorld(world), selection, queue, mode);
}
/**
* Fix the lighting in a selection<br>
* - First removes all lighting, then relights
@ -390,11 +384,7 @@ public class FaweAPI {
* @param selection (assumes cuboid)
* @return
*/
public static int fixLighting(String world, Region selection, final FaweQueue.RelightMode mode) {
return fixLighting(world, selection, null, mode);
}
public static int fixLighting(String world, Region selection, @Nullable FaweQueue queue, final FaweQueue.RelightMode mode) {
public static int fixLighting(World world, Region selection, @Nullable FaweQueue queue, final FaweQueue.RelightMode mode) {
final Vector bot = selection.getMinimumPoint();
final Vector top = selection.getMaximumPoint();
@ -499,7 +489,7 @@ public class FaweAPI {
final int y_offset = loc.y + IntTag.class.cast(tagMap.get("WEOffsetY")).getValue();
final int z_offset = loc.z + IntTag.class.cast(tagMap.get("WEOffsetZ")).getValue();
FaweQueue queue = SetQueue.IMP.getNewQueue(loc.world, true, true);
FaweQueue queue = SetQueue.IMP.getNewQueue(getWorld(loc.world), true, true);
for (int y = 0; y < height; y++) {
final int yy = y_offset + y;

View File

@ -246,6 +246,19 @@ public class FaweCache {
CACHE_COLOR[getCombined(35, 15)] = new Color(0, 0, 0); // Black
}
public static boolean isLiquidOrGas(int id) {
switch (id) {
case 0:
case 8:
case 9:
case 10:
case 11:
return true;
default:
return false;
}
}
public static LightType getLight(int id) {
switch (id) { // Lighting
case 0:

View File

@ -23,7 +23,7 @@ public interface IFawe {
public TaskManager getTaskManager();
public FaweQueue getNewQueue(String world, boolean fast);
public FaweQueue getNewQueue(World world, boolean fast);
public String getWorldName(World world);

View File

@ -79,6 +79,7 @@ public enum BBC {
SELECTION_OUTSET("Region outset", "WorldEdit.Selection"),
SELECTION_SHIFT("Region shifted", "WorldEdit.Selection"),
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
SELECTION_NONE("Make a region selection first", "WorldEdit.Selection"),
BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
@ -91,6 +92,10 @@ public enum BBC {
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2).", "WorldEdit.Brush"),
BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
BRUSH_BLEND_BALL("Blend ball brush equipped (%s0).", "WorldEdit.Brush"),
BRUSH_ERODE("Erode brush equipped (%s0).", "WorldEdit.Brush"),
BRUSH_PASTE_NONE("Nothing to paste", "WorldEdit.Brush"),
ROLLBACK_ELEMENT("Undoing %s0", "WorldEdit.Rollback"),

View File

@ -14,6 +14,7 @@ import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.ArrayDeque;
@ -31,11 +32,11 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
private IFaweQueueMap map;
public ArrayDeque<Runnable> tasks = new ArrayDeque<>();
public MappedFaweQueue(final String world) {
public MappedFaweQueue(final World world) {
this(world, null);
}
public MappedFaweQueue(final String world, IFaweQueueMap map) {
public MappedFaweQueue(final World world, IFaweQueueMap map) {
super(world);
if (map == null) {
map = new DefaultFaweQueueMap(this);

View File

@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.World;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@ -13,13 +14,17 @@ import java.util.UUID;
public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> extends MappedFaweQueue<WORLD, CHUNKSECTION, SECTION> {
public NMSMappedFaweQueue(String world) {
private final int maxY;
public NMSMappedFaweQueue(World world) {
super(world);
this.maxY = world.getMaxY();
addRelightTask();
}
public NMSMappedFaweQueue(String world, IFaweQueueMap map) {
public NMSMappedFaweQueue(World world, IFaweQueueMap map) {
super(world, map);
this.maxY = world.getMaxY();
addRelightTask();
}
@ -57,7 +62,7 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
}
CharFaweChunk chunk = (CharFaweChunk) fc;
boolean relight = false;
boolean[] fix = new boolean[16];
boolean[] fix = new boolean[(maxY + 1) >> 4];
boolean sky = hasSky();
for (int i = 0; i < chunk.ids.length; i++) {
if ((sky && ((chunk.getAir(i) & 4095) != 0 || (chunk.getCount(i) & 4095) != 0)) || chunk.getRelight(i) != 0) {
@ -99,7 +104,7 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
if ((x < 0) || (x > 15) || (z < 0) || (z > 15)) {
return 1;
}
if ((y < 0) || (y > 255)) {
if ((y < 0) || (y > maxY)) {
return 1;
}
final int i = FaweCache.CACHE_I[y][z][x];
@ -181,7 +186,7 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
@Override
public CompoundTag getTileEntity(int x, int y, int z) throws FaweException.FaweChunkLoadException {
if (y < 0 || y > 255) {
if (y < 0 || y > maxY) {
return null;
}
int cx = x >> 4;

View File

@ -16,6 +16,7 @@ public class NMSRelighter {
private final NMSMappedFaweQueue queue;
private final HashMap<Long, RelightSkyEntry> skyToRelight;
private final HashMap<Long, RelightBlockEntry> blocksToRelight;
private final int maxY;
private volatile boolean relighting = false;
private static final int DISPATCH_SIZE = 64;
@ -24,6 +25,7 @@ public class NMSRelighter {
this.queue = queue;
skyToRelight = new HashMap<>();
blocksToRelight = new HashMap<>();
this.maxY = queue.getWEWorld().getMaxY();
}
public boolean addChunk(int cx, int cz, boolean[] fix) {
@ -112,7 +114,7 @@ public class NMSRelighter {
if (y > 0) {
smoothBlockLight(emit, xx, y, zz, xx, y - 1, zz);
}
if (y < 255) {
if (y < maxY) {
smoothBlockLight(emit, xx, y, zz, xx, y + 1, zz);
}
}
@ -147,7 +149,7 @@ public class NMSRelighter {
if (isTransparent(x, y, z - 1)) { queue.setBlockLight(x, y, z - 1, brightness); addBlock(x, y, z - 1); }
if (isTransparent(x, y, z + 1)) { queue.setBlockLight(x, y, z + 1, brightness); addBlock(x, y, z + 1); }
if (y > 0 && isTransparent(x, y - 1, z)) { queue.setBlockLight(x, y - 1, z, brightness); addBlock(x, y - 1, z); }
if (y < 255 && isTransparent(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
if (y < maxY && isTransparent(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
}
public void fixSkyLighting() {
@ -185,7 +187,7 @@ public class NMSRelighter {
Object section = queue.getCachedSection(sections, layer);
if (section == null)continue;
chunk.smooth = false;
for (int j = 0; j < 256; j++) {
for (int j = 0; j <= maxY; j++) {
int x = cacheX[j];
int z = cacheZ[j];
byte value = mask[j];
@ -271,7 +273,7 @@ public class NMSRelighter {
Object section = queue.getCachedSection(sections, y >> 4);
if (section == null) return;
if (direction) {
for (int j = 0; j < 256; j++) {
for (int j = 0; j <= maxY; j++) {
int x = j & 15;
int z = j >> 4;
if (mask[j] >= 14 || (mask[j] == 0 && queue.getOpacity(section, x, y, z) > 1)) {
@ -283,7 +285,7 @@ public class NMSRelighter {
if (value > mask[j]) queue.setSkyLight(section, x, y, z, mask[j] = value);
}
} else {
for (int j = 255; j >= 0; j--) {
for (int j = maxY; j >= 0; j--) {
int x = j & 15;
int z = j >> 4;
if (mask[j] >= 14 || (mask[j] == 0 && queue.getOpacity(section, x, y, z) > 1)) {
@ -340,11 +342,11 @@ public class NMSRelighter {
public RelightSkyEntry(int x, int z, boolean[] fix) {
this.x = x;
this.z = z;
byte[] array = new byte[256];
byte[] array = new byte[maxY + 1];
Arrays.fill(array, (byte) 15);
this.mask = array;
if (fix == null) {
this.fix = new boolean[16];
this.fix = new boolean[(maxY + 1) >> 4];
Arrays.fill(this.fix, true);
} else {
this.fix = fix;

View File

@ -24,7 +24,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
private final File saveFolder;
public MCAQueue(FaweQueue parent) {
super(parent.getWorldName(), new MCAQueueMap());
super(parent.getWEWorld(), new MCAQueueMap());
this.parent = parent;
if (parent instanceof NMSMappedFaweQueue) {
parentNMS = (NMSMappedFaweQueue) parent;
@ -35,7 +35,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
}
public MCAQueue(String world, File saveFolder, boolean hasSky) {
super(world, new MCAQueueMap());
super(null, new MCAQueueMap());
((MCAQueueMap) getFaweQueueMap()).setParentQueue(this);
this.saveFolder = saveFolder;
this.hasSky = hasSky;

View File

@ -16,6 +16,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
@ -151,7 +152,7 @@ public abstract class FawePlayer<T> {
}
public FaweQueue getMaskedFaweQueue(boolean autoQueue) {
FaweQueue queue = SetQueue.IMP.getNewQueue(getLocation().world, true, autoQueue);
FaweQueue queue = SetQueue.IMP.getNewQueue(getWorld(), true, autoQueue);
RegionWrapper[] allowedRegions = getCurrentRegions();
if (allowedRegions.length == 1 && allowedRegions[0].isGlobal()) {
return queue;
@ -275,7 +276,9 @@ public abstract class FawePlayer<T> {
*/
public void setSelection(final RegionWrapper region) {
final Player player = this.getPlayer();
final RegionSelector selector = new CuboidRegionSelector(player.getWorld(), region.getBottomVector(), region.getTopVector());
Vector top = region.getTopVector();
top.setY(getWorld().getMaxY());
final RegionSelector selector = new CuboidRegionSelector(player.getWorld(), region.getBottomVector(), top);
this.getSession().setRegionSelector(player.getWorld(), selector);
}

View File

@ -14,6 +14,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.io.File;
@ -26,14 +27,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class FaweQueue {
private World weWorld;
private final String world;
private ConcurrentLinkedDeque<EditSession> sessions;
private long modified = System.currentTimeMillis();
private RunnableVal2<FaweChunk, FaweChunk> changeTask;
private RunnableVal2<ProgressType, Integer> progressTask;
public FaweQueue(String world) {
this.world = world;
public FaweQueue(World world) {
this.weWorld = world;
this.world = Fawe.imp().getWorldName(world);
}
public enum ProgressType {
@ -58,6 +61,10 @@ public abstract class FaweQueue {
getSessions().add(session);
}
public World getWEWorld() {
return weWorld;
}
public String getWorldName() {
return world;
}
@ -140,6 +147,10 @@ public abstract class FaweQueue {
public abstract File getSaveFolder();
public int getMaxY() {
return weWorld == null ? 255 : weWorld.getMaxY();
}
public void forEachBlockInChunk(int cx, int cz, RunnableVal2<Vector, BaseBlock> onEach) {
int bx = cx << 4;
int bz = cz << 4;
@ -150,7 +161,7 @@ public abstract class FaweQueue {
for (int z = 0; z < 16; z++) {
int zz = z + bz;
mutable.z = zz;
for (int y = 0; y < 256; y++) {
for (int y = 0; y <= getMaxY(); y++) {
int combined = getCombinedId4Data(xx, y, zz);
if (combined == 0) {
continue;
@ -177,7 +188,7 @@ public abstract class FaweQueue {
int xx = x + bx;
for (int z = 0; z < 16; z++) {
int zz = z + bz;
for (int y = 0; y < 256; y++) {
for (int y = 0; y < getMaxY(); y++) {
int combined = getCombinedId4Data(xx, y, zz);
if (combined == 0) {
continue;

View File

@ -1,5 +1,7 @@
package com.boydti.fawe.object;
import java.util.Random;
public class PseudoRandom {
public static PseudoRandom random = new PseudoRandom();
@ -8,6 +10,7 @@ public class PseudoRandom {
public PseudoRandom() {
this.state = System.nanoTime();
new Random().nextDouble();
}
public PseudoRandom(final long state) {
@ -27,6 +30,10 @@ public class PseudoRandom {
return a;
}
public double nextDouble() {
return Math.max(0, Math.min(1, Math.abs(nextLong() / Long.MAX_VALUE)));
}
public int random(final int n) {
if (n == 1) {
return 0;
@ -34,4 +41,8 @@ public class PseudoRandom {
final long r = ((this.nextLong() >>> 32) * n) >> 32;
return (int) r;
}
public int nextInt(int i) {
return random(i);
}
}

View File

@ -0,0 +1,74 @@
package com.boydti.fawe.object.brush;
import com.google.common.collect.Maps;
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.pattern.Pattern;
import java.util.Map;
public class BlendBall implements Brush {
@Override
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
final int outsetSize = (int) (size + 1);
double brushSizeSquared = size * size;
int tx = position.getBlockX();
int ty = position.getBlockY();
int tz = position.getBlockZ();
Map<BaseBlock, Integer> frequency = Maps.newHashMap();
int maxY = editSession.getMaximumPoint().getBlockY();
for (int x = -outsetSize; x <= outsetSize; x++) {
int x0 = x + tx;
for (int y = -outsetSize; y <= outsetSize; y++) {
int y0 = y + ty;
for (int z = -outsetSize; z <= outsetSize; z++) {
if (x * x + y * y + z * z >= brushSizeSquared) {
continue;
}
int z0 = z + tz;
int highest = 1;
BaseBlock currentState = editSession.getBlock(x0, y0, z0);
BaseBlock highestState = currentState;
frequency.clear();
boolean tie = false;
for (int ox = -1; ox <= 1; ox++) {
for (int oz = -1; oz <= 1; oz++) {
for (int oy = -1; oy <= 1; oy++) {
if (oy + y0 < 0 || oy + y0 > maxY) {
continue;
}
BaseBlock state = editSession.getBlock(x0 + ox, y0 + oy, z0 + oz);
Integer count = frequency.get(state);
if (count == null) {
count = 1;
} else {
count++;
}
if (count > highest) {
highest = count;
highestState = state;
tie = false;
} else if (count == highest) {
tie = true;
}
frequency.put(state, count);
}
}
}
if (!tie && currentState != highestState) {
editSession.setBlock(x0, y0, z0, highestState);
}
}
}
}
}
}

View File

@ -1,76 +0,0 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.clipboard.ResizableClipboardBuilder;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.function.NullRegionFunction;
import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.brush.Brush;
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.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.session.ClipboardHolder;
public class CopyBrush implements Brush {
private final BrushTool tool;
private final LocalSession session;
private final Player player;
public CopyBrush(Player player, LocalSession session, BrushTool tool) {
this.tool = tool;
this.session = session;
this.player = player;
}
@Override
public void build(final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
Mask mask = tool.getMask();
if (mask == null) {
mask = Masks.alwaysTrue();
}
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
final int size2 = (int) (size * size);
final int minY = position.getBlockY();
mask = new AbstractDelegateMask(mask) {
private int visited = 0;
@Override
public boolean test(Vector vector) {
if (super.test(vector) && vector.getBlockY() >= minY) {
BaseBlock block = editSession.getLazyBlock(vector);
if (block != EditSession.nullBlock) {
if (visited++ > size2) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
}
builder.add(vector, EditSession.nullBlock, block);
return true;
}
}
return false;
}
};
// Add origin
mask.test(position);
RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction());
visitor.visit(position);
Operations.completeBlindly(visitor);
// Build the clipboard
Clipboard clipboard = builder.build();
clipboard.setOrigin(position);
ClipboardHolder holder = new ClipboardHolder(clipboard, editSession.getWorld().getWorldData());
session.setClipboard(holder);
int blocks = builder.size();
BBC.COMMAND_COPY.send(player, blocks);
}
}

View File

@ -0,0 +1,98 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.clipboard.ResizableClipboardBuilder;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.function.NullRegionFunction;
import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
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.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
public class CopyPastaBrush implements DoubleActionBrush {
private final DoubleActionBrushTool tool;
private final LocalSession session;
private final Player player;
public CopyPastaBrush(Player player, LocalSession session, DoubleActionBrushTool tool) {
this.tool = tool;
this.session = session;
this.player = player;
}
@Override
public void build(DoubleActionBrushTool.BrushAction action, final EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
switch (action) {
case SECONDARY: {
Mask mask = tool.getMask();
if (mask == null) {
mask = Masks.alwaysTrue();
}
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
final int size2 = (int) (size * size);
final int minY = position.getBlockY();
mask = new AbstractDelegateMask(mask) {
private int visited = 0;
@Override
public boolean test(Vector vector) {
if (super.test(vector) && vector.getBlockY() >= minY) {
BaseBlock block = editSession.getLazyBlock(vector);
if (block != EditSession.nullBlock) {
if (visited++ > size2) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
}
builder.add(vector, EditSession.nullBlock, block);
return true;
}
}
return false;
}
};
// Add origin
mask.test(position);
RecursiveVisitor visitor = new RecursiveVisitor(mask, new NullRegionFunction());
visitor.visit(position);
Operations.completeBlindly(visitor);
// Build the clipboard
Clipboard clipboard = builder.build();
clipboard.setOrigin(position);
ClipboardHolder holder = new ClipboardHolder(clipboard, editSession.getWorld().getWorldData());
session.setClipboard(holder);
int blocks = builder.size();
BBC.COMMAND_COPY.send(player, blocks);
return;
}
case PRIMARY: {
try {
ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion();
Vector centerOffset = region.getCenter().subtract(clipboard.getOrigin());
Operation operation = holder
.createPaste(editSession, editSession.getWorld().getWorldData())
.to(position.add(0, 1, 0))
.ignoreAirBlocks(true)
.build();
Operations.completeLegacy(operation);
} catch (EmptyClipboardException e) {
BBC.BRUSH_PASTE_NONE.send(player);
}
}
}
}
}

View File

@ -0,0 +1,10 @@
package com.boydti.fawe.object.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.pattern.Pattern;
public interface DoubleActionBrush {
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException;
}

View File

@ -0,0 +1,194 @@
package com.boydti.fawe.object.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.command.tool.DoubleActionTraceTool;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.session.request.Request;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class DoubleActionBrushTool implements DoubleActionTraceTool {
public enum BrushAction {
PRIMARY,
SECONDARY
}
protected static int MAX_RANGE = 500;
protected int range = -1;
private Mask mask = null;
private DoubleActionBrush brush = null;
@Nullable
private Pattern material;
private double size = 1;
private String permission;
/**
* Construct the tool.
*
* @param permission the permission to check before use is allowed
*/
public DoubleActionBrushTool(String permission) {
checkNotNull(permission);
this.permission = permission;
}
@Override
public boolean canUse(Actor player) {
return player.hasPermission(permission);
}
/**
* Get the filter.
*
* @return the filter
*/
public Mask getMask() {
return mask;
}
/**
* Set the block filter used for identifying blocks to replace.
*
* @param filter the filter to set
*/
public void setMask(Mask filter) {
this.mask = filter;
}
/**
* Set the brush.
*
* @param brush tbe brush
* @param permission the permission
*/
public void setBrush(DoubleActionBrush brush, String permission) {
this.brush = brush;
this.permission = permission;
}
/**
* Get the current brush.
*
* @return the current brush
*/
public DoubleActionBrush getBrush() {
return brush;
}
/**
* Set the material.
*
* @param material the material
*/
public void setFill(@Nullable Pattern material) {
this.material = material;
}
/**
* Get the material.
*
* @return the material
*/
@Nullable public Pattern getMaterial() {
return material;
}
/**
* Get the set brush size.
*
* @return a radius
*/
public double getSize() {
return size;
}
/**
* Set the set brush size.
*
* @param radius a radius
*/
public void setSize(double radius) {
this.size = radius;
}
/**
* Get the set brush range.
*
* @return the range of the brush in blocks
*/
public int getRange() {
return (range < 0) ? MAX_RANGE : Math.min(range, MAX_RANGE);
}
/**
* Set the set brush range.
*
* @param range the range of the brush in blocks
*/
public void setRange(int range) {
this.range = range;
}
public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) {
WorldVector target = null;
target = player.getBlockTrace(getRange(), true);
if (target == null) {
player.printError("No block in sight!");
return true;
}
BlockBag bag = session.getBlockBag(player);
EditSession editSession = session.createEditSession(player);
Request.request().setEditSession(editSession);
if (mask != null) {
Mask existingMask = editSession.getMask();
if (existingMask == null) {
editSession.setMask(mask);
} else if (existingMask instanceof MaskIntersection) {
((MaskIntersection) existingMask).add(mask);
} else {
MaskIntersection newMask = new MaskIntersection(existingMask);
newMask.add(mask);
editSession.setMask(newMask);
}
}
try {
brush.build(action, editSession, target, material, size);
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
if (bag != null) {
bag.flushChanges();
}
session.remember(editSession);
}
return true;
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
return act(BrushAction.PRIMARY, server, config, player, session);
}
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
return act(BrushAction.SECONDARY, server, config, player, session);
}
}

View File

@ -0,0 +1,178 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.FaweClipboard;
import com.boydti.fawe.object.clipboard.OffsetFaweClipboard;
import com.google.common.collect.Maps;
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.function.pattern.Pattern;
import java.util.Map;
public class ErodeBrush implements DoubleActionBrush {
private PseudoRandom rand = new PseudoRandom();
private static final Vector[] FACES_TO_CHECK = {new Vector(0, 0, 1), new Vector(0, 0, -1), new Vector(0, 1, 0), new Vector(0, -1, 0), new Vector(1, 0, 0), new Vector(-1, 0, 0)};
@Override
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
switch (action) {
case PRIMARY: {
int erodeFaces = this.rand.nextInt(5) + 1;
int erodeRec = this.rand.nextInt(4) + 1;
int fillFaces = (int)(this.rand.nextDouble() * this.rand.nextDouble() * 5) + 1;
int fillRec = this.rand.nextInt(3) + 1;
this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size);
break;
}
case SECONDARY: {
int erodeFaces = (int)(this.rand.nextDouble() * this.rand.nextDouble() * 5) + 1;
int erodeRec = this.rand.nextInt(3) + 1;
int fillFaces = this.rand.nextInt(5) + 1;
int fillRec = this.rand.nextInt(4) + 1;
this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size);
break;
}
}
}
protected void erosion(final EditSession es, int erodeFaces, int erodeRec, int fillFaces, int fillRec, Vector target, double size) {
int brushSize = (int) size + 1;
int brushSizeSquared = (int) size * (int) size;
int dimension = brushSize * 2 + 1;
FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension + 2, dimension + 2, dimension + 2), brushSize + 1);
FaweClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension + 2, dimension + 2, dimension + 2), brushSize + 1);
final int bx = target.getBlockX();
final int by = target.getBlockY();
final int bz = target.getBlockZ();
for (int x = -brushSize - 1; x <= brushSize + 1; x++) {
int x0 = x + bx;
for (int y = -brushSize - 1; y <= brushSize + 1; y++) {
int y0 = y + by;
for (int z = -brushSize - 1; z <= brushSize + 1; z++) {
int z0 = z + bz;
BaseBlock state = es.getBlock(x0, y0, z0);
buffer1.setBlock(x, y, z, state);
buffer2.setBlock(x, y, z, state);
}
}
}
int swap = 0;
for (int i = 0; i < erodeRec; ++i) {
erosionIteration(brushSize, brushSizeSquared, erodeFaces, swap % 2 == 0 ? buffer1 : buffer2, swap % 2 == 1 ? buffer1 : buffer2);
swap++;
}
for (int i = 0; i < fillRec; ++i) {
fillIteration(brushSize, brushSizeSquared, fillFaces, swap % 2 == 0 ? buffer1 : buffer2, swap % 2 == 1 ? buffer1 : buffer2);
swap++;
}
FaweClipboard finalBuffer = swap % 2 == 0 ? buffer1 : buffer2;
finalBuffer.forEach(new RunnableVal2<Vector, BaseBlock>() {
@Override
public void run(Vector pos, BaseBlock block) {
es.setBlock(pos.getBlockX() + bx, pos.getBlockY() + by, pos.getBlockZ() + bz, block);
}
}, true);
}
private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces, FaweClipboard current, FaweClipboard target) {
Map<BaseBlock, Integer> frequency = Maps.newHashMap();
for (int x = -brushSize; x <= brushSize; x++) {
for (int y = -brushSize; y <= brushSize; y++) {
for (int z = -brushSize; z <= brushSize; z++) {
target.setBlock(x, y, z, current.getBlock(x, y, z));
if (x * x + y * y + z * z >= brushSizeSquared) {
continue;
}
BaseBlock state = current.getBlock(x, y, z);
if (!FaweCache.isLiquidOrGas(state.getId())) {
continue;
}
int total = 0;
int highest = 1;
BaseBlock highestState = state;
frequency.clear();
for (Vector offs : FACES_TO_CHECK) {
BaseBlock next = current.getBlock(x + offs.getBlockX(), y + offs.getBlockY(), z + offs.getBlockZ());
if (FaweCache.isLiquidOrGas(next.getId())) {
continue;
}
total++;
Integer count = frequency.get(next);
if (count == null) {
count = 1;
} else {
count++;
}
if (count > highest) {
highest = count;
highestState = next;
}
frequency.put(next, count);
}
if (total > fillFaces) {
target.setBlock(x, y, z, highestState);
}
}
}
}
}
private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, FaweClipboard current, FaweClipboard target) {
Map<Integer, Integer> frequency = Maps.newHashMap();
for (int x = -brushSize; x <= brushSize; x++) {
for (int y = -brushSize; y <= brushSize; y++) {
for (int z = -brushSize; z <= brushSize; z++) {
target.setBlock(x, y, z, current.getBlock(x, y, z));
if (x * x + y * y + z * z >= brushSizeSquared) {
continue;
}
BaseBlock state = current.getBlock(x, y, z);
if (FaweCache.isLiquidOrGas(state.getId())) {
continue;
}
int total = 0;
int highest = 1;
int highestState = FaweCache.getCombined(state);
frequency.clear();
for (Vector offs : FACES_TO_CHECK) {
BaseBlock next = current.getBlock(x + offs.getBlockX(), y + offs.getBlockY(), z + offs.getBlockZ());
if (!FaweCache.isLiquidOrGas(next.getId())) {
continue;
}
total++;
Integer count = frequency.get(next.getType());
if (count == null) {
count = 1;
} else {
count++;
}
if (count > highest) {
highest = count;
int combined = FaweCache.getCombined(next);
highestState = combined;
frequency.put(combined, count);
} else {
frequency.put(FaweCache.getCombined(next), count);
}
}
if (total > erodeFaces) {
target.setBlock(x, y, z, FaweCache.CACHE_BLOCK[highestState]);
}
}
}
}
}
}

View File

@ -0,0 +1,38 @@
package com.boydti.fawe.object.brush;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.Patterns;
public class LineBrush implements DoubleActionBrush {
private final boolean shell, select, flat;
private Vector pos1;
public LineBrush(boolean shell, boolean select, boolean flat) {
this.shell = shell;
this.select = select;
this.flat = flat;
}
@Override
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
switch (action) {
case PRIMARY:
if (pos1 == null) {
editSession.debug(BBC.SELECTION_NONE);
return;
}
editSession.drawLine(Patterns.wrap(pattern), pos1, position, size, !shell, flat);
if (!select) {
return;
}
case SECONDARY:
pos1 = position;
return;
}
}
}

View File

@ -103,6 +103,8 @@ public class ScalableHeightMap {
}
public void apply(EditSession session, Mask mask, Vector pos, int size, int rotationMode, double yscale, boolean smooth) throws MaxChangedBlocksException {
Vector top = session.getMaximumPoint();
int maxY = top.getBlockY();
int diameter = 2 * size + 1;
int centerX = pos.getBlockX();
int centerZ = pos.getBlockZ();
@ -132,20 +134,19 @@ public class ScalableHeightMap {
break;
}
raise = (yscale * raise);
int random = PseudoRandom.random.random(256) < (int) ((raise - (int) raise) * 256) ? 1 : 0;
int height = session.getHighestTerrainBlock(xx, zz, 0, 255, true) + (int) raise + random;
int random = PseudoRandom.random.random(maxY + 1) < (int) ((raise - (int) raise) * (maxY + 1)) ? 1 : 0;
int height = session.getHighestTerrainBlock(xx, zz, 0, maxY, true) + (int) raise + random;
newData[index] = height;
}
}
int iterations = 1;
WorldVector min = new WorldVector(LocalWorldAdapter.adapt(session.getWorld()), pos.subtract(size, 255, size));
Vector max = pos.add(size, 255, size);
WorldVector min = new WorldVector(LocalWorldAdapter.adapt(session.getWorld()), pos.subtract(size, maxY, size));
Vector max = pos.add(size, maxY, size);
Region region = new CuboidRegion(session.getWorld(), min, max);
HeightMap heightMap = new HeightMap(session, region, true);
if (smooth) {
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1));
newData = filter.filter(newData, diameter, diameter);
// MainUtil.smoothArray(newData, diameter, 1, 4);
}
heightMap.apply(newData);
}

View File

@ -0,0 +1,83 @@
package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import java.util.List;
public class AbstractDelegateFaweClipboard extends FaweClipboard {
private final FaweClipboard parent;
public AbstractDelegateFaweClipboard(FaweClipboard parent) {
this.parent = parent;
}
@Override
public BaseBlock getBlock(int x, int y, int z) {
return parent.getBlock(x, y, z);
}
@Override
public boolean setBlock(int x, int y, int z, BaseBlock block) {
return parent.setBlock(x, y, z, block);
}
@Override
public void setId(int index, int id) {
parent.setId(index, id);
}
@Override
public void setData(int index, int data) {
parent.setData(index, data);
}
@Override
public void setAdd(int index, int id) {
parent.setAdd(index, id);
}
@Override
public boolean setTile(int x, int y, int z, CompoundTag tag) {
return parent.setTile(x, y, z, tag);
}
@Override
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
return parent.createEntity(world, x, y, z, yaw, pitch, entity);
}
@Override
public List<? extends Entity> getEntities() {
return parent.getEntities();
}
@Override
public boolean remove(ClipboardEntity clipboardEntity) {
return parent.remove(clipboardEntity);
}
@Override
public void setOrigin(Vector offset) {
parent.setOrigin(offset);
}
@Override
public void setDimensions(Vector dimensions) {
parent.setDimensions(dimensions);
}
@Override
public Vector getDimensions() {
return parent.getDimensions();
}
@Override
public void forEach(RunnableVal2<Vector, BaseBlock> task, boolean air) {
parent.forEach(task, air);
}
}

View File

@ -0,0 +1,49 @@
package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
public class OffsetFaweClipboard extends AbstractDelegateFaweClipboard {
private final int ox, oy, oz;
public OffsetFaweClipboard(FaweClipboard parent, int ox, int oy, int oz) {
super(parent);
this.ox = ox;
this.oy = oy;
this.oz = oz;
}
public OffsetFaweClipboard(FaweClipboard parent, int offset) {
this(parent, offset, offset, offset);
}
@Override
public BaseBlock getBlock(int x, int y, int z) {
return super.getBlock(x + ox, y + oy, z + oz);
}
@Override
public boolean setBlock(int x, int y, int z, BaseBlock block) {
return super.setBlock(ox + x, oy + y, oz + z, block);
}
@Override
public boolean setTile(int x, int y, int z, CompoundTag tag) {
return super.setTile(ox + x, oy + y, oz + z, tag);
}
@Override
public void forEach(final RunnableVal2<Vector, BaseBlock> task, boolean air) {
super.forEach(new RunnableVal2<Vector, BaseBlock>() {
@Override
public void run(Vector value, BaseBlock block) {
value.x -= ox;
value.y -= oy;
value.z -= oz;
task.run(value, block);
}
}, air);
}
}

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.regions.general.plot;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweQueue;
@ -16,11 +17,15 @@ import java.util.List;
public class FaweLocalBlockQueue extends LocalBlockQueue {
private FaweQueue IMP;
public final FaweQueue IMP;
public FaweLocalBlockQueue(String world) {
super(world);
IMP = SetQueue.IMP.getNewQueue(FaweAPI.getWorld(world), true, false);
}
public FaweLocalBlockQueue(World world) {
super(Fawe.imp().getWorldName(world));
IMP = SetQueue.IMP.getNewQueue(world, true, false);
}
@ -78,7 +83,7 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
public boolean setBiome(int x, int z, String biome) {
if (!StringMan.isEqual(biome, lastBiome)) {
if (reg == null) {
World weWorld = FaweAPI.getWorld(IMP.getWorldName());
World weWorld = IMP.getWEWorld();
reg = weWorld.getWorldData().getBiomeRegistry();
}
List<BaseBiome> biomes = reg.getBiomes();

View File

@ -44,7 +44,7 @@ public class FaweSchematicHandler extends SchematicHandler {
queue.setTile(x, y, z, compoundTag);
return true;
}
FaweQueue faweQueue = SetQueue.IMP.getNewQueue(queue.getWorld(), true, false);
FaweQueue faweQueue = SetQueue.IMP.getNewQueue(((FaweLocalBlockQueue) queue).IMP.getWEWorld(), true, false);
faweQueue.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(compoundTag));
faweQueue.flush();
return false;

View File

@ -17,7 +17,7 @@ public class DelegateFaweQueue extends FaweQueue {
private FaweQueue parent;
public DelegateFaweQueue(FaweQueue parent) {
super(parent.getWorldName());
super(parent.getWEWorld());
this.parent = parent;
}

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
@ -172,7 +173,7 @@ public class SetQueue {
return inactiveQueues;
}
public FaweQueue getNewQueue(String world, boolean fast, boolean autoqueue) {
public FaweQueue getNewQueue(World world, boolean fast, boolean autoqueue) {
FaweQueue queue = Fawe.imp().getNewQueue(world, fast);
if (autoqueue) {
inactiveQueues.add(queue);

View File

@ -169,6 +169,8 @@ public class EditSession implements Extent {
private Vector mutable = new Vector();
private final int maxY;
public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7");
public static final BaseBiome nullBiome = new BaseBiome(0);
public static final BaseBlock nullBlock = FaweCache.CACHE_BLOCK[0];
@ -253,7 +255,7 @@ public class EditSession implements Extent {
if (world instanceof MCAWorld) {
queue = ((MCAWorld) world).getQueue();
} else {
queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), fastmode, autoQueue);
queue = SetQueue.IMP.getNewQueue(world, fastmode, autoQueue);
}
} else if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
queue = new MCAQueue(queue);
@ -281,6 +283,7 @@ public class EditSession implements Extent {
}
}
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
this.maxY = this.world == null ? 255 : world.getMaxY();
}
/**
@ -709,9 +712,13 @@ public class EditSession implements Extent {
return extent.getLazyBlock(x, y, z);
}
public BaseBlock getBlock(int x, int y, int z) {
return extent.getLazyBlock(x, y, z);
}
@Override
public BaseBlock getBlock(final Vector position) {
if (position.y > 255 || position.y < 0) {
if (position.y > maxY || position.y < 0) {
return nullBlock;
}
return getLazyBlock((int) position.x, (int) position.y, (int) position.z);
@ -1887,8 +1894,8 @@ public class EditSession implements Extent {
if (pos.getBlockY() < 0) {
pos = pos.setY(0);
} else if (((pos.getBlockY() + height) - 1) > 255) {
height = (255 - pos.getBlockY()) + 1;
} else if (((pos.getBlockY() + height) - 1) > maxY) {
height = (maxY - pos.getBlockY()) + 1;
}
final double invRadiusX = 1 / radiusX;
@ -2074,7 +2081,7 @@ public class EditSession implements Extent {
if (dx2 + dz2 > radiusSq) {
continue;
}
for (int y = 255; y >= 1; --y) {
for (int y = maxY; y >= 1; --y) {
final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z));
switch (id) {
case BlockID.ICE:
@ -2126,7 +2133,7 @@ public class EditSession implements Extent {
if (dx2 + dz2 > radiusSq) {
continue;
}
for (int y = 255; y >= 1; --y) {
for (int y = maxY; y >= 1; --y) {
final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z));
if (id == BlockID.AIR) {
continue;
@ -2143,7 +2150,7 @@ public class EditSession implements Extent {
}
// Too high?
if (y == 255) {
if (y == maxY) {
break;
}
@ -2200,7 +2207,7 @@ public class EditSession implements Extent {
if (dx2 + dz2 > radiusSq) {
continue;
}
loop: for (int y = 255; y >= 1; --y) {
loop: for (int y = maxY; y >= 1; --y) {
BaseBlock block = getLazyBlock(x, y, z);
final int id = block.getId();
final int data = block.getData();
@ -2544,6 +2551,10 @@ public class EditSession implements Extent {
return changes;
}
public int drawLine(final Pattern pattern, final Vector pos1, final Vector pos2, final double radius, final boolean filled) throws MaxChangedBlocksException {
return drawLine(pattern, pos1, pos2, radius, filled, false);
}
/**
* Draws a line (out of blocks) between two vectors.
*
@ -2556,7 +2567,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drawLine(final Pattern pattern, final Vector pos1, final Vector pos2, final double radius, final boolean filled) throws MaxChangedBlocksException {
public int drawLine(final Pattern pattern, final Vector pos1, final Vector pos2, final double radius, final boolean filled, boolean flat) throws MaxChangedBlocksException {
Set<Vector> vset = new HashSet<Vector>();
boolean notdrawn = true;
@ -2576,7 +2587,6 @@ public class EditSession implements Extent {
tipx = x1 + (domstep * ((x2 - x1) > 0 ? 1 : -1));
tipy = (int) Math.round(y1 + (((domstep * ((double) dy)) / (dx)) * ((y2 - y1) > 0 ? 1 : -1)));
tipz = (int) Math.round(z1 + (((domstep * ((double) dz)) / (dx)) * ((z2 - z1) > 0 ? 1 : -1)));
vset.add(new Vector(tipx, tipy, tipz));
}
notdrawn = false;
@ -2598,14 +2608,19 @@ public class EditSession implements Extent {
tipz = z1 + (domstep * ((z2 - z1) > 0 ? 1 : -1));
tipy = (int) Math.round(y1 + (((domstep * ((double) dy)) / (dz)) * ((y2 - y1) > 0 ? 1 : -1)));
tipx = (int) Math.round(x1 + (((domstep * ((double) dx)) / (dz)) * ((x2 - x1) > 0 ? 1 : -1)));
vset.add(new Vector(tipx, tipy, tipz));
}
}
vset = this.getBallooned(vset, radius);
if (!filled) {
vset = this.getHollowed(vset);
if (flat) {
vset = this.getStretched(vset, radius);
if (!filled) {
vset = this.getOutline(vset);
}
} else {
vset = this.getBallooned(vset, radius);
if (!filled) {
vset = this.getHollowed(vset);
}
}
return this.setBlocks(vset, pattern);
}
@ -2673,7 +2688,6 @@ public class EditSession implements Extent {
for (final Vector v : vset) {
final int tipx = v.getBlockX(), tipy = v.getBlockY(), tipz = v.getBlockZ();
for (int loopx = tipx - ceilrad; loopx <= (tipx + ceilrad); loopx++) {
for (int loopy = tipy - ceilrad; loopy <= (tipy + ceilrad); loopy++) {
for (int loopz = tipz - ceilrad; loopz <= (tipz + ceilrad); loopz++) {
@ -2687,6 +2701,35 @@ public class EditSession implements Extent {
return returnset;
}
private Set<Vector> getStretched(final Set<Vector> vset, final double radius) {
final Set<Vector> returnset = new HashSet<Vector>();
final int ceilrad = (int) Math.ceil(radius);
for (final Vector v : vset) {
final int tipx = v.getBlockX(), tipy = v.getBlockY(), tipz = v.getBlockZ();
for (int loopx = tipx - ceilrad; loopx <= (tipx + ceilrad); loopx++) {
for (int loopz = tipz - ceilrad; loopz <= (tipz + ceilrad); loopz++) {
if (this.hypot(loopx - tipx, 0, loopz - tipz) <= radius) {
returnset.add(new Vector(loopx, v.getY(), loopz));
}
}
}
}
return returnset;
}
private Set<Vector> getOutline(final Set<Vector> vset) {
final Set<Vector> returnset = new HashSet<Vector>();
for (final Vector v : vset) {
final double x = v.getX(), y = v.getY(), z = v.getZ();
if (!(vset.contains(new Vector(x + 1, y, z))
&& vset.contains(new Vector(x - 1, y, z))
&& vset.contains(new Vector(x, y, z + 1)) && vset.contains(new Vector(x, y, z - 1)))) {
returnset.add(v);
}
}
return returnset;
}
private Set<Vector> getHollowed(final Set<Vector> vset) {
final Set<Vector> returnset = new HashSet<Vector>();
for (final Vector v : vset) {

View File

@ -25,6 +25,7 @@ import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.brush.DoubleActionBrushTool;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
@ -935,6 +936,26 @@ public class LocalSession {
return (BrushTool) tool;
}
/**
* Get the brush tool assigned to the item. If there is no tool assigned
* or the tool is not assigned, the slot will be replaced with the
* brush tool.
*
* @param item the item type ID
* @return the tool, or {@code null}
* @throws InvalidToolBindException if the item can't be bound to that item
*/
public DoubleActionBrushTool getDoubleActionBrushTool(int item) throws InvalidToolBindException {
Tool tool = getTool(item);
if (tool == null || !(tool instanceof DoubleActionBrushTool)) {
tool = new DoubleActionBrushTool("worldedit.brush.sphere");
setTool(item, tool);
}
return (DoubleActionBrushTool) tool;
}
/**
* Set the tool.
*

View File

@ -25,8 +25,12 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.brush.CommandBrush;
import com.boydti.fawe.object.brush.CopyBrush;
import com.boydti.fawe.object.brush.CopyPastaBrush;
import com.boydti.fawe.object.brush.HeightBrush;
import com.boydti.fawe.object.brush.BlendBall;
import com.boydti.fawe.object.brush.DoubleActionBrushTool;
import com.boydti.fawe.object.brush.ErodeBrush;
import com.boydti.fawe.object.brush.LineBrush;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
@ -79,6 +83,63 @@ public class BrushCommands {
this.worldEdit = worldEdit;
}
@Command(
aliases = { "blendball", "bb" },
usage = "[radius]",
desc = "Choose the blend ball brush",
help = "Chooses the blend ball brush",
min = 0,
max = 1
)
@CommandPermissions("worldedit.brush.blendball")
public void blendBallBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand());
tool.setSize(radius);
tool.setBrush(new BlendBall(), "worldedit.brush.blendball");
BBC.BRUSH_SPHERE.send(player, radius);
}
@Command(
aliases = { "erode", "e" },
usage = "[radius]",
desc = "Choose the erode brush",
help = "Chooses the erode brush",
min = 0,
max = 1
)
@CommandPermissions("worldedit.brush.erode")
public void erodeBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
tool.setSize(radius);
tool.setBrush(new ErodeBrush(), "worldedit.brush.erode");
BBC.BRUSH_SPHERE.send(player, radius);
}
@Command(
aliases = { "line", "l" },
usage = "<pattern> [radius]",
flags = "hsf",
desc = "Choose the line brush",
help =
"Chooses the line brush.\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",
min = 1,
max = 2
)
@CommandPermissions("worldedit.brush.line")
public void lineBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, @Switch('f') boolean flat) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
tool.setFill(fill);
tool.setSize(radius);
tool.setBrush(new LineBrush(shell, select, flat), "worldedit.brush.line");
BBC.BRUSH_SPHERE.send(player, radius);
}
@Command(
aliases = { "sphere", "s" },
usage = "<pattern> [radius]",
@ -258,20 +319,21 @@ public class BrushCommands {
}
@Command(
aliases = { "copy" },
aliases = { "copypaste", "copy", "paste", "cp", "copypasta" },
usage = "[depth]",
desc = "Copy brush",
desc = "Copy Paste brush",
help =
"Right click the base of an object to copy.\n",
"Left click the base of an object to copy.\n" +
"Right click to paste",
min = 0,
max = 1
)
@CommandPermissions("worldedit.brush.copy")
public void copy(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand());
DoubleActionBrushTool tool = session.getDoubleActionBrushTool(player.getItemInHand());
tool.setSize(radius);
tool.setBrush(new CopyBrush(player, session, tool), "worldedit.brush.copy");
tool.setBrush(new CopyPastaBrush(player, session, tool), "worldedit.brush.copy");
BBC.BRUSH_COPY.send(player, radius);
}

View File

@ -145,7 +145,7 @@ public class RegionCommands {
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getLocation().world, true, false);
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getWorld(), true, false);
for (Vector pt : region) {
queue.setBlockLight((byte) pt.x, (byte) pt.y, (byte) pt.z, value);
}
@ -169,7 +169,7 @@ public class RegionCommands {
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getLocation().world, true, false);
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getWorld(), true, false);
for (Vector pt : region) {
queue.setSkyLight((byte) pt.x, (byte) pt.y, (byte) pt.z, value);
}

View File

@ -0,0 +1,61 @@
package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Utility methods related to {@link Pattern}s.
*/
public final class Patterns {
private Patterns() {
}
/**
* Wrap an old-style pattern and return a new pattern.
*
* @param pattern the pattern
* @return a new-style pattern
*/
public static Pattern wrap(final com.sk89q.worldedit.patterns.Pattern pattern) {
checkNotNull(pattern);
return new Pattern() {
@Override
public BaseBlock apply(Vector position) {
return pattern.next(position);
}
};
}
/**
* Wrap a new-style pattern and return an old-style pattern.
*
* @param pattern the pattern
* @return an old-style pattern
*/
public static com.sk89q.worldedit.patterns.Pattern wrap(final Pattern pattern) {
checkNotNull(pattern);
return new com.sk89q.worldedit.patterns.Pattern() {
private Vector mutable = new Vector(0, 0, 0);
@Override
public BaseBlock next(Vector position) {
return pattern.apply(position);
}
@Override
public BaseBlock next(int x, int y, int z) {
mutable.x = x;
mutable.y = y;
mutable.z = z;
return next(mutable);
}
};
}
public static Class<?> inject() {
return Patterns.class;
}
}

View File

@ -60,7 +60,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
private static Method methodFromNative;
private static Method methodToNative;
public ForgeQueue_All(String world) {
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
if (methodFromNative == null) {
try {

View File

@ -55,7 +55,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
private static Method methodFromNative;
private static Method methodToNative;
public ForgeQueue_All(String world) {
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
if (methodFromNative == null) {
try {

View File

@ -53,7 +53,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
private static Method methodFromNative;
private static Method methodToNative;
public ForgeQueue_All(String world) {
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
if (methodFromNative == null) {
try {

View File

@ -60,7 +60,7 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
private static Method methodFromNative;
private static Method methodToNative;
public ForgeQueue_All(String world) {
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
if (methodFromNative == null) {
try {

View File

@ -50,7 +50,6 @@ public class NukkitRegistryDumper {
if (item != null && item.getBlock() != null && !visited.contains(item.getBlock().getName())) {
Block block = item.getBlock();
visited.add(block.getName());
System.out.println("BLOCK " + block.getName());
list.add(getProperties(block));
}

View File

@ -117,7 +117,7 @@ public class FaweNukkit implements IFawe, Listener {
}
@Override
public FaweQueue getNewQueue(String world, boolean fast) {
public FaweQueue getNewQueue(World world, boolean fast) {
return new NukkitQueue(this, world);
}

View File

@ -17,6 +17,7 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.World;
import java.io.File;
import java.util.Collection;
import java.util.Map;
@ -31,10 +32,10 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
public static double TPS_TARGET = 18.5;
private static int LIGHT_MASK = 0x739C0;
public NukkitQueue(FaweNukkit fn, String world) {
public NukkitQueue(FaweNukkit fn, World world) {
super(world);
this.faweNukkit = fn;
this.world = faweNukkit.getPlugin().getServer().getLevelByName(world);
this.world = faweNukkit.getPlugin().getServer().getLevelByName(getWorldName());
if (Settings.QUEUE.EXTRA_TIME_MS != Integer.MIN_VALUE) {
ALLOCATE = Settings.QUEUE.EXTRA_TIME_MS;
Settings.QUEUE.EXTRA_TIME_MS = Integer.MIN_VALUE;